From: Joel Holdsworth Date: Fri, 12 Oct 2012 21:41:01 +0000 (+0100) Subject: Moved all classes into the pv namespace X-Git-Tag: pulseview-0.1.0~271 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=51e77110d4316fd0106f8306f5e1f0523c5bf7d7;p=pulseview.git Moved all classes into the pv namespace --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cebe79c..3741e2a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,17 +39,17 @@ find_package(Boost 1.46 COMPONENTS unit_test_framework REQUIRED) set(VERSION 0.1.0) set(pulseview_SOURCES - about.cpp - datasnapshot.cpp - logicdata.cpp - logicdatasnapshot.cpp - logicsignal.cpp main.cpp - mainwindow.cpp - samplingbar.cpp - signaldata.cpp - sigsession.cpp - signal.cpp + pv/about.cpp + pv/datasnapshot.cpp + pv/logicdata.cpp + pv/logicdatasnapshot.cpp + pv/logicsignal.cpp + pv/mainwindow.cpp + pv/samplingbar.cpp + pv/signaldata.cpp + pv/sigsession.cpp + pv/signal.cpp pv/view/header.cpp pv/view/ruler.cpp pv/view/view.cpp @@ -57,10 +57,10 @@ set(pulseview_SOURCES ) set(pulseview_HEADERS - about.h - mainwindow.h - samplingbar.h - sigsession.h + pv/about.h + pv/mainwindow.h + pv/samplingbar.h + pv/sigsession.h pv/view/header.h pv/view/ruler.h pv/view/view.h @@ -68,7 +68,7 @@ set(pulseview_HEADERS ) set(pulseview_FORMS - about.ui + pv/about.ui ) set(pulseview_RESOURCES @@ -76,10 +76,10 @@ set(pulseview_RESOURCES ) set(pulseview_TEST_SOURCES + pv/datasnapshot.cpp + pv/logicdatasnapshot.cpp test/logicdatasnapshot.cpp test/test.cpp - datasnapshot.cpp - logicdatasnapshot.cpp ) qt4_wrap_cpp(pulseview_HEADERS_MOC ${pulseview_HEADERS}) @@ -95,12 +95,14 @@ add_definitions(-DAPP_VERSION="${VERSION}") if(WIN32) include_directories( ${include_directories} + ${CMAKE_CURRENT_BINARY_DIR} ${Boost_INCLUDE_DIRS} ${PKGDEPS_STATIC_INCLUDE_DIRS} ) else(WIN32) include_directories( ${include_directories} + ${CMAKE_CURRENT_BINARY_DIR} ${Boost_INCLUDE_DIRS} ${PKGDEPS_INCLUDE_DIRS} ) diff --git a/about.cpp b/about.cpp deleted file mode 100644 index 05516541..00000000 --- a/about.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -extern "C" { -#include -} - -#include - -#include "about.h" -#include "ui_about.h" - -extern "C" { -/* __STDC_FORMAT_MACROS is required for PRIu64 and friends (in C++). */ -#define __STDC_FORMAT_MACROS -#include -#include -} - -About::About(QWidget *parent) : - QDialog(parent), - ui(new Ui::About) -{ - GSList *l; - struct sr_dev_driver **drivers; - struct sr_input_format **inputs; - struct sr_output_format **outputs; - struct srd_decoder *dec; - QString s; - - ui->setupUi(this); - - /* Setup the version field */ - ui->versionInfo->setText(tr("%1 %2
%3
%4") - .arg(QApplication::applicationName()) - .arg(QApplication::applicationVersion()) - .arg(tr("GNU GPL, version 2 or later")) - .arg(QApplication::organizationDomain())); - - s.append(""); - - /* Set up the supported field */ - s.append(""); - drivers = sr_driver_list(); - for (int i = 0; drivers[i]; ++i) { - s.append(QString("") - .arg(QString(drivers[i]->name)) - .arg(QString(drivers[i]->longname))); - } - - s.append(""); - inputs = sr_input_list(); - for (int i = 0; inputs[i]; ++i) { - s.append(QString("") - .arg(QString(inputs[i]->id)) - .arg(QString(inputs[i]->description))); - } - - s.append(""); - outputs = sr_output_list(); - for (int i = 0; outputs[i]; ++i) { - s.append(QString("") - .arg(QString(outputs[i]->id)) - .arg(QString(outputs[i]->description))); - } - - s.append(""); - for (l = srd_decoder_list(); l; l = l->next) { - dec = (struct srd_decoder *)l->data; - s.append(QString("") - .arg(QString(dec->id)) - .arg(QString(dec->longname))); - } - - s.append("
" + - tr("Supported hardware drivers:") + - "
%1%2
" + - tr("Supported input formats:") + - "
%1%2
" + - tr("Supported output formats:") + - "
%1%2
" + - tr("Supported protocol decoders:") + - "
%1%2
"); - - supportedDoc.reset(new QTextDocument(this)); - supportedDoc->setHtml(s); - ui->supportList->setDocument(supportedDoc.get()); -} - -About::~About() -{ - delete ui; -} diff --git a/about.h b/about.h deleted file mode 100644 index 76c50653..00000000 --- a/about.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef ABOUT_H -#define ABOUT_H - -#include - -#include - -class QTextDocument; - -namespace Ui { -class About; -} - -class About : public QDialog -{ - Q_OBJECT - -public: - explicit About(QWidget *parent = 0); - ~About(); - -private: - Ui::About *ui; - std::auto_ptr supportedDoc; -}; - -#endif // ABOUT_H diff --git a/about.ui b/about.ui deleted file mode 100644 index 10163f9a..00000000 --- a/about.ui +++ /dev/null @@ -1,96 +0,0 @@ - - - About - - - Qt::WindowModal - - - - 0 - 0 - 600 - 400 - - - - About - - - - - - - - - - - - - - :/icons/sigrok-logo-notext.png - - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Ok - - - - - - - - - - - buttonBox - accepted() - About - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - About - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/datasnapshot.cpp b/datasnapshot.cpp deleted file mode 100644 index 6933ea12..00000000 --- a/datasnapshot.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "datasnapshot.h" - -#include -#include -#include - -DataSnapshot::DataSnapshot(int unit_size) : - _data(NULL), - _sample_count(0), - _unit_size(unit_size) -{ - assert(_unit_size > 0); -} - -DataSnapshot::~DataSnapshot() -{ - free(_data); -} - -uint64_t DataSnapshot::get_sample_count() -{ - return _sample_count; -} - -void DataSnapshot::append_data(void *data, uint64_t samples) -{ - _data = realloc(_data, (_sample_count + samples) * _unit_size); - memcpy((uint8_t*)_data + _sample_count * _unit_size, - data, samples * _unit_size); - _sample_count += samples; -} diff --git a/datasnapshot.h b/datasnapshot.h deleted file mode 100644 index 3bf12f9d..00000000 --- a/datasnapshot.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -extern "C" { -#include -} - -class DataSnapshot -{ -public: - DataSnapshot(int unit_size); - - virtual ~DataSnapshot(); - - uint64_t get_sample_count(); - -protected: - void append_data(void *data, uint64_t samples); - -protected: - void *_data; - uint64_t _sample_count; - int _unit_size; -}; diff --git a/logicdata.cpp b/logicdata.cpp deleted file mode 100644 index 73d35d71..00000000 --- a/logicdata.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "logicdata.h" -#include "logicdatasnapshot.h" - -using namespace boost; -using namespace std; - -LogicData::LogicData(const sr_datafeed_meta_logic &meta) : - SignalData(meta.samplerate > 0 ? meta.samplerate : 1), - _num_probes(meta.num_probes) -{ -} - -int LogicData::get_num_probes() const -{ - return _num_probes; -} - -void LogicData::push_snapshot( - boost::shared_ptr &snapshot) -{ - _snapshots.push_front(snapshot); -} - -deque< shared_ptr >& LogicData::get_snapshots() -{ - return _snapshots; -} diff --git a/logicdata.h b/logicdata.h deleted file mode 100644 index cde8eef6..00000000 --- a/logicdata.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "signaldata.h" - -#include -#include - -extern "C" { -#include -} - -class LogicDataSnapshot; - -class LogicData : public SignalData -{ -public: - LogicData(const sr_datafeed_meta_logic &meta); - - int get_num_probes() const; - - void push_snapshot( - boost::shared_ptr &snapshot); - - std::deque< boost::shared_ptr >& - get_snapshots(); - -private: - const int _num_probes; - std::deque< boost::shared_ptr > - _snapshots; -}; diff --git a/logicdatasnapshot.cpp b/logicdatasnapshot.cpp deleted file mode 100644 index 62d8a90b..00000000 --- a/logicdatasnapshot.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "extdef.h" - -#include -#include -#include -#include - -#include - -#include "logicdatasnapshot.h" - -using namespace std; - -const int LogicDataSnapshot::MipMapScalePower = 4; -const int LogicDataSnapshot::MipMapScaleFactor = 1 << MipMapScalePower; -const float LogicDataSnapshot::LogMipMapScaleFactor = logf(MipMapScaleFactor); -const uint64_t LogicDataSnapshot::MipMapDataUnit = 64*1024; // bytes - -LogicDataSnapshot::LogicDataSnapshot( - const sr_datafeed_logic &logic) : - DataSnapshot(logic.unitsize), - _last_append_sample(0) -{ - memset(_mip_map, 0, sizeof(_mip_map)); - append_payload(logic); -} - -LogicDataSnapshot::~LogicDataSnapshot() -{ - BOOST_FOREACH(MipMapLevel &l, _mip_map) - free(l.data); -} - -void LogicDataSnapshot::append_payload( - const sr_datafeed_logic &logic) -{ - assert(_unit_size == logic.unitsize); - - append_data(logic.data, logic.length); - - // Generate the first mip-map from the data - append_payload_to_mipmap(); -} - -void LogicDataSnapshot::reallocate_mip_map(MipMapLevel &m) -{ - const uint64_t new_data_length = ((m.length + MipMapDataUnit - 1) / - MipMapDataUnit) * MipMapDataUnit; - if(new_data_length > m.data_length) - { - m.data_length = new_data_length; - m.data = realloc(m.data, new_data_length * _unit_size); - } -} - -void LogicDataSnapshot::append_payload_to_mipmap() -{ - MipMapLevel &m0 = _mip_map[0]; - uint64_t prev_length; - const uint8_t *src_ptr; - uint8_t *dest_ptr; - uint64_t accumulator; - unsigned int diff_counter; - - // Expand the data buffer to fit the new samples - prev_length = m0.length; - m0.length = _sample_count / MipMapScaleFactor; - - // Break off if there are no new samples to compute - if(m0.length == prev_length) - return; - - reallocate_mip_map(m0); - - dest_ptr = (uint8_t*)m0.data + prev_length * _unit_size; - - // Iterate through the samples to populate the first level mipmap - accumulator = 0; - diff_counter = MipMapScaleFactor; - const uint8_t *end_src_ptr = (uint8_t*)_data + - m0.length * _unit_size * MipMapScaleFactor; - for(src_ptr = (uint8_t*)_data + - prev_length * _unit_size * MipMapScaleFactor; - src_ptr < end_src_ptr;) - { - // Accumulate transitions which have occurred in this sample - accumulator = 0; - diff_counter = MipMapScaleFactor; - while(diff_counter-- > 0) - { - const uint64_t sample = *(uint64_t*)src_ptr; - accumulator |= _last_append_sample ^ sample; - _last_append_sample = sample; - src_ptr += _unit_size; - } - - *(uint64_t*)dest_ptr = accumulator; - dest_ptr += _unit_size; - } - - // Compute higher level mipmaps - for(int level = 1; level < ScaleStepCount; level++) - { - MipMapLevel &m = _mip_map[level]; - const MipMapLevel &ml = _mip_map[level-1]; - - // Expand the data buffer to fit the new samples - prev_length = m.length; - m.length = ml.length / MipMapScaleFactor; - - // Break off if there are no more samples to computed - if(m.length == prev_length) - break; - - reallocate_mip_map(m); - - // Subsample the level lower level - src_ptr = (uint8_t*)ml.data + - _unit_size * prev_length * MipMapScaleFactor; - const uint8_t *end_dest_ptr = - (uint8_t*)m.data + _unit_size * m.length; - for(dest_ptr = (uint8_t*)m.data + - _unit_size * prev_length; - dest_ptr < end_dest_ptr; - dest_ptr += _unit_size) - { - accumulator = 0; - diff_counter = MipMapScaleFactor; - while(diff_counter-- > 0) - { - accumulator |= *(uint64_t*)src_ptr; - src_ptr += _unit_size; - } - - *(uint64_t*)dest_ptr = accumulator; - } - } -} - -uint64_t LogicDataSnapshot::get_sample(uint64_t index) const -{ - assert(_data); - assert(index >= 0 && index < _sample_count); - - return *(uint64_t*)((uint8_t*)_data + index * _unit_size); -} - -void LogicDataSnapshot::get_subsampled_edges( - std::vector &edges, - int64_t start, int64_t end, - float min_length, int sig_index) -{ - int64_t index = start; - int level; - bool last_sample; - bool fast_forward; - - assert(start >= 0); - assert(end <= get_sample_count()); - assert(start <= end); - assert(min_length > 0); - assert(sig_index >= 0); - assert(sig_index < SR_MAX_NUM_PROBES); - - const int64_t block_length = (int64_t)max(min_length, 1.0f); - const int min_level = max((int)floorf(logf(min_length) / - LogMipMapScaleFactor) - 1, 0); - const uint64_t sig_mask = 1ULL << sig_index; - - // Store the initial state - last_sample = (get_sample(start) & sig_mask) != 0; - edges.push_back(pair(index++, last_sample)); - - while(index + block_length <= end) - { - //----- Continue to search -----// - level = min_level; - fast_forward = true; - - if(min_length < MipMapScaleFactor) - { - // Search individual samples up to the beginning of - // the next first level mip map block - const uint64_t final_index = min(end, - pow2_ceil(index, MipMapScalePower)); - - for(index; - index < final_index && - (index & ~(~0 << MipMapScalePower)) != 0; - index++) - { - const bool sample = - (get_sample(index) & sig_mask) != 0; - - // If there was a change we cannot fast forward - if(sample != last_sample) { - fast_forward = false; - break; - } - } - } - else - { - // If resolution is less than a mip map block, - // round up to the beginning of the mip-map block - // for this level of detail - const int min_level_scale_power = - (level + 1) * MipMapScalePower; - index = pow2_ceil(index, min_level_scale_power); - if(index >= end) - break; - - // We can fast forward only if there was no change - const bool sample = - (get_sample(index) & sig_mask) != 0; - fast_forward = last_sample == sample; - } - - if(fast_forward) { - - // Fast forward: This involves zooming out to higher - // levels of the mip map searching for changes, then - // zooming in on them to find the point where the edge - // begins. - - // Slide right and zoom out at the beginnings of mip-map - // blocks until we encounter a change - while(1) { - const int level_scale_power = - (level + 1) * MipMapScalePower; - const uint64_t offset = - index >> level_scale_power; - assert(offset >= 0); - - // Check if we reached the last block at this - // level, or if there was a change in this block - if(offset >= _mip_map[level].length || - (get_subsample(level, offset) & - sig_mask)) - break; - - if((offset & ~(~0 << MipMapScalePower)) == 0) { - // If we are now at the beginning of a - // higher level mip-map block ascend one - // level - if(level + 1 >= ScaleStepCount || - !_mip_map[level + 1].data) - break; - - level++; - } else { - // Slide right to the beginning of the - // next mip map block - index = pow2_ceil(index + 1, - level_scale_power); - } - } - - // Zoom in, and slide right until we encounter a change, - // and repeat until we reach min_level - while(1) { - assert(_mip_map[level].data); - - const int level_scale_power = - (level + 1) * MipMapScalePower; - const uint64_t offset = - index >> level_scale_power; - assert(offset >= 0); - - // Check if we reached the last block at this - // level, or if there was a change in this block - if(offset >= _mip_map[level].length || - (get_subsample(level, offset) & - sig_mask)) { - // Zoom in unless we reached the minimum - // zoom - if(level == min_level) - break; - - level--; - } else { - // Slide right to the beginning of the - // next mip map block - index = pow2_ceil(index + 1, - level_scale_power); - } - } - - // If individual samples within the limit of resolution, - // do a linear search for the next transition within the - // block - if(min_length < MipMapScaleFactor) { - for(index; index < end; index++) { - const bool sample = (get_sample(index) & - sig_mask) != 0; - if(sample != last_sample) - break; - } - } - } - - //----- Store the edge -----// - - // Take the last sample of the quanization block - const int64_t final_index = index + block_length; - if(index + block_length > end) - break; - - // Store the final state - const bool final_sample = - (get_sample(final_index - 1) & sig_mask) != 0; - edges.push_back(pair(index, final_sample)); - - index = final_index; - last_sample = final_sample; - } - - // Add the final state - edges.push_back(pair(end, - get_sample(end) & sig_mask)); -} - -uint64_t LogicDataSnapshot::get_subsample(int level, uint64_t offset) const -{ - assert(level >= 0); - assert(_mip_map[level].data); - return *(uint64_t*)((uint8_t*)_mip_map[level].data + - _unit_size * offset); -} - -int64_t LogicDataSnapshot::pow2_ceil(int64_t x, unsigned int power) -{ - const int64_t p = 1 << power; - return ((x < 0) ? x : (x + p - 1)) / p * p; -} diff --git a/logicdatasnapshot.h b/logicdatasnapshot.h deleted file mode 100644 index 16e8edde..00000000 --- a/logicdatasnapshot.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "datasnapshot.h" - -#include -#include - -namespace LogicDataSnapshotTest { - class Pow2; - class Basic; - class LargeData; - class Pulses; - class LongPulses; -} - -class LogicDataSnapshot : public DataSnapshot -{ -private: - struct MipMapLevel - { - uint64_t length; - uint64_t data_length; - void *data; - }; - -private: - static const int ScaleStepCount = 10; - static const int MipMapScalePower; - static const int MipMapScaleFactor; - static const float LogMipMapScaleFactor; - static const uint64_t MipMapDataUnit; - -public: - typedef std::pair EdgePair; - -public: - LogicDataSnapshot(const sr_datafeed_logic &logic); - - virtual ~LogicDataSnapshot(); - - void append_payload(const sr_datafeed_logic &logic); - -private: - void reallocate_mip_map(MipMapLevel &m); - - void append_payload_to_mipmap(); - -public: - 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] min_length The minimum number of samples that - * can be resolved at this level of detail. - * @param[in] sig_index The index of the signal. - **/ - void get_subsampled_edges(std::vector &edges, - int64_t start, int64_t end, - float min_length, int sig_index); - -private: - uint64_t get_subsample(int level, uint64_t offset) const; - - static int64_t pow2_ceil(int64_t x, unsigned int power); - -private: - struct MipMapLevel _mip_map[ScaleStepCount]; - uint64_t _last_append_sample; - - friend class LogicDataSnapshotTest::Pow2; - friend class LogicDataSnapshotTest::Basic; - friend class LogicDataSnapshotTest::LargeData; - friend class LogicDataSnapshotTest::Pulses; - friend class LogicDataSnapshotTest::LongPulses; -}; diff --git a/logicsignal.cpp b/logicsignal.cpp deleted file mode 100644 index 5be9b015..00000000 --- a/logicsignal.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "extdef.h" - -#include "logicdata.h" -#include "logicdatasnapshot.h" -#include "logicsignal.h" - -using namespace boost; -using namespace std; - -const float LogicSignal::Margin = 10.0f; -const float LogicSignal::Oversampling = 2.0f; - -const QColor LogicSignal::EdgeColour(0x80, 0x80, 0x80); -const QColor LogicSignal::HighColour(0x00, 0xC0, 0x00); -const QColor LogicSignal::LowColour(0xC0, 0x00, 0x00); - -const QColor LogicSignal::LogicSignalColours[10] = { - QColor(0x16, 0x19, 0x1A), // Black - QColor(0x8F, 0x52, 0x02), // Brown - QColor(0xCC, 0x00, 0x00), // Red - QColor(0xF5, 0x79, 0x00), // Orange - QColor(0xED, 0xD4, 0x00), // Yellow - QColor(0x73, 0xD2, 0x16), // Green - QColor(0x34, 0x65, 0xA4), // Blue - QColor(0x75, 0x50, 0x7B), // Violet - QColor(0x88, 0x8A, 0x85), // Grey - QColor(0xEE, 0xEE, 0xEC), // White -}; - -LogicSignal::LogicSignal(QString name, shared_ptr data, - int probe_index) : - Signal(name), - _data(data), - _probe_index(probe_index) -{ - assert(_probe_index >= 0); -} - -void LogicSignal::paint(QPainter &p, const QRect &rect, double scale, - double offset) -{ - QLineF *line; - - vector< pair > edges; - - assert(scale > 0); - assert(_data); - - const float high_offset = rect.top() + Margin; - const float low_offset = rect.bottom() - Margin; - - const deque< shared_ptr > &snapshots = - _data->get_snapshots(); - if(snapshots.empty()) - return; - - const shared_ptr &snapshot = snapshots.front(); - - const double pixels_offset = offset / scale; - const double samplerate = _data->get_samplerate(); - const double start_time = _data->get_start_time(); - const int64_t last_sample = snapshot->get_sample_count() - 1; - const double samples_per_pixel = samplerate * scale; - const double start = samplerate * (offset - start_time); - const double end = start + samples_per_pixel * rect.width(); - - snapshot->get_subsampled_edges(edges, - min(max((int64_t)floor(start), (int64_t)0), last_sample), - min(max((int64_t)ceil(end), (int64_t)0), last_sample), - samples_per_pixel / Oversampling, _probe_index); - assert(edges.size() >= 2); - - // Paint the edges - const unsigned int edge_count = edges.size() - 2; - QLineF *const edge_lines = new QLineF[edge_count]; - line = edge_lines; - - for(vector::const_iterator i = - edges.begin() + 1; - i != edges.end() - 1; i++) { - const int x = (int)((*i).first / samples_per_pixel - - pixels_offset) + rect.left(); - *line++ = QLineF(x, high_offset, x, low_offset); - } - - p.setPen(EdgeColour); - p.drawLines(edge_lines, edge_count); - delete[] edge_lines; - - // Paint the caps - const unsigned int max_cap_line_count = (edges.size() - 1); - QLineF *const cap_lines = new QLineF[max_cap_line_count]; - - p.setPen(HighColour); - paint_caps(p, cap_lines, edges, true, samples_per_pixel, - pixels_offset, rect.left(), high_offset); - p.setPen(LowColour); - paint_caps(p, cap_lines, edges, false, samples_per_pixel, - pixels_offset, rect.left(), low_offset); - - delete[] cap_lines; -} - -int LogicSignal::paint_caps(QPainter &p, QLineF *const lines, - vector< pair > &edges, bool level, - double samples_per_pixel, double pixels_offset, int x_offset, - int y_offset) -{ - QLineF *line = lines; - - for(vector::const_iterator i = edges.begin(); - i != (edges.end() - 1); i++) - if((*i).second == level) { - *line++ = QLineF( - (int)((*i).first / samples_per_pixel - - pixels_offset) + x_offset, y_offset, - (int)((*(i+1)).first / samples_per_pixel - - pixels_offset) + x_offset, y_offset); - } - - p.drawLines(lines, line - lines); -} - -QColor LogicSignal::get_colour() const -{ - return LogicSignalColours[_probe_index % countof(LogicSignalColours)]; -} - -int LogicSignal::get_nominal_offset(const QRect &rect) const -{ - return rect.bottom() - Margin; -} diff --git a/logicsignal.h b/logicsignal.h deleted file mode 100644 index 81fe6a4b..00000000 --- a/logicsignal.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "signal.h" - -#include - -class LogicData; - -class LogicSignal : public Signal -{ -private: - static const float Margin; - static const float Oversampling; - - static const QColor EdgeColour; - static const QColor HighColour; - static const QColor LowColour; - - static const QColor LogicSignalColours[10]; - -public: - LogicSignal(QString name, - boost::shared_ptr data, - int probe_index); - - /** - * Paints the signal with a QPainter - * @param p the QPainter to paint into. - * @param rect the rectangular area to draw the trace into. - * @param scale the scale in seconds per pixel. - * @param offset the time to show at the left hand edge of - * the view in seconds. - **/ - void paint(QPainter &p, const QRect &rect, double scale, double offset); - -private: - - int paint_caps(QPainter &p, QLineF *const lines, - std::vector< std::pair > &edges, - bool level, double samples_per_pixel, double pixels_offset, - int x_offset, int y_offset); - - /** - * Get the colour of the logic signal - */ - QColor get_colour() const; - - /** - * When painting into the rectangle, calculate the y - * offset of the zero point. - **/ - int get_nominal_offset(const QRect &rect) const; - -private: - int _probe_index; - boost::shared_ptr _data; -}; diff --git a/main.cpp b/main.cpp index d15cff89..41f85897 100644 --- a/main.cpp +++ b/main.cpp @@ -26,7 +26,7 @@ extern "C" { #include #include -#include "mainwindow.h" +#include "pv/mainwindow.h" int main(int argc, char *argv[]) { @@ -63,7 +63,7 @@ int main(int argc, char *argv[]) } /* Initialise the main window */ - MainWindow w; + pv::MainWindow w; w.show(); /* Run the application */ diff --git a/mainwindow.cpp b/mainwindow.cpp deleted file mode 100644 index df250eff..00000000 --- a/mainwindow.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -extern "C" { -#include -} - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "about.h" -#include "mainwindow.h" -#include "samplingbar.h" -#include "pv/view/view.h" - -extern "C" { -/* __STDC_FORMAT_MACROS is required for PRIu64 and friends (in C++). */ -#define __STDC_FORMAT_MACROS -#include -#include -#include -#include -#include -} - -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent) -{ - setup_ui(); -} - -void MainWindow::setup_ui() -{ - setObjectName(QString::fromUtf8("MainWindow")); - - resize(1024, 768); - - // Set the window icon - QIcon icon; - icon.addFile(QString::fromUtf8(":/icons/sigrok-logo-notext.png"), - QSize(), QIcon::Normal, QIcon::Off); - setWindowIcon(icon); - - // Setup the UI actions - _action_about = new QAction(this); - _action_about->setObjectName(QString::fromUtf8("actionAbout")); - - _action_view_zoom_in = new QAction(this); - _action_view_zoom_in->setIcon(QIcon::fromTheme("zoom-in")); - _action_view_zoom_in->setObjectName(QString::fromUtf8("actionViewZoomIn")); - - _action_view_zoom_out = new QAction(this); - _action_view_zoom_out->setIcon(QIcon::fromTheme("zoom-out")); - _action_view_zoom_out->setObjectName(QString::fromUtf8("actionViewZoomOut")); - - _action_open = new QAction(this); - _action_open->setIcon(QIcon::fromTheme("document-open")); - _action_open->setObjectName(QString::fromUtf8("actionOpen")); - - // Setup the menu bar - _menu_bar = new QMenuBar(this); - _menu_bar->setGeometry(QRect(0, 0, 400, 25)); - - _menu_file = new QMenu(_menu_bar); - _menu_file->addAction(_action_open); - - _menu_view = new QMenu(_menu_bar); - _menu_view->addAction(_action_view_zoom_in); - _menu_view->addAction(_action_view_zoom_out); - - _menu_help = new QMenu(_menu_bar); - _menu_help->addAction(_action_about); - - _menu_bar->addAction(_menu_file->menuAction()); - _menu_bar->addAction(_menu_view->menuAction()); - _menu_bar->addAction(_menu_help->menuAction()); - - setMenuBar(_menu_bar); - QMetaObject::connectSlotsByName(this); - - // Setup the toolbars - _toolbar = new QToolBar(this); - _toolbar->addAction(_action_open); - _toolbar->addSeparator(); - _toolbar->addAction(_action_view_zoom_in); - _toolbar->addAction(_action_view_zoom_out); - addToolBar(_toolbar); - - _sampling_bar = new SamplingBar(this); - connect(_sampling_bar, SIGNAL(run_stop()), this, - SLOT(run_stop())); - addToolBar(_sampling_bar); - - // Setup the central widget - _central_widget = new QWidget(this); - _vertical_layout = new QVBoxLayout(_central_widget); - _vertical_layout->setSpacing(6); - _vertical_layout->setContentsMargins(0, 0, 0, 0); - setCentralWidget(_central_widget); - - // Setup the status bar - _status_bar = new QStatusBar(this); - setStatusBar(_status_bar); - - setWindowTitle(QApplication::translate("MainWindow", "PulseView", 0, - QApplication::UnicodeUTF8)); - - _action_open->setText(QApplication::translate("MainWindow", "&Open...", 0, QApplication::UnicodeUTF8)); - _action_view_zoom_in->setText(QApplication::translate("MainWindow", "Zoom &In", 0, QApplication::UnicodeUTF8)); - _action_view_zoom_out->setText(QApplication::translate("MainWindow", "Zoom &Out", 0, QApplication::UnicodeUTF8)); - _action_about->setText(QApplication::translate("MainWindow", "&About...", 0, QApplication::UnicodeUTF8)); - - _menu_file->setTitle(QApplication::translate("MainWindow", "&File", 0, QApplication::UnicodeUTF8)); - _menu_view->setTitle(QApplication::translate("MainWindow", "&View", 0, QApplication::UnicodeUTF8)); - _menu_help->setTitle(QApplication::translate("MainWindow", "&Help", 0, QApplication::UnicodeUTF8)); - - _view = new pv::view::View(_session, this); - _vertical_layout->addWidget(_view); -} - -void MainWindow::on_actionOpen_triggered() -{ - QString file_name = QFileDialog::getOpenFileName( - this, tr("Open File"), "", - tr("Sigrok Sessions (*.sr)")); - _session.load_file(file_name.toStdString()); -} - -void MainWindow::on_actionViewZoomIn_triggered() -{ - _view->zoom(1); -} - -void MainWindow::on_actionViewZoomOut_triggered() -{ - _view->zoom(-1); -} - -void MainWindow::on_actionAbout_triggered() -{ - About dlg(this); - dlg.exec(); -} - -void MainWindow::run_stop() -{ - _session.start_capture( - _sampling_bar->get_selected_device(), - _sampling_bar->get_record_length(), - _sampling_bar->get_sample_rate()); -} diff --git a/mainwindow.h b/mainwindow.h deleted file mode 100644 index c0a4248d..00000000 --- a/mainwindow.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include - -#include "sigsession.h" - -class SamplingBar; - -namespace pv { -namespace view { -class View; -} -} - -class QAction; -class QMenuBar; -class QMenu; -class QVBoxLayout; -class QStatusBar; -class QToolBar; -class QWidget; - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow(QWidget *parent = 0); - -private: - void setup_ui(); - -private: - - SigSession _session; - pv::view::View *_view; - - QAction *_action_open; - QAction *_action_view_zoom_in; - QAction *_action_view_zoom_out; - QAction *_action_about; - - QMenuBar *_menu_bar; - QMenu *_menu_file; - QMenu *_menu_view; - QMenu *_menu_help; - - QWidget *_central_widget; - QVBoxLayout *_vertical_layout; - - QToolBar *_toolbar; - SamplingBar *_sampling_bar; - QStatusBar *_status_bar; - -private slots: - - void on_actionOpen_triggered(); - - void on_actionViewZoomIn_triggered(); - - void on_actionViewZoomOut_triggered(); - - void on_actionAbout_triggered(); - - void run_stop(); -}; - -#endif // MAINWINDOW_H diff --git a/pv/about.cpp b/pv/about.cpp new file mode 100644 index 00000000..48c1f59e --- /dev/null +++ b/pv/about.cpp @@ -0,0 +1,114 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +extern "C" { +#include +} + +#include + +#include "about.h" +#include + +extern "C" { +/* __STDC_FORMAT_MACROS is required for PRIu64 and friends (in C++). */ +#define __STDC_FORMAT_MACROS +#include +#include +} + +namespace pv { + +About::About(QWidget *parent) : + QDialog(parent), + ui(new Ui::About) +{ + GSList *l; + struct sr_dev_driver **drivers; + struct sr_input_format **inputs; + struct sr_output_format **outputs; + struct srd_decoder *dec; + QString s; + + ui->setupUi(this); + + /* Setup the version field */ + ui->versionInfo->setText(tr("%1 %2
%3
%4") + .arg(QApplication::applicationName()) + .arg(QApplication::applicationVersion()) + .arg(tr("GNU GPL, version 2 or later")) + .arg(QApplication::organizationDomain())); + + s.append(""); + + /* Set up the supported field */ + s.append(""); + drivers = sr_driver_list(); + for (int i = 0; drivers[i]; ++i) { + s.append(QString("") + .arg(QString(drivers[i]->name)) + .arg(QString(drivers[i]->longname))); + } + + s.append(""); + inputs = sr_input_list(); + for (int i = 0; inputs[i]; ++i) { + s.append(QString("") + .arg(QString(inputs[i]->id)) + .arg(QString(inputs[i]->description))); + } + + s.append(""); + outputs = sr_output_list(); + for (int i = 0; outputs[i]; ++i) { + s.append(QString("") + .arg(QString(outputs[i]->id)) + .arg(QString(outputs[i]->description))); + } + + s.append(""); + for (l = srd_decoder_list(); l; l = l->next) { + dec = (struct srd_decoder *)l->data; + s.append(QString("") + .arg(QString(dec->id)) + .arg(QString(dec->longname))); + } + + s.append("
" + + tr("Supported hardware drivers:") + + "
%1%2
" + + tr("Supported input formats:") + + "
%1%2
" + + tr("Supported output formats:") + + "
%1%2
" + + tr("Supported protocol decoders:") + + "
%1%2
"); + + supportedDoc.reset(new QTextDocument(this)); + supportedDoc->setHtml(s); + ui->supportList->setDocument(supportedDoc.get()); +} + +About::~About() +{ + delete ui; +} + +} // namespace pv diff --git a/pv/about.h b/pv/about.h new file mode 100644 index 00000000..31392b2b --- /dev/null +++ b/pv/about.h @@ -0,0 +1,51 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ABOUT_H +#define ABOUT_H + +#include + +#include + +class QTextDocument; + +namespace Ui { +class About; +} + +namespace pv { + +class About : public QDialog +{ + Q_OBJECT + +public: + explicit About(QWidget *parent = 0); + ~About(); + +private: + Ui::About *ui; + std::auto_ptr supportedDoc; +}; + +} // namespace pv + +#endif // ABOUT_H diff --git a/pv/about.ui b/pv/about.ui new file mode 100644 index 00000000..10163f9a --- /dev/null +++ b/pv/about.ui @@ -0,0 +1,96 @@ + + + About + + + Qt::WindowModal + + + + 0 + 0 + 600 + 400 + + + + About + + + + + + + + + + + + + + :/icons/sigrok-logo-notext.png + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + About + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + About + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/pv/datasnapshot.cpp b/pv/datasnapshot.cpp new file mode 100644 index 00000000..31acca16 --- /dev/null +++ b/pv/datasnapshot.cpp @@ -0,0 +1,55 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "datasnapshot.h" + +#include +#include +#include + +namespace pv { + +DataSnapshot::DataSnapshot(int unit_size) : + _data(NULL), + _sample_count(0), + _unit_size(unit_size) +{ + assert(_unit_size > 0); +} + +DataSnapshot::~DataSnapshot() +{ + free(_data); +} + +uint64_t DataSnapshot::get_sample_count() +{ + return _sample_count; +} + +void DataSnapshot::append_data(void *data, uint64_t samples) +{ + _data = realloc(_data, (_sample_count + samples) * _unit_size); + memcpy((uint8_t*)_data + _sample_count * _unit_size, + data, samples * _unit_size); + _sample_count += samples; +} + +} // namespace pv diff --git a/pv/datasnapshot.h b/pv/datasnapshot.h new file mode 100644 index 00000000..221ebcd3 --- /dev/null +++ b/pv/datasnapshot.h @@ -0,0 +1,45 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +extern "C" { +#include +} + +namespace pv { + +class DataSnapshot +{ +public: + DataSnapshot(int unit_size); + + virtual ~DataSnapshot(); + + uint64_t get_sample_count(); + +protected: + void append_data(void *data, uint64_t samples); + +protected: + void *_data; + uint64_t _sample_count; + int _unit_size; +}; + +} // namespace pv diff --git a/pv/logicdata.cpp b/pv/logicdata.cpp new file mode 100644 index 00000000..c8b3b84d --- /dev/null +++ b/pv/logicdata.cpp @@ -0,0 +1,51 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "logicdata.h" +#include "logicdatasnapshot.h" + +using namespace boost; +using namespace std; + +namespace pv { + +LogicData::LogicData(const sr_datafeed_meta_logic &meta) : + SignalData(meta.samplerate > 0 ? meta.samplerate : 1), + _num_probes(meta.num_probes) +{ +} + +int LogicData::get_num_probes() const +{ + return _num_probes; +} + +void LogicData::push_snapshot( + boost::shared_ptr &snapshot) +{ + _snapshots.push_front(snapshot); +} + +deque< shared_ptr >& LogicData::get_snapshots() +{ + return _snapshots; +} + +} // namespace pv diff --git a/pv/logicdata.h b/pv/logicdata.h new file mode 100644 index 00000000..b21d50ad --- /dev/null +++ b/pv/logicdata.h @@ -0,0 +1,53 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "signaldata.h" + +#include +#include + +extern "C" { +#include +} + +namespace pv { + +class LogicDataSnapshot; + +class LogicData : public SignalData +{ +public: + LogicData(const sr_datafeed_meta_logic &meta); + + int get_num_probes() const; + + void push_snapshot( + boost::shared_ptr &snapshot); + + std::deque< boost::shared_ptr >& + get_snapshots(); + +private: + const int _num_probes; + std::deque< boost::shared_ptr > + _snapshots; +}; + +} // namespace pv diff --git a/pv/logicdatasnapshot.cpp b/pv/logicdatasnapshot.cpp new file mode 100644 index 00000000..347b7e24 --- /dev/null +++ b/pv/logicdatasnapshot.cpp @@ -0,0 +1,359 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "extdef.h" + +#include +#include +#include +#include + +#include + +#include "logicdatasnapshot.h" + +using namespace std; + +namespace pv { + +const int LogicDataSnapshot::MipMapScalePower = 4; +const int LogicDataSnapshot::MipMapScaleFactor = 1 << MipMapScalePower; +const float LogicDataSnapshot::LogMipMapScaleFactor = logf(MipMapScaleFactor); +const uint64_t LogicDataSnapshot::MipMapDataUnit = 64*1024; // bytes + +LogicDataSnapshot::LogicDataSnapshot( + const sr_datafeed_logic &logic) : + DataSnapshot(logic.unitsize), + _last_append_sample(0) +{ + memset(_mip_map, 0, sizeof(_mip_map)); + append_payload(logic); +} + +LogicDataSnapshot::~LogicDataSnapshot() +{ + BOOST_FOREACH(MipMapLevel &l, _mip_map) + free(l.data); +} + +void LogicDataSnapshot::append_payload( + const sr_datafeed_logic &logic) +{ + assert(_unit_size == logic.unitsize); + + append_data(logic.data, logic.length); + + // Generate the first mip-map from the data + append_payload_to_mipmap(); +} + +void LogicDataSnapshot::reallocate_mip_map(MipMapLevel &m) +{ + const uint64_t new_data_length = ((m.length + MipMapDataUnit - 1) / + MipMapDataUnit) * MipMapDataUnit; + if(new_data_length > m.data_length) + { + m.data_length = new_data_length; + m.data = realloc(m.data, new_data_length * _unit_size); + } +} + +void LogicDataSnapshot::append_payload_to_mipmap() +{ + MipMapLevel &m0 = _mip_map[0]; + uint64_t prev_length; + const uint8_t *src_ptr; + uint8_t *dest_ptr; + uint64_t accumulator; + unsigned int diff_counter; + + // Expand the data buffer to fit the new samples + prev_length = m0.length; + m0.length = _sample_count / MipMapScaleFactor; + + // Break off if there are no new samples to compute + if(m0.length == prev_length) + return; + + reallocate_mip_map(m0); + + dest_ptr = (uint8_t*)m0.data + prev_length * _unit_size; + + // Iterate through the samples to populate the first level mipmap + accumulator = 0; + diff_counter = MipMapScaleFactor; + const uint8_t *end_src_ptr = (uint8_t*)_data + + m0.length * _unit_size * MipMapScaleFactor; + for(src_ptr = (uint8_t*)_data + + prev_length * _unit_size * MipMapScaleFactor; + src_ptr < end_src_ptr;) + { + // Accumulate transitions which have occurred in this sample + accumulator = 0; + diff_counter = MipMapScaleFactor; + while(diff_counter-- > 0) + { + const uint64_t sample = *(uint64_t*)src_ptr; + accumulator |= _last_append_sample ^ sample; + _last_append_sample = sample; + src_ptr += _unit_size; + } + + *(uint64_t*)dest_ptr = accumulator; + dest_ptr += _unit_size; + } + + // Compute higher level mipmaps + for(int level = 1; level < ScaleStepCount; level++) + { + MipMapLevel &m = _mip_map[level]; + const MipMapLevel &ml = _mip_map[level-1]; + + // Expand the data buffer to fit the new samples + prev_length = m.length; + m.length = ml.length / MipMapScaleFactor; + + // Break off if there are no more samples to computed + if(m.length == prev_length) + break; + + reallocate_mip_map(m); + + // Subsample the level lower level + src_ptr = (uint8_t*)ml.data + + _unit_size * prev_length * MipMapScaleFactor; + const uint8_t *end_dest_ptr = + (uint8_t*)m.data + _unit_size * m.length; + for(dest_ptr = (uint8_t*)m.data + + _unit_size * prev_length; + dest_ptr < end_dest_ptr; + dest_ptr += _unit_size) + { + accumulator = 0; + diff_counter = MipMapScaleFactor; + while(diff_counter-- > 0) + { + accumulator |= *(uint64_t*)src_ptr; + src_ptr += _unit_size; + } + + *(uint64_t*)dest_ptr = accumulator; + } + } +} + +uint64_t LogicDataSnapshot::get_sample(uint64_t index) const +{ + assert(_data); + assert(index >= 0 && index < _sample_count); + + return *(uint64_t*)((uint8_t*)_data + index * _unit_size); +} + +void LogicDataSnapshot::get_subsampled_edges( + std::vector &edges, + int64_t start, int64_t end, + float min_length, int sig_index) +{ + int64_t index = start; + int level; + bool last_sample; + bool fast_forward; + + assert(start >= 0); + assert(end <= get_sample_count()); + assert(start <= end); + assert(min_length > 0); + assert(sig_index >= 0); + assert(sig_index < SR_MAX_NUM_PROBES); + + const int64_t block_length = (int64_t)max(min_length, 1.0f); + const int min_level = max((int)floorf(logf(min_length) / + LogMipMapScaleFactor) - 1, 0); + const uint64_t sig_mask = 1ULL << sig_index; + + // Store the initial state + last_sample = (get_sample(start) & sig_mask) != 0; + edges.push_back(pair(index++, last_sample)); + + while(index + block_length <= end) + { + //----- Continue to search -----// + level = min_level; + fast_forward = true; + + if(min_length < MipMapScaleFactor) + { + // Search individual samples up to the beginning of + // the next first level mip map block + const uint64_t final_index = min(end, + pow2_ceil(index, MipMapScalePower)); + + for(index; + index < final_index && + (index & ~(~0 << MipMapScalePower)) != 0; + index++) + { + const bool sample = + (get_sample(index) & sig_mask) != 0; + + // If there was a change we cannot fast forward + if(sample != last_sample) { + fast_forward = false; + break; + } + } + } + else + { + // If resolution is less than a mip map block, + // round up to the beginning of the mip-map block + // for this level of detail + const int min_level_scale_power = + (level + 1) * MipMapScalePower; + index = pow2_ceil(index, min_level_scale_power); + if(index >= end) + break; + + // We can fast forward only if there was no change + const bool sample = + (get_sample(index) & sig_mask) != 0; + fast_forward = last_sample == sample; + } + + if(fast_forward) { + + // Fast forward: This involves zooming out to higher + // levels of the mip map searching for changes, then + // zooming in on them to find the point where the edge + // begins. + + // Slide right and zoom out at the beginnings of mip-map + // blocks until we encounter a change + while(1) { + const int level_scale_power = + (level + 1) * MipMapScalePower; + const uint64_t offset = + index >> level_scale_power; + assert(offset >= 0); + + // Check if we reached the last block at this + // level, or if there was a change in this block + if(offset >= _mip_map[level].length || + (get_subsample(level, offset) & + sig_mask)) + break; + + if((offset & ~(~0 << MipMapScalePower)) == 0) { + // If we are now at the beginning of a + // higher level mip-map block ascend one + // level + if(level + 1 >= ScaleStepCount || + !_mip_map[level + 1].data) + break; + + level++; + } else { + // Slide right to the beginning of the + // next mip map block + index = pow2_ceil(index + 1, + level_scale_power); + } + } + + // Zoom in, and slide right until we encounter a change, + // and repeat until we reach min_level + while(1) { + assert(_mip_map[level].data); + + const int level_scale_power = + (level + 1) * MipMapScalePower; + const uint64_t offset = + index >> level_scale_power; + assert(offset >= 0); + + // Check if we reached the last block at this + // level, or if there was a change in this block + if(offset >= _mip_map[level].length || + (get_subsample(level, offset) & + sig_mask)) { + // Zoom in unless we reached the minimum + // zoom + if(level == min_level) + break; + + level--; + } else { + // Slide right to the beginning of the + // next mip map block + index = pow2_ceil(index + 1, + level_scale_power); + } + } + + // If individual samples within the limit of resolution, + // do a linear search for the next transition within the + // block + if(min_length < MipMapScaleFactor) { + for(index; index < end; index++) { + const bool sample = (get_sample(index) & + sig_mask) != 0; + if(sample != last_sample) + break; + } + } + } + + //----- Store the edge -----// + + // Take the last sample of the quanization block + const int64_t final_index = index + block_length; + if(index + block_length > end) + break; + + // Store the final state + const bool final_sample = + (get_sample(final_index - 1) & sig_mask) != 0; + edges.push_back(pair(index, final_sample)); + + index = final_index; + last_sample = final_sample; + } + + // Add the final state + edges.push_back(pair(end, + get_sample(end) & sig_mask)); +} + +uint64_t LogicDataSnapshot::get_subsample(int level, uint64_t offset) const +{ + assert(level >= 0); + assert(_mip_map[level].data); + return *(uint64_t*)((uint8_t*)_mip_map[level].data + + _unit_size * offset); +} + +int64_t LogicDataSnapshot::pow2_ceil(int64_t x, unsigned int power) +{ + const int64_t p = 1 << power; + return ((x < 0) ? x : (x + p - 1)) / p * p; +} + +} // namespace pv diff --git a/pv/logicdatasnapshot.h b/pv/logicdatasnapshot.h new file mode 100644 index 00000000..21541202 --- /dev/null +++ b/pv/logicdatasnapshot.h @@ -0,0 +1,101 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "datasnapshot.h" + +#include +#include + +namespace LogicDataSnapshotTest { + class Pow2; + class Basic; + class LargeData; + class Pulses; + class LongPulses; +} + +namespace pv { + +class LogicDataSnapshot : public DataSnapshot +{ +private: + struct MipMapLevel + { + uint64_t length; + uint64_t data_length; + void *data; + }; + +private: + static const int ScaleStepCount = 10; + static const int MipMapScalePower; + static const int MipMapScaleFactor; + static const float LogMipMapScaleFactor; + static const uint64_t MipMapDataUnit; + +public: + typedef std::pair EdgePair; + +public: + LogicDataSnapshot(const sr_datafeed_logic &logic); + + virtual ~LogicDataSnapshot(); + + void append_payload(const sr_datafeed_logic &logic); + +private: + void reallocate_mip_map(MipMapLevel &m); + + void append_payload_to_mipmap(); + +public: + 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] min_length The minimum number of samples that + * can be resolved at this level of detail. + * @param[in] sig_index The index of the signal. + **/ + void get_subsampled_edges(std::vector &edges, + int64_t start, int64_t end, + float min_length, int sig_index); + +private: + uint64_t get_subsample(int level, uint64_t offset) const; + + static int64_t pow2_ceil(int64_t x, unsigned int power); + +private: + struct MipMapLevel _mip_map[ScaleStepCount]; + uint64_t _last_append_sample; + + friend class LogicDataSnapshotTest::Pow2; + friend class LogicDataSnapshotTest::Basic; + friend class LogicDataSnapshotTest::LargeData; + friend class LogicDataSnapshotTest::Pulses; + friend class LogicDataSnapshotTest::LongPulses; +}; + +} // namespace pv diff --git a/pv/logicsignal.cpp b/pv/logicsignal.cpp new file mode 100644 index 00000000..7543f139 --- /dev/null +++ b/pv/logicsignal.cpp @@ -0,0 +1,158 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "extdef.h" + +#include "logicdata.h" +#include "logicdatasnapshot.h" +#include "logicsignal.h" + +using namespace boost; +using namespace std; + +namespace pv { + +const float LogicSignal::Margin = 10.0f; +const float LogicSignal::Oversampling = 2.0f; + +const QColor LogicSignal::EdgeColour(0x80, 0x80, 0x80); +const QColor LogicSignal::HighColour(0x00, 0xC0, 0x00); +const QColor LogicSignal::LowColour(0xC0, 0x00, 0x00); + +const QColor LogicSignal::LogicSignalColours[10] = { + QColor(0x16, 0x19, 0x1A), // Black + QColor(0x8F, 0x52, 0x02), // Brown + QColor(0xCC, 0x00, 0x00), // Red + QColor(0xF5, 0x79, 0x00), // Orange + QColor(0xED, 0xD4, 0x00), // Yellow + QColor(0x73, 0xD2, 0x16), // Green + QColor(0x34, 0x65, 0xA4), // Blue + QColor(0x75, 0x50, 0x7B), // Violet + QColor(0x88, 0x8A, 0x85), // Grey + QColor(0xEE, 0xEE, 0xEC), // White +}; + +LogicSignal::LogicSignal(QString name, shared_ptr data, + int probe_index) : + Signal(name), + _data(data), + _probe_index(probe_index) +{ + assert(_probe_index >= 0); +} + +void LogicSignal::paint(QPainter &p, const QRect &rect, double scale, + double offset) +{ + QLineF *line; + + vector< pair > edges; + + assert(scale > 0); + assert(_data); + + const float high_offset = rect.top() + Margin; + const float low_offset = rect.bottom() - Margin; + + const deque< shared_ptr > &snapshots = + _data->get_snapshots(); + if(snapshots.empty()) + return; + + const shared_ptr &snapshot = snapshots.front(); + + const double pixels_offset = offset / scale; + const double samplerate = _data->get_samplerate(); + const double start_time = _data->get_start_time(); + const int64_t last_sample = snapshot->get_sample_count() - 1; + const double samples_per_pixel = samplerate * scale; + const double start = samplerate * (offset - start_time); + const double end = start + samples_per_pixel * rect.width(); + + snapshot->get_subsampled_edges(edges, + min(max((int64_t)floor(start), (int64_t)0), last_sample), + min(max((int64_t)ceil(end), (int64_t)0), last_sample), + samples_per_pixel / Oversampling, _probe_index); + assert(edges.size() >= 2); + + // Paint the edges + const unsigned int edge_count = edges.size() - 2; + QLineF *const edge_lines = new QLineF[edge_count]; + line = edge_lines; + + for(vector::const_iterator i = + edges.begin() + 1; + i != edges.end() - 1; i++) { + const int x = (int)((*i).first / samples_per_pixel - + pixels_offset) + rect.left(); + *line++ = QLineF(x, high_offset, x, low_offset); + } + + p.setPen(EdgeColour); + p.drawLines(edge_lines, edge_count); + delete[] edge_lines; + + // Paint the caps + const unsigned int max_cap_line_count = (edges.size() - 1); + QLineF *const cap_lines = new QLineF[max_cap_line_count]; + + p.setPen(HighColour); + paint_caps(p, cap_lines, edges, true, samples_per_pixel, + pixels_offset, rect.left(), high_offset); + p.setPen(LowColour); + paint_caps(p, cap_lines, edges, false, samples_per_pixel, + pixels_offset, rect.left(), low_offset); + + delete[] cap_lines; +} + +int LogicSignal::paint_caps(QPainter &p, QLineF *const lines, + vector< pair > &edges, bool level, + double samples_per_pixel, double pixels_offset, int x_offset, + int y_offset) +{ + QLineF *line = lines; + + for(vector::const_iterator i = edges.begin(); + i != (edges.end() - 1); i++) + if((*i).second == level) { + *line++ = QLineF( + (int)((*i).first / samples_per_pixel - + pixels_offset) + x_offset, y_offset, + (int)((*(i+1)).first / samples_per_pixel - + pixels_offset) + x_offset, y_offset); + } + + p.drawLines(lines, line - lines); +} + +QColor LogicSignal::get_colour() const +{ + return LogicSignalColours[_probe_index % countof(LogicSignalColours)]; +} + +int LogicSignal::get_nominal_offset(const QRect &rect) const +{ + return rect.bottom() - Margin; +} + +} // namespace pv diff --git a/pv/logicsignal.h b/pv/logicsignal.h new file mode 100644 index 00000000..e12f0ca4 --- /dev/null +++ b/pv/logicsignal.h @@ -0,0 +1,79 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "signal.h" + +#include + +namespace pv { + +class LogicData; + +class LogicSignal : public Signal +{ +private: + static const float Margin; + static const float Oversampling; + + static const QColor EdgeColour; + static const QColor HighColour; + static const QColor LowColour; + + static const QColor LogicSignalColours[10]; + +public: + LogicSignal(QString name, + boost::shared_ptr data, + int probe_index); + + /** + * Paints the signal with a QPainter + * @param p the QPainter to paint into. + * @param rect the rectangular area to draw the trace into. + * @param scale the scale in seconds per pixel. + * @param offset the time to show at the left hand edge of + * the view in seconds. + **/ + void paint(QPainter &p, const QRect &rect, double scale, double offset); + +private: + + int paint_caps(QPainter &p, QLineF *const lines, + std::vector< std::pair > &edges, + bool level, double samples_per_pixel, double pixels_offset, + int x_offset, int y_offset); + + /** + * Get the colour of the logic signal + */ + QColor get_colour() const; + + /** + * When painting into the rectangle, calculate the y + * offset of the zero point. + **/ + int get_nominal_offset(const QRect &rect) const; + +private: + int _probe_index; + boost::shared_ptr _data; +}; + +} // namespace pv diff --git a/pv/mainwindow.cpp b/pv/mainwindow.cpp new file mode 100644 index 00000000..2c48dfc6 --- /dev/null +++ b/pv/mainwindow.cpp @@ -0,0 +1,179 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +extern "C" { +#include +} + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "about.h" +#include "mainwindow.h" +#include "samplingbar.h" +#include "pv/view/view.h" + +extern "C" { +/* __STDC_FORMAT_MACROS is required for PRIu64 and friends (in C++). */ +#define __STDC_FORMAT_MACROS +#include +#include +#include +#include +#include +} + +namespace pv { + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent) +{ + setup_ui(); +} + +void MainWindow::setup_ui() +{ + setObjectName(QString::fromUtf8("MainWindow")); + + resize(1024, 768); + + // Set the window icon + QIcon icon; + icon.addFile(QString::fromUtf8(":/icons/sigrok-logo-notext.png"), + QSize(), QIcon::Normal, QIcon::Off); + setWindowIcon(icon); + + // Setup the UI actions + _action_about = new QAction(this); + _action_about->setObjectName(QString::fromUtf8("actionAbout")); + + _action_view_zoom_in = new QAction(this); + _action_view_zoom_in->setIcon(QIcon::fromTheme("zoom-in")); + _action_view_zoom_in->setObjectName(QString::fromUtf8("actionViewZoomIn")); + + _action_view_zoom_out = new QAction(this); + _action_view_zoom_out->setIcon(QIcon::fromTheme("zoom-out")); + _action_view_zoom_out->setObjectName(QString::fromUtf8("actionViewZoomOut")); + + _action_open = new QAction(this); + _action_open->setIcon(QIcon::fromTheme("document-open")); + _action_open->setObjectName(QString::fromUtf8("actionOpen")); + + // Setup the menu bar + _menu_bar = new QMenuBar(this); + _menu_bar->setGeometry(QRect(0, 0, 400, 25)); + + _menu_file = new QMenu(_menu_bar); + _menu_file->addAction(_action_open); + + _menu_view = new QMenu(_menu_bar); + _menu_view->addAction(_action_view_zoom_in); + _menu_view->addAction(_action_view_zoom_out); + + _menu_help = new QMenu(_menu_bar); + _menu_help->addAction(_action_about); + + _menu_bar->addAction(_menu_file->menuAction()); + _menu_bar->addAction(_menu_view->menuAction()); + _menu_bar->addAction(_menu_help->menuAction()); + + setMenuBar(_menu_bar); + QMetaObject::connectSlotsByName(this); + + // Setup the toolbars + _toolbar = new QToolBar(this); + _toolbar->addAction(_action_open); + _toolbar->addSeparator(); + _toolbar->addAction(_action_view_zoom_in); + _toolbar->addAction(_action_view_zoom_out); + addToolBar(_toolbar); + + _sampling_bar = new SamplingBar(this); + connect(_sampling_bar, SIGNAL(run_stop()), this, + SLOT(run_stop())); + addToolBar(_sampling_bar); + + // Setup the central widget + _central_widget = new QWidget(this); + _vertical_layout = new QVBoxLayout(_central_widget); + _vertical_layout->setSpacing(6); + _vertical_layout->setContentsMargins(0, 0, 0, 0); + setCentralWidget(_central_widget); + + // Setup the status bar + _status_bar = new QStatusBar(this); + setStatusBar(_status_bar); + + setWindowTitle(QApplication::translate("MainWindow", "PulseView", 0, + QApplication::UnicodeUTF8)); + + _action_open->setText(QApplication::translate("MainWindow", "&Open...", 0, QApplication::UnicodeUTF8)); + _action_view_zoom_in->setText(QApplication::translate("MainWindow", "Zoom &In", 0, QApplication::UnicodeUTF8)); + _action_view_zoom_out->setText(QApplication::translate("MainWindow", "Zoom &Out", 0, QApplication::UnicodeUTF8)); + _action_about->setText(QApplication::translate("MainWindow", "&About...", 0, QApplication::UnicodeUTF8)); + + _menu_file->setTitle(QApplication::translate("MainWindow", "&File", 0, QApplication::UnicodeUTF8)); + _menu_view->setTitle(QApplication::translate("MainWindow", "&View", 0, QApplication::UnicodeUTF8)); + _menu_help->setTitle(QApplication::translate("MainWindow", "&Help", 0, QApplication::UnicodeUTF8)); + + _view = new pv::view::View(_session, this); + _vertical_layout->addWidget(_view); +} + +void MainWindow::on_actionOpen_triggered() +{ + QString file_name = QFileDialog::getOpenFileName( + this, tr("Open File"), "", + tr("Sigrok Sessions (*.sr)")); + _session.load_file(file_name.toStdString()); +} + +void MainWindow::on_actionViewZoomIn_triggered() +{ + _view->zoom(1); +} + +void MainWindow::on_actionViewZoomOut_triggered() +{ + _view->zoom(-1); +} + +void MainWindow::on_actionAbout_triggered() +{ + About dlg(this); + dlg.exec(); +} + +void MainWindow::run_stop() +{ + _session.start_capture( + _sampling_bar->get_selected_device(), + _sampling_bar->get_record_length(), + _sampling_bar->get_sample_rate()); +} + +} // namespace pv diff --git a/pv/mainwindow.h b/pv/mainwindow.h new file mode 100644 index 00000000..88cbd6fd --- /dev/null +++ b/pv/mainwindow.h @@ -0,0 +1,91 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +#include "sigsession.h" + +class QAction; +class QMenuBar; +class QMenu; +class QVBoxLayout; +class QStatusBar; +class QToolBar; +class QWidget; + +namespace pv { + +class SamplingBar; + +namespace view { +class View; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + +private: + void setup_ui(); + +private: + + SigSession _session; + pv::view::View *_view; + + QAction *_action_open; + QAction *_action_view_zoom_in; + QAction *_action_view_zoom_out; + QAction *_action_about; + + QMenuBar *_menu_bar; + QMenu *_menu_file; + QMenu *_menu_view; + QMenu *_menu_help; + + QWidget *_central_widget; + QVBoxLayout *_vertical_layout; + + QToolBar *_toolbar; + SamplingBar *_sampling_bar; + QStatusBar *_status_bar; + +private slots: + + void on_actionOpen_triggered(); + + void on_actionViewZoomIn_triggered(); + + void on_actionViewZoomOut_triggered(); + + void on_actionAbout_triggered(); + + void run_stop(); +}; + +} // namespace pv + +#endif // MAINWINDOW_H diff --git a/pv/samplingbar.cpp b/pv/samplingbar.cpp new file mode 100644 index 00000000..31047439 --- /dev/null +++ b/pv/samplingbar.cpp @@ -0,0 +1,192 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include + +extern "C" { +#include +} + +#include + +#include "samplingbar.h" + +namespace pv { + +const uint64_t SamplingBar::RecordLengths[11] = { + 1000000, + 2000000, + 5000000, + 10000000, + 25000000, + 50000000, + 100000000, + 250000000, + 500000000, + 1000000000, + 10000000000 +}; + +SamplingBar::SamplingBar(QWidget *parent) : + QToolBar("Sampling Bar", parent), + _device_selector(this), + _record_length_selector(this), + _sample_rate_list(this), + _run_stop_button(this) +{ + connect(&_run_stop_button, SIGNAL(clicked()), this, SIGNAL(run_stop())); + connect(&_device_selector, SIGNAL(currentIndexChanged (int)), + this, SLOT(on_device_selected())); + + _sample_rate_value.setDecimals(0); + _sample_rate_value.setSuffix("Hz"); + + BOOST_FOREACH(uint64_t l, RecordLengths) + { + char *const text = sr_si_string_u64(l, " samples"); + _record_length_selector.addItem(QString(text), + qVariantFromValue(l)); + g_free(text); + } + + _run_stop_button.setText("Run"); + + addWidget(&_device_selector); + addWidget(&_record_length_selector); + _sample_rate_list_action = addWidget(&_sample_rate_list); + _sample_rate_value_action = addWidget(&_sample_rate_value); + addWidget(&_run_stop_button); + + update_device_selector(); + update_sample_rate_selector(); +} + +struct sr_dev_inst* SamplingBar::get_selected_device() const +{ + const int index = _device_selector.currentIndex(); + if(index < 0) + return NULL; + + return (sr_dev_inst*)_device_selector.itemData( + index).value(); +} + +uint64_t SamplingBar::get_record_length() const +{ + const int index = _record_length_selector.currentIndex(); + if(index < 0) + return 0; + + return _record_length_selector.itemData(index).value(); +} + +uint64_t SamplingBar::get_sample_rate() const +{ + assert(_sample_rate_value_action); + assert(_sample_rate_list_action); + + if(_sample_rate_value_action->isVisible()) + return (uint64_t)_sample_rate_value.value(); + else if(_sample_rate_list_action->isVisible()) + { + const int index = _sample_rate_list.currentIndex(); + if(index < 0) + return 0; + + return _sample_rate_list.itemData(index).value(); + } + + return 0; +} + +void SamplingBar::update_device_selector() +{ + GSList *devices = NULL; + + /* Scan all drivers for all devices. */ + struct sr_dev_driver **const drivers = sr_driver_list(); + for (struct sr_dev_driver **driver = drivers; *driver; driver++) { + GSList *tmpdevs = sr_driver_scan(*driver, NULL); + for (GSList *l = tmpdevs; l; l = l->next) + devices = g_slist_append(devices, l->data); + g_slist_free(tmpdevs); + } + + for (GSList *l = devices; l; l = l->next) { + sr_dev_inst *const sdi = (sr_dev_inst*)l->data; + + QString title; + if (sdi->vendor && sdi->vendor[0]) + title += sdi->vendor + QString(" "); + if (sdi->model && sdi->model[0]) + title += sdi->model + QString(" "); + if (sdi->version && sdi->version[0]) + title += sdi->version + QString(" "); + + _device_selector.addItem(title, qVariantFromValue( + (void*)sdi)); + } + + g_slist_free(devices); +} + +void SamplingBar::update_sample_rate_selector() +{ + const sr_dev_inst *const sdi = get_selected_device(); + const struct sr_samplerates *samplerates; + + assert(_sample_rate_value_action); + assert(_sample_rate_list_action); + + if (sr_info_get(sdi->driver, SR_DI_SAMPLERATES, + (const void **)&samplerates, sdi) != SR_OK) + return; + + _sample_rate_list_action->setVisible(false); + _sample_rate_value_action->setVisible(false); + + if (samplerates->step) + { + _sample_rate_value.setRange( + samplerates->low, samplerates->high); + _sample_rate_value.setSingleStep(samplerates->step); + _sample_rate_value_action->setVisible(true); + } + else + { + _sample_rate_list.clear(); + for (const uint64_t *rate = samplerates->list; + *rate; rate++) + _sample_rate_list.addItem( + sr_samplerate_string(*rate), + qVariantFromValue(*rate)); + _sample_rate_list.show(); + _sample_rate_list_action->setVisible(true); + } +} + +void SamplingBar::on_device_selected() +{ + update_sample_rate_selector(); +} + +} // namespace pv diff --git a/pv/samplingbar.h b/pv/samplingbar.h new file mode 100644 index 00000000..170379e0 --- /dev/null +++ b/pv/samplingbar.h @@ -0,0 +1,74 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SAMPLINGBAR_H +#define SAMPLINGBAR_H + +#include + +#include +#include +#include +#include + +class QAction; + +namespace pv { + +class SamplingBar : public QToolBar +{ + Q_OBJECT + +private: + static const uint64_t RecordLengths[11]; + +public: + SamplingBar(QWidget *parent); + + struct sr_dev_inst* get_selected_device() const; + uint64_t get_record_length() const; + uint64_t get_sample_rate() const; + +signals: + void run_stop(); + +private: + void update_device_selector(); + void update_sample_rate_selector(); + +private slots: + void on_device_selected(); + +private: + QComboBox _device_selector; + + QComboBox _record_length_selector; + + QComboBox _sample_rate_list; + QAction *_sample_rate_list_action; + QDoubleSpinBox _sample_rate_value; + QAction *_sample_rate_value_action; + + QToolButton _run_stop_button; +}; + +} // namespace pv + +#endif // SAMPLINGBAR_H diff --git a/pv/signal.cpp b/pv/signal.cpp new file mode 100644 index 00000000..92ef808c --- /dev/null +++ b/pv/signal.cpp @@ -0,0 +1,93 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "signal.h" + +#include "extdef.h" + +namespace pv { + +const QSizeF Signal::LabelPadding(4, 0); + +Signal::Signal(QString name) : + _name(name) +{ +} + +QString Signal::get_name() const +{ + return _name; +} + +void Signal::paint_label(QPainter &p, const QRect &rect) +{ + p.setBrush(get_colour()); + + const QString text(_name); + const QColor colour = get_colour(); + + const QSizeF text_size = p.boundingRect( + QRectF(0, 0, rect.width(), 0), 0, text).size(); + + const float nominal_offset = get_nominal_offset(rect); + const QSizeF label_size( + text_size.width() + LabelPadding.width() * 2, + text_size.height() + LabelPadding.height() * 2); + const float label_arrow_length = label_size.height() / 2; + const QRectF label_rect( + rect.right() - label_arrow_length - label_size.width(), + nominal_offset - label_size.height() / 2, + label_size.width(), label_size.height()); + + // Paint the label + const QPointF points[] = { + label_rect.topLeft(), + label_rect.topRight(), + QPointF(rect.right(), nominal_offset), + label_rect.bottomRight(), + label_rect.bottomLeft() + }; + + const QPointF highlight_points[] = { + QPointF(label_rect.left() + 1, label_rect.top() + 1), + QPointF(label_rect.right(), label_rect.top() + 1), + QPointF(rect.right() - 1, nominal_offset), + QPointF(label_rect.right(), label_rect.bottom() - 1), + QPointF(label_rect.left() + 1, label_rect.bottom() - 1) + }; + + p.setPen(Qt::transparent); + p.setBrush(colour); + p.drawPolygon(points, countof(points)); + + p.setPen(colour.lighter()); + p.setBrush(Qt::transparent); + p.drawPolygon(highlight_points, countof(highlight_points)); + + p.setPen(colour.darker()); + p.setBrush(Qt::transparent); + p.drawPolygon(points, countof(points)); + + // Paint the text + p.setPen((colour.lightness() > 64) ? Qt::black : Qt::white); + p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, text); +} + +} // namespace pv diff --git a/pv/signal.h b/pv/signal.h new file mode 100644 index 00000000..2351a2f9 --- /dev/null +++ b/pv/signal.h @@ -0,0 +1,79 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include + +#include + +namespace pv { + +class SignalData; + +class Signal +{ +private: + static const QSizeF LabelPadding; + +protected: + Signal(QString name); + +public: + QString get_name() const; + + /** + * Paints the signal with a QPainter + * @param p the QPainter to paint into. + * @param rect the rectangular area to draw the trace into. + * @param scale the scale in seconds per pixel. + * @param offset the time to show at the left hand edge of + * the view in seconds. + **/ + virtual void paint(QPainter &p, const QRect &rect, double scale, + double offset) = 0; + + /** + * Paints the signal label into a QGLWidget. + * @param p the QPainter to paint into. + * @param rect the rectangular area to draw the label into. + */ + virtual void paint_label(QPainter &p, const QRect &rect); + +protected: + + /** + * Get the colour of the logic signal + */ + virtual QColor get_colour() const = 0; + + /** + * When painting into the rectangle, calculate the y + * offset of the zero point. + **/ + virtual int get_nominal_offset(const QRect &rect) const = 0; + +protected: + QString _name; +}; + +} // namespace pv diff --git a/pv/signaldata.cpp b/pv/signaldata.cpp new file mode 100644 index 00000000..cf0cb21f --- /dev/null +++ b/pv/signaldata.cpp @@ -0,0 +1,43 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "signaldata.h" + +using namespace std; + +namespace pv { + +SignalData::SignalData(double samplerate) : + _samplerate(samplerate), + _start_time(0) +{ +} + +double SignalData::get_samplerate() const +{ + return _samplerate; +} + +double SignalData::get_start_time() const +{ + return _start_time; +} + +} // namespace pv diff --git a/pv/signaldata.h b/pv/signaldata.h new file mode 100644 index 00000000..57cd543b --- /dev/null +++ b/pv/signaldata.h @@ -0,0 +1,39 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +namespace pv { + +class SignalData +{ +public: + SignalData(double samplerate); + +public: + double get_samplerate() const; + double get_start_time() const; + +protected: + const double _samplerate; + const double _start_time; +}; + +} // namespace pv diff --git a/pv/sigsession.cpp b/pv/sigsession.cpp new file mode 100644 index 00000000..40c46f04 --- /dev/null +++ b/pv/sigsession.cpp @@ -0,0 +1,184 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "sigsession.h" + +#include "logicdata.h" +#include "logicdatasnapshot.h" +#include "logicsignal.h" + +#include + +#include + +using namespace boost; +using namespace std; + +namespace pv { + +// TODO: This should not be necessary +SigSession* SigSession::_session = NULL; + +SigSession::SigSession() +{ + // TODO: This should not be necessary + _session = this; +} + +SigSession::~SigSession() +{ + // TODO: This should not be necessary + _session = NULL; +} + +void SigSession::load_file(const std::string &name) +{ + if (sr_session_load(name.c_str()) == SR_OK) { + /* sigrok session file */ + sr_session_datafeed_callback_add(data_feed_in_proc); + sr_session_start(); + sr_session_run(); + sr_session_stop(); + } +} + +void SigSession::start_capture(struct sr_dev_inst *sdi, + uint64_t record_length, uint64_t sample_rate) +{ + sr_session_new(); + sr_session_datafeed_callback_add(data_feed_in_proc); + + if (sr_session_dev_add(sdi) != SR_OK) { + qDebug() << "Failed to use device."; + sr_session_destroy(); + return; + } + + if (sr_dev_config_set(sdi, SR_HWCAP_LIMIT_SAMPLES, + &record_length) != SR_OK) { + qDebug() << "Failed to configure time-based sample limit."; + sr_session_destroy(); + return; + } + + if (sr_dev_config_set(sdi, SR_HWCAP_SAMPLERATE, + &sample_rate) != SR_OK) { + qDebug() << "Failed to configure samplerate."; + sr_session_destroy(); + return; + } + + if (sr_session_start() != SR_OK) { + qDebug() << "Failed to start session."; + return; + } + + sr_session_run(); + sr_session_destroy(); +} + +vector< shared_ptr >& SigSession::get_signals() +{ + return _signals; +} + +boost::shared_ptr SigSession::get_data() +{ + return _logic_data; +} + +void SigSession::data_feed_in(const struct sr_dev_inst *sdi, + struct sr_datafeed_packet *packet) +{ + assert(sdi); + assert(packet); + + switch (packet->type) { + case SR_DF_HEADER: + _signals.clear(); + break; + + case SR_DF_META_LOGIC: + { + assert(packet->payload); + + const sr_datafeed_meta_logic &meta_logic = + *(sr_datafeed_meta_logic*)packet->payload; + + // Create an empty LogiData for coming data snapshots + _logic_data.reset(new LogicData(meta_logic)); + assert(_logic_data); + if(!_logic_data) + break; + + // Add the signals + for (int i = 0; i < meta_logic.num_probes; i++) + { + const sr_probe *const probe = + (const sr_probe*)g_slist_nth_data( + sdi->probes, i); + if(probe->enabled) + { + boost::shared_ptr signal( + new LogicSignal(probe->name, + _logic_data, + probe->index)); + _signals.push_back(signal); + } + } + + break; + } + + case SR_DF_LOGIC: + + assert(packet->payload); + if(!_cur_logic_snapshot) + { + // Create a new data snapshot + _cur_logic_snapshot = shared_ptr( + new LogicDataSnapshot( + *(sr_datafeed_logic*)packet->payload)); + _logic_data->push_snapshot(_cur_logic_snapshot); + } + else + { + // Append to the existing data snapshot + _cur_logic_snapshot->append_payload( + *(sr_datafeed_logic*)packet->payload); + } + + break; + + case SR_DF_END: + _cur_logic_snapshot.reset(); + data_updated(); + break; + } +} + +void SigSession::data_feed_in_proc(const struct sr_dev_inst *sdi, + struct sr_datafeed_packet *packet) +{ + assert(_session); + _session->data_feed_in(sdi, packet); +} + +} // namespace pv diff --git a/pv/sigsession.h b/pv/sigsession.h new file mode 100644 index 00000000..40fce89f --- /dev/null +++ b/pv/sigsession.h @@ -0,0 +1,84 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SIGSESSION_H +#define SIGSESSION_H + +#include + +#include +#include + +#include + +extern "C" { +#include +} + +namespace pv { + +class LogicData; +class LogicDataSnapshot; +class Signal; + +class SigSession : public QObject +{ + Q_OBJECT + +public: + SigSession(); + + ~SigSession(); + + void load_file(const std::string &name); + + void start_capture(struct sr_dev_inst* sdi, uint64_t record_length, + uint64_t sample_rate); + + std::vector< boost::shared_ptr >& + get_signals(); + + boost::shared_ptr get_data(); + +private: + void data_feed_in(const struct sr_dev_inst *sdi, + struct sr_datafeed_packet *packet); + + static void data_feed_in_proc(const struct sr_dev_inst *sdi, + struct sr_datafeed_packet *packet); + +private: + std::vector< boost::shared_ptr > _signals; + boost::shared_ptr _logic_data; + boost::shared_ptr _cur_logic_snapshot; + +signals: + void data_updated(); + +private: + // TODO: This should not be necessary. Multiple concurrent + // sessions should should be supported and it should be + // possible to associate a pointer with a sr_session. + static SigSession *_session; +}; + +} // namespace pv + +#endif // SIGSESSION_H diff --git a/pv/view/header.cpp b/pv/view/header.cpp index 4efc0ab7..aaa98ab8 100644 --- a/pv/view/header.cpp +++ b/pv/view/header.cpp @@ -21,8 +21,8 @@ #include "header.h" #include "view.h" -#include "../../signal.h" -#include "../../sigsession.h" +#include "../signal.h" +#include "../sigsession.h" #include diff --git a/pv/view/view.cpp b/pv/view/view.cpp index 697d0714..9c4920f9 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -32,9 +32,9 @@ #include "view.h" #include "viewport.h" -#include "../../logicdata.h" -#include "../../logicdatasnapshot.h" -#include "../../sigsession.h" +#include "../logicdata.h" +#include "../logicdatasnapshot.h" +#include "../sigsession.h" using namespace boost; using namespace std; diff --git a/pv/view/view.h b/pv/view/view.h index 042fa96b..d2abbf00 100644 --- a/pv/view/view.h +++ b/pv/view/view.h @@ -25,9 +25,10 @@ #include +namespace pv { + class SigSession; -namespace pv { namespace view { class Header; diff --git a/pv/view/viewport.cpp b/pv/view/viewport.cpp index d837067f..c1490fc8 100644 --- a/pv/view/viewport.cpp +++ b/pv/view/viewport.cpp @@ -21,8 +21,8 @@ #include "view.h" #include "viewport.h" -#include "../../sigsession.h" -#include "../../signal.h" +#include "../sigsession.h" +#include "../signal.h" #include diff --git a/samplingbar.cpp b/samplingbar.cpp deleted file mode 100644 index b2ca6e06..00000000 --- a/samplingbar.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include - -extern "C" { -#include -} - -#include - -#include "samplingbar.h" - -const uint64_t SamplingBar::RecordLengths[11] = { - 1000000, - 2000000, - 5000000, - 10000000, - 25000000, - 50000000, - 100000000, - 250000000, - 500000000, - 1000000000, - 10000000000 -}; - -SamplingBar::SamplingBar(QWidget *parent) : - QToolBar("Sampling Bar", parent), - _device_selector(this), - _record_length_selector(this), - _sample_rate_list(this), - _run_stop_button(this) -{ - connect(&_run_stop_button, SIGNAL(clicked()), this, SIGNAL(run_stop())); - connect(&_device_selector, SIGNAL(currentIndexChanged (int)), - this, SLOT(on_device_selected())); - - _sample_rate_value.setDecimals(0); - _sample_rate_value.setSuffix("Hz"); - - BOOST_FOREACH(uint64_t l, RecordLengths) - { - char *const text = sr_si_string_u64(l, " samples"); - _record_length_selector.addItem(QString(text), - qVariantFromValue(l)); - g_free(text); - } - - _run_stop_button.setText("Run"); - - addWidget(&_device_selector); - addWidget(&_record_length_selector); - _sample_rate_list_action = addWidget(&_sample_rate_list); - _sample_rate_value_action = addWidget(&_sample_rate_value); - addWidget(&_run_stop_button); - - update_device_selector(); - update_sample_rate_selector(); -} - -struct sr_dev_inst* SamplingBar::get_selected_device() const -{ - const int index = _device_selector.currentIndex(); - if(index < 0) - return NULL; - - return (sr_dev_inst*)_device_selector.itemData( - index).value(); -} - -uint64_t SamplingBar::get_record_length() const -{ - const int index = _record_length_selector.currentIndex(); - if(index < 0) - return 0; - - return _record_length_selector.itemData(index).value(); -} - -uint64_t SamplingBar::get_sample_rate() const -{ - assert(_sample_rate_value_action); - assert(_sample_rate_list_action); - - if(_sample_rate_value_action->isVisible()) - return (uint64_t)_sample_rate_value.value(); - else if(_sample_rate_list_action->isVisible()) - { - const int index = _sample_rate_list.currentIndex(); - if(index < 0) - return 0; - - return _sample_rate_list.itemData(index).value(); - } - - return 0; -} - -void SamplingBar::update_device_selector() -{ - GSList *devices = NULL; - - /* Scan all drivers for all devices. */ - struct sr_dev_driver **const drivers = sr_driver_list(); - for (struct sr_dev_driver **driver = drivers; *driver; driver++) { - GSList *tmpdevs = sr_driver_scan(*driver, NULL); - for (GSList *l = tmpdevs; l; l = l->next) - devices = g_slist_append(devices, l->data); - g_slist_free(tmpdevs); - } - - for (GSList *l = devices; l; l = l->next) { - sr_dev_inst *const sdi = (sr_dev_inst*)l->data; - - QString title; - if (sdi->vendor && sdi->vendor[0]) - title += sdi->vendor + QString(" "); - if (sdi->model && sdi->model[0]) - title += sdi->model + QString(" "); - if (sdi->version && sdi->version[0]) - title += sdi->version + QString(" "); - - _device_selector.addItem(title, qVariantFromValue( - (void*)sdi)); - } - - g_slist_free(devices); -} - -void SamplingBar::update_sample_rate_selector() -{ - const sr_dev_inst *const sdi = get_selected_device(); - const struct sr_samplerates *samplerates; - - assert(_sample_rate_value_action); - assert(_sample_rate_list_action); - - if (sr_info_get(sdi->driver, SR_DI_SAMPLERATES, - (const void **)&samplerates, sdi) != SR_OK) - return; - - _sample_rate_list_action->setVisible(false); - _sample_rate_value_action->setVisible(false); - - if (samplerates->step) - { - _sample_rate_value.setRange( - samplerates->low, samplerates->high); - _sample_rate_value.setSingleStep(samplerates->step); - _sample_rate_value_action->setVisible(true); - } - else - { - _sample_rate_list.clear(); - for (const uint64_t *rate = samplerates->list; - *rate; rate++) - _sample_rate_list.addItem( - sr_samplerate_string(*rate), - qVariantFromValue(*rate)); - _sample_rate_list.show(); - _sample_rate_list_action->setVisible(true); - } -} - -void SamplingBar::on_device_selected() -{ - update_sample_rate_selector(); -} diff --git a/samplingbar.h b/samplingbar.h deleted file mode 100644 index 695c5aa0..00000000 --- a/samplingbar.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SAMPLINGBAR_H -#define SAMPLINGBAR_H - -#include - -#include -#include -#include -#include - -class QAction; - -class SamplingBar : public QToolBar -{ - Q_OBJECT - -private: - static const uint64_t RecordLengths[11]; - -public: - SamplingBar(QWidget *parent); - - struct sr_dev_inst* get_selected_device() const; - uint64_t get_record_length() const; - uint64_t get_sample_rate() const; - -signals: - void run_stop(); - -private: - void update_device_selector(); - void update_sample_rate_selector(); - -private slots: - void on_device_selected(); - -private: - QComboBox _device_selector; - - QComboBox _record_length_selector; - - QComboBox _sample_rate_list; - QAction *_sample_rate_list_action; - QDoubleSpinBox _sample_rate_value; - QAction *_sample_rate_value_action; - - QToolButton _run_stop_button; -}; - -#endif // SAMPLINGBAR_H diff --git a/signal.cpp b/signal.cpp deleted file mode 100644 index 77ee301d..00000000 --- a/signal.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "signal.h" - -#include "extdef.h" - -const QSizeF Signal::LabelPadding(4, 0); - -Signal::Signal(QString name) : - _name(name) -{ -} - -QString Signal::get_name() const -{ - return _name; -} - -void Signal::paint_label(QPainter &p, const QRect &rect) -{ - p.setBrush(get_colour()); - - const QString text(_name); - const QColor colour = get_colour(); - - const QSizeF text_size = p.boundingRect( - QRectF(0, 0, rect.width(), 0), 0, text).size(); - - const float nominal_offset = get_nominal_offset(rect); - const QSizeF label_size( - text_size.width() + LabelPadding.width() * 2, - text_size.height() + LabelPadding.height() * 2); - const float label_arrow_length = label_size.height() / 2; - const QRectF label_rect( - rect.right() - label_arrow_length - label_size.width(), - nominal_offset - label_size.height() / 2, - label_size.width(), label_size.height()); - - // Paint the label - const QPointF points[] = { - label_rect.topLeft(), - label_rect.topRight(), - QPointF(rect.right(), nominal_offset), - label_rect.bottomRight(), - label_rect.bottomLeft() - }; - - const QPointF highlight_points[] = { - QPointF(label_rect.left() + 1, label_rect.top() + 1), - QPointF(label_rect.right(), label_rect.top() + 1), - QPointF(rect.right() - 1, nominal_offset), - QPointF(label_rect.right(), label_rect.bottom() - 1), - QPointF(label_rect.left() + 1, label_rect.bottom() - 1) - }; - - p.setPen(Qt::transparent); - p.setBrush(colour); - p.drawPolygon(points, countof(points)); - - p.setPen(colour.lighter()); - p.setBrush(Qt::transparent); - p.drawPolygon(highlight_points, countof(highlight_points)); - - p.setPen(colour.darker()); - p.setBrush(Qt::transparent); - p.drawPolygon(points, countof(points)); - - // Paint the text - p.setPen((colour.lightness() > 64) ? Qt::black : Qt::white); - p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, text); -} diff --git a/signal.h b/signal.h deleted file mode 100644 index 27bd5562..00000000 --- a/signal.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include -#include -#include - -#include - -class SignalData; - -class Signal -{ -private: - static const QSizeF LabelPadding; - -protected: - Signal(QString name); - -public: - QString get_name() const; - - /** - * Paints the signal with a QPainter - * @param p the QPainter to paint into. - * @param rect the rectangular area to draw the trace into. - * @param scale the scale in seconds per pixel. - * @param offset the time to show at the left hand edge of - * the view in seconds. - **/ - virtual void paint(QPainter &p, const QRect &rect, double scale, - double offset) = 0; - - /** - * Paints the signal label into a QGLWidget. - * @param p the QPainter to paint into. - * @param rect the rectangular area to draw the label into. - */ - virtual void paint_label(QPainter &p, const QRect &rect); - -protected: - - /** - * Get the colour of the logic signal - */ - virtual QColor get_colour() const = 0; - - /** - * When painting into the rectangle, calculate the y - * offset of the zero point. - **/ - virtual int get_nominal_offset(const QRect &rect) const = 0; - -protected: - QString _name; -}; diff --git a/signaldata.cpp b/signaldata.cpp deleted file mode 100644 index d2573ff4..00000000 --- a/signaldata.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "signaldata.h" - -using namespace std; - -SignalData::SignalData(double samplerate) : - _samplerate(samplerate), - _start_time(0) -{ -} - -double SignalData::get_samplerate() const -{ - return _samplerate; -} - -double SignalData::get_start_time() const -{ - return _start_time; -} \ No newline at end of file diff --git a/signaldata.h b/signaldata.h deleted file mode 100644 index d85d4369..00000000 --- a/signaldata.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -class SignalData -{ -public: - SignalData(double samplerate); - -public: - double get_samplerate() const; - double get_start_time() const; - -protected: - const double _samplerate; - const double _start_time; -}; diff --git a/sigsession.cpp b/sigsession.cpp deleted file mode 100644 index ac96833f..00000000 --- a/sigsession.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "sigsession.h" - -#include "logicdata.h" -#include "logicdatasnapshot.h" -#include "logicsignal.h" - -#include - -#include - -using namespace boost; -using namespace std; - -// TODO: This should not be necessary -SigSession* SigSession::_session = NULL; - -SigSession::SigSession() -{ - // TODO: This should not be necessary - _session = this; -} - -SigSession::~SigSession() -{ - // TODO: This should not be necessary - _session = NULL; -} - -void SigSession::load_file(const std::string &name) -{ - if (sr_session_load(name.c_str()) == SR_OK) { - /* sigrok session file */ - sr_session_datafeed_callback_add(data_feed_in_proc); - sr_session_start(); - sr_session_run(); - sr_session_stop(); - } -} - -void SigSession::start_capture(struct sr_dev_inst *sdi, - uint64_t record_length, uint64_t sample_rate) -{ - sr_session_new(); - sr_session_datafeed_callback_add(data_feed_in_proc); - - if (sr_session_dev_add(sdi) != SR_OK) { - qDebug() << "Failed to use device."; - sr_session_destroy(); - return; - } - - if (sr_dev_config_set(sdi, SR_HWCAP_LIMIT_SAMPLES, - &record_length) != SR_OK) { - qDebug() << "Failed to configure time-based sample limit."; - sr_session_destroy(); - return; - } - - if (sr_dev_config_set(sdi, SR_HWCAP_SAMPLERATE, - &sample_rate) != SR_OK) { - qDebug() << "Failed to configure samplerate."; - sr_session_destroy(); - return; - } - - if (sr_session_start() != SR_OK) { - qDebug() << "Failed to start session."; - return; - } - - sr_session_run(); - sr_session_destroy(); -} - -vector< shared_ptr >& SigSession::get_signals() -{ - return _signals; -} - -boost::shared_ptr SigSession::get_data() -{ - return _logic_data; -} - -void SigSession::data_feed_in(const struct sr_dev_inst *sdi, - struct sr_datafeed_packet *packet) -{ - assert(sdi); - assert(packet); - - switch (packet->type) { - case SR_DF_HEADER: - _signals.clear(); - break; - - case SR_DF_META_LOGIC: - { - assert(packet->payload); - - const sr_datafeed_meta_logic &meta_logic = - *(sr_datafeed_meta_logic*)packet->payload; - - // Create an empty LogiData for coming data snapshots - _logic_data.reset(new LogicData(meta_logic)); - assert(_logic_data); - if(!_logic_data) - break; - - // Add the signals - for (int i = 0; i < meta_logic.num_probes; i++) - { - const sr_probe *const probe = - (const sr_probe*)g_slist_nth_data( - sdi->probes, i); - if(probe->enabled) - { - boost::shared_ptr signal( - new LogicSignal(probe->name, - _logic_data, - probe->index)); - _signals.push_back(signal); - } - } - - break; - } - - case SR_DF_LOGIC: - - assert(packet->payload); - if(!_cur_logic_snapshot) - { - // Create a new data snapshot - _cur_logic_snapshot = shared_ptr( - new LogicDataSnapshot( - *(sr_datafeed_logic*)packet->payload)); - _logic_data->push_snapshot(_cur_logic_snapshot); - } - else - { - // Append to the existing data snapshot - _cur_logic_snapshot->append_payload( - *(sr_datafeed_logic*)packet->payload); - } - - break; - - case SR_DF_END: - _cur_logic_snapshot.reset(); - data_updated(); - break; - } -} - -void SigSession::data_feed_in_proc(const struct sr_dev_inst *sdi, - struct sr_datafeed_packet *packet) -{ - assert(_session); - _session->data_feed_in(sdi, packet); -} diff --git a/sigsession.h b/sigsession.h deleted file mode 100644 index f7ec3853..00000000 --- a/sigsession.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2012 Joel Holdsworth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SIGSESSION_H -#define SIGSESSION_H - -#include - -#include -#include - -#include - -extern "C" { -#include -} - -class LogicData; -class LogicDataSnapshot; -class Signal; - -class SigSession : public QObject -{ - Q_OBJECT - -public: - SigSession(); - - ~SigSession(); - - void load_file(const std::string &name); - - void start_capture(struct sr_dev_inst* sdi, uint64_t record_length, - uint64_t sample_rate); - - std::vector< boost::shared_ptr >& - get_signals(); - - boost::shared_ptr get_data(); - -private: - void data_feed_in(const struct sr_dev_inst *sdi, - struct sr_datafeed_packet *packet); - - static void data_feed_in_proc(const struct sr_dev_inst *sdi, - struct sr_datafeed_packet *packet); - -private: - std::vector< boost::shared_ptr > _signals; - boost::shared_ptr _logic_data; - boost::shared_ptr _cur_logic_snapshot; - -signals: - void data_updated(); - -private: - // TODO: This should not be necessary. Multiple concurrent - // sessions should should be supported and it should be - // possible to associate a pointer with a sr_session. - static SigSession *_session; -}; - -#endif // SIGSESSION_H diff --git a/test/logicdatasnapshot.cpp b/test/logicdatasnapshot.cpp index 4e31bfae..503b1dda 100644 --- a/test/logicdatasnapshot.cpp +++ b/test/logicdatasnapshot.cpp @@ -24,10 +24,12 @@ #include #include "../extdef.h" -#include "../logicdatasnapshot.h" +#include "../pv/logicdatasnapshot.h" using namespace std; +using pv::LogicDataSnapshot; + BOOST_AUTO_TEST_SUITE(LogicDataSnapshotTest) void push_logic(LogicDataSnapshot &s, unsigned int length, uint8_t value)