File indexing completed on 2024-04-28 13:39:42

0001 /***************************************************************************
0002  *   Copyright (C) 2005 by David Saxton                                    *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "oscilloscopedata.h"
0012 #include "oscilloscope.h"
0013 
0014 using namespace std;
0015 
0016 // BEGIN class ProbeData
0017 ProbeData::ProbeData(int id)
0018     : m_id(id)
0019     , m_drawPosition(0.5)
0020     , m_resetTime(Simulator::self()->time())
0021     , m_color(Qt::black)
0022 {
0023 }
0024 
0025 ProbeData::~ProbeData()
0026 {
0027     unregisterProbe(m_id);
0028 }
0029 
0030 void ProbeData::setColor(QColor color)
0031 {
0032     m_color = color;
0033     emit displayAttributeChanged();
0034 }
0035 // END class ProbeData
0036 
0037 // BEGIN class LogicProbeData
0038 LogicProbeData::LogicProbeData(int id)
0039     : ProbeData(id)
0040 {
0041     m_data = new vector<LogicDataPoint>;
0042 }
0043 
0044 void LogicProbeData::addDataPoint(LogicDataPoint data)
0045 {
0046     if (m_data->size() < MAX_PROBE_DATA_SIZE) {
0047         m_data->push_back(data);
0048     }
0049 }
0050 
0051 void LogicProbeData::eraseData()
0052 {
0053     bool lastValue = false;
0054     bool hasLastValue = false;
0055 
0056     if (!m_data->empty()) {
0057         lastValue = m_data->back().value;
0058         hasLastValue = true;
0059     }
0060 
0061     delete m_data;
0062     m_data = new vector<LogicDataPoint>;
0063 
0064     m_resetTime = Simulator::self()->time();
0065 
0066     if (hasLastValue)
0067         addDataPoint(LogicDataPoint(lastValue, m_resetTime));
0068 }
0069 
0070 uint64_t LogicProbeData::findPos(uint64_t time) const
0071 {
0072     unsigned int pos = m_data->size();
0073     if (!time || !pos)
0074         return 0;
0075 
0076     // binary search
0077 
0078     // TODO: test and debug this code.
0079     unsigned int top = pos;
0080     pos >>= 1;
0081     unsigned int bottom = 0;
0082 
0083     do {
0084         uint64_t datatime = (*m_data)[pos].time;
0085         if (datatime == time)
0086             return pos;
0087 
0088         if (datatime >= time) {
0089             top = pos;
0090             pos -= (top - bottom) >> 1;
0091         } else {
0092             bottom = pos;
0093             pos += (top - bottom) >> 1;
0094         }
0095         // try to avoid infinite loop when top-bottom==1
0096         if (top - bottom == 1) {
0097             if (datatime >= time)
0098                 bottom = top;
0099             else
0100                 top = bottom;
0101         }
0102 
0103     } while (top != bottom && pos != bottom);
0104 
0105     return pos;
0106 }
0107 // END class LogicProbeData
0108 
0109 // BEGIN class FloatingProbeData
0110 FloatingProbeData::FloatingProbeData(int id)
0111     : ProbeData(id)
0112 {
0113     m_data = new vector<float>;
0114     m_scaling = Linear;
0115     m_upperAbsValue = 10.0;
0116     m_lowerAbsValue = 0.1;
0117 }
0118 
0119 void FloatingProbeData::addDataPoint(float data)
0120 {
0121     if (m_data->size() < MAX_PROBE_DATA_SIZE) {
0122         m_data->push_back(data);
0123     }
0124 }
0125 
0126 void FloatingProbeData::eraseData()
0127 {
0128     delete m_data;
0129     m_data = new vector<float>;
0130 
0131     m_resetTime = Simulator::self()->time();
0132 }
0133 
0134 uint64_t FloatingProbeData::findPos(uint64_t time) const
0135 {
0136     if (time <= 0 || uint64_t(time) <= m_resetTime)
0137         return 0;
0138 
0139     uint64_t at = uint64_t((time - m_resetTime) * double(LINEAR_UPDATE_RATE) / double(LOGIC_UPDATE_RATE));
0140 
0141     if (m_data->size() <= at) { // index is out of bound
0142         if (at > 0) {
0143             --at;
0144         }
0145     }
0146 
0147     return at;
0148 }
0149 
0150 uint64_t FloatingProbeData::toTime(uint64_t at) const
0151 {
0152     return uint64_t(m_resetTime + (at * LOGIC_UPDATE_RATE * LINEAR_UPDATE_PERIOD));
0153 }
0154 
0155 void FloatingProbeData::setScaling(Scaling scaling)
0156 {
0157     if (m_scaling == scaling)
0158         return;
0159 
0160     m_scaling = scaling;
0161     emit displayAttributeChanged();
0162 }
0163 
0164 void FloatingProbeData::setUpperAbsValue(double upperAbsValue)
0165 {
0166     if (m_upperAbsValue == upperAbsValue)
0167         return;
0168 
0169     m_upperAbsValue = upperAbsValue;
0170     emit displayAttributeChanged();
0171 }
0172 
0173 void FloatingProbeData::setLowerAbsValue(double lowerAbsValue)
0174 {
0175     if (m_lowerAbsValue == lowerAbsValue)
0176         return;
0177 
0178     m_lowerAbsValue = lowerAbsValue;
0179     emit displayAttributeChanged();
0180 }
0181 // END class FloatingProbeData
0182 
0183 #include "moc_oscilloscopedata.cpp"