X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fhantek-dso%2Fapi.c;h=addc29032c27a99527d572f2293824a118a744cc;hb=c259726a161411a7fe955dd139fce374635ddf7c;hp=dc8dbef87b8823eab3886e0daab6155734d67a6d;hpb=40dda2c3a509e9e031078427e32249e2ebc33ec5;p=libsigrok.git diff --git a/hardware/hantek-dso/api.c b/hardware/hantek-dso/api.c index dc8dbef8..addc2903 100644 --- a/hardware/hantek-dso/api.c +++ b/hardware/hantek-dso/api.c @@ -145,17 +145,31 @@ static const char *coupling[] = { }; SR_PRIV libusb_context *usb_context = NULL; -SR_PRIV GSList *dev_insts = NULL; +SR_PRIV struct sr_dev_driver hantek_dso_driver_info; +static struct sr_dev_driver *hdi = &hantek_dso_driver_info; static struct sr_dev_inst *dso_dev_new(int index, const struct dso_profile *prof) { struct sr_dev_inst *sdi; + struct sr_probe *probe; struct context *ctx; + int i; sdi = sr_dev_inst_new(index, SR_ST_INITIALIZING, prof->vendor, prof->model, NULL); if (!sdi) return NULL; + sdi->driver = hdi; + + /* Add only the real probes -- EXT isn't a source of data, only + * a trigger source internal to the device. + */ + for (i = 0; probe_names[i]; i++) { + if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, + probe_names[i]))) + return NULL; + sdi->probes = g_slist_append(sdi->probes, probe); + } if (!(ctx = g_try_malloc0(sizeof(struct context)))) { sr_err("hantek-dso: ctx malloc failed"); @@ -178,7 +192,7 @@ static struct sr_dev_inst *dso_dev_new(int index, const struct dso_profile *prof ctx->triggersource = g_strdup(DEFAULT_TRIGGER_SOURCE); ctx->triggerposition = DEFAULT_HORIZ_TRIGGERPOS; sdi->priv = ctx; - dev_insts = g_slist_append(dev_insts, sdi); + hdi->instances = g_slist_append(hdi->instances, sdi); return sdi; } @@ -191,35 +205,78 @@ static int configure_probes(struct context *ctx, const GSList *probes) ctx->ch1_enabled = ctx->ch2_enabled = FALSE; for (l = probes; l; l = l->next) { probe = (struct sr_probe *)l->data; - if (probe->index == 1) + if (probe->index == 0) ctx->ch1_enabled = probe->enabled; - else if (probe->index == 2) + else if (probe->index == 1) ctx->ch2_enabled = probe->enabled; } return SR_OK; } -static int hw_init(void) +/* Properly close and free all devices. */ +static void clear_instances(void) { struct sr_dev_inst *sdi; - struct libusb_device_descriptor des; - const struct dso_profile *prof; struct context *ctx; - libusb_device **devlist; - int err, devcnt, i, j; + GSList *l; + + for (l = hdi->instances; l; l = l->next) { + if (!(sdi = l->data)) { + /* Log error, but continue cleaning up the rest. */ + sr_err("hantek-dso: %s: sdi was NULL, continuing", __func__); + continue; + } + if (!(ctx = sdi->priv)) { + /* Log error, but continue cleaning up the rest. */ + sr_err("hantek-dso: %s: sdi->priv was NULL, continuing", __func__); + continue; + } + dso_close(sdi); + sr_usb_dev_inst_free(ctx->usb); + g_free(ctx->triggersource); + + sr_dev_inst_free(sdi); + } + + g_slist_free(hdi->instances); + hdi->instances = NULL; + +} + +static int hw_init(void) +{ if (libusb_init(&usb_context) != 0) { sr_err("hantek-dso: Failed to initialize USB."); - return 0; + return SR_ERR; } - /* Find all Hantek DSO devices and upload firmware to all of them. */ + return SR_OK; +} + +static GSList *hw_scan(GSList *options) +{ + struct sr_dev_inst *sdi; + const struct dso_profile *prof; + struct context *ctx; + GSList *devices; + struct libusb_device_descriptor des; + libusb_device **devlist; + int devcnt, ret, i, j; + + (void)options; devcnt = 0; + devices = 0; + hdi->instances = NULL; + + clear_instances(); + + /* Find all Hantek DSO devices and upload firmware to all of them. */ libusb_get_device_list(usb_context, &devlist); for (i = 0; devlist[i]; i++) { - if ((err = libusb_get_device_descriptor(devlist[i], &des))) { - sr_err("hantek-dso: failed to get device descriptor: %d", err); + if ((ret = libusb_get_device_descriptor(devlist[i], &des))) { + sr_err("hantek-dso: failed to get device descriptor: %d", ret); continue; } @@ -231,6 +288,7 @@ static int hw_init(void) prof = &dev_profiles[j]; sr_dbg("hantek-dso: Found a %s %s.", prof->vendor, prof->model); sdi = dso_dev_new(devcnt, prof); + devices = g_slist_append(devices, sdi); ctx = sdi->priv; if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, prof->firmware) == SR_OK) @@ -251,6 +309,7 @@ static int hw_init(void) sr_dbg("hantek-dso: Found a %s %s.", prof->vendor, prof->model); sdi = dso_dev_new(devcnt, prof); sdi->status = SR_ST_INACTIVE; + devices = g_slist_append(devices, sdi); ctx = sdi->priv; ctx->usb = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), @@ -265,18 +324,15 @@ static int hw_init(void) } libusb_free_device_list(devlist, 1); - return devcnt; + return devices; } -static int hw_dev_open(int dev_index) +static int hw_dev_open(struct sr_dev_inst *sdi) { - struct sr_dev_inst *sdi; struct context *ctx; int64_t timediff_us, timediff_ms; int err; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return SR_ERR_ARG; ctx = sdi->priv; /* @@ -290,7 +346,7 @@ static int hw_dev_open(int dev_index) g_usleep(300 * 1000); timediff_ms = 0; while (timediff_ms < MAX_RENUM_DELAY_MS) { - if ((err = dso_open(dev_index)) == SR_OK) + if ((err = dso_open(sdi)) == SR_OK) break; g_usleep(100 * 1000); timediff_us = g_get_monotonic_time() - ctx->fw_updated; @@ -299,7 +355,7 @@ static int hw_dev_open(int dev_index) } sr_info("hantek-dso: device came back after %d ms", timediff_ms); } else { - err = dso_open(dev_index); + err = dso_open(sdi); } if (err != SR_OK) { @@ -316,12 +372,8 @@ static int hw_dev_open(int dev_index) return SR_OK; } -static int hw_dev_close(int dev_index) +static int hw_dev_close(struct sr_dev_inst *sdi) { - struct sr_dev_inst *sdi; - - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return SR_ERR_ARG; dso_close(sdi); @@ -330,31 +382,8 @@ static int hw_dev_close(int dev_index) static int hw_cleanup(void) { - GSList *l; - struct sr_dev_inst *sdi; - struct context *ctx; - - /* Properly close and free all devices. */ - for (l = dev_insts; l; l = l->next) { - if (!(sdi = l->data)) { - /* Log error, but continue cleaning up the rest. */ - sr_err("hantek-dso: %s: sdi was NULL, continuing", __func__); - continue; - } - if (!(ctx = sdi->priv)) { - /* Log error, but continue cleaning up the rest. */ - sr_err("hantek-dso: %s: sdi->priv was NULL, continuing", __func__); - continue; - } - dso_close(sdi); - sr_usb_dev_inst_free(ctx->usb); - g_free(ctx->triggersource); - - sr_dev_inst_free(sdi); - } - g_slist_free(dev_insts); - dev_insts = NULL; + clear_instances(); if (usb_context) libusb_exit(usb_context); @@ -363,71 +392,55 @@ static int hw_cleanup(void) return SR_OK; } -static const void *hw_dev_info_get(int dev_index, int dev_info_id) +static int hw_info_get(int info_id, const void **data, + const struct sr_dev_inst *sdi) { - struct sr_dev_inst *sdi; - const void *info; uint64_t tmp; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return NULL; + (void)sdi; - info = NULL; - switch (dev_info_id) { - case SR_DI_INST: - info = sdi; + switch (info_id) { + case SR_DI_HWCAPS: + *data = hwcaps; break; case SR_DI_NUM_PROBES: - info = GINT_TO_POINTER(NUM_PROBES); + *data = GINT_TO_POINTER(NUM_PROBES); break; case SR_DI_PROBE_NAMES: - info = probe_names; + *data = probe_names; break; case SR_DI_BUFFERSIZES: - info = buffersizes; + *data = buffersizes; break; case SR_DI_TIMEBASES: - info = timebases; + *data = timebases; break; case SR_DI_TRIGGER_SOURCES: - info = trigger_sources; + *data = trigger_sources; break; case SR_DI_FILTERS: - info = filter_targets; + *data = filter_targets; break; case SR_DI_VDIVS: - info = vdivs; + *data = vdivs; break; case SR_DI_COUPLING: - info = coupling; + *data = coupling; break; /* TODO remove this */ case SR_DI_CUR_SAMPLERATE: - info = &tmp; + *data = &tmp; break; + default: + return SR_ERR_ARG; } - return info; -} - -static int hw_dev_status_get(int dev_index) -{ - struct sr_dev_inst *sdi; - - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return SR_ST_NOT_FOUND; - - return sdi->status; -} - -static const int *hw_hwcap_get_all(void) -{ - return hwcaps; + return SR_OK; } -static int hw_dev_config_set(int dev_index, int hwcap, const void *value) +static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap, + const void *value) { - struct sr_dev_inst *sdi; struct context *ctx; struct sr_rational tmp_rat; float tmp_float; @@ -435,9 +448,6 @@ static int hw_dev_config_set(int dev_index, int hwcap, const void *value) int ret, i; char **targets; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return SR_ERR; - if (sdi->status != SR_ST_ACTIVE) return SR_ERR; @@ -778,19 +788,16 @@ static int handle_event(int fd, int revents, void *cb_data) return TRUE; } -static int hw_dev_acquisition_start(int dev_index, void *cb_data) +static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, + void *cb_data) { const struct libusb_pollfd **lupfd; struct sr_datafeed_packet packet; struct sr_datafeed_header header; struct sr_datafeed_meta_analog meta; - struct sr_dev_inst *sdi; struct context *ctx; int i; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return SR_ERR; - if (sdi->status != SR_ST_ACTIVE) return SR_ERR; @@ -829,15 +836,12 @@ static int hw_dev_acquisition_start(int dev_index, void *cb_data) /* TODO: doesn't really cancel pending transfers so they might come in after * SR_DF_END is sent. */ -static int hw_dev_acquisition_stop(int dev_index, void *cb_data) +static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi, + void *cb_data) { struct sr_datafeed_packet packet; - struct sr_dev_inst *sdi; struct context *ctx; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return SR_ERR; - if (sdi->status != SR_ST_ACTIVE) return SR_ERR; @@ -856,12 +860,12 @@ SR_PRIV struct sr_dev_driver hantek_dso_driver_info = { .api_version = 1, .init = hw_init, .cleanup = hw_cleanup, + .scan = hw_scan, .dev_open = hw_dev_open, .dev_close = hw_dev_close, - .dev_info_get = hw_dev_info_get, - .dev_status_get = hw_dev_status_get, - .hwcap_get_all = hw_hwcap_get_all, + .info_get = hw_info_get, .dev_config_set = hw_dev_config_set, .dev_acquisition_start = hw_dev_acquisition_start, .dev_acquisition_stop = hw_dev_acquisition_stop, + .instances = NULL, };