2 * This file is part of the PulseView project.
4 * Copyright (C) 2017 Soeren Apel <soeren@apelpie.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
25 #include "logicsegment.hpp"
26 #include "decodesignal.hpp"
27 #include "signaldata.hpp"
29 #include <pv/binding/decoder.hpp>
30 #include <pv/data/decode/decoder.hpp>
31 #include <pv/data/decode/row.hpp>
32 #include <pv/session.hpp>
34 using boost::optional;
35 using std::lock_guard;
37 using std::make_shared;
39 using std::shared_ptr;
40 using std::unique_lock;
41 using pv::data::decode::Annotation;
42 using pv::data::decode::Decoder;
43 using pv::data::decode::Row;
48 const double DecodeSignal::DecodeMargin = 1.0;
49 const double DecodeSignal::DecodeThreshold = 0.2;
50 const int64_t DecodeSignal::DecodeChunkLength = 10 * 1024 * 1024;
51 const unsigned int DecodeSignal::DecodeNotifyPeriod = 1024;
53 mutex DecodeSignal::global_srd_mutex_;
56 DecodeSignal::DecodeSignal(pv::Session &session) :
57 SignalBase(nullptr, SignalBase::DecodeChannel),
59 logic_mux_data_invalid_(false),
65 frame_complete_(false)
67 connect(&session_, SIGNAL(capture_state_changed(int)),
68 this, SLOT(on_capture_state_changed(int)));
69 connect(&session_, SIGNAL(data_received()),
70 this, SLOT(on_data_received()));
71 connect(&session_, SIGNAL(frame_ended()),
72 this, SLOT(on_frame_ended()));
74 set_name(tr("Empty decoder signal"));
77 DecodeSignal::~DecodeSignal()
79 if (decode_thread_.joinable()) {
80 decode_interrupt_ = true;
81 decode_input_cond_.notify_one();
82 decode_thread_.join();
85 if (logic_mux_thread_.joinable()) {
86 logic_mux_interrupt_ = true;
87 logic_mux_cond_.notify_one();
88 logic_mux_thread_.join();
92 const vector< shared_ptr<Decoder> >& DecodeSignal::decoder_stack() const
97 void DecodeSignal::stack_decoder(srd_decoder *decoder)
100 stack_.push_back(make_shared<decode::Decoder>(decoder));
102 // Set name if this decoder is the first in the list
103 if (stack_.size() == 1)
104 set_name(QString::fromUtf8(decoder->name));
106 // Include the newly created decode channels in the channel list
107 update_channel_list();
109 auto_assign_signals();
113 void DecodeSignal::remove_decoder(int index)
116 assert(index < (int)stack_.size());
118 // Find the decoder in the stack
119 auto iter = stack_.begin();
120 for (int i = 0; i < index; i++, iter++)
121 assert(iter != stack_.end());
123 // Delete the element
126 // Update channels and decoded data
127 update_channel_list();
131 bool DecodeSignal::toggle_decoder_visibility(int index)
133 auto iter = stack_.cbegin();
134 for (int i = 0; i < index; i++, iter++)
135 assert(iter != stack_.end());
137 shared_ptr<Decoder> dec = *iter;
139 // Toggle decoder visibility
142 state = !dec->shown();
149 void DecodeSignal::reset_decode()
152 annotation_count_ = 0;
153 frame_complete_ = false;
154 samples_decoded_ = 0;
155 error_message_ = QString();
160 void DecodeSignal::begin_decode()
162 if (decode_thread_.joinable()) {
163 decode_interrupt_ = true;
164 decode_input_cond_.notify_one();
165 decode_thread_.join();
168 if (logic_mux_thread_.joinable()) {
169 logic_mux_interrupt_ = true;
170 logic_mux_cond_.notify_one();
171 logic_mux_thread_.join();
176 // Check that all decoders have the required channels
177 for (const shared_ptr<decode::Decoder> &dec : stack_)
178 if (!dec->have_required_channels()) {
179 error_message_ = tr("One or more required channels "
180 "have not been specified");
184 // Add annotation classes
185 for (const shared_ptr<decode::Decoder> &dec : stack_) {
187 const srd_decoder *const decc = dec->decoder();
188 assert(dec->decoder());
190 // Add a row for the decoder if it doesn't have a row list
191 if (!decc->annotation_rows)
192 rows_[Row(decc)] = decode::RowData();
194 // Add the decoder rows
195 for (const GSList *l = decc->annotation_rows; l; l = l->next) {
196 const srd_decoder_annotation_row *const ann_row =
197 (srd_decoder_annotation_row *)l->data;
200 const Row row(decc, ann_row);
202 // Add a new empty row data object
203 rows_[row] = decode::RowData();
205 // Map out all the classes
206 for (const GSList *ll = ann_row->ann_classes;
208 class_rows_[make_pair(decc,
209 GPOINTER_TO_INT(ll->data))] = row;
213 // Make sure the logic output data is complete and up-to-date
214 logic_mux_thread_ = std::thread(&DecodeSignal::logic_mux_proc, this);
216 // Update the samplerate and start time
217 start_time_ = segment_->start_time();
218 samplerate_ = segment_->samplerate();
219 if (samplerate_ == 0.0)
222 decode_interrupt_ = false;
223 decode_thread_ = std::thread(&DecodeSignal::decode_proc, this);
226 QString DecodeSignal::error_message() const
228 lock_guard<mutex> lock(output_mutex_);
229 return error_message_;
232 const vector<data::DecodeChannel> DecodeSignal::get_channels() const
237 void DecodeSignal::auto_assign_signals()
239 bool new_assignment = false;
241 // Try to auto-select channels that don't have signals assigned yet
242 for (data::DecodeChannel &ch : channels_) {
243 if (ch.assigned_signal)
246 for (shared_ptr<data::SignalBase> s : session_.signalbases())
247 if (s->logic_data() && (ch.name.toLower().contains(s->name().toLower()))) {
248 ch.assigned_signal = s.get();
249 new_assignment = true;
253 if (new_assignment) {
254 logic_mux_data_invalid_ = true;
259 void DecodeSignal::assign_signal(const uint16_t channel_id, const SignalBase *signal)
261 for (data::DecodeChannel &ch : channels_)
262 if (ch.id == channel_id) {
263 ch.assigned_signal = signal;
264 logic_mux_data_invalid_ = true;
272 void DecodeSignal::set_initial_pin_state(const uint16_t channel_id, const int init_state)
274 for (data::DecodeChannel &ch : channels_)
275 if (ch.id == channel_id)
276 ch.initial_pin_state = init_state;
283 double DecodeSignal::samplerate() const
288 const pv::util::Timestamp& DecodeSignal::start_time() const
293 int64_t DecodeSignal::get_working_sample_count() const
295 // The working sample count is the highest sample number for
296 // which all used signals have data available, so go through
297 // all channels and use the lowest overall sample count of the
300 // TODO Currently, we assume only a single segment exists
302 int64_t count = std::numeric_limits<int64_t>::max();
303 bool no_signals_assigned = true;
305 for (const data::DecodeChannel &ch : channels_)
306 if (ch.assigned_signal) {
307 no_signals_assigned = false;
309 const shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
310 if (!logic_data || logic_data->logic_segments().empty())
313 const shared_ptr<LogicSegment> segment = logic_data->logic_segments().front();
314 count = min(count, (int64_t)segment->get_sample_count());
317 return (no_signals_assigned ? 0 : count);
320 int64_t DecodeSignal::get_decoded_sample_count() const
322 lock_guard<mutex> decode_lock(output_mutex_);
323 return samples_decoded_;
326 vector<Row> DecodeSignal::visible_rows() const
328 lock_guard<mutex> lock(output_mutex_);
332 for (const shared_ptr<decode::Decoder> &dec : stack_) {
337 const srd_decoder *const decc = dec->decoder();
338 assert(dec->decoder());
340 // Add a row for the decoder if it doesn't have a row list
341 if (!decc->annotation_rows)
342 rows.emplace_back(decc);
344 // Add the decoder rows
345 for (const GSList *l = decc->annotation_rows; l; l = l->next) {
346 const srd_decoder_annotation_row *const ann_row =
347 (srd_decoder_annotation_row *)l->data;
349 rows.emplace_back(decc, ann_row);
356 void DecodeSignal::get_annotation_subset(
357 vector<pv::data::decode::Annotation> &dest,
358 const decode::Row &row, uint64_t start_sample,
359 uint64_t end_sample) const
361 lock_guard<mutex> lock(output_mutex_);
363 const auto iter = rows_.find(row);
364 if (iter != rows_.end())
365 (*iter).second.get_annotation_subset(dest,
366 start_sample, end_sample);
369 void DecodeSignal::save_settings(QSettings &settings) const
371 SignalBase::save_settings(settings);
373 // TODO Save decoder stack, channel mapping and decoder options
376 void DecodeSignal::restore_settings(QSettings &settings)
378 SignalBase::restore_settings(settings);
380 // TODO Restore decoder stack, channel mapping and decoder options
383 uint64_t DecodeSignal::inc_annotation_count()
385 return (annotation_count_++);
388 void DecodeSignal::update_channel_list()
390 vector<data::DecodeChannel> prev_channels = channels_;
395 // Copy existing entries, create new as needed
396 for (shared_ptr<Decoder> decoder : stack_) {
397 const srd_decoder* srd_d = decoder->decoder();
400 // Mandatory channels
401 for (l = srd_d->channels; l; l = l->next) {
402 const struct srd_channel *const pdch = (struct srd_channel *)l->data;
403 bool ch_added = false;
405 // Copy but update ID if this channel was in the list before
406 for (data::DecodeChannel &ch : prev_channels)
407 if (ch.pdch_ == pdch) {
409 channels_.push_back(ch);
415 // Create new entry without a mapped signal
416 data::DecodeChannel ch = {id++, false, nullptr,
417 QString::fromUtf8(pdch->name), QString::fromUtf8(pdch->desc),
418 SRD_INITIAL_PIN_SAME_AS_SAMPLE0, decoder, pdch};
419 channels_.push_back(ch);
424 for (l = srd_d->opt_channels; l; l = l->next) {
425 const struct srd_channel *const pdch = (struct srd_channel *)l->data;
426 bool ch_added = false;
428 // Copy but update ID if this channel was in the list before
429 for (data::DecodeChannel &ch : prev_channels)
430 if (ch.pdch_ == pdch) {
432 channels_.push_back(ch);
438 // Create new entry without a mapped signal
439 data::DecodeChannel ch = {id++, true, nullptr,
440 QString::fromUtf8(pdch->name), QString::fromUtf8(pdch->desc),
441 SRD_INITIAL_PIN_SAME_AS_SAMPLE0, decoder, pdch};
442 channels_.push_back(ch);
447 // Invalidate the logic output data if the channel assignment changed
448 if (prev_channels.size() != channels_.size()) {
449 // The number of channels changed, there's definitely a difference
450 logic_mux_data_invalid_ = true;
452 // Same number but assignment may still differ, so compare all channels
453 for (size_t i = 0; i < channels_.size(); i++) {
454 const data::DecodeChannel &p_ch = prev_channels[i];
455 const data::DecodeChannel &ch = channels_[i];
457 if ((p_ch.pdch_ != ch.pdch_) ||
458 (p_ch.assigned_signal != ch.assigned_signal)) {
459 logic_mux_data_invalid_ = true;
469 void DecodeSignal::logic_mux_proc()
474 optional<int64_t> DecodeSignal::wait_for_data() const
476 unique_lock<mutex> input_lock(input_mutex_);
478 // Do wait if we decoded all samples but we're still capturing
479 // Do not wait if we're done capturing
480 while (!decode_interrupt_ && !frame_complete_ &&
481 (samples_decoded_ >= sample_count_) &&
482 (session_.get_capture_state() != Session::Stopped)) {
484 decode_input_cond_.wait(input_lock);
487 // Return value is valid if we're not aborting the decode,
488 return boost::make_optional(!decode_interrupt_ &&
489 // and there's more work to do...
490 (samples_decoded_ < sample_count_ || !frame_complete_) &&
491 // and if the end of the data hasn't been reached yet
492 (!((samples_decoded_ >= sample_count_) && (session_.get_capture_state() == Session::Stopped))),
496 void DecodeSignal::decode_data(
497 const int64_t abs_start_samplenum, const int64_t sample_count,
498 srd_session *const session)
500 const unsigned int unit_size = segment_->unit_size();
501 const unsigned int chunk_sample_count = DecodeChunkLength / unit_size;
503 for (int64_t i = abs_start_samplenum;
504 !decode_interrupt_ && (i < (abs_start_samplenum + sample_count));
505 i += chunk_sample_count) {
507 const int64_t chunk_end = min(i + chunk_sample_count,
508 abs_start_samplenum + sample_count);
510 const uint8_t* chunk = segment_->get_samples(i, chunk_end);
512 if (srd_session_send(session, i, chunk_end, chunk,
513 (chunk_end - i) * unit_size, unit_size) != SRD_OK) {
514 error_message_ = tr("Decoder reported an error");
521 lock_guard<mutex> lock(output_mutex_);
522 samples_decoded_ = chunk_end;
527 void DecodeSignal::decode_proc()
529 optional<int64_t> sample_count;
530 srd_session *session;
531 srd_decoder_inst *prev_di = nullptr;
533 // Prevent any other decode threads from accessing libsigrokdecode
534 lock_guard<mutex> srd_lock(global_srd_mutex_);
536 // Create the session
537 srd_session_new(&session);
540 // Create the decoders
541 for (const shared_ptr<decode::Decoder> &dec : stack_) {
542 srd_decoder_inst *const di = dec->create_decoder_inst(session);
545 error_message_ = tr("Failed to create decoder instance");
546 srd_session_destroy(session);
551 srd_inst_stack(session, prev_di, di);
556 // Get the initial sample count
558 unique_lock<mutex> input_lock(input_mutex_);
559 sample_count = sample_count_ = get_working_sample_count();
563 srd_session_metadata_set(session, SRD_CONF_SAMPLERATE,
564 g_variant_new_uint64(samplerate_));
566 srd_pd_output_callback_add(session, SRD_OUTPUT_ANN,
567 DecodeSignal::annotation_callback, this);
569 srd_session_start(session);
571 int64_t abs_start_samplenum = 0;
573 decode_data(abs_start_samplenum, *sample_count, session);
574 abs_start_samplenum = *sample_count;
575 } while (error_message_.isEmpty() && (sample_count = wait_for_data()));
577 // Make sure all annotations are known to the frontend
580 // Destroy the session
581 srd_session_destroy(session);
584 void DecodeSignal::annotation_callback(srd_proto_data *pdata, void *decode_signal)
589 DecodeSignal *const ds = (DecodeSignal*)decode_signal;
592 lock_guard<mutex> lock(ds->output_mutex_);
594 const decode::Annotation a(pdata);
598 assert(pdata->pdo->di);
599 const srd_decoder *const decc = pdata->pdo->di->decoder;
602 auto row_iter = ds->rows_.end();
604 // Try looking up the sub-row of this class
605 const auto r = ds->class_rows_.find(make_pair(decc, a.format()));
606 if (r != ds->class_rows_.end())
607 row_iter = ds->rows_.find((*r).second);
609 // Failing that, use the decoder as a key
610 row_iter = ds->rows_.find(Row(decc));
613 assert(row_iter != ds->rows_.end());
614 if (row_iter == ds->rows_.end()) {
615 qDebug() << "Unexpected annotation: decoder = " << decc <<
616 ", format = " << a.format();
621 // Add the annotation
622 (*row_iter).second.push_annotation(a);
624 // Notify the frontend every DecodeNotifyPeriod annotations
625 if (ds->inc_annotation_count() % DecodeNotifyPeriod == 0)
626 ds->new_annotations();
629 void DecodeSignal::on_capture_state_changed(int state)
631 // If a new acquisition was started, we need to start decoding from scratch
632 if (state == Session::Running)
636 void DecodeSignal::on_data_received()
638 logic_mux_cond_.notify_one();
641 void DecodeSignal::on_frame_ended()
643 logic_mux_cond_.notify_one();