Refresh the view realtime when device is stream mode

This commit is contained in:
dreamsourcelabTAI 2023-04-19 17:51:24 +08:00
parent a32ac7f975
commit f59c19be3f
12 changed files with 266 additions and 170 deletions

View File

@ -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);

View File

@ -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 -----------/

View File

@ -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);

View File

@ -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.

View File

@ -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:

View File

@ -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;

View File

@ -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;

View File

@ -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));
}

View File

@ -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;

View File

@ -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())
{

View File

@ -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",

View File

@ -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",