diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp index 5726d52b..9ea67ee1 100644 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -453,7 +453,7 @@ void DecoderStack::do_decode_work() if (_snapshot == NULL) return; - if (_session->is_realtime_mode() == false && _snapshot->empty()) + if (_session->is_realtime_refresh() == false && _snapshot->empty()) { return; } @@ -662,7 +662,7 @@ void DecoderStack::execute_decode_stack() prev_di = di; decode_start = dec->decode_start(); - if (_session->is_realtime_mode() == false) + if (_session->is_realtime_refresh() == false) decode_end = min(dec->decode_end(), _sample_count-1); else decode_end = max(dec->decode_end(), decode_end); diff --git a/DSView/pv/deviceagent.cpp b/DSView/pv/deviceagent.cpp index 49bd9c96..21c97932 100644 --- a/DSView/pv/deviceagent.cpp +++ b/DSView/pv/deviceagent.cpp @@ -370,5 +370,19 @@ GSList *DeviceAgent::get_channels() return false; } + int DeviceAgent::get_operation_mode() + { + int mode_val = 0; + if (get_config_value_int16(SR_CONF_OPERATION_MODE, mode_val)){ + return mode_val; + } + return -1; + } + + bool DeviceAgent::is_stream_mode() + { + return get_operation_mode() == LO_OP_STREAM; + } + //---------------device config end -----------/ diff --git a/DSView/pv/deviceagent.h b/DSView/pv/deviceagent.h index 4fbe52dc..31cad840 100644 --- a/DSView/pv/deviceagent.h +++ b/DSView/pv/deviceagent.h @@ -179,6 +179,10 @@ public: bool channel_is_enable(int index); + int get_operation_mode(); + + bool is_stream_mode(); + private: void config_changed(); bool is_in_history(ds_device_handle dev_handle); diff --git a/DSView/pv/interface/icallbacks.h b/DSView/pv/interface/icallbacks.h index e06fa1c1..e6f4fd10 100644 --- a/DSView/pv/interface/icallbacks.h +++ b/DSView/pv/interface/icallbacks.h @@ -75,6 +75,7 @@ public: #define DSV_MSG_END_COLLECT_WORK_PREV 5005 #define DSV_MSG_END_COLLECT_WORK 5006 #define DSV_MSG_REV_END_PACKET 5007 +#define DSV_MSG_SWAP_CAPTURE_BUFFER 5008 #define DSV_MSG_DEVICE_LIST_UPDATED 6000 #define DSV_MSG_BEGIN_DEVICE_OPTIONS 6001 //Begin show device options dialog. diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 8aebd7d8..2c7f6816 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -1813,7 +1813,8 @@ namespace pv break; case DSV_MSG_CLEAR_DECODE_DATA: - _protocol_widget->reset_view(); + if (_device_agent->get_work_mode() == LOGIC) + _protocol_widget->reset_view(); break; case DSV_MSG_STORE_CONF_PREV: diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index b78ebd82..383cd105 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -112,9 +112,11 @@ namespace pv _is_decoding = false; _bClose = false; _callback = NULL; - _capture_time_id = 0; + _work_time_id = 0; + _capture_times = 0; _confirm_store_time_id = 0; _repeat_wait_prog_step = 10; + _lst_capture_times = 0; _device_agent.set_callback(this); @@ -462,39 +464,37 @@ namespace pv return false; } - int run_dex = 0; - clear_all_decode_task(run_dex); + clear_all_decode_task2(); clear_decode_result(); - + _capture_data->clear(); _view_data->clear(); + _capture_data = _view_data; + _is_stream_mode = false; + _capture_times = 0; - int mode = _device_agent.get_work_mode(); - if (mode == LOGIC && is_repeat_mode()) - { - if (_view_data == _capture_data){ - for (auto dt : _data_list){ - if (dt != _view_data){ - _capture_data = dt; - break; - } - } - } - } - else{ - _capture_data = _view_data; - } + set_cur_snap_samplerate(_device_agent.get_sample_rate()); + set_cur_samplelimits(_device_agent.get_sample_limit()); - _is_stream_mode = false; - if (mode == LOGIC && _device_agent.is_hardware()) + int mode = _device_agent.get_work_mode(); + if (mode == LOGIC) { - int mode_val = 0; - if (_device_agent.get_config_value_int16(SR_CONF_OPERATION_MODE, mode_val)){ - _is_stream_mode = mode_val == LO_OP_STREAM; + if (is_repeat_mode() + && _device_agent.is_hardware() + && _device_agent.is_stream_mode()){ + set_repeat_intvl(0.1); + } + + if (_device_agent.is_hardware()){ + _is_stream_mode = _device_agent.is_stream_mode(); + } + else if (_device_agent.is_demo()){ + _is_stream_mode = true; + } + + if (is_loop_mode() && !_is_stream_mode){ + set_operation_mode(OPT_SINGLE); // Reset the capture mode. } - } - else if (instant && mode == LOGIC && _device_agent.is_demo()){ - _is_stream_mode = true; } update_view(); @@ -505,18 +505,15 @@ namespace pv else _is_instant = instant; - set_cur_snap_samplerate(_device_agent.get_sample_rate()); - set_cur_samplelimits(_device_agent.get_sample_limit()); - _callback->trigger_message(DSV_MSG_START_COLLECT_WORK_PREV); if (exec_capture()) { - _capture_time_id++; + _work_time_id++; _is_working = true; _callback->trigger_message(DSV_MSG_START_COLLECT_WORK); - // Start a timer, for able to refresh the view per (1000 / 30)ms on real-time mode. + // Start a timer, for able to refresh the view per (1000 / 30)ms. if (is_realtime_refresh()){ _refresh_rt_timer.Start(1000 / 30); } @@ -533,68 +530,103 @@ namespace pv dsv_err("%s", "Error!Device is running."); return 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) { _callback->show_error("No probes enabled."); return false; } + + _capture_times++; + + int mode = _device_agent.get_work_mode(); + bool bAddDecoder = false; + bool bSwapBuffer = false; + + 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); + } + } + } + else + { + if (is_single_mode()) + { + if (_is_stream_mode) + bAddDecoder = true; + } + else if (is_repeat_mode()) + { + if (_is_stream_mode) + { + if (_capture_times == 1) + bAddDecoder = true; + else + bSwapBuffer = true; + } + else{ + bSwapBuffer = true; + } + } + else if (is_loop_mode()) + { + bAddDecoder = true; + } + } + + if (bAddDecoder){ + clear_all_decode_task2(); + clear_decode_result(); + } + + if (bSwapBuffer){ + int buf_index = 0; + for(int i=0; i<(int)_data_list.size(); i++){ + if (_data_list[i] == _view_data){ + buf_index = i; + break; + } + } + + 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()); + } capture_init(); - if (_device_agent.start() == false) - { + if (_device_agent.start() == false){ dsv_err("%s", "Start collect error!"); return false; } if (mode == LOGIC) - { - bool bClearDecodeData = false; - // 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){ - int run_dex = 0; - clear_all_decode_task(run_dex); - clear_decode_result(); - bClearDecodeData = true; - } - - for (auto de : _decode_traces) - { + { + 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()) - { + if (bAddDecoder){ de->frame_ended(); add_decode_task(de); - } - } - - if (bClearDecodeData) - _callback->trigger_message(DSV_MSG_CLEAR_DECODE_DATA); + } + } } return true; } - void SigSession::stop_capture() + bool SigSession::stop_capture() { if (!_is_working) - return; + return false; dsv_info("Stop collect."); @@ -605,11 +637,11 @@ namespace pv _repeat_wait_prog_timer.Stop(); _refresh_rt_timer.Stop(); exit_capture(); - return; + return true; } bool wait_upload = false; - if (is_single_mode()) + if (is_single_mode() && _device_agent.get_work_mode() == LOGIC) { GVariant *gvar = _device_agent.get_config(NULL, NULL, SR_CONF_WAIT_UPLOAD); if (gvar != NULL) @@ -639,11 +671,13 @@ namespace pv // On repeat mode, the working status is changed, to post the event message. _callback->trigger_message(DSV_MSG_END_COLLECT_WORK); } + return true; } else { - dsv_info("%s", "Device is uploading."); + dsv_info("%s", "Data is uploading, waiting capture auto end."); } + return false; } void SigSession::exit_capture() @@ -994,7 +1028,17 @@ namespace pv } void SigSession::feed_in_logic(const sr_datafeed_logic &o) - { + { + //Switch the data buffer. + if (o.length > 0 && is_repeat_mode() && _is_stream_mode) + { + if (_capture_times != _lst_capture_times && _capture_times > 1) + { + _lst_capture_times = _capture_times; + _callback->trigger_message(DSV_MSG_SWAP_CAPTURE_BUFFER); + } + } + if (_capture_data->get_logic()->memory_failed()) { dsv_err("%s", "Unexpected logic packet"); @@ -1947,52 +1991,76 @@ namespace pv break; case DSV_MSG_REV_END_PACKET: - { - 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; - //Stop all old task. - clear_all_decode_task(run_dex); - clear_decode_result(); + if (_device_agent.get_work_mode() == LOGIC) + { + bool bAddDecoder = false; + bool bSwapBuffer = false; - // 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; + if (is_single_mode()) + { + if (!_is_stream_mode) + bAddDecoder = true; + } + else if(is_repeat_mode()) + { + if (!_is_stream_mode){ + bAddDecoder = true; + bSwapBuffer = true; } } - _view_data = _capture_data; - buf_index = (buf_index + 1) % 2; + else if (is_loop_mode()) + { + } - _capture_data = _data_list[buf_index]; - _capture_data->clear(); + if (bAddDecoder){ + clear_all_decode_task2(); + clear_decode_result(); + } - set_cur_snap_samplerate(_device_agent.get_sample_rate()); - set_cur_samplelimits(_device_agent.get_sample_limit()); + //Swap caputrued data buffer + if (bSwapBuffer) + { + if (_view_data != _capture_data) + _view_data->clear(); + + _view_data = _capture_data; + attach_data_to_signal(_view_data); + } - attach_data_to_signal(_view_data); + for (auto de : _decode_traces) + { + de->decoder()->set_capture_end_flag(true); + + if (bAddDecoder){ + de->frame_ended(); + add_decode_task(de); + } + } + + _callback->frame_ended(); } + } + break; + + case DSV_MSG_SWAP_CAPTURE_BUFFER: + { + clear_all_decode_task2(); + clear_decode_result(); - for (auto de : _decode_traces) + _view_data = _capture_data; + attach_data_to_signal(_view_data); + + if (_is_stream_mode && is_repeat_mode()) { - de->decoder()->set_capture_end_flag(true); - - // 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){ + for (auto de : _decode_traces){ + de->decoder()->set_capture_end_flag(false); de->frame_ended(); add_decode_task(de); - } - } - - _callback->frame_ended(); + } + } } - } - break; + break; case DSV_MSG_COLLECT_END: break; @@ -2015,8 +2083,7 @@ namespace pv _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); + clear_all_decode_task2(); } init_signals(); @@ -2029,8 +2096,8 @@ namespace pv bool SigSession::is_first_store_confirm() { - if (_capture_time_id != _confirm_store_time_id){ - _confirm_store_time_id = _capture_time_id; + if (_work_time_id != _confirm_store_time_id){ + _confirm_store_time_id = _work_time_id; return true; } return false; diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index 545a2521..b10f7b0a 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -81,9 +81,8 @@ enum DEVICE_STATUS_TYPE{ }; enum COLLECT_OPT_MODE{ OPT_SINGLE = 0, - OPT_REPEAT = 1, - OPT_REALTIME = 2, - OPT_LOOP = 3, + OPT_REPEAT = 1, + OPT_LOOP = 2, }; class SessionData @@ -166,7 +165,7 @@ public: bool set_file(QString name); void close_file(ds_device_handle dev_handle); bool start_capture(bool instant); - void stop_capture(); + bool stop_capture(); bool switch_work_mode(int mode); uint64_t cur_samplerate(); @@ -340,12 +339,16 @@ public: return _opt_mode == OPT_SINGLE; } - inline bool is_realtime_mode(){ - return _opt_mode == OPT_REALTIME; + inline bool is_loop_mode(){ + return _opt_mode == OPT_LOOP; } inline bool is_realtime_refresh(){ - return (is_realtime_mode() || (_is_stream_mode && is_single_mode())); + if (is_loop_mode() || (_is_stream_mode && is_single_mode() )) + return true; + if (_is_stream_mode && is_repeat_mode() && is_single_buffer()) + return true; + return false; } inline bool is_repeating(){ @@ -435,6 +438,12 @@ private: void add_decode_task(view::DecodeTrace *trace); void remove_decode_task(view::DecodeTrace *trace); void clear_all_decode_task(int &runningDex); + + inline void clear_all_decode_task2(){ + int run_dex = 0; + clear_all_decode_task(run_dex); + _callback->trigger_message(DSV_MSG_CLEAR_DECODE_DATA); + } void decode_task_proc(); view::DecodeTrace* get_top_decode_task(); @@ -532,7 +541,9 @@ private: bool _is_saving; bool _is_instant; int _device_status; - int _capture_time_id; + int _work_time_id; + int _capture_times; + int _lst_capture_times; int _confirm_store_time_id; uint64_t _rt_refresh_time_id; uint64_t _rt_ck_refresh_time_id; diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index f15801cf..ebd46039 100644 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -41,7 +41,7 @@ #define SINGLE_ACTION_ICON "/oneloop.svg" #define REPEAT_ACTION_ICON "/repeat.svg" -#define REALTIME_ACTION_ICON "/update.svg" +#define LOOP_ACTION_ICON "/update.svg" using std::map; using std::max; @@ -110,12 +110,12 @@ namespace pv _action_single = new QAction(this); _action_repeat = new QAction(this); - _action_realtime = new QAction(this); + _action_loop = new QAction(this); _mode_menu = new QMenu(this); _mode_menu->addAction(_action_single); _mode_menu->addAction(_action_repeat); - _mode_menu->addAction(_action_realtime); + _mode_menu->addAction(_action_loop); _mode_button.setMenu(_mode_menu); _mode_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); @@ -135,7 +135,7 @@ namespace pv connect(&_sample_count, SIGNAL(currentIndexChanged(int)), this, SLOT(on_samplecount_sel(int))); connect(_action_single, SIGNAL(triggered()), this, SLOT(on_mode())); connect(_action_repeat, SIGNAL(triggered()), this, SLOT(on_mode())); - connect(_action_realtime, SIGNAL(triggered()), this, SLOT(on_mode())); + connect(_action_loop, SIGNAL(triggered()), this, SLOT(on_mode())); connect(&_sample_rate, SIGNAL(currentIndexChanged(int)), this, SLOT(on_samplerate_sel(int))); } @@ -213,7 +213,7 @@ namespace pv _action_single->setText(L_S(STR_PAGE_TOOLBAR, S_ID(IDS_TOOLBAR_CAPTURE_MODE_SINGLE), "&Single")); _action_repeat->setText(L_S(STR_PAGE_TOOLBAR, S_ID(IDS_TOOLBAR_CAPTURE_MODE_REPEAT), "&Repetitive")); - _action_realtime->setText(L_S(STR_PAGE_TOOLBAR, S_ID(IDS_TOOLBAR_CAPTURE_MODE_REALTIME), "Real&time")); + _action_loop->setText(L_S(STR_PAGE_TOOLBAR, S_ID(IDS_TOOLBAR_CAPTURE_MODE_LOOP), "&Loop")); } void SamplingBar::reStyle() @@ -254,7 +254,7 @@ namespace pv _action_single->setIcon(QIcon(iconPath + SINGLE_ACTION_ICON)); _action_repeat->setIcon(QIcon(iconPath + REPEAT_ACTION_ICON)); - _action_realtime->setIcon(QIcon(iconPath + REALTIME_ACTION_ICON)); + _action_loop->setIcon(QIcon(iconPath + LOOP_ACTION_ICON)); update_mode_icon(); } @@ -856,8 +856,11 @@ namespace pv void SamplingBar::on_run_stop() { if (_session->is_working()) - { - _session->stop_capture(); + { + _run_stop_action->setEnabled(false); + if (_session->stop_capture() == false){ + _run_stop_action->setEnabled(true); + } return; } @@ -918,20 +921,10 @@ namespace pv if (_session->is_working()) { - bool wait_upload = false; - - if (_session->is_repeat_mode() == false){ - GVariant *gvar = _device_agent->get_config(NULL, NULL, SR_CONF_WAIT_UPLOAD); - if (gvar != NULL) - { - wait_upload = g_variant_get_boolean(gvar); - g_variant_unref(gvar); - } + _instant_action->setEnabled(false); + if (_session->stop_capture() == false){ + _instant_action->setEnabled(true); } - if (!wait_upload){ - _session->stop_capture(); - } - return; } @@ -1055,7 +1048,7 @@ namespace pv { QString iconPath = GetIconPath(); - _action_realtime->setVisible(false); + _action_loop->setVisible(false); int mode = _device_agent->get_work_mode(); if (mode == LOGIC) @@ -1067,15 +1060,7 @@ namespace pv { update_mode_icon(); _mode_action->setVisible(true); - _action_repeat->setVisible(true); - - if (_device_agent->is_hardware()) - { - int mode_val = 0; - if (_device_agent->get_config_value_int16(SR_CONF_OPERATION_MODE, mode_val)){ - //_action_realtime->setVisible(mode_val == LO_OP_STREAM); - } - } + _action_repeat->setVisible(true); } _run_stop_action->setVisible(true); _instant_action->setVisible(true); @@ -1109,20 +1094,27 @@ namespace pv } else if (act == _action_repeat) { - pv::dialogs::Interval interval_dlg(this); - - interval_dlg.set_interval(_session->get_repeat_intvl()); - interval_dlg.exec(); - - if (interval_dlg.is_done()) + if (_device_agent->is_hardware() && _device_agent->is_stream_mode()) { - _session->set_repeat_intvl(interval_dlg.get_interval()); + _session->set_repeat_intvl(0.1); _session->set_operation_mode(OPT_REPEAT); } + else{ + pv::dialogs::Interval interval_dlg(this); + + interval_dlg.set_interval(_session->get_repeat_intvl()); + interval_dlg.exec(); + + if (interval_dlg.is_done()) + { + _session->set_repeat_intvl(interval_dlg.get_interval()); + _session->set_operation_mode(OPT_REPEAT); + } + } } - else if (act == _action_realtime) + else if (act == _action_loop) { - _session->set_operation_mode(OPT_REALTIME); + _session->set_operation_mode(OPT_LOOP); } update_mode_icon(); @@ -1259,8 +1251,8 @@ namespace pv if (_session->is_repeat_mode()) _mode_button.setIcon(QIcon(iconPath + REPEAT_ACTION_ICON)); - else if (_session->is_realtime_mode()) - _mode_button.setIcon(QIcon(iconPath + REALTIME_ACTION_ICON)); + else if (_session->is_loop_mode()) + _mode_button.setIcon(QIcon(iconPath + LOOP_ACTION_ICON)); else _mode_button.setIcon(QIcon(iconPath + SINGLE_ACTION_ICON)); } diff --git a/DSView/pv/toolbars/samplingbar.h b/DSView/pv/toolbars/samplingbar.h index 2d0b96ca..f838aede 100644 --- a/DSView/pv/toolbars/samplingbar.h +++ b/DSView/pv/toolbars/samplingbar.h @@ -153,7 +153,7 @@ namespace pv QMenu *_mode_menu; QAction *_action_repeat; QAction *_action_single; - QAction *_action_realtime; + QAction *_action_loop; DeviceAgent *_device_agent; ds_device_handle _last_device_handle; diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp index 9be84cc5..65d1c51f 100644 --- a/DSView/pv/view/viewport.cpp +++ b/DSView/pv/view/viewport.cpp @@ -1338,8 +1338,14 @@ void Viewport::set_receive_len(quint64 length) get_captured_progress(progress, progress100); _view.show_captured_progress(_transfer_started, progress100); - // Do not to refresh the view until data collection is complete. - return; + if (_view.session().is_single_buffer()){ + if (_view.session().have_new_realtime_refresh(true) == false){ + return; + } + } + else{ + return; + } } else if (_view.session().is_realtime_refresh()) { diff --git a/lang/cn/toolbar.json b/lang/cn/toolbar.json index f7d6d7e1..188c05be 100644 --- a/lang/cn/toolbar.json +++ b/lang/cn/toolbar.json @@ -36,8 +36,8 @@ "text": "重复(&R)" }, { - "id": "IDS_TOOLBAR_CAPTURE_MODE_REALTIME", - "text": "实时(&T)" + "id": "IDS_TOOLBAR_CAPTURE_MODE_LOOP", + "text": "回滚(&L)" }, { "id": "IDS_TOOLBAR_RUN_START", diff --git a/lang/en/toolbar.json b/lang/en/toolbar.json index d9ca842e..ef18d533 100644 --- a/lang/en/toolbar.json +++ b/lang/en/toolbar.json @@ -36,8 +36,8 @@ "text": "&Repetitive" }, { - "id": "IDS_TOOLBAR_CAPTURE_MODE_REALTIME", - "text": "Real&time" + "id": "IDS_TOOLBAR_CAPTURE_MODE_LOOP", + "text": "&Loop" }, { "id": "IDS_TOOLBAR_RUN_START",