#include "data/decoderstack.hpp"
#include "data/logic.hpp"
#include "data/logicsegment.hpp"
+#include "data/signalbase.hpp"
#include "data/decode/decoder.hpp"
#include "devices/hardwaredevice.hpp"
if (device_)
device_->close();
+ device_.reset();
+
+ // Remove all stored data
+ signals_.clear();
+ {
+ shared_lock<shared_mutex> lock(signals_mutex_);
+ for (const shared_ptr<data::SignalData> d : all_signal_data_)
+ d->clear();
+ }
+ all_signal_data_.clear();
+ cur_logic_segment_.reset();
+
+ for (auto entry : cur_analog_segments_) {
+ shared_ptr<sigrok::Channel>(entry.first).reset();
+ shared_ptr<data::AnalogSegment>(entry.second).reset();
+ }
+
+ logic_data_.reset();
+ decode_traces_.clear();
+
+ signals_changed();
+
device_ = std::move(device);
- device_->open();
+
+ try {
+ device_->open();
+ } catch (const QString &e) {
+ device_.reset();
+ device_selected();
+ throw;
+ }
+
device_->session()->add_datafeed_callback([=]
(shared_ptr<sigrok::Device> device, shared_ptr<Packet> packet) {
data_feed_in(device, packet);
});
- decode_traces_.clear();
-
update_signals();
device_selected();
}
void Session::start_capture(function<void (const QString)> error_handler)
{
+ if (!device_) {
+ error_handler(tr("No active device set, can't start acquisition."));
+ return;
+ }
+
stop_capture();
// Check that at least one channel is enabled
- assert(device_);
const shared_ptr<sigrok::Device> sr_dev = device_->device();
if (sr_dev) {
const auto channels = sr_dev->channels();
}
// Clear signal data
- for (const shared_ptr<data::SignalData> d : get_data())
- d->clear();
+ {
+ shared_lock<shared_mutex> lock(signals_mutex_);
+ for (const shared_ptr<data::SignalData> d : all_signal_data_)
+ d->clear();
+ }
// Begin the session
sampling_thread_ = std::thread(
- &Session::sample_thread_proc, this, device_,
- error_handler);
+ &Session::sample_thread_proc, this, error_handler);
}
void Session::stop_capture()
sampling_thread_.join();
}
-set< shared_ptr<data::SignalData> > Session::get_data() const
-{
- shared_lock<shared_mutex> lock(signals_mutex_);
- set< shared_ptr<data::SignalData> > data;
- for (const shared_ptr<view::Signal> sig : signals_) {
- assert(sig);
- data.insert(sig->data());
- }
-
- return data;
-}
-
double Session::get_samplerate() const
{
double samplerate = 0.0;
- for (const shared_ptr<pv::data::SignalData> d : get_data()) {
- assert(d);
- const vector< shared_ptr<pv::data::Segment> > segments =
- d->segments();
- for (const shared_ptr<pv::data::Segment> &s : segments)
- samplerate = std::max(samplerate, s->samplerate());
+ {
+ shared_lock<shared_mutex> lock(signals_mutex_);
+ for (const shared_ptr<pv::data::SignalData> d : all_signal_data_) {
+ assert(d);
+ const vector< shared_ptr<pv::data::Segment> > segments =
+ d->segments();
+ for (const shared_ptr<pv::data::Segment> &s : segments)
+ samplerate = std::max(samplerate, s->samplerate());
+ }
}
-
// If there is no sample rate given we use samples as unit
if (samplerate == 0.0)
samplerate = 1.0;
dynamic_pointer_cast<view::LogicSignal>(s);
if (l && QString::fromUtf8(pdch->name).
toLower().contains(
- l->name().toLower()))
+ s->base()->name().toLower()))
channels[pdch] = l;
}
decoder_stack->stack().front()->set_channels(channels);
// Create the decode signal
+ shared_ptr<data::SignalBase> signalbase =
+ shared_ptr<data::SignalBase>(new data::SignalBase(nullptr));
+
shared_ptr<view::DecodeTrace> d(
- new view::DecodeTrace(*this, decoder_stack,
+ new view::DecodeTrace(*this, signalbase, decoder_stack,
decode_traces_.size()));
decode_traces_.push_back(d);
} catch (std::runtime_error e) {
void Session::update_signals()
{
- assert(device_);
+ if (!device_) {
+ signals_.clear();
+ logic_data_.reset();
+ return;
+ }
lock_guard<recursive_mutex> lock(data_mutex_);
signals_.clear();
for (auto channel : sr_dev->channels()) {
+ shared_ptr<data::SignalBase> signalbase;
shared_ptr<view::Signal> signal;
// Find the channel in the old signals
const auto iter = std::find_if(
prev_sigs.cbegin(), prev_sigs.cend(),
[&](const shared_ptr<view::Signal> &s) {
- return s->channel() == channel;
+ return s->base()->channel() == channel;
});
if (iter != prev_sigs.end()) {
// Copy the signal from the old set to the new
logic_data_);
} else {
// Create a new signal
+ signalbase = shared_ptr<data::SignalBase>(
+ new data::SignalBase(channel));
+
switch(channel->type()->id()) {
case SR_CHANNEL_LOGIC:
signal = shared_ptr<view::Signal>(
new view::LogicSignal(*this,
- device_, channel,
- logic_data_));
+ device_, signalbase, logic_data_));
+ all_signal_data_.insert(logic_data_);
+ signalbases_.insert(signalbase);
break;
case SR_CHANNEL_ANALOG:
{
- shared_ptr<data::Analog> data(
- new data::Analog());
+ shared_ptr<data::Analog> data(new data::Analog());
+ signalbase->set_data(data);
signal = shared_ptr<view::Signal>(
new view::AnalogSignal(
- *this, channel, data));
+ *this, signalbase));
+ all_signal_data_.insert(data);
+ signalbases_.insert(signalbase);
break;
}
signals_changed();
}
-shared_ptr<view::Signal> Session::signal_from_channel(
- shared_ptr<Channel> channel) const
+shared_ptr<data::SignalBase> Session::signalbase_from_channel(
+ shared_ptr<sigrok::Channel> channel) const
{
- lock_guard<boost::shared_mutex> lock(signals_mutex_);
- for (shared_ptr<view::Signal> sig : signals_) {
+ for (shared_ptr<data::SignalBase> sig : signalbases_) {
assert(sig);
if (sig->channel() == channel)
return sig;
}
- return shared_ptr<view::Signal>();
+ return shared_ptr<data::SignalBase>();
}
-void Session::sample_thread_proc(shared_ptr<devices::Device> device,
- function<void (const QString)> error_handler)
+void Session::sample_thread_proc(function<void (const QString)> error_handler)
{
- assert(device);
assert(error_handler);
- (void)device;
+ if (!device_)
+ return;
cur_samplerate_ = device_->read_config<uint64_t>(ConfigKey::SAMPLERATE);
// The channel containing most samples should be most accurate
uint64_t sample_count = 0;
- for (const shared_ptr<pv::data::SignalData> d : get_data()) {
- assert(d);
- uint64_t temp_count = 0;
-
- const vector< shared_ptr<pv::data::Segment> > segments =
- d->segments();
- for (const shared_ptr<pv::data::Segment> &s : segments)
- temp_count += s->get_sample_count();
-
- if (temp_count > sample_count)
- sample_count = temp_count;
+ {
+ shared_lock<shared_mutex> lock(signals_mutex_);
+ for (const shared_ptr<pv::data::SignalData> d : all_signal_data_) {
+ assert(d);
+ uint64_t temp_count = 0;
+
+ const vector< shared_ptr<pv::data::Segment> > segments =
+ d->segments();
+ for (const shared_ptr<pv::data::Segment> &s : segments)
+ temp_count += s->get_sample_count();
+
+ if (temp_count > sample_count)
+ sample_count = temp_count;
+ }
}
trigger_event(sample_count / get_samplerate());
if (iter != cur_analog_segments_.end())
segment = (*iter).second;
else {
- // If no segment was found, this means we havn't
+ // If no segment was found, this means we haven't
// created one yet. i.e. this is the first packet
// in the sweep containing this segment.
sweep_beginning = true;
cur_analog_segments_[channel] = segment;
// Find the analog data associated with the channel
- shared_ptr<view::AnalogSignal> sig =
- dynamic_pointer_cast<view::AnalogSignal>(
- signal_from_channel(channel));
- assert(sig);
+ shared_ptr<data::SignalBase> base = signalbase_from_channel(channel);
+ assert(base);
- shared_ptr<data::Analog> data(sig->analog_data());
+ shared_ptr<data::Analog> data(base->analog_data());
assert(data);
// Push the segment into the analog data.