diff --git a/DSView/main.cpp b/DSView/main.cpp index f252778d..dce0339f 100644 --- a/DSView/main.cpp +++ b/DSView/main.cpp @@ -54,9 +54,6 @@ void usage() "\n", DS_BIN_NAME, DS_DESCRIPTION); } - -int main2(); - int main(int argc, char *argv[]) { //return main2(); diff --git a/DSView/pv/appcontrol.cpp b/DSView/pv/appcontrol.cpp index f4a19a4e..0504e707 100644 --- a/DSView/pv/appcontrol.cpp +++ b/DSView/pv/appcontrol.cpp @@ -32,6 +32,8 @@ #include "dsvdef.h" #include "config/appconfig.h" #include "log.h" +#include +#include AppControl::AppControl() { @@ -80,9 +82,17 @@ bool AppControl::Init() _session->set_sr_context(sr_ctx); QString resdir = GetResourceDir(); - sr_set_firmware_resource_dir(resdir.toUtf8().data()); - + char res_path[256] = {0}; #ifdef _WIN32 + QTextCodec *codec = QTextCodec::codecForName("System"); + QByteArray str_tmp = codec->fromUnicode(resdir); + strncpy(res_path, str_tmp.data(), sizeof(res_path) - 1); +#else + strncpy(res_path, resdir.toUtf8().data(), sizeof(res_path) - 1); +#endif + sr_set_firmware_resource_dir(res_path); + +#if defined(_WIN32) && defined(DEBUG_INFO) //able run debug with qtcreator QString pythonHome = "c:/python"; QDir pydir; diff --git a/libsigrok4DSL/dsdevice.c b/libsigrok4DSL/dsdevice.c index a36c9f50..2e7a905f 100644 --- a/libsigrok4DSL/dsdevice.c +++ b/libsigrok4DSL/dsdevice.c @@ -256,8 +256,7 @@ SR_PRIV struct sr_usb_dev_inst *sr_usb_dev_inst_new(uint8_t bus, udi->bus = bus; udi->address = address; udi->devhdl = hdl; - udi->usb_dev = NULL; - udi->is_wait_re_connected = 0; + udi->usb_dev = NULL; return udi; } diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index 34780d18..d468dd1e 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -201,6 +201,8 @@ static GSList *scan(GSList *options) const char *conn; enum libusb_speed usb_speed; struct sr_usb_dev_inst *usb_dev_info; + uint8_t bus; + uint8_t address; drvc = di->priv; @@ -273,10 +275,13 @@ static GSList *scan(GSList *options) continue; if (sr_usb_device_is_exists(device_handle)){ - sr_info("Device is exists, handle: %p", device_handle); - continue;; + sr_detail("Device is exists, handle: %p", device_handle); + continue; } - sr_info("Got a new device handle: %p", device_handle); + + bus = libusb_get_bus_number(device_handle); + address = libusb_get_device_address(device_handle); + sr_info("Found a new device,handle:%p,bus:%d,address:%d", device_handle, bus, address); devcnt = g_slist_length(drvc->instances); devc = DSCope_dev_new(prof); @@ -294,6 +299,7 @@ static GSList *scan(GSList *options) sdi->priv = devc; sdi->driver = di; sdi->dev_type = DEV_TYPE_USB; + sdi->handle = (sr_device_handle)device_handle; /* Fill in probelist according to this device's profile. */ if (dsl_setup_probes(sdi, channel_modes[devc->ch_mode].num) != SR_OK){ @@ -305,10 +311,9 @@ static GSList *scan(GSList *options) if (dsl_check_conf_profile(device_handle)) { /* Already has the firmware, so fix the new address. */ - sr_info("Found a DSCope device, name: \"%s\"", prof->model); - - usb_dev_info = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle), - libusb_get_device_address(device_handle), NULL); + sr_info("Found a DSCope device,name:\"%s\",handle:%p", prof->model, device_handle); + + usb_dev_info = sr_usb_dev_inst_new(bus, address, NULL); usb_dev_info->usb_dev = device_handle; sdi->conn = usb_dev_info; sdi->status = SR_ST_INACTIVE; @@ -322,6 +327,9 @@ static GSList *scan(GSList *options) } strcpy(firmware, res_path); strcat(firmware, prof->firmware); + + sr_info("Install firmware bin file, device:\"%s\", file:\"%s\"", prof->model, firmware); + if (ezusb_upload_firmware(device_handle, USB_CONFIGURATION, firmware) == SR_OK) /* Store when this device's FW was updated. */ @@ -331,7 +339,7 @@ static GSList *scan(GSList *options) "device %d.", devcnt); g_free(firmware); - usb_dev_info = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle),0xff, NULL); + usb_dev_info = sr_usb_dev_inst_new(bus, 0xff, NULL); usb_dev_info->usb_dev = device_handle; sdi->conn = usb_dev_info; } diff --git a/libsigrok4DSL/hardware/DSL/dsl.c b/libsigrok4DSL/hardware/DSL/dsl.c index 6a20cc6c..974404a6 100644 --- a/libsigrok4DSL/hardware/DSL/dsl.c +++ b/libsigrok4DSL/hardware/DSL/dsl.c @@ -258,6 +258,7 @@ SR_PRIV gboolean dsl_check_conf_profile(libusb_device *dev) hdl = NULL; ret = FALSE; + while (!ret) { /* Assume the FW has not been loaded, unless proven wrong. */ if (libusb_get_device_descriptor(dev, &des) != 0) @@ -303,21 +304,11 @@ static int hw_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi) drvc = di->priv; devc = sdi->priv; usb = sdi->conn; - - sr_info("%s", "Try to open device instance."); - - if(usb->devhdl == NULL){ - sr_err("%s", "hw_dev_open(), usb->devhdl is null."); - return SR_ERR; - } + if (usb->usb_dev == NULL){ sr_err("%s", "hw_dev_open(), usb->usb_dev is null."); return SR_ERR; } - if (usb->is_wait_re_connected){ - sr_err("Device is waitting reconnect, handle:%p", usb->usb_dev); - return SR_ERR; - } if (sdi->status == SR_ST_ACTIVE) { /* Device is already in use. */ @@ -1293,7 +1284,7 @@ SR_PRIV int dsl_fpga_config(struct libusb_device_handle *hdl, const char *filena uint8_t rd_cmd_data; struct stat f_stat; - sr_info("Configure FPGA using %s", filename); + sr_info("Configure FPGA using \"%s\"", filename); if ((fw = fopen(filename, "rb")) == NULL) { sr_err("Unable to open FPGA bit file %s for reading: %s", filename, strerror(errno)); @@ -1933,7 +1924,7 @@ SR_PRIV int dsl_dev_close(struct sr_dev_inst *sdi) usb = sdi->conn; if (usb->devhdl == NULL){ - sr_info("%s", "dsl_dev_close(),libusb_device_handle is null."); + sr_detail("%s", "dsl_dev_close(),libusb_device_handle is null."); return SR_ERR; } diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index c674284f..be87c831 100644 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -270,6 +270,8 @@ static GSList *scan(GSList *options) const char *conn; enum libusb_speed usb_speed; struct sr_usb_dev_inst *usb_dev_info; + uint8_t bus; + uint8_t address; drvc = di->priv; @@ -343,10 +345,13 @@ static GSList *scan(GSList *options) continue; if (sr_usb_device_is_exists(device_handle)){ - sr_info("Device is exists, handle: %p", device_handle); - continue;; + sr_detail("Device is exists, handle: %p", device_handle); + continue; } - sr_info("Got a new device handle: %p", device_handle); + + bus = libusb_get_bus_number(device_handle); + address = libusb_get_device_address(device_handle); + sr_info("Found a new device,handle:%p,bus:%d,address:%d", device_handle, bus, address); devc = DSLogic_dev_new(prof); if (!devc) @@ -361,6 +366,7 @@ static GSList *scan(GSList *options) sdi->priv = devc; sdi->driver = di; sdi->dev_type = DEV_TYPE_USB; + sdi->handle = (sr_device_handle)device_handle; /* Fill in probelist according to this device's profile. */ if (dsl_setup_probes(sdi, channel_modes[devc->ch_mode].num) != SR_OK){ @@ -372,10 +378,9 @@ static GSList *scan(GSList *options) if (dsl_check_conf_profile(device_handle)) { /* Already has the firmware, so fix the new address. */ - sr_info("Found a DSLogic device,name: \"%s\"", prof->model); + sr_info("Found a DSLogic device,name:\"%s\",handle:%p", prof->model,device_handle); - usb_dev_info = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle), - libusb_get_device_address(device_handle), NULL); + usb_dev_info = sr_usb_dev_inst_new(bus, address, NULL); usb_dev_info->usb_dev = device_handle; sdi->conn = usb_dev_info; @@ -390,6 +395,9 @@ static GSList *scan(GSList *options) } strcpy(firmware, res_path); strcat(firmware, prof->firmware); + + sr_info("Install firmware bin file, device:\"%s\", file:\"%s\"", prof->model, firmware); + if (ezusb_upload_firmware(device_handle, USB_CONFIGURATION, firmware) == SR_OK) /* Store when this device's FW was updated. */ @@ -399,7 +407,7 @@ static GSList *scan(GSList *options) "device %d.", devcnt); g_free(firmware); - usb_dev_info = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle),0xff, NULL); + usb_dev_info = sr_usb_dev_inst_new(bus, 0xff, NULL); usb_dev_info->usb_dev = device_handle; sdi->conn = usb_dev_info; } diff --git a/libsigrok4DSL/hardware/common/usb.c b/libsigrok4DSL/hardware/common/usb.c index c4d4f8c6..f8c800a6 100644 --- a/libsigrok4DSL/hardware/common/usb.c +++ b/libsigrok4DSL/hardware/common/usb.c @@ -196,47 +196,3 @@ SR_PRIV GSList *sr_usb_find_usbtmc(libusb_context *usb_ctx) return devices; } -SR_PRIV int sr_usb_open(libusb_context *usb_ctx, struct sr_usb_dev_inst *usb) -{ - struct libusb_device **devlist; - struct libusb_device_descriptor des; - int ret, r, cnt, i, a, b; - - sr_dbg("Trying to open USB device %d.%d.", usb->bus, usb->address); - - if ((cnt = libusb_get_device_list(usb_ctx, &devlist)) < 0) { - sr_err("Failed to retrieve device list: %s.", - libusb_error_name(cnt)); - return SR_ERR; - } - - ret = SR_ERR; - for (i = 0; i < cnt; i++) { - if ((r = libusb_get_device_descriptor(devlist[i], &des)) < 0) { - sr_err("Failed to get device descriptor: %s.", - libusb_error_name(r)); - continue; - } - - b = libusb_get_bus_number(devlist[i]); - a = libusb_get_device_address(devlist[i]); - if (b != usb->bus || a != usb->address) - continue; - - if ((r = libusb_open(devlist[i], &usb->devhdl)) < 0) { - sr_err("Failed to open device: %s.", - libusb_error_name(r)); - break; - } - - sr_dbg("Opened USB device (VID:PID = %04x:%04x, bus.address = " - "%d.%d).", des.idVendor, des.idProduct, b, a); - - ret = SR_OK; - break; - } - - libusb_free_device_list(devlist, 1); - - return ret; -} diff --git a/libsigrok4DSL/lib_main.c b/libsigrok4DSL/lib_main.c index e5d179ad..ac8addd5 100644 --- a/libsigrok4DSL/lib_main.c +++ b/libsigrok4DSL/lib_main.c @@ -52,12 +52,15 @@ struct sr_lib_context int check_reconnect_times; struct libusb_device *attach_device_handle; struct libusb_device *detach_device_handle; - struct sr_device_info current_device; + struct sr_device_info current_device_info; + struct sr_dev_inst *current_device_instance; }; static void hotplug_event_listen_callback(struct libusb_context *ctx, struct libusb_device *dev, int event); static void usb_hotplug_process_proc(); static void destroy_device_instance(struct sr_dev_inst *dev); +static void close_device_instance(struct sr_dev_inst *dev); +static int open_device_instance(struct sr_dev_inst *dev); static struct sr_lib_context lib_ctx = { .event_callback = NULL, @@ -71,12 +74,13 @@ static struct sr_lib_context lib_ctx = { .check_reconnect_times = 0, .attach_device_handle = NULL, .detach_device_handle = NULL, - .current_device = { - .handle = NULL, + .current_device_info = { + .handle = 0, .name[0] = '\0', .is_current = 0, .dev_type = DEV_TYPE_UNKOWN, }, + .current_device_instance = NULL, }; /** @@ -177,7 +181,7 @@ SR_API void sr_set_firmware_resource_dir(const char *dir) DS_RES_PATH[len + 1] = 0; } - sr_info("Firmware resource path:%s", DS_RES_PATH); + sr_info("Firmware resource path:\"%s\"", DS_RES_PATH); } } @@ -227,7 +231,7 @@ SR_API int sr_device_get_list(struct sr_device_info** out_list, int *out_count) p->handle = dev->handle; strncpy(p->name, dev->name, sizeof(dev->name) - 1); p->dev_type = dev->dev_type; - p->is_current = (dev->handle == lib_ctx.current_device.handle); + p->is_current = (dev == lib_ctx.current_device_instance); p++; } @@ -244,6 +248,114 @@ SR_API int sr_device_get_list(struct sr_device_info** out_list, int *out_count) return SR_OK; } +/** + * Active a device, if success, it will trigs the event of SR_EV_CURRENT_DEVICE_CHANGED. + */ +SR_API int sr_device_select(sr_device_handle handle) +{ + GList *l; + struct sr_dev_inst *dev; + int bFind = 0; + int ret; + + if (handle == NULL){ + return SR_ERR_ARG; + } + ret = SR_OK; + + sr_info("%s", "Begin set current device."); + + pthread_mutex_lock(&lib_ctx.mutext); + + if (lib_ctx.current_device_instance != NULL) { + + sr_info("Close the previous device \"%s\"", lib_ctx.current_device_instance->name); + + close_device_instance(lib_ctx.current_device_instance); + lib_ctx.current_device_instance = NULL; + lib_ctx.current_device_info.handle = NULL; + lib_ctx.current_device_info.name[0] = '\0'; + } + + // To open the new. + for (l = lib_ctx.device_list; l; l = l->next){ + dev = l->data; + if (dev->handle == handle){ + bFind = 1; + + if (dev->dev_type == DEV_TYPE_USB && DS_RES_PATH[0] == '\0'){ + sr_err("%s", "Please call sr_set_firmware_resource_dir() to set the firmware resource path."); + } + + sr_info("Switch \"%s\" to current device.", dev->name); + + if (open_device_instance(dev) == SR_OK) + { + lib_ctx.current_device_info.handle = dev->handle; + lib_ctx.current_device_info.dev_type = dev->dev_type; + lib_ctx.current_device_info.is_current = 1; + strncpy(lib_ctx.current_device_info.name, dev->name, sizeof(lib_ctx.current_device_info.name) - 1); + lib_ctx.current_device_instance = dev; + } + else{ + sr_err("%s", "Open device error!"); + ret = SR_ERR_CALL_STATUS; + } + break; + } + } + + pthread_mutex_unlock(&lib_ctx.mutext); + + sr_info("%s", "End of setting current device."); + + if (!bFind){ + sr_err("sr_device_select() error, can't find the device."); + return SR_ERR_CALL_STATUS; + } + + return ret; +} + +/** + * Active a device, if success, it will trigs the event of SR_EV_CURRENT_DEVICE_CHANGED. + * @index is -1, will select the last one. + */ +SR_API int sr_device_select_by_index(int index) +{ + GList *l; + struct sr_dev_inst *dev; + sr_device_handle handle = NULL; + sr_device_handle lst_handle = NULL; + int i=0; + + pthread_mutex_lock(&lib_ctx.mutext); + + // Get index + for (l = lib_ctx.device_list; l; l = l->next){ + dev = l->data; + lst_handle = dev->handle; + + if (index == i){ + handle = dev->handle; + break; + } + ++i; + } + pthread_mutex_unlock(&lib_ctx.mutext); + + if (index == -1){ + handle = lst_handle; // Get the last one. + } + + if (handle == NULL){ + sr_err("%s", "sr_device_select_by_index(), index is error!"); + return SR_ERR_CALL_STATUS; + } + + return sr_device_select(handle); +} + /**-------------------internal function ---------------*/ /** * Check whether the USB device is in the device list. @@ -299,6 +411,9 @@ SR_API int sr_remove_device(sr_device_handle handle) lib_ctx.device_list = g_slist_remove(lib_ctx.device_list, l->data); destroy_device_instance(dev); bFind = 1; + if (dev == lib_ctx.current_device_instance){ + lib_ctx.current_device_instance = NULL; + } break; } } @@ -325,11 +440,11 @@ SR_API int sr_get_current_device_info(struct sr_device_info *info) info->is_current = 0; info->dev_type = DEV_TYPE_UNKOWN; - if (lib_ctx.current_device.handle != NULL){ - info->handle = lib_ctx.current_device.handle; - strncpy(info->name, lib_ctx.current_device.name, sizeof(info->name)); + if (lib_ctx.current_device_info.handle != NULL){ + info->handle = lib_ctx.current_device_info.handle; + strncpy(info->name, lib_ctx.current_device_info.name, sizeof(info->name)); info->is_current = 1; - info->dev_type = lib_ctx.current_device.dev_type; + info->dev_type = lib_ctx.current_device_info.dev_type; } return SR_OK; @@ -340,11 +455,11 @@ SR_API int sr_get_current_device_info(struct sr_device_info *info) static int update_device_handle(struct libusb_device *old_dev, struct libusb_device *new_dev) { GList *l; - struct sr_dev_inst *dev; + struct sr_dev_inst *dev; struct sr_usb_dev_inst *usb_dev_info; - int bFind = 0; uint8_t bus; - uint8_t address; + uint8_t address; + int bFind = 0; pthread_mutex_lock(&lib_ctx.mutext); @@ -354,24 +469,37 @@ static int update_device_handle(struct libusb_device *old_dev, struct libusb_dev if (dev->dev_type == DEV_TYPE_USB && usb_dev_info != NULL && usb_dev_info->usb_dev == old_dev){ + + // Release the old device and the resource. + if (dev == lib_ctx.current_device_instance){ + sr_info("%s", "Release the old device's resource."); + close_device_instance(dev); + } bus = libusb_get_bus_number(new_dev); address = libusb_get_device_address(new_dev); - - if (bus == usb_dev_info->bus && address == usb_dev_info->address){ - bFind = 1; - usb_dev_info->usb_dev = new_dev; - } - else{ - sr_err("Try to update the device handle, but the bus and addres is not the same!"); - } + usb_dev_info->usb_dev = new_dev; + usb_dev_info->bus = bus; + usb_dev_info->address = address; + dev->handle = new_dev; + bFind = 1; + // Reopen the device. + if (dev == lib_ctx.current_device_instance){ + sr_info("%s", "Reopen the current device."); + open_device_instance(dev); + } break; } } pthread_mutex_unlock(&lib_ctx.mutext); - return bFind; + + if (bFind){ + return SR_OK; + } + + return SR_ERR; } static void hotplug_event_listen_callback(struct libusb_context *ctx, struct libusb_device *dev, int event) @@ -384,7 +512,7 @@ static void hotplug_event_listen_callback(struct libusb_context *ctx, struct lib } if (event == USB_EV_HOTPLUG_ATTACH){ - sr_info("One device attached, handle:%p", dev); + sr_info("One device attached,handle:%p", dev); if (lib_ctx.is_waitting_reconnect){ if (lib_ctx.attach_device_handle != NULL){ @@ -396,7 +524,7 @@ static void hotplug_event_listen_callback(struct libusb_context *ctx, struct lib sr_err("%s", "The detached device handle is null, but the status is waitting for reconnect."); } else{ - if (update_device_handle(lib_ctx.detach_device_handle, dev)){ + if (update_device_handle(lib_ctx.detach_device_handle, dev) != SR_OK){ bDone = 1; sr_info("%s", "One device loose contact, but it reconnect success."); } @@ -419,6 +547,10 @@ static void hotplug_event_listen_callback(struct libusb_context *ctx, struct lib sr_err("One detached device haven't processed complete,handle:%p", lib_ctx.detach_device_handle); } + + if (lib_ctx.current_device_info.handle != NULL && lib_ctx.current_device_info.dev_type == DEV_TYPE_USB){ + + } /** * Begin to wait the device reconnect, if timeout, will process the detach event. */ @@ -440,7 +572,7 @@ static void process_attach_event() struct sr_dev_driver *dr; int num = 0; - sr_info("%s", "Process device attch event."); + sr_info("%s", "Process device attach event."); if (lib_ctx.attach_device_handle == NULL){ sr_err("%s", "The attached device handle is null."); @@ -519,7 +651,7 @@ static void process_detach_event() } pthread_mutex_unlock(&lib_ctx.mutext); - if (ev_dev == lib_ctx.current_device.handle) + if (ev_dev == lib_ctx.current_device_info.handle) ev = SR_EV_CURRENT_DEVICE_DETACH; if (lib_ctx.event_callback != NULL){ @@ -577,3 +709,33 @@ static void destroy_device_instance(struct sr_dev_inst *dev) else if (driver_ins->dev_close) driver_ins->dev_close(dev); } + +static void close_device_instance(struct sr_dev_inst *dev) +{ + if (dev == NULL || dev->driver == NULL){ + sr_err("%s", "close_device_instance() argument error."); + return; + } + struct sr_dev_driver *driver_ins; + driver_ins = dev->driver; + + if (driver_ins->dev_close) + driver_ins->dev_close(dev); +} + +static int open_device_instance(struct sr_dev_inst *dev) +{ + if (dev == NULL || dev->driver == NULL){ + sr_err("%s", "open_device_instance() argument error."); + return SR_ERR_ARG; + } + struct sr_dev_driver *driver_ins; + driver_ins = dev->driver; + + if (driver_ins->dev_open){ + driver_ins->dev_open(dev); + return SR_OK; + } + + return SR_ERR_CALL_STATUS; +} diff --git a/libsigrok4DSL/libsigrok-internal.h b/libsigrok4DSL/libsigrok-internal.h index 32df7c0b..df207fd3 100644 --- a/libsigrok4DSL/libsigrok-internal.h +++ b/libsigrok4DSL/libsigrok-internal.h @@ -183,7 +183,6 @@ struct sr_usb_dev_inst { uint8_t address; struct libusb_device_handle *devhdl; struct libusb_device *usb_dev; - int is_wait_re_connected; }; #define SERIAL_PARITY_NONE 0 @@ -341,8 +340,7 @@ SR_PRIV int ezusb_upload_firmware(libusb_device *dev, int configuration, /*--- hardware/common/usb.c -------------------------------------------------*/ -SR_PRIV GSList *sr_usb_find(libusb_context *usb_ctx, const char *conn); -SR_PRIV int sr_usb_open(libusb_context *usb_ctx, struct sr_usb_dev_inst *usb); +SR_PRIV GSList *sr_usb_find(libusb_context *usb_ctx, const char *conn); /*--- backend.c -------------------------------------------------------------*/ SR_PRIV int sr_init(struct sr_context **ctx); diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index 05b56da6..13ef5319 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -1430,7 +1430,7 @@ SR_API int sr_device_start_collect(); /** * Stop collect data */ -SR_API int sr_device_top_collect(); +SR_API int sr_device_stop_collect(); #ifdef __cplusplus