From 34cab3cf23cbe4a2286cdf0f72a9eb81a46cf6d0 Mon Sep 17 00:00:00 2001 From: dreamsourcelabTAI Date: Fri, 23 Sep 2022 15:44:22 +0800 Subject: [PATCH] Code refactoring 21 --- CMakeLists.txt | 6 +- DSView/config.h | 2 +- DSView/pv/deviceagent.cpp | 37 +- DSView/pv/deviceagent.h | 15 +- DSView/pv/dialogs/storeprogress.cpp | 16 +- DSView/pv/mainwindow.cpp | 86 +- DSView/pv/mainwindow.h | 5 +- DSView/pv/sigsession.cpp | 3698 ++++++++++++++------------- DSView/pv/sigsession.h | 14 +- DSView/pv/storesession.cpp | 36 +- DSView/pv/toolbars/filebar.cpp | 10 +- DSView/pv/toolbars/samplingbar.cpp | 25 +- DSView/pv/toolbars/samplingbar.h | 8 +- DSView/pv/view/devmode.cpp | 45 +- DSView/pv/view/header.cpp | 19 +- DSView/pv/view/view.cpp | 20 +- DSView/pv/view/view.h | 5 +- DSView/pv/view/viewport.cpp | 13 +- libsigrok4DSL/hardware/demo/demo.c | 2 +- libsigrok4DSL/lib_main.c | 59 +- libsigrok4DSL/libsigrok.h | 243 +- 21 files changed, 2315 insertions(+), 2049 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb9be42b..3a8c63ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,9 +31,9 @@ set(DS_TITLE DSView) set(DS_DESCRIPTION "A GUI for instruments of DreamSourceLab") set(DS_VERSION_MAJOR 1) -set(DS_VERSION_MINOR 2) -set(DS_VERSION_MICRO 1) -set(DS_VERSION_STRING ${DS_VERSION_MAJOR}.${DS_VERSION_MINOR}.${DS_VERSION_MICRO} ) +set(DS_VERSION_MINOR 3) +set(DS_VERSION_MICRO 0) +set(DS_VERSION_STRING ${DS_VERSION_MAJOR}.${DS_VERSION_MINOR}.${DS_VERSION_MICRO}-dev ) configure_file ( ${PROJECT_SOURCE_DIR}/DSView/config.h.in diff --git a/DSView/config.h b/DSView/config.h index 063d4fb4..eb6764c4 100644 --- a/DSView/config.h +++ b/DSView/config.h @@ -30,6 +30,6 @@ #define DS_VERSION_MAJOR 1 #define DS_VERSION_MINOR 2 #define DS_VERSION_MICRO 1 -#define DS_VERSION_STRING "1.2.1" +#define DS_VERSION_STRING "1.3.0-dev" #endif diff --git a/DSView/pv/deviceagent.cpp b/DSView/pv/deviceagent.cpp index b01f65ba..06c21a2a 100644 --- a/DSView/pv/deviceagent.cpp +++ b/DSView/pv/deviceagent.cpp @@ -30,6 +30,7 @@ DeviceAgent::DeviceAgent() _di = NULL; _dev_type = 0; _callback = NULL; + _is_new_device = false; } void DeviceAgent::update() @@ -48,6 +49,13 @@ void DeviceAgent::update() _di = info.di; _dev_name = QString::fromLocal8Bit(info.name); _driver_name = QString::fromLocal8Bit(info.driver_name); + + if (is_in_history(_dev_handle) == false){ + _is_new_device = true; + } + else{ + _is_new_device = false; + } } } @@ -59,12 +67,14 @@ void DeviceAgent::update() GVariant* DeviceAgent::get_config(const sr_channel *ch, const sr_channel_group *group, int key) { - assert(_dev_handle); - + assert(_dev_handle); GVariant *data = NULL; if (ds_get_actived_device_config(ch, group, key, &data) != SR_OK) { - dsv_warn("%s%d", "WARNING: Failed to get value of config id:", key); + if (is_hardware()) + dsv_warn("%s%d", "WARNING: Failed to get value of config id:", key); + else + dsv_detail("%s%d", "WARNING: Failed to get value of config id:", key); } return data; } @@ -75,7 +85,10 @@ bool DeviceAgent::set_config(sr_channel *ch, sr_channel_group *group, int key, G if (ds_set_actived_device_config(ch, group, key, data) != SR_OK) { - dsv_warn("%s%d", "WARNING: Failed to set value of config id:", key); + if (is_hardware()) + dsv_warn("%s%d", "WARNING: Failed to set value of config id:", key); + else + dsv_detail("%s%d", "WARNING: Failed to set value of config id:", key); return false; } @@ -244,6 +257,11 @@ bool DeviceAgent::stop() return false; } +void DeviceAgent::release() +{ + ds_release_actived_device(); +} + bool DeviceAgent::have_enabled_channel() { assert(_dev_handle); @@ -314,5 +332,16 @@ GSList *DeviceAgent::get_channels() return ds_get_actived_device_channels(); } + bool DeviceAgent::is_in_history(ds_device_handle dev_handle) + { + for(ds_device_handle h : _history_handles){ + if (h == dev_handle){ + return true; + } + } + _history_handles.push_back(dev_handle); + return false; + } + //---------------device config end -----------/ diff --git a/DSView/pv/deviceagent.h b/DSView/pv/deviceagent.h index 818685f2..73ec5fe3 100644 --- a/DSView/pv/deviceagent.h +++ b/DSView/pv/deviceagent.h @@ -26,6 +26,7 @@ #include #include #include +#include class IDeviceAgentCallback { @@ -147,10 +148,20 @@ public: */ bool stop(); + /** + * Stop and close. + */ + void release(); + bool is_collecting(); -protected: + inline bool is_new_device(){ + return _is_new_device; + } + +private: void config_changed(); + bool is_in_history(ds_device_handle dev_handle); //---------------device config-----------/ public: @@ -172,7 +183,9 @@ private: int _dev_type; QString _dev_name; QString _driver_name; + bool _is_new_device; struct sr_dev_inst *_di; + std::vector _history_handles; IDeviceAgentCallback *_callback; }; diff --git a/DSView/pv/dialogs/storeprogress.cpp b/DSView/pv/dialogs/storeprogress.cpp index f05ad861..7cec1cbc 100644 --- a/DSView/pv/dialogs/storeprogress.cpp +++ b/DSView/pv/dialogs/storeprogress.cpp @@ -30,6 +30,8 @@ #include #include "../ui/msgbox.h" #include "../config/appconfig.h" +#include "../interface/icallbacks.h" +#include "../log.h" namespace pv { namespace dialogs { @@ -122,8 +124,10 @@ void StoreProgress::reject() { using namespace Qt; _store_session.cancel(); - save_done(); + _store_session.session()->set_saving(false); + save_done(); DSDialog::reject(); + _store_session.session()->broadcast_msg(DSV_MSG_SAVE_COMPLETE); } void StoreProgress::accept() @@ -157,7 +161,8 @@ void StoreProgress::accept() //start done if (_isExport){ if (_store_session.export_start()){ - QTimer::singleShot(100, this, SLOT(timeout())); + _store_session.session()->set_saving(true); + QTimer::singleShot(100, this, SLOT(timeout())); } else{ save_done(); @@ -167,7 +172,8 @@ void StoreProgress::accept() } else{ if (_store_session.save_start()){ - QTimer::singleShot(100, this, SLOT(timeout())); + _store_session.session()->set_saving(true); + QTimer::singleShot(100, this, SLOT(timeout())); } else{ save_done(); @@ -248,9 +254,11 @@ void StoreProgress::show_error() } void StoreProgress::closeEvent(QCloseEvent* e) -{ +{ _store_session.cancel(); + _store_session.session()->set_saving(false); DSDialog::closeEvent(e); + _store_session.session()->broadcast_msg(DSV_MSG_SAVE_COMPLETE); } void StoreProgress::on_progress_updated() diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 4723a136..44040791 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -109,8 +109,8 @@ namespace pv _session->set_callback(this); _device_agent = _session->get_device(); _session->add_msg_listener(this); - - _bFirstLoad = true; + + _is_auto_switch_device = false; setup_ui(); @@ -269,7 +269,10 @@ namespace pv connect(_protocol_widget, SIGNAL(protocol_updated()), this, SLOT(on_signals_changed())); - // SamplingBar + // SamplingBar + connect(_sampling_bar, SIGNAL(sig_store_session_data()), this, SLOT(on_save())); + + // connect(_dso_trigger_widget, SIGNAL(set_trig_pos(int)), _view, SLOT(set_trig_pos(int))); _logo_bar->set_mainform_callback(this); @@ -305,8 +308,8 @@ namespace pv { assert(_sampling_bar); if (!selected_device->name().contains("virtual")) { - _file_bar->set_settings_en(true); - _logo_bar->dsl_connected(true); + + #if QT_VERSION >= 0x050400 QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); #else @@ -322,8 +325,8 @@ namespace pv on_load_session(ses_name); } } else { - _file_bar->set_settings_en(false); - _logo_bar->dsl_connected(false); + + QDir dir(GetResourceDir()); if (dir.exists()) { @@ -340,8 +343,7 @@ namespace pv _trig_bar->restore_status(); //load specified file name from application startup param - if (_bFirstLoad){ - _bFirstLoad = false; + if (_bFirstLoad){ QString ldFileName(AppControl::Instance()->_open_file_name.c_str()); @@ -1354,6 +1356,14 @@ namespace pv _measure_widget->reload(); } + bool MainWindow::confirm_to_store_data() + { + if (_session->have_hardware_data()){ + return MsgBox::Confirm(tr("Save captured data?")); + } + return false; + } + void MainWindow::OnMessage(int msg) { switch (msg) @@ -1380,24 +1390,25 @@ namespace pv _trig_bar->update_view_status(); break; - case DSV_MSG_NEW_USB_DEVICE: - check_usb_device_speed(); + case DSV_MSG_CURRENT_DEVICE_CHANGE_PREV: + _protocol_widget->del_all_protocol(); + _view->reload(); break; case DSV_MSG_CURRENT_DEVICE_CHANGED: + { if (_msg != NULL){ _msg->close(); _msg = NULL; } _sampling_bar->update_device_list(); - reset_all_view(); - break; - - case DSV_MSG_CURRENT_DEVICE_CHANGE_PREV: - _protocol_widget->del_all_protocol(); - _view->reload(); - break; + reset_all_view(); + bool is_hardware = _session->get_device()->is_hardware(); + _logo_bar->dsl_connected(is_hardware); + _file_bar->update_view_status(); + } + break; case DSV_MSG_DEVICE_OPTIONS_UPDATED: _trigger_widget->device_updated(); @@ -1410,15 +1421,50 @@ namespace pv _view->timebase_changed(); break; - case DSV_MSG_DEVICE_MODE_CHANGED: + case DSV_MSG_DEVICE_MODE_CHANGED: _view->mode_changed(); reset_all_view(); break; + case DSV_MSG_NEW_USB_DEVICE: + if (confirm_to_store_data()){ + _is_auto_switch_device = true; + on_save(); + } + else{ + _session->set_default_device(); + check_usb_device_speed(); + } + break; + case DSV_MSG_CURRENT_DEVICE_DETACHED: + // Save current config, and switch to the last device. _session->device_event_object()->device_updated(); session_save(); - _view->hide_calibration(); + _view->hide_calibration(); + if (confirm_to_store_data()){ + _is_auto_switch_device = true; + on_save(); + } + else{ + _session->set_default_device(); + } + break; + + case DSV_MSG_SAVE_COMPLETE: + if (_is_auto_switch_device){ + _is_auto_switch_device = false; + _session->set_default_device(); + if (_session->get_device()->is_new_device()) + check_usb_device_speed(); + } + else{ + ds_device_handle devh = _sampling_bar->get_next_device_handle(); + if (devh != NULL_HANDLE){ + dsv_info("%s", "Auto switch to the selected device."); + _session->set_device(devh); + } + } break; } } diff --git a/DSView/pv/mainwindow.h b/DSView/pv/mainwindow.h index e54372ad..8f54c038 100644 --- a/DSView/pv/mainwindow.h +++ b/DSView/pv/mainwindow.h @@ -144,6 +144,7 @@ public: private: void check_usb_device_speed(); void reset_all_view(); + bool confirm_to_store_data(); private: //ISessionCallback @@ -216,10 +217,10 @@ private: QTranslator _qtTrans; QTranslator _myTrans; - EventObject _event; - bool _bFirstLoad; + EventObject _event; SigSession *_session; DeviceAgent *_device_agent; + bool _is_auto_switch_device; }; } // namespace pv diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 6e01b2f8..44afccfe 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -20,10 +20,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #include - #include "sigsession.h" #include "mainwindow.h" @@ -54,809 +52,376 @@ #include #include #include - +#include + #include "data/decode/decoderstatus.h" #include "dsvdef.h" #include "log.h" #include "config/appconfig.h" #include "utility/path.h" - -namespace pv { +#include "ui/msgbox.h" -// TODO: This should not be necessary -SigSession* SigSession::_session = NULL; +namespace pv +{ -SigSession::SigSession() -{ // TODO: This should not be necessary - _session = this; - _group_cnt = 0; + SigSession *SigSession::_session = NULL; - _map_zoom = 0; - _repeat_hold_prg = 0; - _repeat_intvl = 1; - _error = No_err; - _is_instant = false; - _is_working = false; - _is_repeat_mode = false; - _is_saving = false; - _device_status = ST_INIT; - - _noData_cnt = 0; - _data_lock = false; - _data_updated = false; - _is_auto_sel_device = false; - _is_trig_new_device_msg = false; - - this->add_msg_listener(this); - - _decoder_model = new pv::data::DecoderModel(NULL); - - _lissajous_trace = NULL; - _math_trace = NULL; - _dso_feed = false; - _stop_scale = 1; - _is_decoding = false; - _bClose = false; - _callback = NULL; - - _device_agent.set_callback(this); - - // Create snapshots & data containers - _logic_data = new data::Logic(new data::LogicSnapshot()); - _dso_data = new data::Dso(new data::DsoSnapshot()); - _analog_data = new data::Analog(new data::AnalogSnapshot()); - _group_data = new data::Group(); - _group_cnt = 0; - - _feed_timer.Stop(); - _feed_timer.SetCallback(std::bind(&SigSession::feed_timeout, this)); - _repeate_timer.SetCallback(std::bind(&SigSession::repeat_capture_wait_timout, this)); -} - -SigSession::SigSession(SigSession &o) -{ - (void)o; -} - -SigSession::~SigSession() -{ -} - -bool SigSession::init() -{ - ds_log_set_context(dsv_log_context()); - - ds_set_event_callback(device_lib_event_callback); - - ds_set_datafeed_callback(data_feed_callback); - - // firmware resource directory - QString resdir = GetResourceDir(); - std::string res_path = pv::path::ToUnicodePath(resdir); - ds_set_firmware_resource_dir(res_path.c_str()); - - if (ds_lib_init() != SR_OK) + SigSession::SigSession() { - dsv_err("%s", "DSView run ERROR: collect lib init failed."); - return false; - } + // TODO: This should not be necessary + _session = this; + _group_cnt = 0; - return true; -} - -void SigSession::uninit() -{ - this->Close(); - - ds_lib_exit(); -} - -bool SigSession::set_default_device() -{ - assert(!_is_saving); - assert(!_is_working); - - struct ds_device_info *array = NULL; - int count = 0; - - dsv_info("%s", "Set default device."); - - if (ds_get_device_list(&array, &count) != SR_OK) - { - dsv_err("%s", "Get device list error!"); - return false; - } - if (count < 1 || array == NULL) - { - dsv_err("%s", "SigSession::set_default_device, Device list is empty!"); - return false; - } - - struct ds_device_info *dev = (array + count - 1); - ds_device_handle dev_handle = dev->handle; - - free(array); - - if (set_device(dev_handle)){ - return true; - } - return false; -} - -bool SigSession::set_device(ds_device_handle dev_handle) -{ - assert(!_is_saving); - assert(!_is_working); - - if (_callback != NULL){ - _callback->trigger_message(DSV_MSG_CURRENT_DEVICE_CHANGE_PREV); - } - - if (ds_active_device(dev_handle) != SR_OK){ - dsv_err("%s", "Switch device error!"); - return false; - } - _device_agent.update(); - _device_status = ST_INIT; - - init_signals(); - - RELEASE_ARRAY(_group_traces); - clear_all_decoder(); - - if (_device_agent.is_file()) - dsv_info("%s\"%s\"", "Switch to file: ", _device_agent.name().toUtf8().data()); - else - dsv_info("%s\"%s\"", "Switch to device: ", _device_agent.name().toUtf8().data()); - - _cur_snap_samplerate = _device_agent.get_sample_rate(); - _cur_samplelimits = _device_agent.get_sample_limit(); - - if (_device_agent.get_work_mode() == DSO) - _is_repeat_mode = true; - else + _map_zoom = 0; + _repeat_hold_prg = 0; + _repeat_intvl = 1; + _error = No_err; + _is_instant = false; + _is_working = false; _is_repeat_mode = false; + _is_saving = false; + _device_status = ST_INIT; + _noData_cnt = 0; + _data_lock = false; + _data_updated = false; - // The current device changed. - _callback->trigger_message(DSV_MSG_CURRENT_DEVICE_CHANGED); - - return true; -} + this->add_msg_listener(this); + _decoder_model = new pv::data::DecoderModel(NULL); -bool SigSession::set_file(QString name) -{ - assert(!_is_saving); - assert(!_is_working); + _lissajous_trace = NULL; + _math_trace = NULL; + _dso_feed = false; + _stop_scale = 1; + _is_decoding = false; + _bClose = false; + _callback = NULL; - dsv_info("Load file:\"%s\"", name.toUtf8().data()); + _device_agent.set_callback(this); - std::string path = path::ToUnicodePath(name); + // Create snapshots & data containers + _logic_data = new data::Logic(new data::LogicSnapshot()); + _dso_data = new data::Dso(new data::DsoSnapshot()); + _analog_data = new data::Analog(new data::AnalogSnapshot()); + _group_data = new data::Group(); + _group_cnt = 0; - if (ds_device_from_file(path.c_str()) != SR_OK) - { - dsv_err("%s", "Load file error!"); - return false; - } - - return set_default_device(); -} - -void SigSession::close_file(ds_device_handle dev_handle) -{ - assert(dev_handle); - - if (dev_handle == _device_agent.handle() && _is_working){ - dsv_err("%s", "The virtual device is running, can't remove it."); - return; - } - bool isCurrent = dev_handle == _device_agent.handle(); - - if (ds_remove_device(dev_handle) != SR_OK){ - dsv_err("%s", "Remove virtual deivice error!"); - } - - if (isCurrent) - set_default_device(); -} - - -bool SigSession::have_hardware_data() - { - if (_device_agent.have_instance() && _device_agent.is_hardware()){ - Snapshot *data = get_signal_snapshot(); - return data->have_data(); - } - return false; - } - - struct ds_device_info* SigSession::get_device_list(int &out_count, int &actived_index) - { - out_count = 0; - actived_index = -1; - struct ds_device_info *array = NULL; - - if (ds_get_device_list(&array, &out_count) == SR_OK) - { - actived_index = ds_get_actived_device_index(); - return array; - } - return NULL; - } - -uint64_t SigSession::cur_samplerate() -{ - // samplerate for current viewport - if (_device_agent.get_work_mode() == DSO) - return _device_agent.get_sample_rate(); - else - return cur_snap_samplerate(); -} - -uint64_t SigSession::cur_snap_samplerate() -{ - // samplerate for current snapshot - return _cur_snap_samplerate; -} - -double SigSession::cur_sampletime() -{ - return cur_samplelimits() * 1.0 / cur_samplerate(); -} - -double SigSession::cur_snap_sampletime() -{ - return cur_samplelimits() * 1.0 / cur_snap_samplerate(); -} - -double SigSession::cur_view_time() -{ - return _device_agent.get_time_base() * DS_CONF_DSO_HDIVS * 1.0 / SR_SEC(1); -} - -void SigSession::set_cur_snap_samplerate(uint64_t samplerate) -{ - assert(samplerate != 0); - _cur_snap_samplerate = samplerate; - // sample rate for all SignalData - // Logic/Analog/Dso - if (_logic_data) - _logic_data->set_samplerate(_cur_snap_samplerate); - if (_analog_data) - _analog_data->set_samplerate(_cur_snap_samplerate); - if (_dso_data) - _dso_data->set_samplerate(_cur_snap_samplerate); - // Group - if (_group_data) - _group_data->set_samplerate(_cur_snap_samplerate); - - - // DecoderStack - for(auto &d : _decode_traces) - { - d->decoder()->set_samplerate(_cur_snap_samplerate); - } - - // Math - if (_math_trace && _math_trace->enabled()) - _math_trace->get_math_stack()->set_samplerate(_device_agent.get_sample_rate()); - // SpectrumStack - for(auto & m : _spectrum_traces) - m->get_spectrum_stack()->set_samplerate(_cur_snap_samplerate); - - _callback->cur_snap_samplerate_changed(); -} - -void SigSession::set_cur_samplelimits(uint64_t samplelimits) -{ - assert(samplelimits != 0); - _cur_samplelimits = samplelimits; -} - -void SigSession::capture_init() -{ - // update instant setting - _device_agent.set_config(NULL, NULL, SR_CONF_INSTANT, g_variant_new_boolean(_is_instant)); - _callback->update_capture(); - - 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; - - int work_mode = _device_agent.get_work_mode(); - if (work_mode == DSO || work_mode == ANALOG) - _feed_timer.Start(FeedInterval); - else _feed_timer.Stop(); + _feed_timer.SetCallback(std::bind(&SigSession::feed_timeout, this)); + _repeate_timer.SetCallback(std::bind(&SigSession::repeat_capture_wait_timout, this)); + } - _noData_cnt = 0; - data_unlock(); - - // container init - container_init(); - - // update current hw offset - for(auto &s : _signals) + SigSession::SigSession(SigSession &o) { - assert(s); - view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) { - dsoSig->set_zero_ratio(dsoSig->get_zero_ratio()); + (void)o; + } + + SigSession::~SigSession() + { + } + + bool SigSession::init() + { + ds_log_set_context(dsv_log_context()); + + ds_set_event_callback(device_lib_event_callback); + + ds_set_datafeed_callback(data_feed_callback); + + // firmware resource directory + QString resdir = GetResourceDir(); + std::string res_path = pv::path::ToUnicodePath(resdir); + ds_set_firmware_resource_dir(res_path.c_str()); + + if (ds_lib_init() != SR_OK) + { + dsv_err("%s", "DSView run ERROR: collect lib init failed."); + return false; } - view::AnalogSignal *analogSig = NULL; - if ((analogSig = dynamic_cast(s))) { - analogSig->set_zero_ratio(analogSig->get_zero_ratio()); - } - } -} -void SigSession::container_init() -{ - // Logic - if (_logic_data) - _logic_data->init(); - - // Group - if (_group_data) - _group_data->init(); - - // Dso - if (_analog_data) - _analog_data->init(); - - // Analog - if (_dso_data) - _dso_data->init(); - - // SpectrumStack - for(auto &m : _spectrum_traces) - { - assert(m); - m->get_spectrum_stack()->init(); - } - - if (_math_trace) - _math_trace->get_math_stack()->init(); - - // DecoderStack - for(auto &d : _decode_traces) - { - d->decoder()->init(); - } -} - - bool SigSession::start_capture(bool instant) - { - assert(_callback); - - dsv_info("%s", "Start collect."); - - if (_is_working){ - dsv_err("%s", "Error! Is working now."); - return false; - } - - // Check that a device instance has been selected. - if (_device_agent.have_instance() == false) { - dsv_err("%s", "Error!No device selected"); - assert(false); - } - if (_device_agent.is_collecting()){ - dsv_err("%s", "Error!Device is running."); - return false; - } - - // update setting - if (_device_agent.is_file()) - _is_instant = true; - else - _is_instant = instant; - - _callback->trigger_message(DSV_MSG_START_COLLECT_WORK_PREV); - - return exec_capture(); - } - -bool SigSession::exec_capture() -{ - if (_device_agent.is_collecting()){ - dsv_err("%s", "Error!Device is running."); - return false; - } - - // stop all decode tasks - int run_dex = 0; - clear_all_decode_task(run_dex); - - // reset measure of dso signal - for(auto &s : _signals) - { - view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) - dsoSig->set_mValid(false); - } - - if (_device_agent.have_enabled_channel() == false){ - _callback->show_error("No probes enabled."); - return false; - } - - capture_init(); - - if (_device_agent.start() == false) - { - dsv_err("%s", "Start collect error!"); - return false; - } - - _is_working = true; - _callback->trigger_message(DSV_MSG_START_COLLECT_WORK); - return true; -} - -void SigSession::stop_capture() -{ - dsv_info("%s", "Stop collect."); - - if (!_is_working){ - return; - } - - bool wait_upload = false; - if (!_is_repeat_mode) { - 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); - } - } - if (!wait_upload) { - _is_working = false; - _callback->trigger_message(DSV_MSG_END_COLLECT_WORK_PREV); - exit_capture(); - } - else{ - dsv_info("%s", "Device is uploading."); - } -} - -void SigSession::exit_capture() -{ - _is_instant = false; - - if (_device_agent.is_collecting()){ - _device_agent.stop(); - } -} - -bool SigSession::get_capture_status(bool &triggered, int &progress) -{ - uint64_t sample_limits = cur_samplelimits(); - sr_status status; - - if (_device_agent.get_status(status, true)){ - triggered = status.trig_hit & 0x01; - uint64_t captured_cnt = status.trig_hit >> 2; - captured_cnt = ((uint64_t)status.captured_cnt0 + - ((uint64_t)status.captured_cnt1 << 8) + - ((uint64_t)status.captured_cnt2 << 16) + - ((uint64_t)status.captured_cnt3 << 24) + - (captured_cnt << 32)); - if (_device_agent.get_work_mode() == DSO) - captured_cnt = captured_cnt * _signals.size() / get_ch_num(SR_CHANNEL_DSO); - if (triggered) - progress = (sample_limits - captured_cnt) * 100.0 / sample_limits; - else - progress = captured_cnt * 100.0 / sample_limits; return true; } - return false; -} -std::vector& SigSession::get_signals() -{ - return _signals; -} - -std::vector& SigSession::get_group_signals() -{ - return _group_traces; -} - -std::set SigSession::get_data() -{ - std::set data; - - for(auto &sig : _signals) { - assert(sig); - data.insert(sig->data()); - } - - return data; -} - -void SigSession::check_update() -{ - ds_lock_guard lock(_data_mutex); - - if (_device_agent.is_collecting() == false) - return; - - if (_data_updated) { - data_updated(); - _data_updated = false; - _noData_cnt = 0; - data_auto_unlock(); - } - else { - if (++_noData_cnt >= (WaitShowTime/FeedInterval)) - nodata_timeout(); - } -} - -void SigSession::add_group() -{ - std::list probe_index_list; - - auto i = _signals.begin(); - while (i != _signals.end()) { - if ((*i)->get_type() == SR_CHANNEL_LOGIC && (*i)->selected()) - probe_index_list.push_back((*i)->get_index()); - i++; - } - - if (probe_index_list.size() > 1) { - _group_data->init(); - _group_data->set_samplerate(_cur_snap_samplerate); - auto signal = new view::GroupSignal("New Group", _group_data, probe_index_list, _group_cnt); - _group_traces.push_back(signal); - _group_cnt++; - - const auto &snapshots = _logic_data->get_snapshots(); - if (!snapshots.empty()) - { - auto p = new data::GroupSnapshot(snapshots.front(), signal->get_index_list()); - _group_data->push_snapshot(p); - } - - signals_changed(); - data_updated(); - } -} - -void SigSession::del_group() -{ - auto i = _group_traces.begin(); - - while (i != _group_traces.end()) { - - pv::view::GroupSignal *psig = *(i); - - if (psig->selected()) { - auto j = _group_traces.begin(); - while(j != _group_traces.end()) { - if ((*j)->get_sec_index() > psig->get_sec_index()) - (*j)->set_sec_index((*j)->get_sec_index() - 1); - j++; - } - - auto &snapshots = _group_data->get_snapshots(); - if (!snapshots.empty()) { - int dex = psig->get_sec_index(); - pv::data::GroupSnapshot *pshot = _group_data->get_snapshots().at(dex); - delete pshot; - - auto k = snapshots.begin(); - k += (*i)->get_sec_index(); - _group_data->get_snapshots().erase(k); - } - - delete psig; - - i = _group_traces.erase(i); - - _group_cnt--; - continue; - } - i++; - } - - signals_changed(); - data_updated(); -} - -void SigSession::init_signals() -{ - assert(!_is_working); - - if (_device_agent.have_instance() == false){ - assert(false); - } - - std::vector sigs; - view::Signal *signal = NULL; - unsigned int logic_probe_count = 0; - unsigned int dso_probe_count = 0; - unsigned int analog_probe_count = 0; - - _logic_data->clear(); - _dso_data->clear(); - _analog_data->clear(); - _group_data->clear(); - - // Clear the decode traces - clear_all_decoder(); - - // Detect what data types we will receive - if(_device_agent.have_instance()) { - - for (const GSList *l = _device_agent.get_channels(); l; l = l->next) - { - const sr_channel *const probe = (const sr_channel *)l->data; - - switch(probe->type) { - case SR_CHANNEL_LOGIC: - if(probe->enabled) - logic_probe_count++; - break; - - case SR_CHANNEL_DSO: - dso_probe_count++; - break; - - case SR_CHANNEL_ANALOG: - if(probe->enabled) - analog_probe_count++; - break; - } - } - } - - // Make the logic probe list - RELEASE_ARRAY(_group_traces); - - std::vector().swap(_group_traces); - - for (GSList *l = _device_agent.get_channels(); l; l = l->next) + void SigSession::uninit() { - sr_channel *probe = - (sr_channel *)l->data; - assert(probe); - signal = NULL; + this->Close(); - switch (probe->type) - { - case SR_CHANNEL_LOGIC: - if (probe->enabled) - signal = new view::LogicSignal(_logic_data, probe); - break; - - case SR_CHANNEL_DSO: - signal = new view::DsoSignal(_dso_data, probe); - break; - - case SR_CHANNEL_ANALOG: - if (probe->enabled) - signal = new view::AnalogSignal(_analog_data, probe); - break; - } - if (signal != NULL) - sigs.push_back(signal); + ds_lib_exit(); } - RELEASE_ARRAY(_signals); - std::vector().swap(_signals); - _signals = sigs; - - spectrum_rebuild(); - lissajous_disable(); - math_disable(); -} - -void SigSession::reload() -{ - if (_device_agent.have_instance() == false){ - assert(false); - } - - if (_is_working) - return; - - std::vector sigs; - view::Signal *signal = NULL; - - // Make the logic probe list - for (GSList *l = _device_agent.get_channels(); l; l = l->next) + bool SigSession::set_default_device() { - sr_channel *probe = - (sr_channel *)l->data; - assert(probe); - signal = NULL; + assert(!_is_saving); + assert(!_is_working); - switch (probe->type) + struct ds_device_info *array = NULL; + int count = 0; + + dsv_info("%s", "Set default device."); + + if (ds_get_device_list(&array, &count) != SR_OK) { - case SR_CHANNEL_LOGIC: - if (probe->enabled) - { - auto i = _signals.begin(); - while (i != _signals.end()) - { - if ((*i)->get_index() == probe->index) - { - view::LogicSignal *logicSig = NULL; - if ((logicSig = dynamic_cast(*i))) - signal = new view::LogicSignal(logicSig, _logic_data, probe); - break; - } - i++; - } - if (signal == NULL) - { - signal = new view::LogicSignal(_logic_data, probe); - } - } - break; - - case SR_CHANNEL_ANALOG: - if (probe->enabled) - { - auto i = _signals.begin(); - while (i != _signals.end()) - { - if ((*i)->get_index() == probe->index) - { - view::AnalogSignal *analogSig = NULL; - if ((analogSig = dynamic_cast(*i))) - signal = new view::AnalogSignal(analogSig, _analog_data, probe); - break; - } - i++; - } - if (signal == NULL) - { - signal = new view::AnalogSignal(_analog_data, probe); - } - } - break; + dsv_err("%s", "Get device list error!"); + return false; } - if (signal != NULL) - sigs.push_back(signal); + if (count < 1 || array == NULL) + { + dsv_err("%s", "Error! Device list is empty, can't set default device."); + return false; + } + + struct ds_device_info *dev = (array + count - 1); + ds_device_handle dev_handle = dev->handle; + + free(array); + + if (set_device(dev_handle)) + { + return true; + } + return false; } - if (!sigs.empty()) + bool SigSession::set_device(ds_device_handle dev_handle) { - RELEASE_ARRAY(_signals); - std::vector().swap(_signals); - _signals = sigs; - } + assert(!_is_saving); + assert(!_is_working); - spectrum_rebuild(); -} + // Release old device. + _device_agent.release(); -void SigSession::refresh(int holdtime) -{ - ds_lock_guard lock(_data_mutex); - - data_lock(); - - if (_logic_data) { - _logic_data->init(); - - for(auto &d : _decode_traces) - { - d->decoder()->init(); + if (_callback != NULL) + { + _callback->trigger_message(DSV_MSG_CURRENT_DEVICE_CHANGE_PREV); } + + if (ds_active_device(dev_handle) != SR_OK) + { + dsv_err("%s", "Switch device error!"); + return false; + } + + _device_agent.update(); + _device_status = ST_INIT; + + init_signals(); + + RELEASE_ARRAY(_group_traces); + clear_all_decoder(); + + if (_device_agent.is_file()) + dsv_info("%s\"%s\"", "Switch to file: ", _device_agent.name().toUtf8().data()); + else + dsv_info("%s\"%s\"", "Switch to device: ", _device_agent.name().toUtf8().data()); + + _cur_snap_samplerate = _device_agent.get_sample_rate(); + _cur_samplelimits = _device_agent.get_sample_limit(); + + if (_device_agent.get_work_mode() == DSO) + _is_repeat_mode = true; + else + _is_repeat_mode = false; + + // The current device changed. + _callback->trigger_message(DSV_MSG_CURRENT_DEVICE_CHANGED); + + return true; } - if (_dso_data) { - _dso_data->init(); + bool SigSession::set_file(QString name) + { + assert(!_is_saving); + assert(!_is_working); + + dsv_info("Load file:\"%s\"", name.toUtf8().data()); + + std::string path = path::ToUnicodePath(name); + + if (ds_device_from_file(path.c_str()) != SR_OK) + { + dsv_err("%s", "Load file error!"); + return false; + } + + return set_default_device(); + } + + void SigSession::close_file(ds_device_handle dev_handle) + { + assert(dev_handle); + + if (dev_handle == _device_agent.handle() && _is_working) + { + dsv_err("%s", "The virtual device is running, can't remove it."); + return; + } + bool isCurrent = dev_handle == _device_agent.handle(); + + if (ds_remove_device(dev_handle) != SR_OK) + { + dsv_err("%s", "Remove virtual deivice error!"); + } + + if (isCurrent) + set_default_device(); + } + + bool SigSession::have_hardware_data() + { + if (_device_agent.have_instance() && _device_agent.is_hardware()) + { + Snapshot *data = get_signal_snapshot(); + return data->have_data(); + } + return false; + } + + struct ds_device_info *SigSession::get_device_list(int &out_count, int &actived_index) + { + out_count = 0; + actived_index = -1; + struct ds_device_info *array = NULL; + + if (ds_get_device_list(&array, &out_count) == SR_OK) + { + actived_index = ds_get_actived_device_index(); + return array; + } + return NULL; + } + + uint64_t SigSession::cur_samplerate() + { + // samplerate for current viewport + if (_device_agent.get_work_mode() == DSO) + return _device_agent.get_sample_rate(); + else + return cur_snap_samplerate(); + } + + uint64_t SigSession::cur_snap_samplerate() + { + // samplerate for current snapshot + return _cur_snap_samplerate; + } + + double SigSession::cur_sampletime() + { + return cur_samplelimits() * 1.0 / cur_samplerate(); + } + + double SigSession::cur_snap_sampletime() + { + return cur_samplelimits() * 1.0 / cur_snap_samplerate(); + } + + double SigSession::cur_view_time() + { + return _device_agent.get_time_base() * DS_CONF_DSO_HDIVS * 1.0 / SR_SEC(1); + } + + void SigSession::set_cur_snap_samplerate(uint64_t samplerate) + { + assert(samplerate != 0); + _cur_snap_samplerate = samplerate; + // sample rate for all SignalData + // Logic/Analog/Dso + if (_logic_data) + _logic_data->set_samplerate(_cur_snap_samplerate); + if (_analog_data) + _analog_data->set_samplerate(_cur_snap_samplerate); + if (_dso_data) + _dso_data->set_samplerate(_cur_snap_samplerate); + // Group + if (_group_data) + _group_data->set_samplerate(_cur_snap_samplerate); + + // DecoderStack + for (auto &d : _decode_traces) + { + d->decoder()->set_samplerate(_cur_snap_samplerate); + } + + // Math + if (_math_trace && _math_trace->enabled()) + _math_trace->get_math_stack()->set_samplerate(_device_agent.get_sample_rate()); // SpectrumStack - for(auto &m : _spectrum_traces) + for (auto &m : _spectrum_traces) + m->get_spectrum_stack()->set_samplerate(_cur_snap_samplerate); + + _callback->cur_snap_samplerate_changed(); + } + + void SigSession::set_cur_samplelimits(uint64_t samplelimits) + { + assert(samplelimits != 0); + _cur_samplelimits = samplelimits; + } + + void SigSession::capture_init() + { + // update instant setting + _device_agent.set_config(NULL, NULL, SR_CONF_INSTANT, g_variant_new_boolean(_is_instant)); + _callback->update_capture(); + + 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; + + int work_mode = _device_agent.get_work_mode(); + if (work_mode == DSO || work_mode == ANALOG) + _feed_timer.Start(FeedInterval); + else + _feed_timer.Stop(); + + _noData_cnt = 0; + data_unlock(); + + // container init + container_init(); + + // update current hw offset + for (auto &s : _signals) + { + assert(s); + view::DsoSignal *dsoSig = NULL; + if ((dsoSig = dynamic_cast(s))) + { + dsoSig->set_zero_ratio(dsoSig->get_zero_ratio()); + } + view::AnalogSignal *analogSig = NULL; + if ((analogSig = dynamic_cast(s))) + { + analogSig->set_zero_ratio(analogSig->get_zero_ratio()); + } + } + } + + void SigSession::container_init() + { + // Logic + if (_logic_data) + _logic_data->init(); + + // Group + if (_group_data) + _group_data->init(); + + // Dso + if (_analog_data) + _analog_data->init(); + + // Analog + if (_dso_data) + _dso_data->init(); + + // SpectrumStack + for (auto &m : _spectrum_traces) { assert(m); m->get_spectrum_stack()->init(); @@ -864,1015 +429,1572 @@ void SigSession::refresh(int holdtime) if (_math_trace) _math_trace->get_math_stack()->init(); - } - if (_analog_data) { - _analog_data->init(); - } - - _out_timer.TimeOut(holdtime, std::bind(&SigSession::feed_timeout, this)); - _data_updated = true; -} - -void SigSession::data_lock() -{ - _data_lock = true; -} - -void SigSession::data_unlock() -{ - _data_lock = false; -} - -bool SigSession::get_data_lock() -{ - return _data_lock; -} - -void SigSession::data_auto_lock(int lock) { - _data_auto_lock = lock; -} - -void SigSession::data_auto_unlock() { - if (_data_auto_lock > 0) - _data_auto_lock--; - else if (_data_auto_lock < 0) - _data_auto_lock = 0; -} - -bool SigSession::get_data_auto_lock() { - return _data_auto_lock != 0; -} - -void SigSession::feed_in_header(const sr_dev_inst *sdi) -{ - (void)sdi; - _trigger_pos = 0; - _callback->receive_header(); -} - -void SigSession::feed_in_meta(const sr_dev_inst *sdi, - const sr_datafeed_meta &meta) -{ - (void)sdi; - - for (const GSList *l = meta.config; l; l = l->next) { - const sr_config *const src = (const sr_config*)l->data; - switch (src->key) { - case SR_CONF_SAMPLERATE: - /// @todo handle samplerate changes - /// samplerate = (uint64_t *)src->value; - break; - } - } -} - -void SigSession::feed_in_trigger(const ds_trigger_pos &trigger_pos) -{ - _hw_replied = true; - if (_device_agent.get_work_mode() != DSO) { - _trigger_flag = (trigger_pos.status & 0x01); - if (_trigger_flag) { - _trigger_pos = trigger_pos.real_pos; - _callback->receive_trigger(_trigger_pos); - } - } else { - int probe_count = 0; - int probe_en_count = 0; - for (const GSList *l = _device_agent.get_channels(); l; l = l->next) { - const sr_channel *const probe = (const sr_channel *)l->data; - if (probe->type == SR_CHANNEL_DSO) { - probe_count++; - if (probe->enabled) - probe_en_count++; - } - } - _trigger_pos = trigger_pos.real_pos * probe_count / probe_en_count; - _callback->receive_trigger(_trigger_pos); - } -} - -void SigSession::feed_in_logic(const sr_datafeed_logic &logic) -{ - if (!_logic_data || _logic_data->snapshot()->memory_failed()) { - dsv_err("%s", "Unexpected logic packet"); - return; - } - - if (logic.data_error == 1) { - _error = Test_data_err; - _error_pattern = logic.error_pattern; - _callback->session_error(); - } - - if (_logic_data->snapshot()->last_ended()) { - _logic_data->snapshot()->first_payload(logic, _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 - // this after both analog and logic sweeps have begun. - _callback->frame_began(); - } else { - // Append to the existing data snapshot - _logic_data->snapshot()->append_payload(logic); - } - - if (_logic_data->snapshot()->memory_failed()) { - _error = Malloc_err; - _callback->session_error(); - return; - } - - receive_data(logic.length * 8 / get_ch_num(SR_CHANNEL_LOGIC)); - - _callback->data_received(); - - _data_updated = true; -} - -void SigSession::feed_in_dso(const sr_datafeed_dso &dso) -{ - if(!_dso_data || _dso_data->snapshot()->memory_failed()) - { - dsv_err("%s", "Unexpected dso packet"); - return; // This dso packet was not expected. - } - - if (_dso_data->snapshot()->last_ended()) - { - std::map sig_enable; - // reset scale of dso signal - for(auto &s : _signals) + // DecoderStack + for (auto &d : _decode_traces) + { + d->decoder()->init(); + } + } + + bool SigSession::start_capture(bool instant) + { + assert(_callback); + + dsv_info("%s", "Start collect."); + + if (_is_working) + { + dsv_err("%s", "Error! Is working now."); + return false; + } + + // Check that a device instance has been selected. + if (_device_agent.have_instance() == false) + { + dsv_err("%s", "Error!No device selected"); + assert(false); + } + if (_device_agent.is_collecting()) + { + dsv_err("%s", "Error!Device is running."); + return false; + } + + // update setting + if (_device_agent.is_file()) + _is_instant = true; + else + _is_instant = instant; + + _callback->trigger_message(DSV_MSG_START_COLLECT_WORK_PREV); + + return exec_capture(); + } + + bool SigSession::exec_capture() + { + if (_device_agent.is_collecting()) + { + dsv_err("%s", "Error!Device is running."); + return false; + } + + // stop all decode tasks + int run_dex = 0; + clear_all_decode_task(run_dex); + + // reset measure of dso signal + for (auto &s : _signals) { - assert(s); view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) { - dsoSig->set_scale(dsoSig->get_view_rect().height()); - sig_enable[dsoSig->get_index()] = dsoSig->enabled(); - } + if ((dsoSig = dynamic_cast(s))) + dsoSig->set_mValid(false); } - // first payload - _dso_data->snapshot()->first_payload(dso, _device_agent.get_sample_limit(), sig_enable, _is_instant); - } else { - // Append to the existing data snapshot - _dso_data->snapshot()->append_payload(dso); - } - - for(auto &s : _signals) { - view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s)) && (dsoSig->enabled())) - dsoSig->paint_prepare(); - } - - if (dso.num_samples != 0) { - // update current sample rate - set_cur_snap_samplerate(_device_agent.get_sample_rate()); - - } - - if (_dso_data->snapshot()->memory_failed()) { - _error = Malloc_err; - _callback->session_error(); - return; - } - - // calculate related spectrum results - for(auto &m : _spectrum_traces) - { - assert(m); - if (m->enabled()) - m->get_spectrum_stack()->calc_fft(); - } - - // calculate related math results - if (_math_trace && _math_trace->enabled()) { - _math_trace->get_math_stack()->realloc(_device_agent.get_sample_limit()); - _math_trace->get_math_stack()->calc_math(); - } - - _trigger_flag = dso.trig_flag; - _trigger_ch = dso.trig_ch; - receive_data(dso.num_samples); - - if (!_is_instant) - data_lock(); - - _data_updated = true; -} - -void SigSession::feed_in_analog(const sr_datafeed_analog &analog) -{ - - if(!_analog_data || _analog_data->snapshot()->memory_failed()) - { - dsv_err("%s", "Unexpected analog packet"); - return; // This analog packet was not expected. - } - - if (_analog_data->snapshot()->last_ended()) - { - // reset scale of analog signal - for(auto &s : _signals) + if (_device_agent.have_enabled_channel() == false) { - assert(s); - view::AnalogSignal *analogSig = NULL; - if ((analogSig = dynamic_cast(s))) { - analogSig->set_scale(analogSig->get_totalHeight()); + _callback->show_error("No probes enabled."); + return false; + } + + capture_init(); + + if (_device_agent.start() == false) + { + dsv_err("%s", "Start collect error!"); + return false; + } + + _is_working = true; + _callback->trigger_message(DSV_MSG_START_COLLECT_WORK); + return true; + } + + void SigSession::stop_capture() + { + dsv_info("%s", "Stop collect."); + + if (!_is_working) + { + return; + } + + //_feed_timer + + bool wait_upload = false; + if (!_is_repeat_mode) + { + 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); } } - - // first payload - _analog_data->snapshot()->first_payload(analog, _device_agent.get_sample_limit(), _device_agent.get_channels()); - } - else { - // Append to the existing data snapshot - _analog_data->snapshot()->append_payload(analog); - } - - if (_analog_data->snapshot()->memory_failed()) { - _error = Malloc_err; - _callback->session_error(); - return; - } - - receive_data(analog.num_samples); - _data_updated = true; -} - -void SigSession::data_feed_in(const struct sr_dev_inst *sdi, - const struct sr_datafeed_packet *packet) -{ - assert(sdi); - assert(packet); - - ds_lock_guard lock(_data_mutex); - - // dsv_info("%s", "Receive data."); - - if (_data_lock && packet->type != SR_DF_END) - return; - - if (packet->type != SR_DF_END && - packet->status != SR_PKT_OK) { - _error = Pkt_data_err; - _callback->session_error(); - return; - } - - switch (packet->type) { - case SR_DF_HEADER: - feed_in_header(sdi); - break; - - case SR_DF_META: - assert(packet->payload); - feed_in_meta(sdi, - *(const sr_datafeed_meta*)packet->payload); - break; - - case SR_DF_TRIGGER: - assert(packet->payload); - feed_in_trigger(*(const ds_trigger_pos*)packet->payload); - break; - - case SR_DF_LOGIC: - assert(packet->payload); - feed_in_logic(*(const sr_datafeed_logic*)packet->payload); - break; - - case SR_DF_DSO: - assert(packet->payload); - feed_in_dso(*(const sr_datafeed_dso*)packet->payload); - break; - - case SR_DF_ANALOG: - assert(packet->payload); - feed_in_analog(*(const sr_datafeed_analog*)packet->payload); - break; - - case SR_DF_OVERFLOW: - { - if (_error == No_err) { - _error = Data_overflow; - _callback->session_error(); + if (!wait_upload) + { + _is_working = false; + _callback->trigger_message(DSV_MSG_END_COLLECT_WORK_PREV); + exit_capture(); + } + else + { + dsv_info("%s", "Device is uploading."); } - break; } - case SR_DF_END: - { - if (!_logic_data->snapshot()->empty()){ - for (auto &g : _group_traces) - { - assert(g); - auto p = new data::GroupSnapshot(_logic_data->get_snapshots().front(), g->get_index_list()); + void SigSession::exit_capture() + { + _is_instant = false; + + _feed_timer.Stop(); + + if (_device_agent.is_collecting()) + { + _device_agent.stop(); + } + } + + bool SigSession::get_capture_status(bool &triggered, int &progress) + { + uint64_t sample_limits = cur_samplelimits(); + sr_status status; + + if (_device_agent.get_status(status, true)) + { + triggered = status.trig_hit & 0x01; + uint64_t captured_cnt = status.trig_hit >> 2; + captured_cnt = ((uint64_t)status.captured_cnt0 + + ((uint64_t)status.captured_cnt1 << 8) + + ((uint64_t)status.captured_cnt2 << 16) + + ((uint64_t)status.captured_cnt3 << 24) + + (captured_cnt << 32)); + if (_device_agent.get_work_mode() == DSO) + captured_cnt = captured_cnt * _signals.size() / get_ch_num(SR_CHANNEL_DSO); + if (triggered) + progress = (sample_limits - captured_cnt) * 100.0 / sample_limits; + else + progress = captured_cnt * 100.0 / sample_limits; + return true; + } + return false; + } + + std::vector &SigSession::get_signals() + { + return _signals; + } + + std::vector &SigSession::get_group_signals() + { + return _group_traces; + } + + std::set SigSession::get_data() + { + std::set data; + + for (auto &sig : _signals) + { + assert(sig); + data.insert(sig->data()); + } + + return data; + } + + void SigSession::check_update() + { + ds_lock_guard lock(_data_mutex); + + if (_device_agent.is_collecting() == false) + return; + + if (_data_updated) + { + data_updated(); + _data_updated = false; + _noData_cnt = 0; + data_auto_unlock(); + } + else + { + if (++_noData_cnt >= (WaitShowTime / FeedInterval)) + nodata_timeout(); + } + } + + void SigSession::add_group() + { + std::list probe_index_list; + + auto i = _signals.begin(); + while (i != _signals.end()) + { + if ((*i)->get_type() == SR_CHANNEL_LOGIC && (*i)->selected()) + probe_index_list.push_back((*i)->get_index()); + i++; + } + + if (probe_index_list.size() > 1) + { + _group_data->init(); + _group_data->set_samplerate(_cur_snap_samplerate); + auto signal = new view::GroupSignal("New Group", _group_data, probe_index_list, _group_cnt); + _group_traces.push_back(signal); + _group_cnt++; + + const auto &snapshots = _logic_data->get_snapshots(); + if (!snapshots.empty()) + { + auto p = new data::GroupSnapshot(snapshots.front(), signal->get_index_list()); _group_data->push_snapshot(p); } + + signals_changed(); + data_updated(); } - _logic_data->snapshot()->capture_ended(); - _dso_data->snapshot()->capture_ended(); - _analog_data->snapshot()->capture_ended(); - - for (auto trace : _decode_traces){ - trace->decoder()->frame_ended(); - trace->frame_ended(); - add_decode_task(trace); - } - - if (packet->status != SR_PKT_OK) { - _error = Pkt_data_err; - _callback->session_error(); - } - - _callback->frame_ended(); - - if (_device_agent.get_work_mode() != LOGIC){ - set_session_time(QDateTime::currentDateTime()); - } - - break; } - } -} -void SigSession::data_feed_callback(const struct sr_dev_inst *sdi, - const struct sr_datafeed_packet *packet) -{ - assert(_session); - _session->data_feed_in(sdi, packet); -} + void SigSession::del_group() + { + auto i = _group_traces.begin(); -uint16_t SigSession::get_ch_num(int type) -{ - uint16_t num_channels = 0; - uint16_t logic_ch_num = 0; - uint16_t dso_ch_num = 0; - uint16_t analog_ch_num = 0; - - if (_device_agent.have_instance()) { - for(auto &s : _signals) + while (i != _group_traces.end()) { - assert(s); - if (dynamic_cast(s) && s->enabled()) { - logic_ch_num++; - } - if (dynamic_cast(s) && s->enabled()) { - dso_ch_num++; - } - if (dynamic_cast(s) && s->enabled()) { - analog_ch_num++; + + pv::view::GroupSignal *psig = *(i); + + if (psig->selected()) + { + auto j = _group_traces.begin(); + while (j != _group_traces.end()) + { + if ((*j)->get_sec_index() > psig->get_sec_index()) + (*j)->set_sec_index((*j)->get_sec_index() - 1); + j++; + } + + auto &snapshots = _group_data->get_snapshots(); + if (!snapshots.empty()) + { + int dex = psig->get_sec_index(); + pv::data::GroupSnapshot *pshot = _group_data->get_snapshots().at(dex); + delete pshot; + + auto k = snapshots.begin(); + k += (*i)->get_sec_index(); + _group_data->get_snapshots().erase(k); + } + + delete psig; + + i = _group_traces.erase(i); + + _group_cnt--; + continue; } + i++; } + + signals_changed(); + data_updated(); } - switch(type) { - case SR_CHANNEL_LOGIC: - num_channels = logic_ch_num; break; - case SR_CHANNEL_DSO: - num_channels = dso_ch_num; break; - case SR_CHANNEL_ANALOG: - num_channels = analog_ch_num; break; - default: - num_channels = logic_ch_num+dso_ch_num+analog_ch_num; break; + void SigSession::init_signals() + { + assert(!_is_working); + + if (_device_agent.have_instance() == false) + { + assert(false); + } + + std::vector sigs; + view::Signal *signal = NULL; + unsigned int logic_probe_count = 0; + unsigned int dso_probe_count = 0; + unsigned int analog_probe_count = 0; + + _logic_data->clear(); + _dso_data->clear(); + _analog_data->clear(); + _group_data->clear(); + + // Clear the decode traces + clear_all_decoder(); + + // Detect what data types we will receive + if (_device_agent.have_instance()) + { + + for (const GSList *l = _device_agent.get_channels(); l; l = l->next) + { + const sr_channel *const probe = (const sr_channel *)l->data; + + switch (probe->type) + { + case SR_CHANNEL_LOGIC: + if (probe->enabled) + logic_probe_count++; + break; + + case SR_CHANNEL_DSO: + dso_probe_count++; + break; + + case SR_CHANNEL_ANALOG: + if (probe->enabled) + analog_probe_count++; + break; + } + } + } + + // Make the logic probe list + RELEASE_ARRAY(_group_traces); + + std::vector().swap(_group_traces); + + for (GSList *l = _device_agent.get_channels(); l; l = l->next) + { + sr_channel *probe = + (sr_channel *)l->data; + assert(probe); + signal = NULL; + + switch (probe->type) + { + case SR_CHANNEL_LOGIC: + if (probe->enabled) + signal = new view::LogicSignal(_logic_data, probe); + break; + + case SR_CHANNEL_DSO: + signal = new view::DsoSignal(_dso_data, probe); + break; + + case SR_CHANNEL_ANALOG: + if (probe->enabled) + signal = new view::AnalogSignal(_analog_data, probe); + break; + } + if (signal != NULL) + sigs.push_back(signal); + } + + RELEASE_ARRAY(_signals); + std::vector().swap(_signals); + _signals = sigs; + + spectrum_rebuild(); + lissajous_disable(); + math_disable(); } - return num_channels; -} - -bool SigSession::add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus, - std::list &sub_decoders){ - - if (dec == NULL){ - dsv_err("%s", "Decoder instance is null!"); - assert(false); - } - - dsv_info("Create new decoder,name:\"%s\",id:\"%s\"", dec->name, dec->id); - - try { - - bool ret = false; - - // Create the decoder - std::map probes; - data::DecoderStack *decoder_stack = new data::DecoderStack(this, dec, dstatus); - assert(decoder_stack); - - // Make a list of all the probes - std::vector all_probes; - for(const GSList *i = dec->channels; i; i = i->next) - all_probes.push_back((const srd_channel*)i->data); - - for(const GSList *i = dec->opt_channels; i; i = i->next) - all_probes.push_back((const srd_channel*)i->data); - - decoder_stack->stack().front()->set_probes(probes); - - // Create the decode signal - view::DecodeTrace *trace = new view::DecodeTrace(this, decoder_stack, _decode_traces.size()); - assert(trace); - - //add sub decoder - for(auto sub : sub_decoders){ - trace->decoder()->add_sub_decoder(sub); + void SigSession::reload() + { + if (_device_agent.have_instance() == false) + { + assert(false); } - sub_decoders.clear(); - // set view early for decode start/end region setting - for(auto &s : _signals) { - if (s->get_view()) { - trace->set_view(s->get_view()); + if (_is_working) + return; + + std::vector sigs; + view::Signal *signal = NULL; + + // Make the logic probe list + for (GSList *l = _device_agent.get_channels(); l; l = l->next) + { + sr_channel *probe = + (sr_channel *)l->data; + assert(probe); + signal = NULL; + + switch (probe->type) + { + case SR_CHANNEL_LOGIC: + if (probe->enabled) + { + auto i = _signals.begin(); + while (i != _signals.end()) + { + if ((*i)->get_index() == probe->index) + { + view::LogicSignal *logicSig = NULL; + if ((logicSig = dynamic_cast(*i))) + signal = new view::LogicSignal(logicSig, _logic_data, probe); + break; + } + i++; + } + if (signal == NULL) + { + signal = new view::LogicSignal(_logic_data, probe); + } + } + break; + + case SR_CHANNEL_ANALOG: + if (probe->enabled) + { + auto i = _signals.begin(); + while (i != _signals.end()) + { + if ((*i)->get_index() == probe->index) + { + view::AnalogSignal *analogSig = NULL; + if ((analogSig = dynamic_cast(*i))) + signal = new view::AnalogSignal(analogSig, _analog_data, probe); + break; + } + i++; + } + if (signal == NULL) + { + signal = new view::AnalogSignal(_analog_data, probe); + } + } + break; + } + if (signal != NULL) + sigs.push_back(signal); + } + + if (!sigs.empty()) + { + RELEASE_ARRAY(_signals); + std::vector().swap(_signals); + _signals = sigs; + } + + spectrum_rebuild(); + } + + void SigSession::refresh(int holdtime) + { + ds_lock_guard lock(_data_mutex); + + data_lock(); + + if (_logic_data) + { + _logic_data->init(); + + for (auto &d : _decode_traces) + { + d->decoder()->init(); + } + } + + if (_dso_data) + { + _dso_data->init(); + // SpectrumStack + for (auto &m : _spectrum_traces) + { + assert(m); + m->get_spectrum_stack()->init(); + } + + if (_math_trace) + _math_trace->get_math_stack()->init(); + } + + if (_analog_data) + { + _analog_data->init(); + } + + _out_timer.TimeOut(holdtime, std::bind(&SigSession::feed_timeout, this)); + _data_updated = true; + } + + void SigSession::data_lock() + { + _data_lock = true; + } + + void SigSession::data_unlock() + { + _data_lock = false; + } + + bool SigSession::get_data_lock() + { + return _data_lock; + } + + void SigSession::data_auto_lock(int lock) + { + _data_auto_lock = lock; + } + + void SigSession::data_auto_unlock() + { + if (_data_auto_lock > 0) + _data_auto_lock--; + else if (_data_auto_lock < 0) + _data_auto_lock = 0; + } + + bool SigSession::get_data_auto_lock() + { + return _data_auto_lock != 0; + } + + void SigSession::feed_in_header(const sr_dev_inst *sdi) + { + (void)sdi; + _trigger_pos = 0; + _callback->receive_header(); + } + + void SigSession::feed_in_meta(const sr_dev_inst *sdi, + const sr_datafeed_meta &meta) + { + (void)sdi; + + for (const GSList *l = meta.config; l; l = l->next) + { + const sr_config *const src = (const sr_config *)l->data; + switch (src->key) + { + case SR_CONF_SAMPLERATE: + /// @todo handle samplerate changes + /// samplerate = (uint64_t *)src->value; break; } } + } - if (silent) { - ret = true; - } else if (trace->create_popup(true)) { - ret = true; + void SigSession::feed_in_trigger(const ds_trigger_pos &trigger_pos) + { + _hw_replied = true; + if (_device_agent.get_work_mode() != DSO) + { + _trigger_flag = (trigger_pos.status & 0x01); + if (_trigger_flag) + { + _trigger_pos = trigger_pos.real_pos; + _callback->receive_trigger(_trigger_pos); + } + } + else + { + int probe_count = 0; + int probe_en_count = 0; + for (const GSList *l = _device_agent.get_channels(); l; l = l->next) + { + const sr_channel *const probe = (const sr_channel *)l->data; + if (probe->type == SR_CHANNEL_DSO) + { + probe_count++; + if (probe->enabled) + probe_en_count++; + } + } + _trigger_pos = trigger_pos.real_pos * probe_count / probe_en_count; + _callback->receive_trigger(_trigger_pos); + } + } + + void SigSession::feed_in_logic(const sr_datafeed_logic &logic) + { + if (!_logic_data || _logic_data->snapshot()->memory_failed()) + { + dsv_err("%s", "Unexpected logic packet"); + return; } - if (ret) - { - _decode_traces.push_back(trace); - - //add decode task from ui - if (!silent){ + if (logic.data_error == 1) + { + _error = Test_data_err; + _error_pattern = logic.error_pattern; + _callback->session_error(); + } + + if (_logic_data->snapshot()->last_ended()) + { + _logic_data->snapshot()->first_payload(logic, _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 + // this after both analog and logic sweeps have begun. + _callback->frame_began(); + } + else + { + // Append to the existing data snapshot + _logic_data->snapshot()->append_payload(logic); + } + + if (_logic_data->snapshot()->memory_failed()) + { + _error = Malloc_err; + _callback->session_error(); + return; + } + + receive_data(logic.length * 8 / get_ch_num(SR_CHANNEL_LOGIC)); + + _callback->data_received(); + + _data_updated = true; + } + + void SigSession::feed_in_dso(const sr_datafeed_dso &dso) + { + if (!_dso_data || _dso_data->snapshot()->memory_failed()) + { + dsv_err("%s", "Unexpected dso packet"); + return; // This dso packet was not expected. + } + + if (_dso_data->snapshot()->last_ended()) + { + std::map sig_enable; + // reset scale of dso signal + for (auto &s : _signals) + { + assert(s); + view::DsoSignal *dsoSig = NULL; + if ((dsoSig = dynamic_cast(s))) + { + dsoSig->set_scale(dsoSig->get_view_rect().height()); + sig_enable[dsoSig->get_index()] = dsoSig->enabled(); + } + } + + // first payload + _dso_data->snapshot()->first_payload(dso, _device_agent.get_sample_limit(), sig_enable, _is_instant); + } + else + { + // Append to the existing data snapshot + _dso_data->snapshot()->append_payload(dso); + } + + for (auto &s : _signals) + { + view::DsoSignal *dsoSig = NULL; + if ((dsoSig = dynamic_cast(s)) && (dsoSig->enabled())) + dsoSig->paint_prepare(); + } + + if (dso.num_samples != 0) + { + // update current sample rate + set_cur_snap_samplerate(_device_agent.get_sample_rate()); + } + + if (_dso_data->snapshot()->memory_failed()) + { + _error = Malloc_err; + _callback->session_error(); + return; + } + + // calculate related spectrum results + for (auto &m : _spectrum_traces) + { + assert(m); + if (m->enabled()) + m->get_spectrum_stack()->calc_fft(); + } + + // calculate related math results + if (_math_trace && _math_trace->enabled()) + { + _math_trace->get_math_stack()->realloc(_device_agent.get_sample_limit()); + _math_trace->get_math_stack()->calc_math(); + } + + _trigger_flag = dso.trig_flag; + _trigger_ch = dso.trig_ch; + receive_data(dso.num_samples); + + if (!_is_instant) + data_lock(); + + _data_updated = true; + } + + void SigSession::feed_in_analog(const sr_datafeed_analog &analog) + { + + if (!_analog_data || _analog_data->snapshot()->memory_failed()) + { + dsv_err("%s", "Unexpected analog packet"); + return; // This analog packet was not expected. + } + + if (_analog_data->snapshot()->last_ended()) + { + // reset scale of analog signal + for (auto &s : _signals) + { + assert(s); + view::AnalogSignal *analogSig = NULL; + if ((analogSig = dynamic_cast(s))) + { + analogSig->set_scale(analogSig->get_totalHeight()); + } + } + + // first payload + _analog_data->snapshot()->first_payload(analog, _device_agent.get_sample_limit(), _device_agent.get_channels()); + } + else + { + // Append to the existing data snapshot + _analog_data->snapshot()->append_payload(analog); + } + + if (_analog_data->snapshot()->memory_failed()) + { + _error = Malloc_err; + _callback->session_error(); + return; + } + + receive_data(analog.num_samples); + _data_updated = true; + } + + void SigSession::data_feed_in(const struct sr_dev_inst *sdi, + const struct sr_datafeed_packet *packet) + { + assert(sdi); + assert(packet); + + ds_lock_guard lock(_data_mutex); + + // dsv_info("%s", "Receive data."); + + if (_data_lock && packet->type != SR_DF_END) + return; + + if (packet->type != SR_DF_END && + packet->status != SR_PKT_OK) + { + _error = Pkt_data_err; + _callback->session_error(); + return; + } + + switch (packet->type) + { + case SR_DF_HEADER: + feed_in_header(sdi); + break; + + case SR_DF_META: + assert(packet->payload); + feed_in_meta(sdi, + *(const sr_datafeed_meta *)packet->payload); + break; + + case SR_DF_TRIGGER: + assert(packet->payload); + feed_in_trigger(*(const ds_trigger_pos *)packet->payload); + break; + + case SR_DF_LOGIC: + assert(packet->payload); + feed_in_logic(*(const sr_datafeed_logic *)packet->payload); + break; + + case SR_DF_DSO: + assert(packet->payload); + feed_in_dso(*(const sr_datafeed_dso *)packet->payload); + break; + + case SR_DF_ANALOG: + assert(packet->payload); + feed_in_analog(*(const sr_datafeed_analog *)packet->payload); + break; + + case SR_DF_OVERFLOW: + { + if (_error == No_err) + { + _error = Data_overflow; + _callback->session_error(); + } + break; + } + case SR_DF_END: + { + if (!_logic_data->snapshot()->empty()) + { + for (auto &g : _group_traces) + { + assert(g); + + auto p = new data::GroupSnapshot(_logic_data->get_snapshots().front(), g->get_index_list()); + _group_data->push_snapshot(p); + } + } + _logic_data->snapshot()->capture_ended(); + _dso_data->snapshot()->capture_ended(); + _analog_data->snapshot()->capture_ended(); + + for (auto trace : _decode_traces) + { + trace->decoder()->frame_ended(); + trace->frame_ended(); add_decode_task(trace); } - - signals_changed(); - data_updated(); + + if (packet->status != SR_PKT_OK) + { + _error = Pkt_data_err; + _callback->session_error(); + } + + _callback->frame_ended(); + + if (_device_agent.get_work_mode() != LOGIC) + { + set_session_time(QDateTime::currentDateTime()); + } + + break; + } + } + } + + void SigSession::data_feed_callback(const struct sr_dev_inst *sdi, + const struct sr_datafeed_packet *packet) + { + assert(_session); + _session->data_feed_in(sdi, packet); + } + + uint16_t SigSession::get_ch_num(int type) + { + uint16_t num_channels = 0; + uint16_t logic_ch_num = 0; + uint16_t dso_ch_num = 0; + uint16_t analog_ch_num = 0; + + if (_device_agent.have_instance()) + { + for (auto &s : _signals) + { + assert(s); + if (dynamic_cast(s) && s->enabled()) + { + logic_ch_num++; + } + if (dynamic_cast(s) && s->enabled()) + { + dso_ch_num++; + } + if (dynamic_cast(s) && s->enabled()) + { + analog_ch_num++; + } + } + } + + switch (type) + { + case SR_CHANNEL_LOGIC: + num_channels = logic_ch_num; + break; + case SR_CHANNEL_DSO: + num_channels = dso_ch_num; + break; + case SR_CHANNEL_ANALOG: + num_channels = analog_ch_num; + break; + default: + num_channels = logic_ch_num + dso_ch_num + analog_ch_num; + break; + } + + return num_channels; + } + + bool SigSession::add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus, + std::list &sub_decoders) + { + + if (dec == NULL) + { + dsv_err("%s", "Decoder instance is null!"); + assert(false); + } + + dsv_info("Create new decoder,name:\"%s\",id:\"%s\"", dec->name, dec->id); + + try + { + + bool ret = false; + + // Create the decoder + std::map probes; + data::DecoderStack *decoder_stack = new data::DecoderStack(this, dec, dstatus); + assert(decoder_stack); + + // Make a list of all the probes + std::vector all_probes; + for (const GSList *i = dec->channels; i; i = i->next) + all_probes.push_back((const srd_channel *)i->data); + + for (const GSList *i = dec->opt_channels; i; i = i->next) + all_probes.push_back((const srd_channel *)i->data); + + decoder_stack->stack().front()->set_probes(probes); + + // Create the decode signal + view::DecodeTrace *trace = new view::DecodeTrace(this, decoder_stack, _decode_traces.size()); + assert(trace); + + // add sub decoder + for (auto sub : sub_decoders) + { + trace->decoder()->add_sub_decoder(sub); + } + sub_decoders.clear(); + + // set view early for decode start/end region setting + for (auto &s : _signals) + { + if (s->get_view()) + { + trace->set_view(s->get_view()); + break; + } + } + + if (silent) + { + ret = true; + } + else if (trace->create_popup(true)) + { + ret = true; + } + + if (ret) + { + _decode_traces.push_back(trace); + + // add decode task from ui + if (!silent) + { + add_decode_task(trace); + } + + signals_changed(); + data_updated(); + } + else + { + delete trace; + } + + return ret; + } + catch (...) + { + dsv_err("%s", "Error!add_decoder() throws an exception."); + } + + return false; + } + + std::vector &SigSession::get_decode_signals() + { + return _decode_traces; + } + + int SigSession::get_trace_index_by_key_handel(void *handel) + { + int dex = 0; + + for (auto tr : _decode_traces) + { + if (tr->decoder()->get_key_handel() == handel) + { + return dex; + } + ++dex; + } + + return -1; + } + + void SigSession::remove_decoder(int index) + { + int size = (int)_decode_traces.size(); + assert(index < size); + + auto it = _decode_traces.begin() + index; + auto trace = (*it); + _decode_traces.erase(it); + + bool isRunning = trace->decoder()->IsRunning(); + + remove_decode_task(trace); + + if (isRunning) + { + // destroy it in thread + trace->_delete_flag = true; } else { delete trace; + signals_changed(); + } + } + + void SigSession::remove_decoder_by_key_handel(void *handel) + { + int dex = get_trace_index_by_key_handel(handel); + remove_decoder(dex); + } + + void SigSession::rst_decoder(int index) + { + auto trace = get_decoder_trace(index); + + if (trace && trace->create_popup(false)) + { + remove_decode_task(trace); // remove old task + trace->decoder()->clear(); + add_decode_task(trace); + data_updated(); + } + } + + void SigSession::rst_decoder_by_key_handel(void *handel) + { + int dex = get_trace_index_by_key_handel(handel); + rst_decoder(dex); + } + + pv::data::DecoderModel *SigSession::get_decoder_model() + { + return _decoder_model; + } + + void SigSession::spectrum_rebuild() + { + bool has_dso_signal = false; + for (auto &s : _signals) + { + view::DsoSignal *dsoSig = NULL; + if ((dsoSig = dynamic_cast(s))) + { + has_dso_signal = true; + // check already have + auto iter = _spectrum_traces.begin(); + for (unsigned int i = 0; i < _spectrum_traces.size(); i++, iter++) + if ((*iter)->get_index() == dsoSig->get_index()) + break; + // if not, rebuild + if (iter == _spectrum_traces.end()) + { + auto spectrum_stack = new data::SpectrumStack(this, dsoSig->get_index()); + auto spectrum_trace = new view::SpectrumTrace(this, spectrum_stack, dsoSig->get_index()); + _spectrum_traces.push_back(spectrum_trace); + } + } } - return ret; + if (!has_dso_signal) + { + RELEASE_ARRAY(_spectrum_traces); + } - } catch(...) { - - } - - return false; -} - -std::vector& SigSession::get_decode_signals() -{ - return _decode_traces; -} - -int SigSession::get_trace_index_by_key_handel(void *handel) -{ - int dex = 0; - - for(auto tr : _decode_traces){ - if (tr->decoder()->get_key_handel() == handel){ - return dex; - } - ++dex; - } - - return -1; -} - -void SigSession::remove_decoder(int index) -{ - int size = (int)_decode_traces.size(); - assert(index < size); - - auto it = _decode_traces.begin() + index; - auto trace = (*it); - _decode_traces.erase(it); - - bool isRunning = trace->decoder()->IsRunning(); - - remove_decode_task(trace); - - if (isRunning){ - //destroy it in thread - trace->_delete_flag = true; - } - else{ - delete trace; signals_changed(); - } -} - - void SigSession::remove_decoder_by_key_handel(void *handel) - { - int dex = get_trace_index_by_key_handel(handel); - remove_decoder(dex); - } - -void SigSession::rst_decoder(int index) -{ - auto trace = get_decoder_trace(index); - - if (trace && trace->create_popup(false) ){ - remove_decode_task(trace); //remove old task - trace->decoder()->clear(); - add_decode_task(trace); - data_updated(); } -} -void SigSession::rst_decoder_by_key_handel(void *handel) -{ - int dex = get_trace_index_by_key_handel(handel); - rst_decoder(dex); -} + std::vector &SigSession::get_spectrum_traces() + { + return _spectrum_traces; + } -pv::data::DecoderModel* SigSession::get_decoder_model() -{ - return _decoder_model; -} + void SigSession::lissajous_rebuild(bool enable, int xindex, int yindex, double percent) + { + DESTROY_OBJECT(_lissajous_trace); + _lissajous_trace = new view::LissajousTrace(enable, _dso_data, xindex, yindex, percent); + signals_changed(); + } -void SigSession::spectrum_rebuild() -{ - bool has_dso_signal = false; - for(auto &s : _signals) { - view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) { - has_dso_signal = true; - // check already have - auto iter = _spectrum_traces.begin(); - for(unsigned int i = 0; i < _spectrum_traces.size(); i++, iter++) - if ((*iter)->get_index() == dsoSig->get_index()) - break; - // if not, rebuild - if (iter == _spectrum_traces.end()) { - auto spectrum_stack = new data::SpectrumStack(this, dsoSig->get_index()); - auto spectrum_trace = new view::SpectrumTrace(this, spectrum_stack, dsoSig->get_index()); - _spectrum_traces.push_back(spectrum_trace); + void SigSession::lissajous_disable() + { + if (_lissajous_trace) + _lissajous_trace->set_enable(false); + } + + view::LissajousTrace *SigSession::get_lissajous_trace() + { + return _lissajous_trace; + } + + void SigSession::math_rebuild(bool enable, view::DsoSignal *dsoSig1, + view::DsoSignal *dsoSig2, + data::MathStack::MathType type) + { + ds_lock_guard lock(_data_mutex); + + auto math_stack = new data::MathStack(this, dsoSig1, dsoSig2, type); + DESTROY_OBJECT(_math_trace); + _math_trace = new view::MathTrace(enable, math_stack, dsoSig1, dsoSig2); + + if (_math_trace && _math_trace->enabled()) + { + _math_trace->get_math_stack()->set_samplerate(_dso_data->samplerate()); + _math_trace->get_math_stack()->realloc(_device_agent.get_sample_limit()); + _math_trace->get_math_stack()->calc_math(); + } + signals_changed(); + } + + void SigSession::math_disable() + { + if (_math_trace) + _math_trace->set_enable(false); + } + + view::MathTrace *SigSession::get_math_trace() + { + return _math_trace; + } + + void SigSession::set_session_time(QDateTime time) + { + _session_time = time; + } + + QDateTime SigSession::get_session_time() + { + return _session_time; + } + + uint64_t SigSession::get_trigger_pos() + { + return _trigger_pos; + } + + bool SigSession::trigd() + { + return _trigger_flag; + } + + uint8_t SigSession::trigd_ch() + { + return _trigger_ch; + } + + void SigSession::nodata_timeout() + { + GVariant *gvar = _device_agent.get_config(NULL, NULL, SR_CONF_TRIGGER_SOURCE); + if (gvar == NULL) + return; + if (g_variant_get_byte(gvar) != DSO_TRIGGER_AUTO) + { + _callback->show_wait_trigger(); + } + } + + void SigSession::feed_timeout() + { + data_unlock(); + + if (!_data_updated) + { + if (++_noData_cnt >= (WaitShowTime / FeedInterval)) + nodata_timeout(); + } + } + + data::Snapshot *SigSession::get_snapshot(int type) + { + if (type == SR_CHANNEL_LOGIC) + return _logic_data->snapshot(); + else if (type == SR_CHANNEL_ANALOG) + return _analog_data->snapshot(); + else if (type == SR_CHANNEL_DSO) + return _dso_data->snapshot(); + else + return NULL; + } + + SigSession::error_state SigSession::get_error() + { + return _error; + } + + void SigSession::set_error(error_state state) + { + _error = state; + } + + void SigSession::clear_error() + { + _error_pattern = 0; + _error = No_err; + } + + uint64_t SigSession::get_error_pattern() + { + return _error_pattern; + } + + double SigSession::get_repeat_intvl() + { + return _repeat_intvl; + } + + void SigSession::set_repeat_intvl(double interval) + { + _repeat_intvl = interval; + } + + bool SigSession::repeat_check() + { + if (!_is_working) + { + return false; + } + + if (_device_agent.get_work_mode() == LOGIC) + { + _repeat_hold_prg = 100; + _callback->repeat_hold(_repeat_hold_prg); + _out_timer.TimeOut(_repeat_intvl * 1000 / RepeatHoldDiv, std::bind(&SigSession::repeat_update, this)); + return true; + } + else + { + return false; + } + } + + void SigSession::repeat_update() + { + if (!_is_instant && _is_working && _is_repeat_mode) + { + _repeat_hold_prg -= 100 / RepeatHoldDiv; + if (_repeat_hold_prg != 0) + { + _out_timer.TimeOut(_repeat_intvl * 1000 / RepeatHoldDiv, std::bind(&SigSession::repeat_update, this)); + } + _callback->repeat_hold(_repeat_hold_prg); + if (_repeat_hold_prg == 0) + repeat_resume(); + } + } + + int SigSession::get_repeat_hold() + { + if (!_is_instant && _is_working && _is_repeat_mode) + return _repeat_hold_prg; + else + return 0; + } + + void SigSession::set_map_zoom(int index) + { + _map_zoom = index; + } + + int SigSession::get_map_zoom() + { + return _map_zoom; + } + + void SigSession::auto_end() + { + for (auto &s : _signals) + { + view::DsoSignal *dsoSig = NULL; + if ((dsoSig = dynamic_cast(s))) + { + dsoSig->auto_end(); } } } - if (!has_dso_signal){ - RELEASE_ARRAY(_spectrum_traces); - } - - signals_changed(); -} - -std::vector& SigSession::get_spectrum_traces() -{ - return _spectrum_traces; -} - -void SigSession::lissajous_rebuild(bool enable, int xindex, int yindex, double percent) -{ - DESTROY_OBJECT(_lissajous_trace); - _lissajous_trace = new view::LissajousTrace(enable, _dso_data, xindex, yindex, percent); - signals_changed(); -} - -void SigSession::lissajous_disable() -{ - if (_lissajous_trace) - _lissajous_trace->set_enable(false); -} - -view::LissajousTrace* SigSession::get_lissajous_trace() -{ - return _lissajous_trace; -} - -void SigSession::math_rebuild(bool enable,view::DsoSignal *dsoSig1, - view::DsoSignal *dsoSig2, - data::MathStack::MathType type) -{ - ds_lock_guard lock(_data_mutex); - - auto math_stack = new data::MathStack(this, dsoSig1, dsoSig2, type); - DESTROY_OBJECT(_math_trace); - _math_trace = new view::MathTrace(enable, math_stack, dsoSig1, dsoSig2); - - if (_math_trace && _math_trace->enabled()) { - _math_trace->get_math_stack()->set_samplerate(_dso_data->samplerate()); - _math_trace->get_math_stack()->realloc(_device_agent.get_sample_limit()); - _math_trace->get_math_stack()->calc_math(); - } - signals_changed(); -} - -void SigSession::math_disable() -{ - if (_math_trace) - _math_trace->set_enable(false); -} - -view::MathTrace* SigSession::get_math_trace() -{ - return _math_trace; -} - -void SigSession::set_session_time(QDateTime time) -{ - _session_time = time; -} - -QDateTime SigSession::get_session_time() -{ - return _session_time; -} - -uint64_t SigSession::get_trigger_pos() -{ - return _trigger_pos; -} - -bool SigSession::trigd() -{ - return _trigger_flag; -} - -uint8_t SigSession::trigd_ch() -{ - return _trigger_ch; -} - -void SigSession::nodata_timeout() -{ - GVariant *gvar = _device_agent.get_config(NULL, NULL, SR_CONF_TRIGGER_SOURCE); - if (gvar == NULL) - return; - if (g_variant_get_byte(gvar) != DSO_TRIGGER_AUTO) { - _callback->show_wait_trigger(); - } -} - -void SigSession::feed_timeout() -{ - data_unlock(); - - if (!_data_updated) { - if (++_noData_cnt >= (WaitShowTime/FeedInterval)) - nodata_timeout(); - } -} - -data::Snapshot* SigSession::get_snapshot(int type) -{ - if (type == SR_CHANNEL_LOGIC) - return _logic_data->snapshot(); - else if (type == SR_CHANNEL_ANALOG) - return _analog_data->snapshot(); - else if (type == SR_CHANNEL_DSO) - return _dso_data->snapshot(); - else - return NULL; -} - -SigSession::error_state SigSession::get_error() -{ - return _error; -} - -void SigSession::set_error(error_state state) -{ - _error = state; -} - -void SigSession::clear_error() -{ - _error_pattern = 0; - _error = No_err; -} - -uint64_t SigSession::get_error_pattern() -{ - return _error_pattern; -} - -double SigSession::get_repeat_intvl() -{ - return _repeat_intvl; -} - -void SigSession::set_repeat_intvl(double interval) -{ - _repeat_intvl = interval; -} - -bool SigSession::repeat_check() -{ - if (!_is_working) { - return false; - } - - if (_device_agent.get_work_mode() == LOGIC) { - _repeat_hold_prg = 100; - _callback->repeat_hold(_repeat_hold_prg); - _out_timer.TimeOut(_repeat_intvl * 1000 / RepeatHoldDiv, std::bind(&SigSession::repeat_update, this)); - return true; - } else { - return false; - } -} - -void SigSession::repeat_update() -{ - if (!_is_instant && _is_working && _is_repeat_mode) { - _repeat_hold_prg -= 100/RepeatHoldDiv; - if (_repeat_hold_prg != 0){ - _out_timer.TimeOut(_repeat_intvl * 1000 / RepeatHoldDiv, std::bind(&SigSession::repeat_update, this)); - } - _callback->repeat_hold(_repeat_hold_prg); - if (_repeat_hold_prg == 0) - repeat_resume(); - } -} - -int SigSession::get_repeat_hold() -{ - if (!_is_instant && _is_working && _is_repeat_mode) - return _repeat_hold_prg; - else - return 0; -} - -void SigSession::set_map_zoom(int index) -{ - _map_zoom = index; -} - -int SigSession::get_map_zoom() -{ - return _map_zoom; -} - -void SigSession::auto_end() -{ - for(auto &s : _signals) { - view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) { - dsoSig->auto_end(); - } - } -} - -void SigSession::set_save_start(uint64_t start) -{ - _save_start = start; -} - -void SigSession::set_save_end(uint64_t end) -{ - _save_end = end; -} - -uint64_t SigSession::get_save_start() -{ - return _save_start; -} - -uint64_t SigSession::get_save_end() -{ - return _save_end; -} - -float SigSession::stop_scale() -{ - return _stop_scale; -} - -void SigSession::set_stop_scale(float scale) -{ - _stop_scale = scale; -} - -void SigSession::Open() -{ -} - -void SigSession::Close() -{ - if (_bClose) - return; - - _bClose = true; - exit_capture(); - - // TODO: This should not be necessary - _session = NULL; -} - -//append a decode task, and try create a thread - void SigSession::add_decode_task(view::DecodeTrace *trace) - { - std::lock_guard lock(_decode_task_mutex); - _decode_tasks.push_back(trace); - - if (!_is_decoding) - { - if (_decode_thread.joinable()) - _decode_thread.join(); - - _decode_thread = std::thread(&SigSession::decode_task_proc, this); - _is_decoding = true; - } - } - - void SigSession::remove_decode_task(view::DecodeTrace *trace) - { - std::lock_guard lock(_decode_task_mutex); - - for (auto it = _decode_tasks.begin(); it != _decode_tasks.end(); it++){ - if ((*it) == trace){ - (*it)->decoder()->stop_decode_work(); - _decode_tasks.erase(it); - dsv_info("%s", "remove a waiting decode task"); - return; - } - } - - //the task maybe is running - trace->decoder()->stop_decode_work(); - } - - void SigSession::clear_all_decoder(bool bUpdateView) - { - //create the wait task deque - int dex = -1; - clear_all_decode_task(dex); - - view::DecodeTrace *runningTrace = NULL; - if (dex != -1){ - runningTrace = _decode_traces[dex]; - runningTrace->_delete_flag = true; //destroy it in thread - } - - for (auto trace : _decode_traces) - { - if (trace != runningTrace){ - delete trace; - } - } - _decode_traces.clear(); - - //wait thread end - if (_decode_thread.joinable()) - { - _decode_thread.join(); - } - - if (!is_closed() && bUpdateView){ - signals_changed(); - } - } - - void SigSession::clear_all_decode_task(int &runningDex) - { - std::lock_guard lock(_decode_task_mutex); - - //remove wait task - for (auto trace : _decode_tasks){ - trace->decoder()->stop_decode_work(); //set decode proc stop flag - } - _decode_tasks.clear(); - - //make sure the running task can stop - runningDex = -1; - int dex = 0; - for (auto trace : _decode_traces) - { - if (trace->decoder()->IsRunning()) - { - trace->decoder()->stop_decode_work(); - runningDex = dex; - } - dex++; - } - } - - view::DecodeTrace* SigSession::get_decoder_trace(int index) - { - if (index >= 0 && index < (int)_decode_traces.size()){ - return _decode_traces[index]; - } - assert(false); - } - - view::DecodeTrace* SigSession::get_top_decode_task() - { - std::lock_guard lock(_decode_task_mutex); - - auto it = _decode_tasks.begin(); - if (it != _decode_tasks.end()){ - auto p = (*it); - _decode_tasks.erase(it); - return p; - } - - return NULL; - } - - //the decode task thread proc - void SigSession::decode_task_proc() - { - dsv_info("%s", "------->decode thread start"); - auto task = get_top_decode_task(); - - while (task != NULL) - { - if (!task->_delete_flag){ - task->decoder()->begin_decode_work(); - } - - if (task->_delete_flag){ - dsv_info("%s", "destroy a decoder in task thread"); - - DESTROY_QT_LATER(task); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - if (!_bClose){ - signals_changed(); - } - } - - task = get_top_decode_task(); - } - - dsv_info("%s", "------->decode thread end"); - _is_decoding = false; - } - - Snapshot *SigSession::get_signal_snapshot() - { - int mode = _device_agent.get_work_mode(); - if (mode == ANALOG) - return _analog_data->snapshot(); - else if (mode == DSO) - return _dso_data->snapshot(); - else - return _logic_data->snapshot(); - } - - void SigSession::device_lib_event_callback(int event) - { - if (_session == NULL) - { - dsv_err("%s", "Error!Global variable \"_session\" is null."); - return; - } - _session->on_device_lib_event(event); - } - -void SigSession::on_device_lib_event(int event) -{ - if (_callback == NULL){ - dsv_info("%s", "The callback is null, so the device event was ignored."); - return; - } - - switch (event) + void SigSession::set_save_start(uint64_t start) { - case DS_EV_DEVICE_RUNNING: - _device_status = ST_RUNNING; - receive_data(0); - break; - - case DS_EV_DEVICE_STOPPED: - _device_status = ST_STOPPED; - // Confirm that SR_DF_END was received - if (!_logic_data->snapshot()->last_ended() - || !_dso_data->snapshot()->last_ended() - || !_analog_data->snapshot()->last_ended()) - { - dsv_err("%s", "Error!The data is not completed."); - assert(false); - } - break; + _save_start = start; + } - case DS_EV_COLLECT_TASK_START: - _callback->trigger_message(DSV_MSG_COLLECT_START); - break; + void SigSession::set_save_end(uint64_t end) + { + _save_end = end; + } - case DS_EV_COLLECT_TASK_END: - case DS_EV_COLLECT_TASK_END_BY_ERROR: - case DS_EV_COLLECT_TASK_END_BY_DETACHED: + uint64_t SigSession::get_save_start() + { + return _save_start; + } + + uint64_t SigSession::get_save_end() + { + return _save_end; + } + + float SigSession::stop_scale() + { + return _stop_scale; + } + + void SigSession::set_stop_scale(float scale) + { + _stop_scale = scale; + } + + void SigSession::Open() + { + } + + void SigSession::Close() + { + if (_bClose) + return; + + _bClose = true; + exit_capture(); + + // TODO: This should not be necessary + _session = NULL; + } + + // append a decode task, and try create a thread + void SigSession::add_decode_task(view::DecodeTrace *trace) + { + std::lock_guard lock(_decode_task_mutex); + _decode_tasks.push_back(trace); + + if (!_is_decoding) + { + if (_decode_thread.joinable()) + _decode_thread.join(); + + _decode_thread = std::thread(&SigSession::decode_task_proc, this); + _is_decoding = true; + } + } + + void SigSession::remove_decode_task(view::DecodeTrace *trace) + { + std::lock_guard lock(_decode_task_mutex); + + for (auto it = _decode_tasks.begin(); it != _decode_tasks.end(); it++) + { + if ((*it) == trace) + { + (*it)->decoder()->stop_decode_work(); + _decode_tasks.erase(it); + dsv_info("%s", "remove a waiting decode task"); + return; + } + } + + // the task maybe is running + trace->decoder()->stop_decode_work(); + } + + void SigSession::clear_all_decoder(bool bUpdateView) + { + // create the wait task deque + int dex = -1; + clear_all_decode_task(dex); + + view::DecodeTrace *runningTrace = NULL; + if (dex != -1) + { + runningTrace = _decode_traces[dex]; + runningTrace->_delete_flag = true; // destroy it in thread + } + + for (auto trace : _decode_traces) + { + if (trace != runningTrace) + { + delete trace; + } + } + _decode_traces.clear(); + + // wait thread end + if (_decode_thread.joinable()) + { + _decode_thread.join(); + } + + if (!is_closed() && bUpdateView) + { + signals_changed(); + } + } + + void SigSession::clear_all_decode_task(int &runningDex) + { + std::lock_guard lock(_decode_task_mutex); + + // remove wait task + for (auto trace : _decode_tasks) + { + trace->decoder()->stop_decode_work(); // set decode proc stop flag + } + _decode_tasks.clear(); + + // make sure the running task can stop + runningDex = -1; + int dex = 0; + for (auto trace : _decode_traces) + { + if (trace->decoder()->IsRunning()) + { + trace->decoder()->stop_decode_work(); + runningDex = dex; + } + dex++; + } + } + + view::DecodeTrace *SigSession::get_decoder_trace(int index) + { + if (index >= 0 && index < (int)_decode_traces.size()) + { + return _decode_traces[index]; + } + assert(false); + } + + view::DecodeTrace *SigSession::get_top_decode_task() + { + std::lock_guard lock(_decode_task_mutex); + + auto it = _decode_tasks.begin(); + if (it != _decode_tasks.end()) + { + auto p = (*it); + _decode_tasks.erase(it); + return p; + } + + return NULL; + } + + // the decode task thread proc + void SigSession::decode_task_proc() + { + dsv_info("%s", "------->decode thread start"); + auto task = get_top_decode_task(); + + while (task != NULL) + { + if (!task->_delete_flag) + { + task->decoder()->begin_decode_work(); + } + + if (task->_delete_flag) + { + dsv_info("%s", "destroy a decoder in task thread"); + + DESTROY_QT_LATER(task); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + if (!_bClose) + { + signals_changed(); + } + } + + task = get_top_decode_task(); + } + + dsv_info("%s", "------->decode thread end"); + _is_decoding = false; + } + + Snapshot *SigSession::get_signal_snapshot() + { + int mode = _device_agent.get_work_mode(); + if (mode == ANALOG) + return _analog_data->snapshot(); + else if (mode == DSO) + return _dso_data->snapshot(); + else + return _logic_data->snapshot(); + } + + void SigSession::device_lib_event_callback(int event) + { + if (_session == NULL) + { + dsv_err("%s", "Error!Global variable \"_session\" is null."); + return; + } + _session->on_device_lib_event(event); + } + + void SigSession::on_device_lib_event(int event) + { + if (_callback == NULL) + { + dsv_detail("%s", "The callback is null, so the device event was ignored."); + return; + } + + switch (event) + { + case DS_EV_DEVICE_RUNNING: + _device_status = ST_RUNNING; + receive_data(0); + break; + + case DS_EV_DEVICE_STOPPED: + _device_status = ST_STOPPED; + // Confirm that SR_DF_END was received + if (!_logic_data->snapshot()->last_ended() + || !_dso_data->snapshot()->last_ended() + || !_analog_data->snapshot()->last_ended()) + { + dsv_err("%s", "Error!The data is not completed."); + assert(false); + } + break; + + case DS_EV_COLLECT_TASK_START: + _callback->trigger_message(DSV_MSG_COLLECT_START); + break; + + case DS_EV_COLLECT_TASK_END: + case DS_EV_COLLECT_TASK_END_BY_ERROR: + case DS_EV_COLLECT_TASK_END_BY_DETACHED: { _callback->trigger_message(DSV_MSG_COLLECT_END); if (_logic_data->snapshot()->last_ended() == false) - dsv_err("%s", "The collected data is error!"); + dsv_err("%s", "The collected data is error!"); if (_dso_data->snapshot()->last_ended() == false) - dsv_err("%s", "The collected data is error!"); + dsv_err("%s", "The collected data is error!"); if (_analog_data->snapshot()->last_ended() == false) - dsv_err("%s", "The collected data is error!"); + dsv_err("%s", "The collected data is error!"); // trigger next collect - if (!_is_instant - && _is_repeat_mode - && _is_working - && event == DS_EV_COLLECT_TASK_END) + if (!_is_instant && _is_repeat_mode && _is_working && event == DS_EV_COLLECT_TASK_END) { _callback->trigger_message(DSV_MSG_TRIG_NEXT_COLLECT); } - else{ + else + { _is_working = false; _is_instant = false; _callback->trigger_message(DSV_MSG_END_COLLECT_WORK); @@ -1880,115 +2002,97 @@ void SigSession::on_device_lib_event(int event) } break; - case DS_EV_NEW_DEVICE_ATTACH: - case DS_EV_CURRENT_DEVICE_DETACH: + case DS_EV_NEW_DEVICE_ATTACH: + case DS_EV_CURRENT_DEVICE_DETACH: { if (_is_working) stop_capture(); - if (DS_EV_CURRENT_DEVICE_DETACH == event){ - _callback->trigger_message(DSV_MSG_CURRENT_DEVICE_DETACHED); - } - - int work_mode = _device_agent.get_work_mode(); - - if (have_hardware_data() && (work_mode == LOGIC || work_mode == ANALOG)) - { - // Try to save current device data, and auto select the lastest device later. - _is_auto_sel_device = true; - if (!_is_saving) - store_session_data(); - - _is_trig_new_device_msg = DS_EV_NEW_DEVICE_ATTACH == event; - } - else{ - set_default_device(); - - if (DS_EV_NEW_DEVICE_ATTACH == event) - _callback->trigger_message(DSV_MSG_NEW_USB_DEVICE); - } + if (DS_EV_NEW_DEVICE_ATTACH == event) + _callback->trigger_message(DSV_MSG_NEW_USB_DEVICE); + else + _callback->trigger_message(DSV_MSG_CURRENT_DEVICE_DETACHED); } break; - case DS_EV_INACTIVE_DEVICE_DETACH: - _callback->trigger_message(DSV_MSG_DEVICE_LIST_UPDATED); // Update list only. - break; + case DS_EV_INACTIVE_DEVICE_DETACH: + _callback->trigger_message(DSV_MSG_DEVICE_LIST_UPDATED); // Update list only. + break; - default: - dsv_err("%s", "Error!Unknown device event."); - break; + default: + dsv_err("%s", "Error!Unknown device event."); + break; + } } -} - void SigSession::add_msg_listener(IMessageListener *ln) - { - _msg_listeners.push_back(ln); - } - - void SigSession::broadcast_msg(int msg) - { - for (IMessageListener *cb : _msg_listeners) - { - cb->OnMessage(msg); - } - } - - void SigSession::set_repeat_mode(bool repeat) - { - assert(!_is_working); - - if(_is_repeat_mode != repeat) - { - _is_repeat_mode = repeat; - _repeat_hold_prg = 0; - } - } - - void SigSession::repeat_capture_wait_timout() - { - exec_capture(); - } - - void SigSession::OnMessage(int msg) - { - switch (msg) + void SigSession::add_msg_listener(IMessageListener *ln) { - case DSV_MSG_DEVICE_OPTIONS_UPDATED: - reload(); - break; + _msg_listeners.push_back(ln); + } - case DSV_MSG_TRIG_NEXT_COLLECT: - if (_repeat_intvl > 0) + void SigSession::broadcast_msg(int msg) + { + for (IMessageListener *cb : _msg_listeners) + { + cb->OnMessage(msg); + } + } + + void SigSession::set_repeat_mode(bool repeat) + { + assert(!_is_working); + + if (_is_repeat_mode != repeat) + { + _is_repeat_mode = repeat; + _repeat_hold_prg = 0; + } + } + + void SigSession::repeat_capture_wait_timout() + { + exec_capture(); + } + + void SigSession::OnMessage(int msg) + { + switch (msg) + { + case DSV_MSG_DEVICE_OPTIONS_UPDATED: + reload(); + break; + + case DSV_MSG_TRIG_NEXT_COLLECT: + if (_repeat_intvl > 0) _repeate_timer.Start(_repeat_intvl * 1000); else exec_capture(); - break; - - case DSV_MSG_SAVE_COMPLETE: - bool ret = false; - if (_is_auto_sel_device) - ret = set_default_device(); - if (ret && _is_trig_new_device_msg){ - _callback->trigger_message(DSV_MSG_NEW_USB_DEVICE); + break; } - break; } - } - void SigSession::DeviceConfigChanged() - { + void SigSession::DeviceConfigChanged() + { + //Nonthing. + } - } + bool SigSession::switch_work_mode(int mode) + { + assert(!_is_working); - void SigSession::store_session_data() - { + if (_device_agent.get_work_mode() != mode) + { + GVariant *val = g_variant_new_int16(mode); + _device_agent.set_config(NULL + ,NULL + ,SR_CONF_DEVICE_MODE + ,val); + init_signals(); + dsv_info("%s", "Work mode is changed."); + broadcast_msg(DSV_MSG_DEVICE_MODE_CHANGED); + return true; + } + return false; + } - } - - void SigSession::on_work_mode_changed() - { - init_signals(); - } - - } // namespace pv diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index 4be2bf39..d7652268 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -134,11 +134,11 @@ public: void Close(); bool set_default_device(); - bool set_device(ds_device_handle dev_handle); + bool set_device(ds_device_handle dev_handle); bool set_file(QString name); void close_file(ds_device_handle dev_handle); bool start_capture(bool instant); - void stop_capture(); + void stop_capture(); uint64_t cur_samplerate(); uint64_t cur_snap_samplerate(); @@ -291,12 +291,11 @@ public: void check_update(); void set_map_zoom(int index); void auto_end(); - void store_session_data(); bool have_hardware_data(); struct ds_device_info* get_device_list(int &out_count, int &actived_index); void add_msg_listener(IMessageListener *ln); void broadcast_msg(int msg); - void on_work_mode_changed(); + bool switch_work_mode(int mode); private: bool exec_capture(); @@ -329,7 +328,7 @@ private: void feed_timeout(); void repeat_update(); void container_init(); - void init_signals(); + void init_signals(); //IMessageListener void OnMessage(int msg); @@ -411,8 +410,7 @@ private: int _map_zoom; bool _dso_feed; float _stop_scale; - bool _bClose; - bool _is_auto_sel_device; + bool _bClose; uint64_t _save_start; uint64_t _save_end; @@ -422,8 +420,8 @@ private: int _repeat_hold_prg; // The time sleep progress bool _is_saving; bool _is_instant; - bool _is_trig_new_device_msg; int _device_status; + ISessionCallback *_callback; DeviceAgent _device_agent; diff --git a/DSView/pv/storesession.cpp b/DSView/pv/storesession.cpp index e4a152e5..a0a7a15f 100644 --- a/DSView/pv/storesession.cpp +++ b/DSView/pv/storesession.cpp @@ -353,23 +353,22 @@ bool StoreSession::meta_gen(data::Snapshot *snapshot, std::string &str) struct sr_status status; const sr_dev_inst *sdi = NULL; char meta[300] = {0}; - - /* - sdi = _session->get_device()->dev_inst(); sprintf(meta, "%s", "[version]\n"); str += meta; sprintf(meta, "version = %d\n", File_Version); str += meta; sprintf(meta, "%s", "[header]\n"); str += meta; - if (sdi->driver) { - sprintf(meta, "driver = %s\n", sdi->driver->name); str += meta; - sprintf(meta, "device mode = %d\n", sdi->mode); str += meta; + int mode = _session->get_device()->get_work_mode(); + + if (true) { + sprintf(meta, "driver = %s\n", _session->get_device()->driver_name().toLocal8Bit().data()); str += meta; + sprintf(meta, "device mode = %d\n", mode); str += meta; } sprintf(meta, "capturefile = data\n"); str += meta; sprintf(meta, "total samples = %" PRIu64 "\n", snapshot->get_sample_count()); str += meta; - if (sdi->mode != LOGIC) { + if (mode != LOGIC) { sprintf(meta, "total probes = %d\n", snapshot->get_channel_num()); str += meta; sprintf(meta, "total blocks = %d\n", snapshot->get_block_num()); str += meta; } @@ -377,7 +376,7 @@ bool StoreSession::meta_gen(data::Snapshot *snapshot, std::string &str) data::LogicSnapshot *logic_snapshot = NULL; if ((logic_snapshot = dynamic_cast(snapshot))) { uint16_t to_save_probes = 0; - for (l = sdi->channels; l; l = l->next) { + for (l = _session->get_device()->get_channels(); l; l = l->next) { probe = (struct sr_channel *)l->data; if (probe->enabled && logic_snapshot->has_data(probe->index)) to_save_probes++; @@ -390,7 +389,7 @@ bool StoreSession::meta_gen(data::Snapshot *snapshot, std::string &str) sprintf(meta, "samplerate = %s\n", s); str += meta; - if (sdi->mode == DSO) { + if (mode == DSO) { gvar = _session->get_device()->get_config(NULL, NULL, SR_CONF_TIMEBASE); if (gvar != NULL) { uint64_t tmp_u64 = g_variant_get_uint64(gvar); @@ -427,9 +426,11 @@ bool StoreSession::meta_gen(data::Snapshot *snapshot, std::string &str) sprintf(meta, "ref max = %d\n", tmp_u32); str += meta; g_variant_unref(gvar); } - } else if (sdi->mode == LOGIC) { + } + else if (mode == LOGIC) { sprintf(meta, "trigger time = %lld\n", _session->get_session_time().toMSecsSinceEpoch()); str += meta; - } else if (sdi->mode == ANALOG) { + } + else if (mode == ANALOG) { data::AnalogSnapshot *analog_snapshot = NULL; if ((analog_snapshot = dynamic_cast(snapshot))) { uint8_t tmp_u8 = analog_snapshot->get_unit_bytes(); @@ -452,17 +453,17 @@ bool StoreSession::meta_gen(data::Snapshot *snapshot, std::string &str) probecnt = 0; - for (l = sdi->channels; l; l = l->next) { + for (l = _session->get_device()->get_channels(); l; l = l->next) { probe = (struct sr_channel *)l->data; if (!snapshot->has_data(probe->index)) continue; - if (sdi->mode == LOGIC && !probe->enabled) + if (mode == LOGIC && !probe->enabled) continue; if (probe->name) { - int sigdex = (sdi->mode == LOGIC) ? probe->index : probecnt; + int sigdex = (mode == LOGIC) ? probe->index : probecnt; sprintf(meta, "probe%d = %s\n", sigdex, probe->name); str += meta; } @@ -472,7 +473,7 @@ bool StoreSession::meta_gen(data::Snapshot *snapshot, std::string &str) str += meta; } - if (sdi->mode == DSO) + if (mode == DSO) { sprintf(meta, " enable%d = %d\n", probecnt, probe->enabled); str += meta; @@ -487,7 +488,7 @@ bool StoreSession::meta_gen(data::Snapshot *snapshot, std::string &str) sprintf(meta, " vTrig%d = %d\n", probecnt, probe->trig_value); str += meta; - if (sr_status_get(sdi, &status, false) == SR_OK) + if (_session->get_device()->get_device_status(status, false)) { if (probe->index == 0) { @@ -553,7 +554,7 @@ bool StoreSession::meta_gen(data::Snapshot *snapshot, std::string &str) } } } - else if (sdi->mode == ANALOG) + else if (mode == ANALOG) { sprintf(meta, " enable%d = %d\n", probecnt, probe->enabled); str += meta; @@ -572,7 +573,6 @@ bool StoreSession::meta_gen(data::Snapshot *snapshot, std::string &str) } probecnt++; } - */ return true; } diff --git a/DSView/pv/toolbars/filebar.cpp b/DSView/pv/toolbars/filebar.cpp index f826fe00..933209e5 100644 --- a/DSView/pv/toolbars/filebar.cpp +++ b/DSView/pv/toolbars/filebar.cpp @@ -135,6 +135,13 @@ void FileBar::on_actionOpen_triggered() //open data file AppConfig &app = AppConfig::Instance(); + if (_session->have_hardware_data()){ + if (MsgBox::Confirm(tr("Save captured data?"))){ + sig_save(); + return; + } + } + // Show the dialog const QString file_name = QFileDialog::getOpenFileName( this, @@ -234,8 +241,9 @@ void FileBar::on_actionCapture_triggered() void FileBar::update_view_status() { bool bEnable = _session->is_working() == false; + bool is_hardware = _session->get_device()->is_hardware(); _file_button.setEnabled(bEnable); - _menu_session->setEnabled(bEnable); + _menu_session->setEnabled(bEnable && is_hardware); } } // namespace toolbars diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index 0ccdbb1e..11eaace6 100644 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -36,6 +36,7 @@ #include "../dsvdef.h" #include "../log.h" #include "../deviceagent.h" +#include "../ui/msgbox.h" using std::map; using std::max; @@ -68,6 +69,8 @@ namespace pv _is_run_as_instant = false; _last_device_handle = NULL_HANDLE; + _last_device_index = -1; + _next_switch_device = NULL_HANDLE; _session = session; _device_agent = _session->get_device(); @@ -959,7 +962,20 @@ namespace pv _session->session_save(); ds_device_handle devHandle = (ds_device_handle)_device_selector.currentData().toULongLong(); + if (_session->have_hardware_data()){ + if (MsgBox::Confirm(tr("Save captured data?"))) + { + _updating_device_list = true; + _device_selector.setCurrentIndex(_last_device_index); + _updating_device_list = false; + _next_switch_device = devHandle; // Save end, auto switch to this device. + sig_store_session_data(); + return; + } + } + _session->set_device(devHandle); + _last_device_index = _device_selector.currentIndex(); } void SamplingBar::enable_toggle(bool enable) @@ -1098,8 +1114,8 @@ namespace pv update_sample_rate_selector(); _last_device_handle = cur_dev_handle; } - + _last_device_index = select_index; int width = _device_selector.sizeHint().width(); _device_selector.setFixedWidth(min(width + 15, _device_selector.maximumWidth())); _device_selector.view()->setMinimumWidth(width + 30); @@ -1153,5 +1169,12 @@ namespace pv } } + ds_device_handle SamplingBar::get_next_device_handle() + { + ds_device_handle h = _next_switch_device; + _next_switch_device = NULL_HANDLE; + return h; + } + } // namespace toolbars } // namespace pv diff --git a/DSView/pv/toolbars/samplingbar.h b/DSView/pv/toolbars/samplingbar.h index b9000262..0be8872b 100644 --- a/DSView/pv/toolbars/samplingbar.h +++ b/DSView/pv/toolbars/samplingbar.h @@ -85,7 +85,11 @@ namespace pv void update_device_list(); void reload(); void update_view_status(); - void config_device(); + void config_device(); + ds_device_handle get_next_device_handle(); + + signals: + void sig_store_session_data(); private: void changeEvent(QEvent *event); @@ -137,6 +141,8 @@ namespace pv DeviceAgent *_device_agent; ds_device_handle _last_device_handle; + ds_device_handle _next_switch_device; + int _last_device_index; bool _is_run_as_instant; }; diff --git a/DSView/pv/view/devmode.cpp b/DSView/pv/view/devmode.cpp index ba299d52..e6515b27 100644 --- a/DSView/pv/view/devmode.cpp +++ b/DSView/pv/view/devmode.cpp @@ -195,31 +195,30 @@ void DevMode::on_mode_change() for(auto i = _mode_list.begin();i != _mode_list.end(); i++) { - if ((*i).first == action) { - if (_device_agent->get_work_mode() != (*i).second->mode) { - _session->set_repeat_mode(false); - _session->stop_capture(); - _session->session_save(); - _device_agent->set_config(NULL, NULL, - SR_CONF_DEVICE_MODE, - g_variant_new_int16((*i).second->mode)); - - _session->on_work_mode_changed(); + if ((*i).first == action){ - auto *mode_name = get_mode_name((*i).second->mode); - QString icon_fname = iconPath + "/" + QString::fromLocal8Bit(mode_name->_logo); - - _mode_btn->setIcon(QIcon(icon_fname)); - if (lan == LAN_CN) - _mode_btn->setText(mode_name->_name_cn); - else - _mode_btn->setText(mode_name->_name_en); - - _session->broadcast_msg(DSV_MSG_DEVICE_MODE_CHANGED); + int mode = (*i).second->mode; + if (_device_agent->get_work_mode() == mode){ + dsv_info("%s", "Current mode is set."); + break; } + + _session->stop_capture(); + _session->set_repeat_mode(false); + _session->session_save(); + _session->switch_work_mode(mode); - break; - } + auto *mode_name = get_mode_name(mode); + QString icon_fname = iconPath + "/" + QString::fromLocal8Bit(mode_name->_logo); + + _mode_btn->setIcon(QIcon(icon_fname)); + if (lan == LAN_CN) + _mode_btn->setText(mode_name->_name_cn); + else + _mode_btn->setText(mode_name->_name_en); + + break; + } } } @@ -229,7 +228,7 @@ void DevMode::on_close() assert(false); } - if (_bFile && MsgBox::Confirm(tr("are you sure to close the device?"))){ + if (_bFile && MsgBox::Confirm(tr("Are you sure to close the device?"))){ _session->close_file(_device_agent->handle()); } } diff --git a/DSView/pv/view/header.cpp b/DSView/pv/view/header.cpp index 185fb0e4..6eaa78ea 100644 --- a/DSView/pv/view/header.cpp +++ b/DSView/pv/view/header.cpp @@ -101,7 +101,8 @@ int Header::get_nameEditWidth() pv::view::Trace* Header::get_mTrace(int &action, const QPoint &pt) { const int w = width(); - const auto &traces = _view.get_traces(ALL_VIEW); + std::vector traces; + _view.get_traces(ALL_VIEW, traces); for(auto &t : traces) { @@ -124,7 +125,8 @@ void Header::paintEvent(QPaintEvent*) style()->drawPrimitive(QStyle::PE_Widget, &o, &painter, this); const int w = width(); - const auto &traces = _view.get_traces(ALL_VIEW); + std::vector traces; + _view.get_traces(ALL_VIEW, traces); const bool dragging = !_drag_traces.empty(); QColor fore(QWidget::palette().color(QWidget::foregroundRole())); @@ -143,7 +145,9 @@ void Header::mouseDoubleClickEvent(QMouseEvent *event) { assert(event); - const auto &traces = _view.get_traces(ALL_VIEW); + std::vector traces; + + _view.get_traces(ALL_VIEW, traces); if (event->button() & Qt::LeftButton) { _mouse_down_point = event->pos(); @@ -166,7 +170,8 @@ void Header::mousePressEvent(QMouseEvent *event) { assert(event); - const auto &traces = _view.get_traces(ALL_VIEW); + std::vector traces; + _view.get_traces(ALL_VIEW, traces); int action; const bool instant = _view.session().is_instant(); @@ -236,7 +241,8 @@ void Header::mouseReleaseEvent(QMouseEvent *event) _view.signals_changed(); _view.set_all_update(true); - const auto &traces = _view.get_traces(ALL_VIEW); + std::vector traces; + _view.get_traces(ALL_VIEW, traces); for(auto &t : traces){ t->select(false); @@ -288,7 +294,8 @@ void Header::wheelEvent(QWheelEvent *event) if (isVertical) { - const auto &traces = _view.get_traces(ALL_VIEW); + std::vector traces; + _view.get_traces(ALL_VIEW, traces); // Vertical scrolling double shift = 0; diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index 3507592f..ef679820 100644 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -366,7 +366,7 @@ void View::set_preScale_preOffset() set_scale_offset(_preScale, _preOffset); } -std::vector View::get_traces(int type) +void View::get_traces(int type, std::vector &traces) { assert(_session); @@ -376,8 +376,7 @@ std::vector View::get_traces(int type) const auto &decode_sigs = _session->get_decode_signals(); const auto &spectrums = _session->get_spectrum_traces(); - - std::vector traces; + for(auto &t : sigs) { if (type == ALL_VIEW || _trace_view_map[t->get_type()] == type) traces.push_back(t); @@ -409,7 +408,6 @@ std::vector View::get_traces(int type) traces.push_back(math); stable_sort(traces.begin(), traces.end(), compare_trace_v_offsets); - return traces; } bool View::compare_trace_v_offsets(const Trace *a, @@ -576,8 +574,9 @@ const QPoint& View::hover_point() } void View::normalize_layout() -{ - auto traces = get_traces(ALL_VIEW); +{ + std::vector traces; + get_traces(ALL_VIEW, traces); int v_min = INT_MAX; for(auto &t : traces){ @@ -686,7 +685,10 @@ void View::signals_changed() std::vector time_traces; std::vector fft_traces; - for(auto &t : get_traces(ALL_VIEW)) { + std::vector traces; + get_traces(ALL_VIEW, traces); + + for(auto &t : traces) { if (_trace_view_map[t->get_type()] == TIME_VIEW) time_traces.push_back(t); else if (_trace_view_map[t->get_type()] == FFT_VIEW) @@ -845,7 +847,9 @@ int View::headerWidth() { int headerWidth = _header->get_nameEditWidth(); - const auto &traces = get_traces(ALL_VIEW); + std::vector traces; + get_traces(ALL_VIEW, traces); + if (!traces.empty()) { for(auto &t : traces) headerWidth = max(t->get_name_width() + t->get_leftWidth() + t->get_rightWidth(), diff --git a/DSView/pv/view/view.h b/DSView/pv/view/view.h index ead5d8ca..917fd116 100644 --- a/DSView/pv/view/view.h +++ b/DSView/pv/view/view.h @@ -144,7 +144,7 @@ public: void set_scale_offset(double scale, int64_t offset); void set_preScale_preOffset(); - std::vector get_traces(int type); + void get_traces(int type, std::vector &traces); /** * Returns true if cursors are displayed. false otherwise. @@ -337,6 +337,9 @@ public: void set_device(); void set_receive_len(uint64_t len); +private: + + private: SigSession *_session; diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp index 5980b89f..1b9b56e6 100644 --- a/DSView/pv/view/viewport.cpp +++ b/DSView/pv/view/viewport.cpp @@ -113,8 +113,9 @@ Viewport::Viewport(View &parent, View_type type) : int Viewport::get_total_height() { int h = 0; + std::vector traces; + _view.get_traces(_type, traces); - const auto &traces = _view.get_traces(_type); for(auto &t : traces) { assert(t); h += (int)(t->get_totalHeight()); @@ -152,8 +153,8 @@ void Viewport::paintEvent(QPaintEvent *event) QColor back(QWidget::palette().color(QWidget::backgroundRole())); fore.setAlpha(View::ForeAlpha); _view.set_back(false); - - const auto &traces = _view.get_traces(_type); + std::vector traces; + _view.get_traces(_type, traces); for(auto &t : traces) { @@ -200,7 +201,8 @@ void Viewport::paintEvent(QPaintEvent *event) void Viewport::paintSignals(QPainter &p, QColor fore, QColor back) { - const auto &traces = _view.get_traces(_type); + std::vector traces; + _view.get_traces(_type, traces); if (_view.session().get_device()->get_work_mode() == LOGIC) { @@ -867,7 +869,8 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event) _action_type = NO_ACTION; _dso_trig_moved = false; - const auto &traces = _view.get_traces(ALL_VIEW); + std::vector traces; + _view.get_traces(ALL_VIEW, traces); for(auto &t : traces){ t->select(false); diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index 5ae0198f..c3f04623 100644 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -433,7 +433,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dev_probes_free(sdi); setup_probes(sdi, num_probes); adjust_samplerate(devc); - sr_dbg("%s: setting mode to %d", __func__, sdi->mode); + sr_info("%s: setting mode to %d", __func__, sdi->mode); } else if (id == SR_CONF_PATTERN_MODE) { stropt = g_variant_get_string(data, NULL); diff --git a/libsigrok4DSL/lib_main.c b/libsigrok4DSL/lib_main.c index 1d97e198..4107152b 100644 --- a/libsigrok4DSL/lib_main.c +++ b/libsigrok4DSL/lib_main.c @@ -157,11 +157,7 @@ SR_API int ds_lib_exit() sr_info("Uninit %s.", SR_LIB_NAME); - if (ds_is_collecting()) - { - ds_stop_collect(); // stop collect. - } - + ds_release_actived_device(); sr_close_hotplug(lib_ctx.sr_ctx); lib_ctx.lib_exit_flag = 1; // all thread to exit @@ -327,7 +323,7 @@ SR_API int ds_active_device(ds_device_handle handle) if (ds_is_collecting()) { - sr_err("%s", "One device is collecting, switch device error."); + sr_err("%s", "Error!The current device is collecting, can not switch it."); return SR_ERR_CALL_STATUS; } @@ -736,10 +732,7 @@ END: * Stop collect data */ SR_API int ds_stop_collect() -{ - struct sr_dev_inst *di; - di = lib_ctx.actived_device_instance; - +{ sr_info("%s", "Stop collect."); if (!ds_is_collecting()) @@ -756,7 +749,33 @@ SR_API int ds_stop_collect() g_thread_join(lib_ctx.collect_thread); lib_ctx.collect_thread = NULL; - close_device_instance(di); + return SR_OK; +} + +/** + * Check if the device is collecting. + */ +SR_API int ds_is_collecting() +{ + if (lib_ctx.collect_thread != NULL) + { + return 1; + } + return 0; +} + +SR_API int ds_release_actived_device() +{ + if (lib_ctx.actived_device_instance == NULL){ + return SR_ERR_CALL_STATUS; + } + if (ds_is_collecting()){ + ds_stop_collect(); + } + + sr_info("%s", "Release current actived device."); + + close_device_instance(lib_ctx.actived_device_instance); // Destroy current session. sr_session_destroy(); @@ -1027,18 +1046,6 @@ SR_PRIV int current_device_acquisition_stop() return SR_ERR; } -/** - * Check if the device is collecting. - */ -SR_API int ds_is_collecting() -{ - if (lib_ctx.collect_thread != NULL) - { - return 1; - } - return 0; -} - /**--------------------internal function end-----------*/ /**-------------------private function ---------------*/ @@ -1152,11 +1159,13 @@ static void hotplug_event_listen_callback(struct libusb_context *ctx, struct lib lib_ctx.detach_device_handle); } - if (lib_ctx.actived_device_instance != NULL && lib_ctx.actived_device_instance->handle == (ds_device_handle)dev && ds_is_collecting()) + if (lib_ctx.actived_device_instance != NULL + && lib_ctx.actived_device_instance->handle == (ds_device_handle)dev + && ds_is_collecting()) { sr_info("%s", "The actived device is detached, will stop collect thread."); lib_ctx.is_stop_by_detached = 1; - ds_stop_collect(); + ds_release_actived_device(); } /** diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index bbde11e4..cb02f701 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -751,22 +751,22 @@ enum sr_config_option_id{ SR_CONF_LOGIC_ANALYZER = 10000, /** The device can act as an oscilloscope. */ - SR_CONF_OSCILLOSCOPE, + SR_CONF_OSCILLOSCOPE = 10001, /** The device can act as a multimeter. */ - SR_CONF_MULTIMETER, + SR_CONF_MULTIMETER = 10002, /** The device is a demo device. */ - SR_CONF_DEMO_DEV, + SR_CONF_DEMO_DEV = 10003, /** The device can act as a sound level meter. */ - SR_CONF_SOUNDLEVELMETER, + SR_CONF_SOUNDLEVELMETER = 10004, /** The device can measure temperature. */ - SR_CONF_THERMOMETER, + SR_CONF_THERMOMETER = 10005, /** The device can measure humidity. */ - SR_CONF_HYGROMETER, + SR_CONF_HYGROMETER = 10006, /*--- Driver scan options -------------------------------------------*/ @@ -801,7 +801,7 @@ enum sr_config_option_id{ * This is always an optional parameter, since a driver typically * knows the speed at which the device wants to communicate. */ - SR_CONF_SERIALCOMM, + SR_CONF_SERIALCOMM = 20001, /*--- Device configuration ------------------------------------------*/ @@ -809,222 +809,222 @@ enum sr_config_option_id{ SR_CONF_SAMPLERATE = 30000, /** The device supports setting a pre/post-trigger capture ratio. */ - SR_CONF_CAPTURE_RATIO, + SR_CONF_CAPTURE_RATIO = 30001, /** */ - SR_CONF_USB_SPEED, - SR_CONF_USB30_SUPPORT, - SR_CONF_DEVICE_MODE, - SR_CONF_INSTANT, - SR_CONF_STATUS, + SR_CONF_USB_SPEED = 30002, + SR_CONF_USB30_SUPPORT = 30003, + SR_CONF_DEVICE_MODE = 30004, + SR_CONF_INSTANT = 30005, + SR_CONF_STATUS = 30006, /** The device supports setting a pattern (pattern generator mode). */ - SR_CONF_PATTERN_MODE, + SR_CONF_PATTERN_MODE = 30007, /** The device supports Run Length Encoding. */ - SR_CONF_RLE, + SR_CONF_RLE = 30008, /** Need wait to uplad captured data */ - SR_CONF_WAIT_UPLOAD, + SR_CONF_WAIT_UPLOAD = 30009, /** The device supports setting trigger slope. */ - SR_CONF_TRIGGER_SLOPE, + SR_CONF_TRIGGER_SLOPE = 30010, /** Trigger source. */ - SR_CONF_TRIGGER_SOURCE, + SR_CONF_TRIGGER_SOURCE = 30011, /** Trigger channel */ - SR_CONF_TRIGGER_CHANNEL, + SR_CONF_TRIGGER_CHANNEL = 30012, /** Trigger Value. */ - SR_CONF_TRIGGER_VALUE, + SR_CONF_TRIGGER_VALUE = 30013, /** Horizontal trigger position. */ - SR_CONF_HORIZ_TRIGGERPOS, + SR_CONF_HORIZ_TRIGGERPOS = 30014, /** Trigger hold off time */ - SR_CONF_TRIGGER_HOLDOFF, + SR_CONF_TRIGGER_HOLDOFF = 30015, /** Trigger Margin */ - SR_CONF_TRIGGER_MARGIN, + SR_CONF_TRIGGER_MARGIN = 30016, /** Buffer size. */ - SR_CONF_BUFFERSIZE, + SR_CONF_BUFFERSIZE = 30017, /** Time base. */ - SR_CONF_MAX_TIMEBASE, - SR_CONF_MIN_TIMEBASE, - SR_CONF_TIMEBASE, + SR_CONF_MAX_TIMEBASE = 30018, + SR_CONF_MIN_TIMEBASE = 30019, + SR_CONF_TIMEBASE = 30020, /** Filter. */ - SR_CONF_FILTER, + SR_CONF_FILTER = 30021, /** DSO configure sync */ - SR_CONF_DSO_SYNC, + SR_CONF_DSO_SYNC = 30022, /** How many bits for each sample */ - SR_CONF_UNIT_BITS, - SR_CONF_REF_MIN, - SR_CONF_REF_MAX, + SR_CONF_UNIT_BITS = 30023, + SR_CONF_REF_MIN = 30024, + SR_CONF_REF_MAX = 30025, /** Valid channel number */ - SR_CONF_TOTAL_CH_NUM, + SR_CONF_TOTAL_CH_NUM = 30026, /** Valid channel number */ - SR_CONF_VLD_CH_NUM, + SR_CONF_VLD_CH_NUM = 30027, /** 32 channel support */ - SR_CONF_LA_CH32, + SR_CONF_LA_CH32 = 30028, /** Zero */ - SR_CONF_HAVE_ZERO, - SR_CONF_ZERO, - SR_CONF_ZERO_SET, - SR_CONF_ZERO_LOAD, - SR_CONF_ZERO_DEFAULT, - SR_CONF_ZERO_COMB_FGAIN, - SR_CONF_ZERO_COMB, - SR_CONF_VOCM, - SR_CONF_CALI, + SR_CONF_HAVE_ZERO = 30029, + SR_CONF_ZERO = 30030, + SR_CONF_ZERO_SET = 30031, + SR_CONF_ZERO_LOAD = 30032, + SR_CONF_ZERO_DEFAULT = 30033, + SR_CONF_ZERO_COMB_FGAIN = 30034, + SR_CONF_ZERO_COMB = 30035, + SR_CONF_VOCM = 30036, + SR_CONF_CALI = 30037, /** status for dso channel */ - SR_CONF_STATUS_PERIOD, - SR_CONF_STATUS_PCNT, - SR_CONF_STATUS_MAX, - SR_CONF_STATUS_MIN, - SR_CONF_STATUS_PLEN, - SR_CONF_STATUS_LLEN, - SR_CONF_STATUS_LEVEL, - SR_CONF_STATUS_PLEVEL, - SR_CONF_STATUS_LOW, - SR_CONF_STATUS_HIGH, - SR_CONF_STATUS_RLEN, - SR_CONF_STATUS_FLEN, - SR_CONF_STATUS_RMS, - SR_CONF_STATUS_MEAN, + SR_CONF_STATUS_PERIOD = 30038, + SR_CONF_STATUS_PCNT = 30039, + SR_CONF_STATUS_MAX = 30040, + SR_CONF_STATUS_MIN = 30041, + SR_CONF_STATUS_PLEN = 30042, + SR_CONF_STATUS_LLEN = 30043, + SR_CONF_STATUS_LEVEL = 30044, + SR_CONF_STATUS_PLEVEL = 30045, + SR_CONF_STATUS_LOW = 30046, + SR_CONF_STATUS_HIGH = 30047, + SR_CONF_STATUS_RLEN = 30048, + SR_CONF_STATUS_FLEN = 30049, + SR_CONF_STATUS_RMS = 30050, + SR_CONF_STATUS_MEAN = 30051, /** Stream */ - SR_CONF_STREAM, + SR_CONF_STREAM = 30052, /** DSO Roll */ - SR_CONF_ROLL, + SR_CONF_ROLL = 30053, /** Test */ - SR_CONF_TEST, - SR_CONF_EEPROM, - SR_CONF_TUNE, - SR_CONF_TUNE_SEL, - SR_CONF_EXTEND_ID, - SR_CONF_EXTEND_DATA, + SR_CONF_TEST = 30054, + SR_CONF_EEPROM = 30055, + SR_CONF_TUNE = 30056, + SR_CONF_TUNE_SEL = 30057, + SR_CONF_EXTEND_ID = 30058, + SR_CONF_EXTEND_DATA = 30059, /** The device supports setting its sample interval, in ms. */ - SR_CONF_SAMPLE_INTERVAL, + SR_CONF_SAMPLE_INTERVAL = 30060, /** Number of timebases, as related to SR_CONF_TIMEBASE. */ - SR_CONF_NUM_TIMEBASE, + SR_CONF_NUM_TIMEBASE = 30061, /** Number of vertical divisions, as related to SR_CONF_PROBE_VDIV. */ - SR_CONF_NUM_VDIV, + SR_CONF_NUM_VDIV = 30062, /** clock type (internal/external) */ - SR_CONF_CLOCK_TYPE, + SR_CONF_CLOCK_TYPE = 30063, /** clock edge (posedge/negedge) */ - SR_CONF_CLOCK_EDGE, + SR_CONF_CLOCK_EDGE = 30064, /** Device operation mode */ - SR_CONF_OPERATION_MODE, + SR_CONF_OPERATION_MODE = 30065, /** Device buffer options */ - SR_CONF_BUFFER_OPTIONS, + SR_CONF_BUFFER_OPTIONS = 30066, /** Device channel mode */ - SR_CONF_CHANNEL_MODE, + SR_CONF_CHANNEL_MODE = 30067, /** RLE compress support */ - SR_CONF_RLE_SUPPORT, + SR_CONF_RLE_SUPPORT = 30068, /** Signal max height **/ - SR_CONF_MAX_HEIGHT, - SR_CONF_MAX_HEIGHT_VALUE, + SR_CONF_MAX_HEIGHT = 30069, + SR_CONF_MAX_HEIGHT_VALUE = 30070, /** Device sample threshold */ - SR_CONF_THRESHOLD, - SR_CONF_VTH, + SR_CONF_THRESHOLD = 30071, + SR_CONF_VTH = 30072, /** Hardware capacity **/ - SR_CONF_MAX_DSO_SAMPLERATE, - SR_CONF_MAX_DSO_SAMPLELIMITS, - SR_CONF_HW_DEPTH, + SR_CONF_MAX_DSO_SAMPLERATE = 30073, + SR_CONF_MAX_DSO_SAMPLELIMITS = 30074, + SR_CONF_HW_DEPTH = 30075, /** bandwidth */ - SR_CONF_BANDWIDTH, - SR_CONF_BANDWIDTH_LIMIT, + SR_CONF_BANDWIDTH = 30076, + SR_CONF_BANDWIDTH_LIMIT = 30077, /*--- Probe configuration -------------------------------------------*/ /** Probe options */ - SR_CONF_PROBE_CONFIGS, + SR_CONF_PROBE_CONFIGS = 30078, /** Probe options */ - SR_CONF_PROBE_SESSIONS, + SR_CONF_PROBE_SESSIONS = 30079, /** Enable */ - SR_CONF_PROBE_EN, + SR_CONF_PROBE_EN = 30080, /** Coupling */ - SR_CONF_PROBE_COUPLING, + SR_CONF_PROBE_COUPLING = 30081, /** Volts/div */ - SR_CONF_PROBE_VDIV, + SR_CONF_PROBE_VDIV = 30082, /** Factor */ - SR_CONF_PROBE_FACTOR, + SR_CONF_PROBE_FACTOR = 30083, /** Mapping */ - SR_CONF_PROBE_MAP_DEFAULT, - SR_CONF_PROBE_MAP_UNIT, - SR_CONF_PROBE_MAP_MIN, - SR_CONF_PROBE_MAP_MAX, + SR_CONF_PROBE_MAP_DEFAULT = 30084, + SR_CONF_PROBE_MAP_UNIT = 30085, + SR_CONF_PROBE_MAP_MIN = 30086, + SR_CONF_PROBE_MAP_MAX = 30087, /** Vertical offset */ - SR_CONF_PROBE_OFFSET, - SR_CONF_PROBE_HW_OFFSET, - SR_CONF_PROBE_PREOFF, - SR_CONF_PROBE_PREOFF_DEFAULT, - SR_CONF_PROBE_PREOFF_MARGIN, + SR_CONF_PROBE_OFFSET = 30088, + SR_CONF_PROBE_HW_OFFSET = 30089, + SR_CONF_PROBE_PREOFF = 30090, + SR_CONF_PROBE_PREOFF_DEFAULT = 30091, + SR_CONF_PROBE_PREOFF_MARGIN = 30092, /** VGain */ - SR_CONF_PROBE_VGAIN, - SR_CONF_PROBE_VGAIN_DEFAULT, - SR_CONF_PROBE_VGAIN_RANGE, - SR_CONF_PROBE_COMB_COMP_EN, - SR_CONF_PROBE_COMB_COMP, + SR_CONF_PROBE_VGAIN = 30093, + SR_CONF_PROBE_VGAIN_DEFAULT = 30094, + SR_CONF_PROBE_VGAIN_RANGE = 30095, + SR_CONF_PROBE_COMB_COMP_EN = 30096, + SR_CONF_PROBE_COMB_COMP = 30097, /*--- Special stuff -------------------------------------------------*/ /** Device options for a particular device. */ - SR_CONF_DEVICE_OPTIONS, + SR_CONF_DEVICE_OPTIONS = 30098, /** Sessions */ - SR_CONF_DEVICE_SESSIONS, + SR_CONF_DEVICE_SESSIONS = 30099, /** Session filename. */ - SR_CONF_SESSIONFILE, + SR_CONF_SESSIONFILE = 30100, /** The device supports specifying a capturefile to inject. */ - SR_CONF_CAPTUREFILE, + SR_CONF_CAPTUREFILE = 30101, /** Session file version */ - SR_CONF_FILE_VERSION, + SR_CONF_FILE_VERSION = 30102, /** The device supports setting the number of probes. */ - SR_CONF_CAPTURE_NUM_PROBES, + SR_CONF_CAPTURE_NUM_PROBES = 30103, /** The device supports setting the number of data blocks. */ - SR_CONF_NUM_BLOCKS, + SR_CONF_NUM_BLOCKS = 30104, /** language (string code) **/ - SR_CONF_LANGUAGE, + SR_CONF_LANGUAGE = 30105, /*--- Acquisition modes ---------------------------------------------*/ @@ -1038,39 +1038,39 @@ enum sr_config_option_id{ * The device supports setting a sample number limit (how many * samples should be acquired). */ - SR_CONF_LIMIT_SAMPLES, + SR_CONF_LIMIT_SAMPLES = 50001, /** * Absolute time record for session driver */ - SR_CONF_TRIGGER_TIME, + SR_CONF_TRIGGER_TIME = 50002, /** * Trigger position for session driver */ - SR_CONF_TRIGGER_POS, + SR_CONF_TRIGGER_POS = 50003, /** * The actual sample count received */ - SR_CONF_ACTUAL_SAMPLES, + SR_CONF_ACTUAL_SAMPLES = 50004, /** * The device supports setting a frame limit (how many * frames should be acquired). */ - SR_CONF_LIMIT_FRAMES, + SR_CONF_LIMIT_FRAMES = 50005, /** * The device supports continuous sampling. Neither a time limit * nor a sample number limit has to be supplied, it will just acquire * samples continuously, until explicitly stopped by a certain command. */ - SR_CONF_CONTINUOUS, + SR_CONF_CONTINUOUS = 50006, /** The device has internal storage, into which data is logged. This * starts or stops the internal logging. */ - SR_CONF_DATALOG, + SR_CONF_DATALOG = 50007, }; /** Device instance status. */ @@ -1410,6 +1410,11 @@ SR_API int ds_stop_collect(); */ SR_API int ds_is_collecting(); +/** + * Close the actived device. + */ +SR_API int ds_release_actived_device(); + /*---config -----------------------------------------------*/ SR_API int ds_get_actived_device_config(const struct sr_channel *ch, const struct sr_channel_group *cg,