diff --git a/DSView/pv/appcontrol.cpp b/DSView/pv/appcontrol.cpp index 911b496a..c17ac902 100644 --- a/DSView/pv/appcontrol.cpp +++ b/DSView/pv/appcontrol.cpp @@ -32,6 +32,7 @@ #include "config/appconfig.h" #include "log.h" #include "utility/path.h" +#include "utility/encoding.h" AppControl::AppControl() { @@ -66,6 +67,8 @@ bool AppControl::Init() { _session->init(); + pv::encoding::init(); + srd_log_set_context(dsv_log_context()); #if defined(_WIN32) && defined(DEBUG_INFO) diff --git a/DSView/pv/data/snapshot.h b/DSView/pv/data/snapshot.h index 5113aef0..c4dbf85a 100644 --- a/DSView/pv/data/snapshot.h +++ b/DSView/pv/data/snapshot.h @@ -77,6 +77,7 @@ public: virtual bool has_data(int index) = 0; virtual int get_block_num() = 0; virtual uint64_t get_block_size(int block_index) = 0; + virtual uint64_t get_real_sample_count() = 0; protected: virtual void free_data(); diff --git a/DSView/pv/dialogs/deviceoptions.cpp b/DSView/pv/dialogs/deviceoptions.cpp index d65ba4c8..d8bb0cc4 100644 --- a/DSView/pv/dialogs/deviceoptions.cpp +++ b/DSView/pv/dialogs/deviceoptions.cpp @@ -76,9 +76,8 @@ void ChannelLabel::on_checked() namespace pv { namespace dialogs { -DeviceOptions::DeviceOptions(QWidget *parent, DevInst *dev_inst) : +DeviceOptions::DeviceOptions(QWidget *parent) : DSDialog(parent), - _dev_inst(dev_inst), _device_options_binding(_dev_inst->dev_inst()) { _scroll_panel = NULL; diff --git a/DSView/pv/dialogs/deviceoptions.h b/DSView/pv/dialogs/deviceoptions.h index 38eadfe1..47db8746 100644 --- a/DSView/pv/dialogs/deviceoptions.h +++ b/DSView/pv/dialogs/deviceoptions.h @@ -81,7 +81,7 @@ class DeviceOptions : public DSDialog, public IChannelCheck Q_OBJECT public: - DeviceOptions(QWidget *parent, DevInst *dev_inst); + DeviceOptions(QWidget *parent); ~DeviceOptions(); @@ -115,8 +115,7 @@ private slots: void on_calibration(); void channel_enable(); -private: - DevInst *_dev_inst; +private: std::vector _probes_checkBox_list; std::vector _sub_lays; diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index f038d074..4b5ff2bf 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -1603,7 +1603,8 @@ void MainWindow::data_received(){ } void MainWindow::update_device_list(struct ds_device_info *array, int count, int select_index) -{ +{ + _sampling_bar->update_device_list(array, count, select_index); } } // namespace pv diff --git a/DSView/pv/prop/binding/deviceoptions.cpp b/DSView/pv/prop/binding/deviceoptions.cpp index 1ceb1053..ebebb5eb 100644 --- a/DSView/pv/prop/binding/deviceoptions.cpp +++ b/DSView/pv/prop/binding/deviceoptions.cpp @@ -31,6 +31,7 @@ #include "../int.h" #include "../../config/appconfig.h" #include "../../log.h" +#include "../../appcontrol.h" using namespace std; @@ -38,14 +39,14 @@ namespace pv { namespace prop { namespace binding { -DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : - _sdi(sdi) +DeviceOptions::DeviceOptions() { GVariant *gvar_opts, *gvar_list; gsize num_opts; - if ((sr_config_list(sdi->driver, sdi, NULL, SR_CONF_DEVICE_OPTIONS, - &gvar_opts) != SR_OK)) + SigSession *session = AppControl::Instance()->GetSession(); + + if (session->get_device_config_list(NULL, SR_CONF_DEVICE_OPTIONS, &gvar_opts) == false) /* Driver supports no device instance options. */ return; @@ -143,8 +144,7 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : g_variant_unref(gvar_opts); } -GVariant* DeviceOptions::config_getter( - const struct sr_dev_inst *sdi, int key) +GVariant* DeviceOptions::config_getter(int key) { GVariant *data = NULL; if (sr_config_get(sdi->driver, sdi, NULL, NULL, key, &data) != SR_OK) { @@ -154,8 +154,7 @@ GVariant* DeviceOptions::config_getter( return data; } -void DeviceOptions::config_setter( - struct sr_dev_inst *sdi, int key, GVariant* value) +void DeviceOptions::config_setter(int key, GVariant* value) { if (sr_config_set(sdi, NULL, NULL, key, value) != SR_OK){ dsv_warn("%s%d", "WARNING: Failed to set value of config id:", key); @@ -267,8 +266,7 @@ QString DeviceOptions::print_samplerate(GVariant *const gvar) return qstring; } -GVariant* DeviceOptions::samplerate_double_getter( - const struct sr_dev_inst *sdi) +GVariant* DeviceOptions::samplerate_double_getter() { GVariant *const gvar = config_getter(sdi, SR_CONF_SAMPLERATE); @@ -283,8 +281,7 @@ GVariant* DeviceOptions::samplerate_double_getter( return gvar_double; } -void DeviceOptions::samplerate_double_setter( - struct sr_dev_inst *sdi, GVariant *value) +void DeviceOptions::samplerate_double_setter(GVariant *value) { GVariant *const gvar = g_variant_new_uint64( g_variant_get_double(value)); diff --git a/DSView/pv/prop/binding/deviceoptions.h b/DSView/pv/prop/binding/deviceoptions.h index 5481ba0c..1678ae70 100644 --- a/DSView/pv/prop/binding/deviceoptions.h +++ b/DSView/pv/prop/binding/deviceoptions.h @@ -38,19 +38,19 @@ namespace binding { class DeviceOptions : public Binding { public: - DeviceOptions(struct sr_dev_inst *sdi); + DeviceOptions(); private: - static GVariant* config_getter( - const struct sr_dev_inst *sdi, int key); - static void config_setter( - struct sr_dev_inst *sdi, int key, GVariant* value); + static GVariant* config_getter(int key); + + static void config_setter(int key, GVariant* value); void bind_bool(const QString &name, const QString label, int key); - void bind_enum(const QString &name, const QString label, int key, - GVariant *const gvar_list, + + void bind_enum(const QString &name, const QString label, int key, GVariant *const gvar_list, boost::function printer = print_gvariant); + void bind_int(const QString &name, const QString label, int key, QString suffix, boost::optional< std::pair > range); @@ -60,23 +60,21 @@ private: static QString print_gvariant(GVariant *const gvar); - void bind_samplerate(const QString &name, const QString label, - GVariant *const gvar_list); + void bind_samplerate(const QString &name, const QString label,GVariant *const gvar_list); + static QString print_samplerate(GVariant *const gvar); - static GVariant* samplerate_double_getter( - const struct sr_dev_inst *sdi); - static void samplerate_double_setter( - struct sr_dev_inst *sdi, GVariant *value); + + static GVariant* samplerate_double_getter(); + + static void samplerate_double_setter(GVariant *value); static QString print_timebase(GVariant *const gvar); + static QString print_vdiv(GVariant *const gvar); - void bind_bandwidths(const QString &name, const QString label, int key, - GVariant *const gvar_list, + void bind_bandwidths(const QString &name, const QString label, int key,GVariant *const gvar_list, boost::function printer = print_gvariant); - -protected: - struct sr_dev_inst *const _sdi; + }; } // binding diff --git a/DSView/pv/prop/binding/probeoptions.cpp b/DSView/pv/prop/binding/probeoptions.cpp index 9b8fcfc1..9acf3959 100644 --- a/DSView/pv/prop/binding/probeoptions.cpp +++ b/DSView/pv/prop/binding/probeoptions.cpp @@ -36,11 +36,11 @@ namespace pv { namespace prop { namespace binding { -ProbeOptions::ProbeOptions(struct sr_dev_inst *sdi, struct sr_channel *probe) : - Binding(), - _sdi(sdi), +ProbeOptions::ProbeOptions(ds_device_handle dev_handel, struct sr_channel *probe) : + Binding(), _probe(probe) { + _dev_handel = dev_handel; GVariant *gvar_opts, *gvar_list; gsize num_opts; diff --git a/DSView/pv/prop/binding/probeoptions.h b/DSView/pv/prop/binding/probeoptions.h index bfedad72..26696740 100644 --- a/DSView/pv/prop/binding/probeoptions.h +++ b/DSView/pv/prop/binding/probeoptions.h @@ -37,7 +37,7 @@ namespace binding { class ProbeOptions : public Binding { public: - ProbeOptions(struct sr_dev_inst *sdi, + ProbeOptions(ds_device_handle dev_handel, struct sr_channel *probe); private: @@ -71,7 +71,7 @@ private: static QString print_coupling(GVariant *const gvar); protected: - struct sr_dev_inst *const _sdi; + ds_device_handle _dev_handel; struct sr_channel *const _probe; }; diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index cf612281..dec0b748 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -23,6 +23,7 @@ #include + #include "sigsession.h" #include "mainwindow.h" #include "device/device.h" @@ -88,6 +89,7 @@ SigSession::SigSession() _noData_cnt = 0; _data_lock = false; _data_updated = false; + _active_last_device_flag = false; _decoder_model = new pv::data::DecoderModel(NULL); @@ -115,7 +117,10 @@ SigSession::SigSession() _feed_timer.SetCallback(std::bind(&SigSession::feed_timeout, this)); } -SigSession::SigSession(SigSession &o){(void)o;} +SigSession::SigSession(SigSession &o) +{ + (void)o; +} SigSession::~SigSession() { @@ -1885,37 +1890,81 @@ void SigSession::set_stop_scale(float scale) _bDecodeRunning = false; } - void SigSession::get_device_list(std::vector &devices) + Snapshot* SigSession::get_signal_snapshot() { - struct ds_device_info *array = NULL; - int num = 0; - - if (ds_get_device_list(&array, &num) != SR_OK){ - dsv_err("%s", "Failed to get device list!"); - return; - } + int mode = ds_get_actived_device_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", "device_lib_event_callback() error, _session is null."); + return; + } + _session->on_device_lib_event(event); + } + + void SigSession::on_device_lib_event(int event) { struct ds_device_info *array = NULL; int count = 0; + int index = -1; + + if (event == DS_EV_NEW_DEVICE_ATTACH || event == DS_EV_CURRENT_DEVICE_DETACH){ + Snapshot *data = get_signal_snapshot(); - if (_session == NULL){ - dsv_err("%s", "device_lib_event_callback() error, _session is null."); - return; + if (data->get_real_sample_count() > 0) + { + if (ds_is_collecting()){ + ds_stop_collect(); + } + update_collect_status_view(); + + // Try to save current device data, and auto select the lastest device later. + _active_last_device_flag = true; + store_session_data(); + return; + } } - if (ds_device_get_list(&array, &count) != SR_OK){ - dsv_err("%s", "Failed to get device list!"); + if (ds_get_device_list(&array, &count) != SR_OK){ + dsv_err("%s", "Get device list error!"); return; } - - _session->_callback->update_device_list(array, count); - - if (array != NULL){ - free(array); + if (count < 1 || array == NULL){ + dsv_err("%s", "Device list is empty!"); + return; } + + if (event == DS_EV_NEW_DEVICE_ATTACH || event == DS_EV_CURRENT_DEVICE_DETACH){ + index = count -1; + + if (ds_is_collecting()){ + ds_stop_collect(); + } + update_collect_status_view(); + + if (ds_active_device_by_index(index) != SR_OK){ + dsv_err("%s", "Active device error!"); + free(array); + return; + } + + init_device_view(); + } + else{ + index = ds_get_actived_device_index(); + } + + _callback->update_device_list(array, count, index); + + free(array); } bool SigSession::init() @@ -1947,9 +1996,98 @@ void SigSession::set_stop_scale(float scale) ds_lib_exit(); } + void SigSession::update_collect_status_view() + { + + } + + void SigSession::init_device_view() + { + + } + + void SigSession::store_session_data() + { + + } + + //---------------device api-----------/ + int SigSession::get_device_work_mode() { return ds_get_actived_device_mode(); } + bool SigSession::get_device_info(struct ds_device_info &info) + { + if (ds_get_actived_device_info(&info) == SR_OK){ + return info.handle != NULL; + } + return false; + } + + bool SigSession::get_device_config(const struct sr_channel *ch, + const struct sr_channel_group *cg, + int key, GVariant **data) + { + + if (ds_get_actived_device_config(ch, cg, key, data) == SR_OK){ + return true; + } + + return false; + } + + bool SigSession::set_device_config(const struct sr_channel *ch, + const struct sr_channel_group *cg, + int key, GVariant *data) + { + + if (ds_set_actived_device_config(ch, cg, key, data) == SR_OK){ + return true; + } + + return false; + } + + bool SigSession::get_device_config_list(const struct sr_channel_group *cg, + int key, GVariant **data) + { + + if (ds_get_actived_device_config_list(cg, key, data) == SR_OK){ + return true; + } + return false; + } + + const struct sr_config_info* SigSession::get_device_config_info(int key) + { + return ds_get_actived_device_config_info(key); + } + + const struct sr_config_info* SigSession::get_device_config_info_by_name(const char *optname) + { + return ds_get_actived_device_config_info_by_name(optname); + } + + bool SigSession::get_device_status(struct sr_status &status, gboolean prg) + { + if (ds_get_actived_device_status(&status, prg) == SR_OK){ + return true; + } + return false; + } + + struct sr_config* new_config(int key, GVariant *data) + { + return ds_new_config(key, data); + } + + void free_config(struct sr_config *src) + { + ds_free_config(src); + } + + //---------------device api end-----------/ + } // namespace pv diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index 00a0f407..82ee0ba7 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -36,7 +36,8 @@ #include "data/mathstack.h" #include "interface/icallbacks.h" #include "dstimer.h" -#include +#include +#include struct srd_decoder; @@ -83,6 +84,7 @@ class MathTrace; } using namespace pv::device; +using namespace pv::data; //created by MainWindow class SigSession @@ -126,7 +128,9 @@ public: ~SigSession(); - DevInst* get_device(); + inline DeviceAgent* get_device(){ + return &_device_agent; + } /** * Sets device instance that will be used in the next capture session. @@ -277,7 +281,34 @@ public: return _is_device_reattach; } - int get_device_work_mode(); + void store_session_data(); + +//---------------device api-----------/ +public: + int get_device_work_mode(); + + bool get_device_info(struct ds_device_info &info); + + bool get_device_config(const struct sr_channel *ch, + const struct sr_channel_group *cg, + int key, GVariant **data); + + bool set_device_config(const struct sr_channel *ch, + const struct sr_channel_group *cg, + int key, GVariant *data); + + bool get_device_config_list(const struct sr_channel_group *cg, + int key, GVariant **data); + + const struct sr_config_info* get_device_config_info(int key); + + const struct sr_config_info* get_device_config_info_by_name(const char *optname); + + bool get_device_status(struct sr_status &status, gboolean prg); + + struct sr_config* new_config(int key, GVariant *data); + + void free_config(struct sr_config *src); private: inline void data_updated(){ @@ -308,8 +339,7 @@ private: void data_unlock(); void nodata_timeout(); void feed_timeout(); - void repeat_update(); - + void repeat_update(); private: /** @@ -331,16 +361,19 @@ private: void feed_in_dso(const sr_datafeed_dso &dso); void feed_in_analog(const sr_datafeed_analog &analog); void data_feed_in(const struct sr_dev_inst *sdi, - const struct sr_datafeed_packet *packet); - - void get_device_list(std::vector &devices); + const struct sr_datafeed_packet *packet); static void data_feed_callback(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *packet); static void device_lib_event_callback(int event); + void on_device_lib_event(int event); - + Snapshot* get_signal_snapshot(); + + void update_collect_status_view(); + void init_device_view(); + private: /** @@ -417,8 +450,11 @@ private: volatile int _wait_reattch_times; bool _is_device_reattach; QString _last_device_name; + bool _active_last_device_flag; ISessionCallback *_callback; + + DeviceAgent _device_agent; private: // TODO: This should not be necessary. Multiple concurrent diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index d19cfc85..88e417dc 100644 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -56,8 +56,7 @@ SamplingBar::SamplingBar(SigSession *session, QWidget *parent) : _enable(true), _sampling(false), _device_type(this), - _device_selector(this), - _updating_device_selector(false), + _device_selector(this), _configure_button(this), _sample_count(this), _sample_rate(this), @@ -68,7 +67,7 @@ SamplingBar::SamplingBar(SigSession *session, QWidget *parent) : _mode_button(this), _instant(false) { - _is_seting = false; + _is_seting_list = false; setMovable(false); setContentsMargins(0,0,0,0); @@ -81,7 +80,6 @@ SamplingBar::SamplingBar(SigSession *session, QWidget *parent) : _sample_count.setSizeAdjustPolicy(DsComboBox::AdjustToContents); _device_selector.setMaximumWidth(ComboBoxMaxWidth); - //_run_stop_button.setToolButtonStyle(Qt::ToolButtonTextBesideIcon); _run_stop_button.setObjectName(tr("run_stop_button")); QWidget *leftMargin = new QWidget(this); @@ -116,7 +114,6 @@ SamplingBar::SamplingBar(SigSession *session, QWidget *parent) : _instant_action = addWidget(&_instant_button); set_sampling(false); - //retranslateUi(); connect(&_device_selector, SIGNAL(currentIndexChanged (int)), this, SLOT(on_device_selected())); connect(&_configure_button, SIGNAL(clicked()),this, SLOT(on_configure())); @@ -139,15 +136,19 @@ void SamplingBar::changeEvent(QEvent *event) void SamplingBar::retranslateUi() { - DevInst *dev_inst = get_selected_device(); - if (dev_inst && dev_inst->dev_inst()) { - if (dev_inst->name().contains("virtual-demo")) + struct ds_device_info inf; + bool haveDev = _session->get_device_info(inf); + + if (haveDev) { + if (inf.dev_type == DEV_TYPE_DEMO) _device_type.setText(tr("Demo")); - else if (dev_inst->name().contains("virtual")) + else if (inf.dev_type == DEV_TYPE_FILELOG) _device_type.setText(tr("File")); else { int usb_speed = LIBUSB_SPEED_HIGH; - GVariant *gvar = dev_inst->get_config(NULL, NULL, SR_CONF_USB_SPEED); + GVariant *gvar = NULL; + _session->get_device_config(NULL, NULL, SR_CONF_USB_SPEED, &gvar); + if (gvar != NULL) { usb_speed = g_variant_get_int32(gvar); g_variant_unref(gvar); @@ -163,17 +164,17 @@ void SamplingBar::retranslateUi() _configure_button.setText(tr("Options")); _mode_button.setText(tr("Mode")); - sr_dev_inst *dev_c = _session->get_dev_inst_c(); + int mode = _session->get_device_work_mode(); if (_instant) { - if (dev_c && dev_c->mode == DSO) + if (haveDev && mode == DSO) _instant_button.setText(_sampling ? tr("Stop") : tr("Single")); else _instant_button.setText(_sampling ? tr("Stop") : tr("Instant")); _run_stop_button.setText(tr("Start")); } else { _run_stop_button.setText(_sampling ? tr("Stop") : tr("Start")); - if (dev_c && dev_c->mode == DSO) + if (haveDev && mode == DSO) _instant_button.setText(tr("Single")); else _instant_button.setText(tr("Instant")); @@ -185,15 +186,19 @@ void SamplingBar::retranslateUi() void SamplingBar::reStyle() { - DevInst *dev_inst = get_selected_device(); - if (dev_inst && dev_inst->dev_inst()) { - if (dev_inst->name().contains("virtual-demo")) + struct ds_device_info inf; + bool haveDev = _session->get_device_info(inf); + + if (haveDev){ + if (inf.dev_type == DEV_TYPE_DEMO) _device_type.setIcon(QIcon(":/icons/demo.svg")); - else if (dev_inst->name().contains("virtual")) + else if (inf.dev_type == DEV_TYPE_FILELOG) _device_type.setIcon(QIcon(":/icons/data.svg")); else { int usb_speed = LIBUSB_SPEED_HIGH; - GVariant *gvar = dev_inst->get_config(NULL, NULL, SR_CONF_USB_SPEED); + GVariant *gvar = NULL; + _session->get_device_config(NULL, NULL, SR_CONF_USB_SPEED, &gvar); + if (gvar != NULL) { usb_speed = g_variant_get_int32(gvar); g_variant_unref(gvar); @@ -219,70 +224,17 @@ void SamplingBar::reStyle() } } -void SamplingBar::set_device_list(const std::list &devices, DevInst *selected) -{ - int selected_index = -1; - - assert(selected); - - _updating_device_selector = true; - - _device_selector.clear(); - _device_selector_map.clear(); - - for (DevInst *dev_inst : devices) { - assert(dev_inst); - const QString title = dev_inst->format_device_title(); - const void *id = dev_inst->get_id(); - assert(id); - - if (selected == dev_inst) - selected_index = _device_selector.count(); - - _device_selector_map[id] = dev_inst; - _device_selector.addItem(title, - QVariant::fromValue((void*)id)); - } - int width = _device_selector.sizeHint().width(); - _device_selector.setFixedWidth(min(width+15, _device_selector.maximumWidth())); - _device_selector.view()->setMinimumWidth(width+30); - - // The selected device should have been in the list - assert(selected_index != -1); - _device_selector.setCurrentIndex(selected_index); - - update_sample_rate_selector(); - - _updating_device_selector = false; -} - -DevInst* SamplingBar::get_selected_device() -{ - const int index = _device_selector.currentIndex(); - if (index < 0) - return NULL; - - const void *const id = - _device_selector.itemData(index).value(); - assert(id); - - auto it = _device_selector_map.find(id); - if (it == _device_selector_map.end()) - return NULL; - - return (*it).second; -} - void SamplingBar::on_configure() { sig_hide_calibration(); int ret; - DevInst *dev_inst = get_selected_device(); - assert(dev_inst); + struct ds_device_info inf; + bool haveDev = _session->get_device_info(inf); pv::dialogs::DeviceOptions dlg(this, dev_inst); ret = dlg.exec(); + if (ret == QDialog::Accepted) { sig_device_updated(); update_sample_rate_selector(); @@ -375,8 +327,7 @@ bool SamplingBar::get_instant() } void SamplingBar::set_sampling(bool sampling) -{ - std::lock_guard lock(_sampling_mutex); +{ _sampling = sampling; if (!sampling) { @@ -922,9 +873,7 @@ void SamplingBar::on_instant_stop() } void SamplingBar::on_device_selected() -{ - if (_updating_device_selector) - return; +{ _session->stop_capture(); _session->session_save(); @@ -1037,17 +986,29 @@ void SamplingBar::on_mode() } void SamplingBar::update_device_list(struct ds_device_info *array, int count, int select_index) - { - if (array == NULL || count == 0){ - return; - } - _is_seting = true; + { + assert(array); + assert(count > 0); + + _is_seting_list = true; + struct ds_device_info *p = NULL; + + _device_selector.clear(); for (int i=0; iname), QVariant::fromValue(p->handle)); } + + _device_selector.setCurrentIndex(select_index); + + update_sample_rate_selector(); + + int width = _device_selector.sizeHint().width(); + _device_selector.setFixedWidth(min(width+15, _device_selector.maximumWidth())); + _device_selector.view()->setMinimumWidth(width+30); - _is_seting = false; + _is_seting_list = false; } } // namespace toolbars diff --git a/DSView/pv/toolbars/samplingbar.h b/DSView/pv/toolbars/samplingbar.h index 9bddf932..8c6492e6 100644 --- a/DSView/pv/toolbars/samplingbar.h +++ b/DSView/pv/toolbars/samplingbar.h @@ -73,8 +73,7 @@ namespace pv public: SamplingBar(SigSession *session, QWidget *parent); - void set_device_list(const std::list &devices, DevInst* selected); - DevInst *get_selected_device(); + void update_sample_rate_selector(); void set_sampling(bool sampling); @@ -131,15 +130,12 @@ namespace pv void reload(); private: - SigSession *_session; - mutable std::mutex _sampling_mutex; + SigSession *_session; bool _enable; bool _sampling; QToolButton _device_type; - DsComboBox _device_selector; - std::map _device_selector_map; - bool _updating_device_selector; + DsComboBox _device_selector; QToolButton _configure_button; DsComboBox _sample_count; @@ -158,7 +154,7 @@ namespace pv QAction *_action_repeat; QAction *_action_single; bool _instant; - bool _is_seting; + bool _is_seting_list; }; } // namespace toolbars diff --git a/DSView/pv/utility/encoding.cpp b/DSView/pv/utility/encoding.cpp index 7d4696bf..a891f8c6 100644 --- a/DSView/pv/utility/encoding.cpp +++ b/DSView/pv/utility/encoding.cpp @@ -28,17 +28,27 @@ #include #endif +#ifdef _WIN32 +#include +#endif + namespace pv{ namespace encoding{ + void init() + { +#ifdef _WIN32 + QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); +#endif + } + void set_utf8(QTextStream &stream) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) stream.setEncoding(QStringConverter::Utf8); #else - //QTextCodec *code = QTextCodec::codecForName("UTF-8"); - // stream.setCodec(code); - stream.setCodec("UTF-8"); + QTextCodec *code = QTextCodec::codecForName("UTF-8"); + stream.setCodec(code); #endif } } diff --git a/DSView/pv/utility/encoding.h b/DSView/pv/utility/encoding.h index b4e8858b..158714f2 100644 --- a/DSView/pv/utility/encoding.h +++ b/DSView/pv/utility/encoding.h @@ -26,6 +26,8 @@ class QTextStream; namespace pv{ namespace encoding{ + + void init(); void set_utf8(QTextStream &stream); } diff --git a/libsigrok4DSL/backend.c b/libsigrok4DSL/backend.c index 3130db91..e617496b 100644 --- a/libsigrok4DSL/backend.c +++ b/libsigrok4DSL/backend.c @@ -355,7 +355,7 @@ done: * * @since 0.1.0 (but the API changed in 0.2.0) */ -SR_API int sr_exit(struct sr_context *ctx) +SR_PRIV int sr_exit(struct sr_context *ctx) { if (!ctx) { sr_err("%s(): libsigrok context was NULL.", __func__); diff --git a/libsigrok4DSL/dsdevice.c b/libsigrok4DSL/dsdevice.c index f053eea4..f0e6b117 100644 --- a/libsigrok4DSL/dsdevice.c +++ b/libsigrok4DSL/dsdevice.c @@ -315,6 +315,29 @@ SR_PRIV void sr_serial_dev_inst_free(struct sr_serial_dev_inst *serial) g_free(serial->serialcomm); g_free(serial); } + +SR_PRIV int sr_enable_device_channel(struct sr_dev_inst *sdi, const struct sr_channel *probe, gboolean enable) +{ + GSList *l; + int ret; + struct sr_channel *ch; + + if (sdi == NULL || probe == NULL){ + return SR_ERR_ARG; + } + + ret = SR_ERR_CALL_STATUS; + for (l=sdi->channels; l; l = l->next){ + if (l->data == probe){ + ch = l->data; + ch->enabled = enable; + ret = SR_OK; + break; + } + } + + return ret; +} /** @} */ diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index c5dc062a..5ae0198f 100644 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -229,6 +229,7 @@ static int dev_destroy(struct sr_dev_inst *sdi) { hw_dev_close(sdi); sr_dev_inst_free(sdi); + return SR_OK; } static int hw_cleanup(void) diff --git a/libsigrok4DSL/hwdriver.c b/libsigrok4DSL/hwdriver.c index 44127103..5f90b934 100644 --- a/libsigrok4DSL/hwdriver.c +++ b/libsigrok4DSL/hwdriver.c @@ -204,7 +204,7 @@ SR_PRIV void sr_hw_cleanup_all(void) } /** A floating reference can be passed in for data. */ -SR_API struct sr_config *sr_config_new(int key, GVariant *data) +SR_PRIV struct sr_config *sr_config_new(int key, GVariant *data) { struct sr_config *src; @@ -216,7 +216,7 @@ SR_API struct sr_config *sr_config_new(int key, GVariant *data) return src; } -SR_API void sr_config_free(struct sr_config *src) +SR_PRIV void sr_config_free(struct sr_config *src) { if (!src || !src->data) { @@ -248,7 +248,7 @@ SR_API void sr_config_free(struct sr_config *src) * but this is not to be flagged as an error by the caller; merely * as an indication that it's not applicable. */ -SR_API int sr_config_get(const struct sr_dev_driver *driver, +SR_PRIV int sr_config_get(const struct sr_dev_driver *driver, const struct sr_dev_inst *sdi, const struct sr_channel *ch, const struct sr_channel_group *cg, @@ -285,7 +285,7 @@ SR_API int sr_config_get(const struct sr_dev_driver *driver, * but this is not to be flagged as an error by the caller; merely * as an indication that it's not applicable. */ -SR_API int sr_config_set(struct sr_dev_inst *sdi, +SR_PRIV int sr_config_set(struct sr_dev_inst *sdi, struct sr_channel *ch, struct sr_channel_group *cg, int key, GVariant *data) @@ -324,7 +324,7 @@ SR_API int sr_config_set(struct sr_dev_inst *sdi, * but this is not to be flagged as an error by the caller; merely * as an indication that it's not applicable. */ -SR_API int sr_config_list(const struct sr_dev_driver *driver, +SR_PRIV int sr_config_list(const struct sr_dev_driver *driver, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg, int key, GVariant **data) @@ -349,7 +349,7 @@ SR_API int sr_config_list(const struct sr_dev_driver *driver, * @return A pointer to a struct sr_config_info, or NULL if the key * was not found. */ -SR_API const struct sr_config_info *sr_config_info_get(int key) +SR_PRIV const struct sr_config_info *sr_config_info_get(int key) { int i; @@ -372,7 +372,7 @@ SR_API const struct sr_config_info *sr_config_info_get(int key) * but this is not to be flagged as an error by the caller; merely * as an indication that it's not applicable. */ -SR_API int sr_status_get(const struct sr_dev_inst *sdi, +SR_PRIV int sr_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg) { int ret; @@ -395,7 +395,7 @@ SR_API int sr_status_get(const struct sr_dev_inst *sdi, * @return A pointer to a struct sr_config_info, or NULL if the key * was not found. */ -SR_API const struct sr_config_info *sr_config_info_name_get(const char *optname) +SR_PRIV const struct sr_config_info *sr_config_info_name_get(const char *optname) { int i; diff --git a/libsigrok4DSL/lib_main.c b/libsigrok4DSL/lib_main.c index a7942c2d..5883a25c 100644 --- a/libsigrok4DSL/lib_main.c +++ b/libsigrok4DSL/lib_main.c @@ -420,21 +420,23 @@ SR_API int ds_active_device_by_index(int index) SR_API int ds_get_actived_device_index() { int dex = -1; - GList *l; + GList *l; int i = 0; - if (lib_ctx.actived_device_instance == NULL){ + if (lib_ctx.actived_device_instance == NULL) + { return -1; } pthread_mutex_lock(&lib_ctx.mutext); for (l = lib_ctx.device_list; l; l = l->next) - { - if ((struct sr_dev_inst *)l->data == lib_ctx.actived_device_instance){ + { + if ((struct sr_dev_inst *)l->data == lib_ctx.actived_device_instance) + { dex = i; break; - } + } i++; } @@ -447,31 +449,22 @@ SR_API int ds_get_actived_device_index() * Get the decive supports work mode, mode list: LOGIC、ANALOG、DSO * return type see struct sr_dev_mode. */ -SR_API const GSList *ds_get_device_mode_list(ds_device_handle handle) +SR_API const GSList *ds_get_actived_device_mode_list() { GList *l; - struct sr_dev_inst *dev; - struct sr_dev_inst *fd_dev; - fd_dev = NULL; + struct sr_dev_inst *dev; - pthread_mutex_lock(&lib_ctx.mutext); + dev = lib_ctx.actived_device_instance ; - for (l = lib_ctx.device_list; l; l = l->next){ - dev = l->data; - if (dev->handle == handle){ - fd_dev = dev; - break; - } + if (dev == NULL){ + sr_err("%s", "Have no actived device."); + } + if (dev->driver == NULL || dev->driver->dev_mode_list){ + sr_err("%s", "Module not implemented."); + return NULL; } - pthread_mutex_unlock(&lib_ctx.mutext); - - if (dev && dev->driver && dev->driver->dev_mode_list) - return dev->driver->dev_mode_list(dev); - - sr_err("%s", "ds_device_get_mode_list() error, can't find the device."); - - return NULL; + return dev->driver->dev_mode_list(dev); } /** @@ -484,7 +477,7 @@ SR_API int ds_remove_device(ds_device_handle handle) struct sr_dev_inst *dev; struct sr_dev_inst *di; int bFind = 0; - + di = lib_ctx.actived_device_instance; if (handle == NULL) @@ -492,7 +485,8 @@ SR_API int ds_remove_device(ds_device_handle handle) return SR_ERR_ARG; } - if (di != NULL && di->handle == handle && ds_is_collecting()){ + if (di != NULL && di->handle == handle && ds_is_collecting()) + { sr_err("%s", "Device is collecting, can't remove it."); return SR_ERR_CALL_STATUS; } @@ -542,7 +536,7 @@ SR_API int ds_get_actived_device_info(struct ds_device_info *fill_info) } fill_info->handle = NULL; - fill_info->name[0] = '\0'; + fill_info->name[0] = '\0'; fill_info->dev_type = DEV_TYPE_UNKOWN; if (lib_ctx.actived_device_info.handle != NULL) @@ -550,20 +544,22 @@ SR_API int ds_get_actived_device_info(struct ds_device_info *fill_info) fill_info->handle = lib_ctx.actived_device_info.handle; strncpy(fill_info->name, lib_ctx.actived_device_info.name, sizeof(fill_info->name)); fill_info->dev_type = lib_ctx.actived_device_info.dev_type; + return SR_OK; } - return SR_OK; + return SR_ERR_CALL_STATUS; } /** * Get actived device work model. mode list:LOGIC、ANALOG、DSO */ SR_API int ds_get_actived_device_mode() -{ +{ int mode = UNKNOWN_DSL_MODE; pthread_mutex_lock(&lib_ctx.mutext); - if (lib_ctx.actived_device_instance != NULL){ + if (lib_ctx.actived_device_instance != NULL) + { mode = lib_ctx.actived_device_instance->mode; } pthread_mutex_unlock(&lib_ctx.mutext); @@ -731,6 +727,108 @@ int ds_channel_is_enabled() return 0; } +/**-------------------public end ---------------*/ + +/**-------------------config -------------------*/ +SR_API int ds_get_actived_device_config(const struct sr_channel *ch, + const struct sr_channel_group *cg, + int key, GVariant **data) +{ + if (lib_ctx.actived_device_instance == NULL){ + sr_err("%s", "Have no actived device."); + return SR_ERR_CALL_STATUS; + } + + return sr_config_get(lib_ctx.actived_device_instance->driver, + lib_ctx.actived_device_instance, + ch, + cg, + key, + data); +} + +SR_API int ds_set_actived_device_config(const struct sr_channel *ch, + const struct sr_channel_group *cg, + int key, GVariant *data) +{ + if (lib_ctx.actived_device_instance == NULL){ + sr_err("%s", "Have no actived device."); + return SR_ERR_CALL_STATUS; + } + + return sr_config_set( + lib_ctx.actived_device_instance, + ch, + cg, + key, + data); +} + +SR_API int ds_get_actived_device_config_list(const struct sr_channel_group *cg, + int key, GVariant **data) +{ + if (lib_ctx.actived_device_instance == NULL){ + sr_err("%s", "Have no actived device."); + return SR_ERR_CALL_STATUS; + } + + return sr_config_list(lib_ctx.actived_device_instance->driver, + lib_ctx.actived_device_instance, + cg, + key, + data); +} + +SR_API const struct sr_config_info* ds_get_actived_device_config_info(int key) +{ + if (lib_ctx.actived_device_instance == NULL){ + sr_err("%s", "Have no actived device."); + return SR_ERR_CALL_STATUS; + } + + return sr_config_info_get(key); +} + +SR_API const struct sr_config_info* ds_get_actived_device_config_info_by_name(const char *optname) +{ + if (lib_ctx.actived_device_instance == NULL){ + sr_err("%s", "Have no actived device."); + return SR_ERR_CALL_STATUS; + } + return sr_config_info_name_get(optname); +} + +SR_API int ds_get_actived_device_status(struct sr_status *status, gboolean prg) +{ + if (lib_ctx.actived_device_instance == NULL){ + sr_err("%s", "Have no actived device."); + return SR_ERR_CALL_STATUS; + } + + return sr_status_get(lib_ctx.actived_device_instance, status, prg); +} + +SR_API struct sr_config *ds_new_config(int key, GVariant *data) +{ + return sr_config_new(key, data); +} + +SR_API void ds_free_config(struct sr_config *src) +{ + sr_config_free(src); +} + +/**-----------channel -------------*/ +SR_API int ds_enable_device_channel(const struct sr_channel *ch, gboolean enable) +{ + if (lib_ctx.actived_device_instance == NULL){ + return SR_ERR_CALL_STATUS; + } + return sr_enable_device_channel(lib_ctx.actived_device_instance, ch, enable); +} + +/**-------------------config end-------------------*/ + /**-------------------internal function ---------------*/ /** * Check whether the USB device is in the device list. @@ -739,7 +837,6 @@ SR_PRIV int sr_usb_device_is_exists(libusb_device *usb_dev) { GList *l; struct sr_dev_inst *dev; - struct sr_usb_dev_inst *usb_dev_info; int bFind = 0; if (usb_dev == NULL) @@ -753,8 +850,7 @@ SR_PRIV int sr_usb_device_is_exists(libusb_device *usb_dev) for (l = lib_ctx.device_list; l; l = l->next) { dev = l->data; - usb_dev_info = dev->conn; - if (dev->dev_type == DEV_TYPE_USB && usb_dev_info != NULL && usb_dev_info->usb_dev == usb_dev) + if (dev->handle == (ds_device_handle)usb_dev) { bFind = 1; } @@ -807,13 +903,14 @@ SR_PRIV int current_device_acquisition_stop() */ SR_API int ds_is_collecting() { - if (lib_ctx.collect_thread != NULL){ + if (lib_ctx.collect_thread != NULL) + { return 1; } return 0; } -/**--------------------internal function end------------------*/ +/**--------------------internal function end-----------*/ /**-------------------private function ---------------*/ @@ -832,9 +929,8 @@ static int update_device_handle(struct libusb_device *old_dev, struct libusb_dev { dev = l->data; usb_dev_info = dev->conn; - if (dev->dev_type == DEV_TYPE_USB && usb_dev_info != NULL && usb_dev_info->usb_dev == old_dev) + if (usb_dev_info != NULL && dev->handle == (ds_device_handle)old_dev) { - // Release the old device and the resource. if (dev == lib_ctx.actived_device_instance) { @@ -990,7 +1086,8 @@ static void process_attach_event() // Tell user one new device attched, and the list is updated. - if (num > 0){ + if (num > 0) + { post_event_async(DS_EV_NEW_DEVICE_ATTACH); } @@ -1003,7 +1100,6 @@ static void process_detach_event() int ev = DS_EV_INACTIVE_DEVICE_DETACH; GList *l; struct sr_dev_inst *dev; - struct sr_usb_dev_inst *usb_dev_info; struct sr_dev_driver *driver_ins; sr_info("%s", "Process device detach event."); @@ -1021,10 +1117,14 @@ static void process_detach_event() for (l = lib_ctx.device_list; l; l = l->next) { dev = l->data; - usb_dev_info = dev->conn; - if (dev->dev_type == DEV_TYPE_USB && usb_dev_info != NULL && usb_dev_info->usb_dev == ev_dev) + if (dev->handle == (ds_device_handle)ev_dev) { + if (lib_ctx.actived_device_instance != dev && ds_is_collecting()){ + sr_info("%s", "The actived device is detached, will stop collect thread."); + ds_stop_collect(); + } + // Found the device, and remove it. lib_ctx.device_list = g_slist_remove(lib_ctx.device_list, l->data); destroy_device_instance(dev); @@ -1052,11 +1152,13 @@ static void usb_hotplug_process_proc() { sr_hotplug_wait_timout(lib_ctx.sr_ctx); - if (lib_ctx.attach_event_flag){ + if (lib_ctx.attach_event_flag) + { process_attach_event(); lib_ctx.attach_event_flag = 0; } - if (lib_ctx.detach_event_flag){ + if (lib_ctx.detach_event_flag) + { process_detach_event(); lib_ctx.detach_event_flag = 0; } @@ -1067,7 +1169,8 @@ static void usb_hotplug_process_proc() { lib_ctx.check_reconnect_times++; // 500ms - if (lib_ctx.check_reconnect_times == 5){ + if (lib_ctx.check_reconnect_times == 5) + { // Device loose contact,wait for it reconnection timeout. lib_ctx.detach_event_flag = 1; // use detach event lib_ctx.is_waitting_reconnect = 0; @@ -1075,7 +1178,8 @@ static void usb_hotplug_process_proc() } } - if (lib_ctx.callback_thread_count > 0){ + if (lib_ctx.callback_thread_count > 0) + { sr_info("%d callback thread is actived, waiting all ends...", lib_ctx.callback_thread_count); } @@ -1083,7 +1187,7 @@ static void usb_hotplug_process_proc() while (lib_ctx.callback_thread_count > 0) { _sleep(100); - } + } sr_info("%s", "Hotplug thread end!"); } @@ -1139,12 +1243,14 @@ static int open_device_instance(struct sr_dev_inst *dev) static void post_event_proc(int event) { - if (lib_ctx.event_callback != NULL){ + if (lib_ctx.event_callback != NULL) + { lib_ctx.event_callback(event); } pthread_mutex_lock(&lib_ctx.mutext); - lib_ctx.callback_thread_count--;; + lib_ctx.callback_thread_count--; + ; pthread_mutex_unlock(&lib_ctx.mutext); } diff --git a/libsigrok4DSL/libsigrok-internal.h b/libsigrok4DSL/libsigrok-internal.h index f42945cc..8eb502af 100644 --- a/libsigrok4DSL/libsigrok-internal.h +++ b/libsigrok4DSL/libsigrok-internal.h @@ -225,6 +225,8 @@ SR_PRIV struct sr_channel *sr_channel_new(uint16_t index, int type, gboolean enabled, const char *name); SR_PRIV void sr_dev_probes_free(struct sr_dev_inst *sdi); +SR_PRIV int sr_enable_device_channel(struct sr_dev_inst *sdi, const struct sr_channel *probe, gboolean enable); + /* Generic device instances */ SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int index, int status, const char *vendor, const char *model, const char *version); @@ -371,5 +373,27 @@ SR_PRIV int ds_data_forward(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *packet); SR_PRIV int current_device_acquisition_stop(); + +/*--- hwdriver.c ------------------------------------------------------------*/ + +SR_PRIV int sr_config_get(const struct sr_dev_driver *driver, + const struct sr_dev_inst *sdi, + const struct sr_channel *ch, + const struct sr_channel_group *cg, + int key, GVariant **data); +SR_PRIV int sr_config_set(struct sr_dev_inst *sdi, + struct sr_channel *ch, + struct sr_channel_group *cg, + int key, GVariant *data); +SR_PRIV int sr_config_list(const struct sr_dev_driver *driver, + const struct sr_dev_inst *sdi, + const struct sr_channel_group *cg, + int key, GVariant **data); +SR_PRIV const struct sr_config_info *sr_config_info_get(int key); +SR_PRIV const struct sr_config_info *sr_config_info_name_get(const char *optname); +SR_PRIV int sr_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg); +SR_PRIV struct sr_config *sr_config_new(int key, GVariant *data); +SR_PRIV void sr_config_free(struct sr_config *src); + #endif diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index 72bb2fe1..876a2451 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -1184,29 +1184,6 @@ SR_API int sr_dev_trigger_set(const struct sr_dev_inst *sdi, uint16_t probenum, const char *trigger); -/*--- hwdriver.c ------------------------------------------------------------*/ - - -SR_API int sr_config_get(const struct sr_dev_driver *driver, - const struct sr_dev_inst *sdi, - const struct sr_channel *ch, - const struct sr_channel_group *cg, - int key, GVariant **data); -SR_API int sr_config_set(struct sr_dev_inst *sdi, - struct sr_channel *ch, - struct sr_channel_group *cg, - int key, GVariant *data); -SR_API int sr_config_list(const struct sr_dev_driver *driver, - const struct sr_dev_inst *sdi, - const struct sr_channel_group *cg, - int key, GVariant **data); -SR_API const struct sr_config_info *sr_config_info_get(int key); -SR_API const struct sr_config_info *sr_config_info_name_get(const char *optname); -SR_API int sr_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg); -SR_API struct sr_config *sr_config_new(int key, GVariant *data); -SR_API void sr_config_free(struct sr_config *src); - - /*--- input/input.c ---------------------------------------------------------*/ SR_API struct sr_input_format **sr_input_list(void); @@ -1282,7 +1259,7 @@ enum dslib_event_type DS_EV_INACTIVE_DEVICE_DETACH = 2, }; -typedef unsigned long long ds_device_handle; +typedef void* ds_device_handle; /** * Device base info @@ -1383,18 +1360,18 @@ SR_API int ds_get_actived_device_index(); */ SR_API int ds_device_from_file(const char *file_path); -/** - * Get the decive supports work mode, mode list: LOGIC、ANALOG、DSO - * return type see struct sr_dev_mode. - */ -SR_API const GSList *ds_get_device_mode_list(ds_device_handle handle); - /** * Remove one device from the list, and destory it. * User need to call ds_get_device_list() to get the new list. */ SR_API int ds_remove_device(ds_device_handle handle); +/** + * Get the decive supports work mode, mode list: LOGIC、ANALOG、DSO + * return type see struct sr_dev_mode. + */ +SR_API const GSList *ds_get_actived_device_mode_list(); + /** * Get the actived device info. * If the actived device is not exists, the handle filed will be set null. @@ -1421,6 +1398,30 @@ SR_API int ds_stop_collect(); */ SR_API int ds_is_collecting(); +/*---config -----------------------------------------------*/ +SR_API int ds_get_actived_device_config(const struct sr_channel *ch, + const struct sr_channel_group *cg, + int key, GVariant **data); + +SR_API int ds_set_actived_device_config(const struct sr_channel *ch, + const struct sr_channel_group *cg, + int key, GVariant *data); + +SR_API int ds_get_actived_device_config_list(const struct sr_channel_group *cg, + int key, GVariant **data); + +SR_API const struct sr_config_info* ds_get_actived_device_config_info(int key); + +SR_API const struct sr_config_info* ds_get_actived_device_config_info_by_name(const char *optname); + +SR_API int ds_get_actived_device_status(struct sr_status *status, gboolean prg); + +SR_API struct sr_config *ds_new_config(int key, GVariant *data); + +SR_API void ds_free_config(struct sr_config *src); + +/*----------channel----------*/ +SR_API int ds_enable_device_channel(const struct sr_channel *ch, gboolean enable); #ifdef __cplusplus }