X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fhantek-dso%2Fapi.c;h=0847da558aabbacb361a4b6db3538514a199aecf;hb=47f4f073e0a7fe68a55001180c3c9092551f2108;hp=31b52509b2fbbab2cca31344b72328ffad70f38e;hpb=269971ddce18664a2ad06b7e2f56dcad70d155bb;p=libsigrok.git diff --git a/hardware/hantek-dso/api.c b/hardware/hantek-dso/api.c index 31b52509..0847da55 100644 --- a/hardware/hantek-dso/api.c +++ b/hardware/hantek-dso/api.c @@ -31,7 +31,6 @@ #include #include "libsigrok.h" #include "libsigrok-internal.h" -#include "config.h" #include "dso.h" @@ -146,8 +145,7 @@ static const char *coupling[] = { SR_PRIV struct sr_dev_driver hantek_dso_driver_info; static struct sr_dev_driver *hdi = &hantek_dso_driver_info; -static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi, - void *cb_data); +static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data); static struct sr_dev_inst *dso_dev_new(int index, const struct dso_profile *prof) { @@ -200,13 +198,16 @@ static struct sr_dev_inst *dso_dev_new(int index, const struct dso_profile *prof return sdi; } -static int configure_probes(struct dev_context *devc, const GSList *probes) +static int configure_probes(const struct sr_dev_inst *sdi) { + struct dev_context *devc; const struct sr_probe *probe; const GSList *l; + devc = sdi->priv; + devc->ch1_enabled = devc->ch2_enabled = FALSE; - for (l = probes; l; l = l->next) { + for (l = sdi->probes; l; l = l->next) { probe = (struct sr_probe *)l->data; if (probe->index == 0) devc->ch1_enabled = probe->enabled; @@ -218,7 +219,7 @@ static int configure_probes(struct dev_context *devc, const GSList *probes) } /* Properly close and free all devices. */ -static void clear_instances(void) +static int clear_instances(void) { struct sr_dev_inst *sdi; struct drv_context *drvc; @@ -247,6 +248,7 @@ static void clear_instances(void) g_slist_free(drvc->instances); drvc->instances = NULL; + return SR_OK; } static int hw_init(void) @@ -255,10 +257,10 @@ static int hw_init(void) if (!(drvc = g_try_malloc0(sizeof(struct drv_context)))) { sr_err("hantek-dso: driver context malloc failed."); - return SR_ERR; + return SR_ERR_MALLOC; } - if (libusb_init(&drvc->usb_context) != 0) { + if (libusb_init(NULL) != 0) { g_free(drvc); sr_err("hantek-dso: Failed to initialize USB."); return SR_ERR; @@ -289,7 +291,7 @@ static GSList *hw_scan(GSList *options) clear_instances(); /* Find all Hantek DSO devices and upload firmware to all of them. */ - libusb_get_device_list(drvc->usb_context, &devlist); + libusb_get_device_list(NULL, &devlist); for (i = 0; devlist[i]; i++) { if ((ret = libusb_get_device_descriptor(devlist[i], &des))) { sr_err("hantek-dso: failed to get device descriptor: %d", ret); @@ -343,6 +345,15 @@ static GSList *hw_scan(GSList *options) return devices; } +static GSList *hw_dev_list(void) +{ + struct drv_context *drvc; + + drvc = hdi->priv; + + return drvc->instances; +} + static int hw_dev_open(struct sr_dev_inst *sdi) { struct dev_context *devc; @@ -405,9 +416,7 @@ static int hw_cleanup(void) clear_instances(); - if (drvc->usb_context) - libusb_exit(drvc->usb_context); - drvc->usb_context = NULL; + libusb_exit(NULL); return SR_OK; } @@ -477,9 +486,6 @@ static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap, case SR_HWCAP_LIMIT_FRAMES: devc->limit_frames = *(const uint64_t *)value; break; - case SR_HWCAP_PROBECONFIG: - ret = configure_probes(devc, (const GSList *)value); - break; case SR_HWCAP_TRIGGER_SLOPE: tmp_u64 = *(const int *)value; if (tmp_u64 != SLOPE_NEGATIVE && tmp_u64 != SLOPE_POSITIVE) @@ -595,6 +601,7 @@ static void send_chunk(struct dev_context *devc, unsigned char *buf, analog.num_samples = num_samples; analog.mq = SR_MQ_VOLTAGE; analog.unit = SR_UNIT_VOLT; + /* TODO: Check malloc return value. */ analog.data = g_try_malloc(analog.num_samples * sizeof(float) * num_probes); data_offset = 0; for (i = 0; i < analog.num_samples; i++) { @@ -709,9 +716,7 @@ static void receive_transfer(struct libusb_transfer *transfer) if (devc->limit_frames && ++devc->num_frames == devc->limit_frames) { /* Terminate session */ - /* TODO: don't leave pending USB transfers hanging */ - packet.type = SR_DF_END; - sr_session_send(ctx->cb_data, &packet); + devc->dev_state = STOPPING; } else { devc->dev_state = NEW_CAPTURE; } @@ -721,11 +726,12 @@ static void receive_transfer(struct libusb_transfer *transfer) static int handle_event(int fd, int revents, void *cb_data) { + const struct sr_dev_inst *sdi; struct sr_datafeed_packet packet; struct timeval tv; - int num_probes; - struct drv_context *drvc; struct dev_context *devc; + const struct libusb_pollfd **lupfd; + int num_probes, i; uint32_t trigger_offset; uint8_t capturestate; @@ -733,14 +739,30 @@ static int handle_event(int fd, int revents, void *cb_data) (void)fd; (void)revents; - drvc = hdi->priv; sdi = cb_data; devc = sdi->priv; + if (devc->dev_state == STOPPING) { + /* We've been told to wind up the acquisition. */ + sr_dbg("hantek-dso: stopping acquisition"); + /* TODO: doesn't really cancel pending transfers so they might + * come in after SR_DF_END is sent. */ + lupfd = libusb_get_pollfds(NULL); + for (i = 0; lupfd[i]; i++) + sr_source_remove(lupfd[i]->fd); + free(lupfd); + + packet.type = SR_DF_END; + sr_session_send(sdi, &packet); + + devc->dev_state = IDLE; + + return TRUE; + } + /* Always handle pending libusb events. */ tv.tv_sec = tv.tv_usec = 0; - libusb_handle_events_timeout(drvc->usb_context, &tv); + libusb_handle_events_timeout(NULL, &tv); - ctx = cb_data; /* TODO: ugh */ if (devc->dev_state == NEW_CAPTURE) { if (dso_capture_start(devc) != SR_OK) @@ -782,6 +804,7 @@ static int handle_event(int fd, int revents, void *cb_data) devc->trigger_offset = trigger_offset; num_probes = (devc->ch1_enabled && devc->ch2_enabled) ? 2 : 1; + /* TODO: Check malloc return value. */ devc->framebuf = g_try_malloc(devc->framesize * num_probes * 2); devc->samp_buffered = devc->samp_received = 0; @@ -819,17 +842,20 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, struct sr_datafeed_packet packet; struct sr_datafeed_header header; struct sr_datafeed_meta_analog meta; - struct drv_context *drvc; struct dev_context *devc; int i; - drvc = hdi->priv; if (sdi->status != SR_ST_ACTIVE) return SR_ERR; devc = sdi->priv; devc->cb_data = cb_data; + if (configure_probes(sdi) != SR_OK) { + sr_err("hantek-dso: failed to configured probes"); + return SR_ERR; + } + if (dso_init(devc) != SR_OK) return SR_ERR; @@ -837,10 +863,10 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, return SR_ERR; devc->dev_state = CAPTURE; - lupfd = libusb_get_pollfds(drvc->usb_context); + lupfd = libusb_get_pollfds(NULL); for (i = 0; lupfd[i]; i++) sr_source_add(lupfd[i]->fd, lupfd[i]->events, TICK, handle_event, - ctx); + (void *)sdi); free(lupfd); /* Send header packet to the session bus. */ @@ -859,11 +885,7 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, return SR_OK; } -/* TODO: doesn't really cancel pending transfers so they might come in after - * SR_DF_END is sent. - */ -static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi, - void *cb_data) +static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data) { struct dev_context *devc; @@ -872,11 +894,8 @@ static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi, if (sdi->status != SR_ST_ACTIVE) return SR_ERR; - ctx = sdi->priv; - ctx->dev_state = IDLE; - - packet.type = SR_DF_END; - sr_session_send(cb_data, &packet); + devc = sdi->priv; + devc->dev_state = STOPPING; return SR_OK; } @@ -888,6 +907,8 @@ SR_PRIV struct sr_dev_driver hantek_dso_driver_info = { .init = hw_init, .cleanup = hw_cleanup, .scan = hw_scan, + .dev_list = hw_dev_list, + .dev_clear = clear_instances, .dev_open = hw_dev_open, .dev_close = hw_dev_close, .info_get = hw_info_get,