diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp index efcad23e..ce6f0b6c 100644 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -439,7 +439,7 @@ void DecoderStack::do_decode_work() for(auto s : _session->get_signals()) { if(s->get_index() == (*dec->channels().begin()).second && s->signal_type() == LOGIC_SIGNAL) { - _snapshot = ((pv::view::LogicSignal*)s)->logic_data(); + _snapshot = ((pv::view::LogicSignal*)s)->data(); if (_snapshot != NULL) break; } diff --git a/DSView/pv/data/mathstack.cpp b/DSView/pv/data/mathstack.cpp index 4e38a256..a3656af6 100644 --- a/DSView/pv/data/mathstack.cpp +++ b/DSView/pv/data/mathstack.cpp @@ -317,7 +317,7 @@ void MathStack::calc_math() _math_state = Running; - const auto data = _dsoSig1->dso_data(); + const auto data = _dsoSig1->data(); if (data->empty() || _math.size() < _total_sample_num) return; diff --git a/DSView/pv/data/spectrumstack.cpp b/DSView/pv/data/spectrumstack.cpp index 8566fdd6..e089f270 100644 --- a/DSView/pv/data/spectrumstack.cpp +++ b/DSView/pv/data/spectrumstack.cpp @@ -176,7 +176,7 @@ void SpectrumStack::calc_fft() if (s->signal_type() == DSO_SIGNAL) { dsoSig = (view::DsoSignal*)s; if (dsoSig->get_index() == _index && dsoSig->enabled()) { - data = dsoSig->dso_data(); + data = dsoSig->data(); break; } } diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 2b5a50e0..14b8aced 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -893,7 +893,6 @@ namespace pv } } - //_session->init_signals(); _session->reload(); // load signal setting diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 7558e1d7..ed957074 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -64,6 +64,13 @@ namespace pv _cur_samplelimits = 0; } + void SessionData::clear() + { + logic.clear(); + analog.clear(); + dso.clear(); + } + // TODO: This should not be necessary SigSession *SigSession::_session = NULL; @@ -124,9 +131,7 @@ namespace pv SigSession::~SigSession() { for(auto p : _data_list){ - p->get_logic()->clear(); - p->get_dso()->clear(); - p->get_analog()->clear(); + p->clear(); delete p; } _data_list.clear(); @@ -375,24 +380,30 @@ namespace pv set_cur_snap_samplerate(_device_agent.get_sample_rate()); set_cur_samplelimits(_device_agent.get_sample_limit()); set_stop_scale(1); + _data_updated = false; _trigger_flag = false; _trigger_ch = 0; _hw_replied = false; _rt_refresh_time_id = 0; - _rt_ck_refresh_time_id = 0; - - int work_mode = _device_agent.get_work_mode(); - if (work_mode == DSO || work_mode == ANALOG) - _feed_timer.Start(FeedInterval); - else - _feed_timer.Stop(); - + _rt_ck_refresh_time_id = 0; _noData_cnt = 0; _data_lock = false; - // container init - container_init(); + // Init data container + _capture_data->clear(); + + int mode = _device_agent.get_work_mode(); + if (mode == DSO) + { + for (auto m : _spectrum_traces){ + m->get_spectrum_stack()->init(); + } + + if (_math_trace){ + _math_trace->get_math_stack()->init(); + } + } // update current hw offset for (auto s : _signals) @@ -406,28 +417,12 @@ namespace pv analogSig->set_zero_ratio(analogSig->get_zero_ratio()); } } - } - void SigSession::container_init() - { - _capture_data->get_logic()->init(); - _capture_data->get_analog()->init(); - _capture_data->get_dso()->init(); - - // SpectrumStack - for (auto m : _spectrum_traces) - { - m->get_spectrum_stack()->init(); - } - - if (_math_trace) - _math_trace->get_math_stack()->init(); - - // DecoderStack - for (auto d : _decode_traces) - { - d->decoder()->init(); - } + // Start timer + if (mode == DSO || mode == ANALOG) + _feed_timer.Start(FeedInterval); + else + _feed_timer.Stop(); } bool SigSession::start_capture(bool instant) @@ -453,6 +448,11 @@ namespace pv dsv_err("%s", "Error!Device is running."); return false; } + + if (_view_data != _capture_data){ + _capture_data->clear(); + _capture_data = _view_data; + } // update setting if (_device_agent.is_file()) @@ -465,30 +465,13 @@ namespace pv _callback->trigger_message(DSV_MSG_START_COLLECT_WORK_PREV); - _view_data->get_dso()->set_threshold(0); // Reset threshold value - - if (exec_capture()) + if (exec_capture(true)) { _capture_time_id++; _is_working = true; - _callback->trigger_message(DSV_MSG_START_COLLECT_WORK); + _callback->trigger_message(DSV_MSG_START_COLLECT_WORK); - if (_device_agent.get_work_mode() == LOGIC) - { - for (auto de : _decode_traces) - { - de->decoder()->set_capture_end_flag(false); - - // On real-time mode, create the decode task when capture started. - if (is_realtime_mode()) - { - de->frame_ended(); - add_decode_task(de); - } - } - } - - // Start a timer, for able to refresh the view per (1000 / 30)ms + // Start a timer, for able to refresh the view per (1000 / 30)ms on real-time mode. if (is_realtime_mode()){ _refresh_rt_timer.Start(1000 / 30); } @@ -498,26 +481,25 @@ namespace pv return false; } - bool SigSession::exec_capture() + bool SigSession::exec_capture(bool bFirst) { if (_device_agent.is_collecting()) { dsv_err("%s", "Error!Device is running."); return false; } - - // Clear the previous decoder tasks. - int run_dex = 0; - clear_all_decode_task(run_dex); - - // reset measure of dso signal - for (auto s : _signals) - { - if (s->signal_type() == DSO_SIGNAL){ - view::DsoSignal *dsoSig = (view::DsoSignal*)s; - dsoSig->set_mValid(false); + + int mode = _device_agent.get_work_mode(); + if (mode == DSO || mode == ANALOG) + { + // reset measure of dso signal + for (auto s : _signals){ + if (s->signal_type() == DSO_SIGNAL){ + view::DsoSignal *dsoSig = (view::DsoSignal*)s; + dsoSig->set_mValid(false); + } } - } + } if (_device_agent.have_enabled_channel() == false) { @@ -533,6 +515,29 @@ namespace pv return false; } + if (mode == LOGIC) + { + // On repeate mode, the last data can use to decode, so can't remove the current decode task. + // And on this mode, the decode task will be created when capture end. + if (is_repeat_mode() == false || bFirst){ + int run_dex = 0; + clear_all_decode_task(run_dex); + clear_decode_result(); + } + + for (auto de : _decode_traces) + { + de->decoder()->set_capture_end_flag(false); + + // On real-time mode, create the decode task when capture started. + if (is_realtime_mode()) + { + de->frame_ended(); + add_decode_task(de); + } + } + } + return true; } @@ -654,11 +659,8 @@ namespace pv } } - void SigSession::init_signals() - { - assert(!_is_working); - + { if (_device_agent.have_instance() == false) { assert(false); @@ -822,16 +824,12 @@ namespace pv ds_lock_guard lock(_data_mutex); _data_lock = true; - _view_data->get_logic()->init(); - for (auto d : _decode_traces) - { - d->decoder()->init(); - } + clear_decode_result(); _view_data->get_dso()->init(); - // SpectrumStack + for (auto m : _spectrum_traces) { m->get_spectrum_stack()->init(); @@ -922,15 +920,15 @@ namespace pv void SigSession::feed_in_logic(const sr_datafeed_logic &o) { - if (_view_data->get_logic()->memory_failed()) + if (_capture_data->get_logic()->memory_failed()) { dsv_err("%s", "Unexpected logic packet"); return; } - if (_view_data->get_logic()->last_ended()) + if (_capture_data->get_logic()->last_ended()) { - _view_data->get_logic()->first_payload(o, _device_agent.get_sample_limit(), _device_agent.get_channels()); + _capture_data->get_logic()->first_payload(o, _device_agent.get_sample_limit(), _device_agent.get_channels()); // @todo Putting this here means that only listeners querying // for logic will be notified. Currently the only user of // frame_began is DecoderStack, but in future we need to signal @@ -940,10 +938,10 @@ namespace pv else { // Append to the existing data snapshot - _view_data->get_logic()->append_payload(o); + _capture_data->get_logic()->append_payload(o); } - if (_view_data->get_logic()->memory_failed()) + if (_capture_data->get_logic()->memory_failed()) { _error = Malloc_err; _callback->session_error(); @@ -957,13 +955,13 @@ namespace pv void SigSession::feed_in_dso(const sr_datafeed_dso &o) { - if (_view_data->get_dso()->memory_failed()) + if (_capture_data->get_dso()->memory_failed()) { dsv_err("%s", "Unexpected dso packet"); return; // This dso packet was not expected. } - if (_view_data->get_dso()->last_ended()) + if (_capture_data->get_dso()->last_ended()) { std::map sig_enable; // reset scale of dso signal @@ -977,12 +975,12 @@ namespace pv } // first payload - _view_data->get_dso()->first_payload(o, _device_agent.get_sample_limit(), sig_enable, _is_instant); + _capture_data->get_dso()->first_payload(o, _device_agent.get_sample_limit(), sig_enable, _is_instant); } else { // Append to the existing data snapshot - _view_data->get_dso()->append_payload(o); + _capture_data->get_dso()->append_payload(o); } for (auto s : _signals) @@ -999,7 +997,7 @@ namespace pv set_cur_snap_samplerate(_device_agent.get_sample_rate()); } - if (_view_data->get_dso()->memory_failed()) + if (_capture_data->get_dso()->memory_failed()) { _error = Malloc_err; _callback->session_error(); @@ -1036,13 +1034,13 @@ namespace pv void SigSession::feed_in_analog(const sr_datafeed_analog &o) { - if (_view_data->get_analog()->memory_failed()) + if (_capture_data->get_analog()->memory_failed()) { dsv_err("%s", "Unexpected analog packet"); return; // This analog packet was not expected. } - if (_view_data->get_analog()->last_ended()) + if (_capture_data->get_analog()->last_ended()) { // reset scale of analog signal for (auto s : _signals) @@ -1054,15 +1052,15 @@ namespace pv } // first payload - _view_data->get_analog()->first_payload(o, _device_agent.get_sample_limit(), _device_agent.get_channels()); + _capture_data->get_analog()->first_payload(o, _device_agent.get_sample_limit(), _device_agent.get_channels()); } else { // Append to the existing data snapshot - _view_data->get_analog()->append_payload(o); + _capture_data->get_analog()->append_payload(o); } - if (_view_data->get_analog()->memory_failed()) + if (_capture_data->get_analog()->memory_failed()) { _error = Malloc_err; _callback->session_error(); @@ -1135,26 +1133,28 @@ namespace pv } case SR_DF_END: { - _view_data->get_logic()->capture_ended(); - _view_data->get_dso()->capture_ended(); - _view_data->get_analog()->capture_ended(); - - int mode = _device_agent.get_work_mode(); - - // Post a message to start all decode tasks. - if (mode == LOGIC) - _callback->trigger_message(DSV_MSG_REV_END_PACKET); + _capture_data->get_logic()->capture_ended(); + _capture_data->get_dso()->capture_ended(); + _capture_data->get_analog()->capture_ended(); if (packet->status != SR_PKT_OK) { _error = Pkt_data_err; _callback->session_error(); } + else + { + int mode = _device_agent.get_work_mode(); - _callback->frame_ended(); - - if (mode != LOGIC) - set_session_time(QDateTime::currentDateTime()); + // Post a message to start all decode tasks. + if (mode == LOGIC){ + _callback->trigger_message(DSV_MSG_REV_END_PACKET); + } + else{ + set_session_time(QDateTime::currentDateTime()); + _callback->frame_ended(); + } + } break; } @@ -1571,9 +1571,7 @@ namespace pv for (auto trace : _decode_traces) { if (trace != runningTrace) - { delete trace; - } } _decode_traces.clear(); @@ -1708,9 +1706,9 @@ namespace pv case DS_EV_DEVICE_STOPPED: _device_status = ST_STOPPED; // Confirm that SR_DF_END was received - if ( !_view_data->get_logic()->last_ended() - || !_view_data->get_dso()->last_ended() - || !_view_data->get_analog()->last_ended()) + if ( !_capture_data->get_logic()->last_ended() + || !_capture_data->get_dso()->last_ended() + || !_capture_data->get_analog()->last_ended()) { dsv_err("%s", "Error!The data is not completed."); assert(false); @@ -1727,13 +1725,13 @@ namespace pv { _callback->trigger_message(DSV_MSG_COLLECT_END); - if (_view_data->get_logic()->last_ended() == false) + if (_capture_data->get_logic()->last_ended() == false) dsv_err("%s", "The collected data is error!"); - if (_view_data->get_dso()->last_ended() == false) + if (_capture_data->get_dso()->last_ended() == false) dsv_err("%s", "The collected data is error!"); - if (_view_data->get_analog()->last_ended() == false) + if (_capture_data->get_analog()->last_ended() == false) dsv_err("%s", "The collected data is error!"); // trigger next collect @@ -1807,7 +1805,7 @@ namespace pv if (_is_working) { _callback->repeat_hold(_repeat_hold_prg); - exec_capture(); + exec_capture(false); } } @@ -1857,7 +1855,7 @@ namespace pv else { _repeat_hold_prg = 0; - exec_capture(); + exec_capture(false); } } } @@ -1867,17 +1865,46 @@ namespace pv { if (_device_agent.get_work_mode() == LOGIC) { + // On repeate mode, remove the current decode task when capture ended. + if (is_repeat_mode()){ + int run_dex = 0; + clear_all_decode_task(run_dex); + clear_decode_result(); + + // Change the captrue data container. + int buf_index = 0; + for(int i=0; i<(int)_data_list.size(); i++){ + if (_data_list[i] == _capture_data){ + buf_index = i; + break; + } + } + _view_data = _capture_data; + buf_index = (buf_index + 1) % 2; + + _capture_data = _data_list[buf_index]; + _capture_data->clear(); + + set_cur_snap_samplerate(_device_agent.get_sample_rate()); + set_cur_samplelimits(_device_agent.get_sample_limit()); + + attach_data_to_signal(_view_data); + } + for (auto de : _decode_traces) { de->decoder()->set_capture_end_flag(true); - // If is not the real-time mode, try to create all decode tasks. + // On real-time mode, the decode task have be created when capture start, + // so not need to create new decode task here. if (is_realtime_mode() == false){ de->frame_ended(); add_decode_task(de); - } + } } - } + + _callback->frame_ended(); + } } break; @@ -1894,12 +1921,18 @@ namespace pv bool SigSession::switch_work_mode(int mode) { assert(!_is_working); + int cur_mode = _device_agent.get_work_mode(); - if (_device_agent.get_work_mode() != mode) + if (cur_mode != mode) { GVariant *val = g_variant_new_int16(mode); _device_agent.set_config(NULL, NULL, SR_CONF_DEVICE_MODE, val); + if (cur_mode == LOGIC){ + int run_dex = 0; + clear_all_decode_task(run_dex); + } + init_signals(); dsv_info("%s", "Work mode is changed."); broadcast_msg(DSV_MSG_DEVICE_MODE_CHANGED); @@ -1933,4 +1966,39 @@ namespace pv return false; } + void SigSession::clear_decode_result() + { + for (auto d : _decode_traces) + { + d->decoder()->init(); + } + } + + void SigSession::attach_data_to_signal(SessionData *data) + { + assert(data); + + view::LogicSignal *s1; + view::AnalogSignal *s2; + view::DsoSignal *s3; + + for (auto sig : _signals){ + int type = sig->signal_type(); + switch(type){ + case LOGIC_SIGNAL: + s1 = (view::LogicSignal*)sig; + s1->set_data(data->get_logic()); + break; + case ANALOG_SIGNAL: + s2 = (view::AnalogSignal*)sig; + s2->set_data(data->get_analog()); + break; + case DSO_SIGNAL: + s3 = (view::DsoSignal*)sig; + s3->set_data(data->get_dso()); + break; + } + } + } + } // namespace pv diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index a4559e42..92239039 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -102,6 +102,8 @@ public: return &dso; } + void clear(); + public: uint64_t _cur_snap_samplerate; uint64_t _cur_samplelimits; @@ -163,10 +165,11 @@ public: bool set_file(QString name); void close_file(ds_device_handle dev_handle); bool start_capture(bool instant); - void stop_capture(); + void stop_capture(); + bool switch_work_mode(int mode); + uint64_t cur_samplerate(); uint64_t cur_snap_samplerate(); - uint64_t cur_samplelimits(); double cur_sampletime(); double cur_snap_sampletime(); @@ -378,8 +381,7 @@ public: bool have_hardware_data(); struct ds_device_base_info* get_device_list(int &out_count, int &actived_index); void add_msg_listener(IMessageListener *ln); - void broadcast_msg(int msg); - bool switch_work_mode(int mode); + void broadcast_msg(int msg); bool have_new_realtime_refresh(bool keep); private: @@ -387,7 +389,7 @@ private: void set_cur_snap_samplerate(uint64_t samplerate); void math_disable(); - bool exec_capture(); + bool exec_capture(bool bFirst); void exit_capture(); inline void data_updated(){ @@ -412,10 +414,10 @@ private: void capture_init(); void nodata_timeout(); - void feed_timeout(); - - void container_init(); + void feed_timeout(); void init_signals(); + void clear_decode_result(); + void attach_data_to_signal(SessionData *data); //IMessageListener void OnMessage(int msg); diff --git a/DSView/pv/view/analogsignal.cpp b/DSView/pv/view/analogsignal.cpp index 4fb782fb..874fd3cf 100644 --- a/DSView/pv/view/analogsignal.cpp +++ b/DSView/pv/view/analogsignal.cpp @@ -702,5 +702,11 @@ QString AnalogSignal::get_voltage(double v, int p, bool scaled) return abs(v) >= 1000 ? QString::number(v/1000.0, 'f', p) + mapUnit : QString::number(v, 'f', p) + "m" + mapUnit; } +void AnalogSignal::set_data(data::AnalogSnapshot *data) +{ + assert(data); + _data = data; +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/analogsignal.h b/DSView/pv/view/analogsignal.h index b2988676..7ae93f6a 100644 --- a/DSView/pv/view/analogsignal.h +++ b/DSView/pv/view/analogsignal.h @@ -50,10 +50,10 @@ private: static const uint8_t DefaultBits = 8; public: - AnalogSignal(pv::data::AnalogSnapshot *data, + AnalogSignal(data::AnalogSnapshot *data, sr_channel *probe); - AnalogSignal(view::AnalogSignal* s, pv::data::AnalogSnapshot *data, sr_channel *probe); + AnalogSignal(view::AnalogSignal* s, data::AnalogSnapshot *data, sr_channel *probe); virtual ~AnalogSignal(); @@ -77,6 +77,12 @@ public: return _ref_max; } + inline data::AnalogSnapshot* data(){ + return _data; + } + + void set_data(data::AnalogSnapshot *data); + int get_hw_offset(); int commit_settings(); diff --git a/DSView/pv/view/dsosignal.cpp b/DSView/pv/view/dsosignal.cpp index fe0aa741..0a02e0cf 100644 --- a/DSView/pv/view/dsosignal.cpp +++ b/DSView/pv/view/dsosignal.cpp @@ -1504,5 +1504,11 @@ void DsoSignal::call_auto_end(){ session->auto_end(); } +void DsoSignal::set_data(data::DsoSnapshot *data) +{ + assert(data); + _data = data; +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/dsosignal.h b/DSView/pv/view/dsosignal.h index 538125c3..9d516dfa 100644 --- a/DSView/pv/view/dsosignal.h +++ b/DSView/pv/view/dsosignal.h @@ -87,10 +87,12 @@ public: virtual ~DsoSignal(); - inline data::DsoSnapshot* dso_data(){ + inline data::DsoSnapshot* data(){ return _data; } + void set_data(data::DsoSnapshot *data); + void set_scale(int height); inline float get_scale(){ diff --git a/DSView/pv/view/logicsignal.cpp b/DSView/pv/view/logicsignal.cpp index 1b7a9dd7..f50932b3 100644 --- a/DSView/pv/view/logicsignal.cpp +++ b/DSView/pv/view/logicsignal.cpp @@ -495,5 +495,11 @@ void LogicSignal::paint_mark(QPainter &p, int xstart, int xend, int type) } } +void LogicSignal::set_data(data::LogicSnapshot* data) +{ + assert(data); + _data = data; +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/logicsignal.h b/DSView/pv/view/logicsignal.h index 1ed050fe..3619cfea 100644 --- a/DSView/pv/view/logicsignal.h +++ b/DSView/pv/view/logicsignal.h @@ -71,9 +71,11 @@ public: return _probe; } - inline data::LogicSnapshot* logic_data(){ + inline data::LogicSnapshot* data(){ return _data; } + + void set_data(data::LogicSnapshot* data); inline LogicSetRegions get_trig(){ return _trig; diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp index ca9ca192..9a0f80d7 100644 --- a/DSView/pv/view/viewport.cpp +++ b/DSView/pv/view/viewport.cpp @@ -210,10 +210,9 @@ void Viewport::paintSignals(QPainter &p, QColor fore, QColor back) std::vector traces; _view.get_traces(_type, traces); - if (_view.session().get_device()->get_work_mode() == LOGIC) { - - for(auto t : traces) - { + if (_view.session().get_device()->get_work_mode() == LOGIC) + { + for(auto t : traces){ if (t->enabled()) t->paint_mid(p, 0, t->get_view_rect().right(), fore, back); } @@ -359,6 +358,11 @@ void Viewport::paintProgress(QPainter &p, QColor fore, QColor back) { (void)back; + if (_view.session().get_device()->get_work_mode() == LOGIC + && _view.session().is_repeat_mode()){ + return; + } + using pv::view::Signal; const uint64_t sample_limits = _view.session().cur_samplelimits(); @@ -1200,9 +1204,17 @@ void Viewport::set_receive_len(quint64 length) _sample_received += length; } - if (_view.session().is_realtime_mode() && _view.session().have_new_realtime_refresh(true) == false){ - return; - } + if (_view.session().get_device()->get_work_mode() == LOGIC) + { + if (_view.session().is_realtime_mode() && _view.session().have_new_realtime_refresh(true) == false){ + return; + } + + // On repeate mode, Not to refresh view when capturring. + if (_view.session().is_repeat_mode()){ + return; + } + } // Received new data, and refresh the view. update();