From: Soeren Apel Date: Tue, 3 Mar 2020 21:23:05 +0000 (+0100) Subject: Continue work on SRD_OUTPUT_LOGIC X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=883041605ce8536ece950b1de191cfe71068dfba;p=pulseview.git Continue work on SRD_OUTPUT_LOGIC --- diff --git a/pv/data/decode/decoder.cpp b/pv/data/decode/decoder.cpp index b1cf42d5..ebcbc1c9 100644 --- a/pv/data/decode/decoder.cpp +++ b/pv/data/decode/decoder.cpp @@ -341,7 +341,7 @@ const vector Decoder::logic_output_channels() const (srd_decoder_logic_output_channel*)l->data; result.emplace_back(QString::fromUtf8(ch_data->id), - QString::fromUtf8(ch_data->desc), ch_data->samplerate); + QString::fromUtf8(ch_data->desc)); } return result; diff --git a/pv/data/decode/decoder.hpp b/pv/data/decode/decoder.hpp index e86deccd..ac1052e6 100644 --- a/pv/data/decode/decoder.hpp +++ b/pv/data/decode/decoder.hpp @@ -90,10 +90,9 @@ struct DecodeChannel }; struct DecoderLogicOutputChannel { - DecoderLogicOutputChannel (QString id, QString desc, uint64_t sr) : - id(id), desc(desc), samplerate(sr) {}; + DecoderLogicOutputChannel (QString id, QString desc) : + id(id), desc(desc) {}; QString id, desc; - uint64_t samplerate; }; struct DecodeBinaryClassInfo diff --git a/pv/data/decodesignal.cpp b/pv/data/decodesignal.cpp index 9decbe30..2de6fbee 100644 --- a/pv/data/decodesignal.cpp +++ b/pv/data/decodesignal.cpp @@ -168,6 +168,10 @@ void DecodeSignal::reset_decode(bool shutting_down) current_segment_id_ = 0; segments_.clear(); + for (const shared_ptr& dec : stack_) + if (dec->has_logic_output()) + output_logic_[dec->get_srd_decoder()]->clear(); + logic_mux_data_.reset(); logic_mux_data_invalid_ = true; @@ -380,11 +384,11 @@ void DecodeSignal::update_output_signals() if (!ch_exists) { shared_ptr logic_data = make_shared(logic_channels.size()); - logic_data->set_samplerate(first_ch.samplerate); + logic_data->set_samplerate(get_samplerate()); output_logic_[dec->get_srd_decoder()] = logic_data; shared_ptr logic_segment = make_shared( - *logic_data, 0, (logic_data->num_channels() + 7) / 8, first_ch.samplerate); + *logic_data, 0, (logic_data->num_channels() + 7) / 8, get_samplerate()); logic_data->push_segment(logic_segment); uint index = 0; @@ -399,12 +403,17 @@ void DecodeSignal::update_output_signals() session_.add_generated_signal(signal); index++; } + } else { + shared_ptr logic_data = output_logic_[dec->get_srd_decoder()]; + logic_data->set_samplerate(get_samplerate()); + for (shared_ptr& segment : logic_data->logic_segments()) + segment->set_samplerate(get_samplerate()); } } } // TODO Delete signals that no longer have a corresponding decoder (also from session) - // TODO Check whether all sample rates are the same as the session's + // TODO Assert that all sample rates are the same as the session's // TODO Set colors to the same as the decoder's background color } @@ -1417,6 +1426,9 @@ void DecodeSignal::start_srd_session() return; } + // Update the samplerates for the output logic channels + update_output_signals(); + // Create the session srd_session_new(&srd_session_); assert(srd_session_); @@ -1733,16 +1745,20 @@ void DecodeSignal::logic_output_callback(srd_proto_data *pdata, void *decode_sig last_segment = dynamic_pointer_cast(segments.back()); else { // Happens when the data was cleared - all segments are gone then + // segment_id is always 0 as it's the first segment last_segment = make_shared( *output_logic, 0, (output_logic->num_channels() + 7) / 8, output_logic->get_samplerate()); output_logic->push_segment(last_segment); } - last_segment->append_subsignal_payload(pdl->logic_class, (void*)pdl->data, pdl->size); + vector data; + for (unsigned int i = pdata->start_sample; i < pdata->end_sample; i++) + data.emplace_back(*((uint8_t*)pdl->data)); + + last_segment->append_subsignal_payload(pdl->logic_class, data.data(), data.size()); - qInfo() << "Received" << pdl->size << "bytes /" << pdl->size \ - << "samples of logic output for class" << pdl->logic_class << "from decoder" \ - << QString::fromUtf8(decc->name); + qInfo() << "Received logic output state change for class" << pdl->logic_class << "from decoder" \ + << QString::fromUtf8(decc->name) << "from" << pdata->start_sample << "to" << pdata->end_sample; } void DecodeSignal::on_capture_state_changed(int state) diff --git a/pv/data/logicsegment.cpp b/pv/data/logicsegment.cpp index 354c14f8..d02a23a2 100644 --- a/pv/data/logicsegment.cpp +++ b/pv/data/logicsegment.cpp @@ -365,18 +365,22 @@ void LogicSegment::append_payload(void *data, uint64_t data_size) void LogicSegment::append_subsignal_payload(unsigned int index, void *data, uint64_t data_size) { - static vector merged_data; // Using static also places it on the heap + static vector merged_data; // To preserve intermediate data across calls - for (uint64_t i = 0; i < data_size * unit_size_; i++) - merged_data.emplace_back(0); + if (index == 0) + for (uint64_t i = 0; i < data_size * unit_size_; i++) + merged_data.emplace_back(0); // Set the bits for this sub-signal where needed // Note: the bytes in *data must either be 0 or 1, nothing else - unsigned int index_byte = index / 8; + unsigned int index_byte_offs = index / 8; + uint8_t* output_data = merged_data.data() + index_byte_offs; + uint8_t* input_data = (uint8_t*)data; + for (uint64_t i = 0; i < data_size; i++) { - unsigned int offs = i * unit_size_ + index_byte; - uint8_t* data_byte = merged_data.data() + offs; - *data_byte |= *((uint8_t*)data + i) << index; + assert((i * unit_size_ + index_byte_offs) < merged_data.size()); + *output_data |= (input_data[i] << index); + output_data += unit_size_; } if (index == owner_.num_channels() - 1) {