#include "logicdatasnapshot.h"
using namespace boost;
+using namespace std;
LogicData::LogicData(const sr_datafeed_meta_logic &meta) :
SignalData(meta.samplerate),
{
_snapshots.push(snapshot);
}
+
+queue< shared_ptr<LogicDataSnapshot> >& LogicData::get_snapshots()
+{
+ return _snapshots;
+}
#include "signaldata.h"
+#include <boost/shared_ptr.hpp>
+#include <queue>
+
extern "C" {
#include <libsigrok/libsigrok.h>
}
void push_snapshot(
boost::shared_ptr<LogicDataSnapshot> &snapshot);
+ std::queue< boost::shared_ptr<LogicDataSnapshot> >&
+ get_snapshots();
+
private:
const int _num_probes;
+ std::queue< boost::shared_ptr<LogicDataSnapshot> >
+ _snapshots;
};
#include <assert.h>
-#include <QDebug>
+using namespace std;
LogicDataSnapshot::LogicDataSnapshot(
const sr_datafeed_logic &logic) :
{
assert(_unit_size == logic.unitsize);
- qDebug() << "SR_DF_LOGIC (length =" << logic.length
- << ", unitsize = " << logic.unitsize << ")";
-
append_data(logic.data, logic.length);
}
+
+uint64_t LogicDataSnapshot::get_sample(uint64_t index) const
+{
+ assert(_data);
+ assert(index >= 0 && index < _data_length);
+
+ return *(uint64_t*)((uint8_t*)_data + index * _unit_size);
+}
+
+void LogicDataSnapshot::get_subsampled_edges(
+ std::vector<EdgePair> &edges,
+ int64_t start, int64_t end,
+ int64_t quantization_length, int sig_index)
+{
+ assert(start >= 0);
+ assert(end < get_sample_count());
+ assert(start <= end);
+ assert(quantization_length > 0);
+ assert(sig_index >= 0);
+ assert(sig_index < SR_MAX_NUM_PROBES);
+
+ const uint64_t sig_mask = 1 << sig_index;
+
+ // Add the initial state
+ bool last_sample = get_sample(start) & sig_mask;
+ edges.push_back(pair<int64_t, bool>(start, last_sample));
+
+ for(int64_t i = start + 1; i < end - 1; i++)
+ {
+ const bool sample = get_sample(i) & sig_mask;
+
+ // Check if we hit an edge
+ if(sample != last_sample)
+ {
+ // Take the last sample of the quanization block
+ const int64_t final_index =
+ min((i - (i % quantization_length) +
+ quantization_length - 1), end);
+
+ // Store the final state
+ const bool final_sample = get_sample(final_index) & sig_mask;
+ edges.push_back(pair<int64_t, bool>(
+ final_index, final_sample));
+
+ // Continue to sampling
+ i = final_index;
+ last_sample = final_sample;
+ }
+ }
+
+ // Add the final state
+ edges.push_back(pair<int64_t, bool>(end - 1,
+ get_sample(end - 1) & sig_mask));
+}
#include "datasnapshot.h"
+#include <utility>
+#include <vector>
+
class LogicDataSnapshot : public DataSnapshot
{
+public:
+ typedef std::pair<int64_t, bool> EdgePair;
+
public:
LogicDataSnapshot(const sr_datafeed_logic &logic);
void append_payload(const sr_datafeed_logic &logic);
+
+ uint64_t get_sample(uint64_t index) const;
+
+ /**
+ * Parses a logic data snapshot to generate a list of transitions
+ * in a time interval to a given level of detail.
+ * @param[out] edges The vector to place the edges into.
+ * @param[in] start The start sample index.
+ * @param[in] end The end sample index.
+ * @param[in] quantization_length The minimum period of time that
+ * can be resolved at this level of detail.
+ * @param[in] sig_index The index of the signal.
+ **/
+ void get_subsampled_edges(std::vector<EdgePair> &edges,
+ int64_t start, int64_t end,
+ int64_t quantization_length, int sig_index);
};
#include <GL/gl.h>
#include <GL/glext.h>
+#include "logicdata.h"
+#include "logicdatasnapshot.h"
#include "logicsignal.h"
-struct LogicVertex
-{
- GLfloat x, y;
-};
+using namespace boost;
+using namespace std;
-LogicSignal::LogicSignal(QString name, boost::shared_ptr<SignalData> data,
+LogicSignal::LogicSignal(QString name, shared_ptr<LogicData> data,
int probe_index) :
- Signal(name, data),
+ Signal(name),
+ _data(data),
_probe_index(probe_index)
{
assert(_probe_index >= 0);
void LogicSignal::paint(QGLWidget &widget, const QRect &rect,
uint64_t scale, int64_t offset)
{
- GLuint vbo_id;
+ Point2F *vertex;
+
+ vector< pair<int64_t, bool> > edges;
+
+ assert(_data);
+
+ const queue< shared_ptr<LogicDataSnapshot> > &snapshots =
+ _data->get_snapshots();
+ if(snapshots.empty())
+ return;
+
+ const shared_ptr<LogicDataSnapshot> &snapshot = snapshots.front();
+
+ const int64_t start = 0;
+ const int64_t end = 8000;
+ const int64_t quantization_length = 4;
+
+ snapshot->get_subsampled_edges(edges, start, end,
+ quantization_length, _probe_index);
+
+ // Paint the edges
+ const unsigned int edge_point_count = (edges.size() - 2) * 2;
+ Point2F *const edge_points = new Point2F[edge_point_count];
+ vertex = edge_points;
+
+ for(vector<LogicDataSnapshot::EdgePair>::const_iterator i = edges.begin() + 1;
+ i != edges.end() - 1; i++)
+ {
+ const int x = edge.first / quantization_length +
+ rect.left();
+
+ vertex->x = x, vertex->y = 10 + rect.top() - 1;
+ vertex++;
+ vertex->x = x, vertex->y = 40 + rect.top();
+ vertex++;
+ }
glColor3f(0,0,1);
- LogicVertex vetices[3];
- vetices[0].x = rect.left();
- vetices[0].y = rect.top();
- vetices[1].x = rect.right();
- vetices[1].y = rect.bottom();
- vetices[2].x = rect.right();
- vetices[2].y = rect.top();
+ paint_lines(edge_points, edge_point_count);
+ delete[] edge_points;
+
+ // Paint the caps
+ const unsigned int cap_point_count = (edges.size() - 1) * 2;
+ Point2F *const cap_points = new Point2F[cap_point_count];
+ vertex = cap_points;
+
+ for(vector<LogicDataSnapshot::EdgePair>::const_iterator i = edges.begin();
+ i != (edges.end() - 1); i++)
+ {
+ const int y = ((*i).second ? 10 : 40) + rect.top();
+
+ vertex->x = (*i).first / quantization_length +
+ rect.left() - 1;
+ vertex->y = y;
+ vertex++;
+
+ vertex->x = (*(i+1)).first / quantization_length +
+ rect.left();
+ vertex->y = y;
+ vertex++;
+ }
+
+ glColor3f(0,0,1);
+ paint_lines(cap_points, cap_point_count);
+ delete[] cap_points;
+}
+
+void LogicSignal::paint_lines(Point2F *points, int count)
+{
+ GLuint vbo_id;
+
+ assert(points);
glGenBuffers(1, &vbo_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vetices), NULL, GL_STATIC_DRAW);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vetices), vetices);
+ const unsigned int vbo_length = count * sizeof(Point2F);
+ glBufferData(GL_ARRAY_BUFFER, vbo_length, NULL, GL_STATIC_DRAW);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, vbo_length, points);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
- glVertexPointer(2, GL_FLOAT, sizeof(LogicVertex), 0);
+ glVertexPointer(2, GL_FLOAT, sizeof(Point2F), 0);
glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(GL_LINE_STRIP, 0, 2);
+ glDrawArrays(GL_LINES, 0, count);
glDisableClientState(GL_VERTEX_ARRAY);
+
+ glDeleteBuffers(1, &vbo_id);
}
class LogicSignal : public Signal
{
+private:
+ struct Point2F
+ {
+ GLfloat x, y;
+ };
+
public:
- LogicSignal(QString name, boost::shared_ptr<SignalData> data,
+ LogicSignal(QString name,
+ boost::shared_ptr<LogicData> data,
int probe_index);
/**
void paint(QGLWidget &widget, const QRect &rect, uint64_t scale,
int64_t offset);
+private:
+ static void paint_lines(Point2F *points, int count);
+
private:
int _probe_index;
+ boost::shared_ptr<LogicData> _data;
};
#include <memory.h>
-Signal::Signal(QString name, boost::shared_ptr<SignalData> data) :
- _name(name),
- _data(data)
+Signal::Signal(QString name) :
+ _name(name)
{
}
class Signal
{
protected:
- Signal(QString name, boost::shared_ptr<SignalData> data);
+ Signal(QString name);
public:
QString get_name() const;
protected:
QString _name;
- boost::shared_ptr<SignalData> _data;
};
#include "signaldata.h"
+using namespace std;
+
SignalData::SignalData(uint64_t samplerate) :
- _samplerate(samplerate)
+ _samplerate(samplerate),
+ _start_time(0)
{
}
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <boost/shared_ptr.hpp>
-#include <queue>
#include <stdint.h>
-class DataSnapshot;
-
class SignalData
{
public:
protected:
const uint64_t _samplerate;
-
- std::queue< boost::shared_ptr<DataSnapshot> > _snapshots;
+ const int64_t _start_time;
};