X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fdslogic%2Fapi.c;h=8e49c92adc368d44c371be9b6a004863e696f416;hb=4bd770f56b1658d0d17e4b15f808d0a98bf6e325;hp=d5899d55d67b5a2573ac389b806124e23c540f48;hpb=adcb9951f8a52852e65f99d45083a3e6b9a1981a;p=libsigrok.git diff --git a/src/hardware/dslogic/api.c b/src/hardware/dslogic/api.c index d5899d55..8e49c92a 100644 --- a/src/hardware/dslogic/api.c +++ b/src/hardware/dslogic/api.c @@ -19,55 +19,30 @@ */ #include -#include "protocol.h" -#include "dslogic.h" #include +#include "protocol.h" static const struct dslogic_profile supported_device[] = { - /* DreamSourceLab DSLogic (before FW upload) */ - { 0x2a0e, 0x0001, "DreamSourceLab", "DSLogic", NULL, - "dreamsourcelab-dslogic-fx2.fw", - 0, NULL, NULL}, - /* DreamSourceLab DSLogic (after FW upload) */ + /* DreamSourceLab DSLogic */ { 0x2a0e, 0x0001, "DreamSourceLab", "DSLogic", NULL, "dreamsourcelab-dslogic-fx2.fw", - 0, "DreamSourceLab", "DSLogic"}, - - /* DreamSourceLab DSCope (before FW upload) */ - { 0x2a0e, 0x0002, "DreamSourceLab", "DSCope", NULL, - "dreamsourcelab-dscope-fx2.fw", - 0, NULL, NULL}, - /* DreamSourceLab DSCope (after FW upload) */ + 0, "DreamSourceLab", "DSLogic", 256 * 1048576ULL}, + /* DreamSourceLab DSCope */ { 0x2a0e, 0x0002, "DreamSourceLab", "DSCope", NULL, "dreamsourcelab-dscope-fx2.fw", - 0, "DreamSourceLab", "DSCope"}, - - /* DreamSourceLab DSLogic Pro (before FW upload) */ + 0, "DreamSourceLab", "DSCope", 256 * 1048576ULL}, + /* DreamSourceLab DSLogic Pro */ { 0x2a0e, 0x0003, "DreamSourceLab", "DSLogic Pro", NULL, "dreamsourcelab-dslogic-pro-fx2.fw", - 0, NULL, NULL}, - /* DreamSourceLab DSLogic Pro (after FW upload) */ - { 0x2a0e, 0x0003, "DreamSourceLab", "DSLogic Pro", NULL, - "dreamsourcelab-dslogic-pro-fx2.fw", - 0, "DreamSourceLab", "DSLogic"}, - - /* DreamSourceLab DSLogic Plus (before FW upload) */ - { 0x2a0e, 0x0020, "DreamSourceLab", "DSLogic Plus", NULL, - "dreamsourcelab-dslogic-plus-fx2.fw", - 0, NULL, NULL}, - /* DreamSourceLab DSLogic Plus (after FW upload) */ + 0, "DreamSourceLab", "DSLogic", 256 * 1048576ULL}, + /* DreamSourceLab DSLogic Plus */ { 0x2a0e, 0x0020, "DreamSourceLab", "DSLogic Plus", NULL, "dreamsourcelab-dslogic-plus-fx2.fw", - 0, "DreamSourceLab", "DSLogic"}, - - /* DreamSourceLab DSLogic Basic (before FW upload) */ - { 0x2a0e, 0x0021, "DreamSourceLab", "DSLogic Basic", NULL, - "dreamsourcelab-dslogic-basic-fx2.fw", - 0, NULL, NULL}, - /* DreamSourceLab DSLogic Basic (after FW upload) */ + 0, "DreamSourceLab", "DSLogic", 256 * 1048576ULL}, + /* DreamSourceLab DSLogic Basic */ { 0x2a0e, 0x0021, "DreamSourceLab", "DSLogic Basic", NULL, "dreamsourcelab-dslogic-basic-fx2.fw", - 0, "DreamSourceLab", "DSLogic"}, + 0, "DreamSourceLab", "DSLogic", 256 * 1024ULL}, ALL_ZERO }; @@ -99,12 +74,11 @@ static const char *const signal_edge_names[] = { }; static const struct { - int range; gdouble low; gdouble high; -} volt_thresholds[] = { - { DS_VOLTAGE_RANGE_18_33_V, 0.7, 1.4 }, - { DS_VOLTAGE_RANGE_5_V, 1.4, 3.6 }, +} dslogic_voltage_thresholds[] = { + { 0.7, 1.4 }, + { 1.4, 3.6 }, }; static const uint64_t samplerates[] = { @@ -244,10 +218,9 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) for (j = 0; supported_device[j].vid; j++) { if (des.idVendor == supported_device[j].vid && des.idProduct == supported_device[j].pid && - (!supported_device[j].usb_manufacturer || - !strcmp(manufacturer, supported_device[j].usb_manufacturer)) && - (!supported_device[j].usb_product || - !strcmp(product, supported_device[j].usb_product))) { + (!strcmp(manufacturer, supported_device[j].usb_manufacturer)) && + (!strcmp(product, "USB-based Instrument") || + !strcmp(product, supported_device[j].usb_product))) { prof = &supported_device[j]; break; } @@ -269,7 +242,7 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) cg = g_malloc0(sizeof(struct sr_channel_group)); cg->name = g_strdup("Logic"); for (j = 0; j < 16; j++) { - sprintf(channel_name, "D%d", j); + sprintf(channel_name, "%d", j); ch = sr_channel_new(sdi, j, SR_CHANNEL_LOGIC, TRUE, channel_name); cg->channels = g_slist_append(cg->channels, ch); @@ -283,8 +256,7 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) devc->samplerates = samplerates; devc->num_samplerates = ARRAY_SIZE(samplerates); - has_firmware = usb_match_manuf_prod(devlist[i], "DreamSourceLab", "DSLogic") - || usb_match_manuf_prod(devlist[i], "DreamSourceLab", "DSCope"); + has_firmware = usb_match_manuf_prod(devlist[i], "DreamSourceLab", "USB-based Instrument"); if (has_firmware) { /* Already has the firmware, so fix the new address. */ @@ -332,7 +304,6 @@ static int dev_open(struct sr_dev_inst *sdi) struct sr_dev_driver *di = sdi->driver; struct sr_usb_dev_inst *usb; struct dev_context *devc; - const char *fpga_firmware = NULL; int ret; int64_t timediff_us, timediff_ms; @@ -392,22 +363,8 @@ static int dev_open(struct sr_dev_inst *sdi) return SR_ERR; } - if (!strcmp(devc->profile->model, "DSLogic")) { - if (devc->voltage_threshold == DS_VOLTAGE_RANGE_18_33_V) - fpga_firmware = DSLOGIC_FPGA_FIRMWARE_3V3; - else - fpga_firmware = DSLOGIC_FPGA_FIRMWARE_5V; - } else if (!strcmp(devc->profile->model, "DSLogic Pro")){ - fpga_firmware = DSLOGIC_PRO_FPGA_FIRMWARE; - } else if (!strcmp(devc->profile->model, "DSLogic Plus")){ - fpga_firmware = DSLOGIC_PLUS_FPGA_FIRMWARE; - } else if (!strcmp(devc->profile->model, "DSLogic Basic")){ - fpga_firmware = DSLOGIC_BASIC_FPGA_FIRMWARE; - } else if (!strcmp(devc->profile->model, "DSCope")) { - fpga_firmware = DSCOPE_FPGA_FIRMWARE; - } - if ((ret = dslogic_fpga_firmware_upload(sdi, fpga_firmware)) != SR_OK) + if ((ret = dslogic_fpga_firmware_upload(sdi)) != SR_OK) return ret; if (devc->cur_samplerate == 0) { @@ -415,6 +372,9 @@ static int dev_open(struct sr_dev_inst *sdi) devc->cur_samplerate = devc->samplerates[0]; } + if (devc->cur_threshold == 0.0) + devc->cur_threshold = 1.5; + return SR_OK; } @@ -443,7 +403,7 @@ static int config_get(uint32_t key, GVariant **data, struct dev_context *devc; struct sr_usb_dev_inst *usb; GVariant *range[2]; - unsigned int i; + unsigned int i, voltage_range; char str[128]; (void)cg; @@ -466,14 +426,25 @@ static int config_get(uint32_t key, GVariant **data, *data = g_variant_new_string(str); break; case SR_CONF_VOLTAGE_THRESHOLD: - for (i = 0; i < ARRAY_SIZE(volt_thresholds); i++) { - if (volt_thresholds[i].range != devc->voltage_threshold) - continue; - range[0] = g_variant_new_double(volt_thresholds[i].low); - range[1] = g_variant_new_double(volt_thresholds[i].high); - *data = g_variant_new_tuple(range, 2); - break; + if (!strcmp(devc->profile->model, "DSLogic")) { + voltage_range = 0; + + for (i = 0; i < ARRAY_SIZE(dslogic_voltage_thresholds); i++) + if (dslogic_voltage_thresholds[i].low == + devc->cur_threshold) { + voltage_range = i; + break; + } + + range[0] = g_variant_new_double( + dslogic_voltage_thresholds[voltage_range].low); + range[1] = g_variant_new_double( + dslogic_voltage_thresholds[voltage_range].high); + } else { + range[0] = g_variant_new_double(devc->cur_threshold); + range[1] = g_variant_new_double(devc->cur_threshold); } + *data = g_variant_new_tuple(range, 2); break; case SR_CONF_LIMIT_SAMPLES: *data = g_variant_new_uint64(devc->limit_samples); @@ -566,25 +537,19 @@ static int config_set(uint32_t key, GVariant *data, break; case SR_CONF_VOLTAGE_THRESHOLD: g_variant_get(data, "(dd)", &low, &high); - ret = SR_ERR_ARG; - for (i = 0; (unsigned int)i < ARRAY_SIZE(volt_thresholds); i++) { - if (fabs(volt_thresholds[i].low - low) < 0.1 && - fabs(volt_thresholds[i].high - high) < 0.1) { - devc->voltage_threshold = volt_thresholds[i].range; - break; - } - } if (!strcmp(devc->profile->model, "DSLogic")) { - if (devc->voltage_threshold == DS_VOLTAGE_RANGE_5_V) - ret = dslogic_fpga_firmware_upload(sdi, DSLOGIC_FPGA_FIRMWARE_5V); - else - ret = dslogic_fpga_firmware_upload(sdi, DSLOGIC_FPGA_FIRMWARE_3V3); - } else if (!strcmp(devc->profile->model, "DSLogic Pro")) { - ret = dslogic_fpga_firmware_upload(sdi, DSLOGIC_PRO_FPGA_FIRMWARE); - } else if (!strcmp(devc->profile->model, "DSLogic Plus")) { - ret = dslogic_fpga_firmware_upload(sdi, DSLOGIC_PLUS_FPGA_FIRMWARE); - } else if (!strcmp(devc->profile->model, "DSLogic Basic")) { - ret = dslogic_fpga_firmware_upload(sdi, DSLOGIC_BASIC_FPGA_FIRMWARE); + for (i = 0; (unsigned int)i < + ARRAY_SIZE(dslogic_voltage_thresholds); i++) { + if (fabs(dslogic_voltage_thresholds[i].low - low) < 0.1 && + fabs(dslogic_voltage_thresholds[i].high - high) < 0.1) { + devc->cur_threshold = + dslogic_voltage_thresholds[i].low; + break; + } + } + ret = dslogic_fpga_firmware_upload(sdi); + } else { + ret = dslogic_set_voltage_threshold(sdi, (low + high) / 2.0); } break; case SR_CONF_EXTERNAL_CLOCK: @@ -610,10 +575,11 @@ static int config_set(uint32_t key, GVariant *data, static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { - struct dev_context *devc; + struct dev_context *devc = NULL; GVariant *gvar, *range[2]; GVariantBuilder gvb; unsigned int i; + double v; (void)cg; @@ -633,15 +599,23 @@ static int config_list(uint32_t key, GVariant **data, } break; case SR_CONF_VOLTAGE_THRESHOLD: - if (!sdi->priv) - return SR_ERR_ARG; - devc = sdi->priv; + if (sdi->priv) + devc = sdi->priv; g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY); - for (i = 0; i < ARRAY_SIZE(volt_thresholds); i++) { - range[0] = g_variant_new_double(volt_thresholds[i].low); - range[1] = g_variant_new_double(volt_thresholds[i].high); - gvar = g_variant_new_tuple(range, 2); - g_variant_builder_add_value(&gvb, gvar); + if (devc && !strcmp(devc->profile->model, "DSLogic")) { + for (i = 0; i < ARRAY_SIZE(dslogic_voltage_thresholds); i++) { + range[0] = g_variant_new_double(dslogic_voltage_thresholds[i].low); + range[1] = g_variant_new_double(dslogic_voltage_thresholds[i].high); + gvar = g_variant_new_tuple(range, 2); + g_variant_builder_add_value(&gvb, gvar); + } + } else { + for (v = 0.0; v <= 5.0; v += 0.1) { + range[0] = g_variant_new_double(v); + range[1] = g_variant_new_double(v); + gvar = g_variant_new_tuple(range, 2); + g_variant_builder_add_value(&gvb, gvar); + } } *data = g_variant_builder_end(&gvb); break; @@ -664,204 +638,6 @@ static int config_list(uint32_t key, GVariant **data, return SR_OK; } -static int receive_data(int fd, int revents, void *cb_data) -{ - struct timeval tv; - struct drv_context *drvc; - - (void)fd; - (void)revents; - - drvc = (struct drv_context *)cb_data; - - tv.tv_sec = tv.tv_usec = 0; - libusb_handle_events_timeout(drvc->sr_ctx->libusb_ctx, &tv); - - return TRUE; -} - -static int start_transfers(const struct sr_dev_inst *sdi) -{ - struct dev_context *devc; - struct sr_usb_dev_inst *usb; - struct libusb_transfer *transfer; - unsigned int i, num_transfers; - int timeout, ret; - unsigned char *buf; - size_t size; - - devc = sdi->priv; - usb = sdi->conn; - - devc->sent_samples = 0; - devc->acq_aborted = FALSE; - devc->empty_transfer_count = 0; - devc->trigger_fired = TRUE; - - num_transfers = dslogic_get_number_of_transfers(devc); - - if (devc->cur_samplerate == SR_MHZ(100)) - num_transfers = 16; - else if (devc->cur_samplerate == SR_MHZ(200)) - num_transfers = 8; - else if (devc->cur_samplerate == SR_MHZ(400)) - num_transfers = 4; - - size = dslogic_get_buffer_size(devc); - devc->submitted_transfers = 0; - - devc->transfers = g_try_malloc0(sizeof(*devc->transfers) * num_transfers); - if (!devc->transfers) { - sr_err("USB transfers malloc failed."); - return SR_ERR_MALLOC; - } - - timeout = dslogic_get_timeout(devc); - devc->num_transfers = num_transfers; - for (i = 0; i < num_transfers; i++) { - if (!(buf = g_try_malloc(size))) { - sr_err("USB transfer buffer malloc failed."); - return SR_ERR_MALLOC; - } - transfer = libusb_alloc_transfer(0); - libusb_fill_bulk_transfer(transfer, usb->devhdl, - 6 | LIBUSB_ENDPOINT_IN, buf, size, - dslogic_receive_transfer, (void *)sdi, timeout); - sr_info("submitting transfer: %d", i); - if ((ret = libusb_submit_transfer(transfer)) != 0) { - sr_err("Failed to submit transfer: %s.", - libusb_error_name(ret)); - libusb_free_transfer(transfer); - g_free(buf); - dslogic_abort_acquisition(devc); - return SR_ERR; - } - devc->transfers[i] = transfer; - devc->submitted_transfers++; - } - - std_session_send_df_header(sdi); - - return SR_OK; -} - -static void LIBUSB_CALL trigger_receive(struct libusb_transfer *transfer) -{ - const struct sr_dev_inst *sdi; - struct dslogic_trigger_pos *tpos; - struct dev_context *devc; - - sdi = transfer->user_data; - devc = sdi->priv; - if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { - sr_dbg("Trigger transfer canceled."); - /* Terminate session. */ - std_session_send_df_end(sdi); - usb_source_remove(sdi->session, devc->ctx); - devc->num_transfers = 0; - g_free(devc->transfers); - } else if (transfer->status == LIBUSB_TRANSFER_COMPLETED - && transfer->actual_length == sizeof(struct dslogic_trigger_pos)) { - tpos = (struct dslogic_trigger_pos *)transfer->buffer; - sr_info("tpos real_pos %d ram_saddr %d cnt %d", tpos->real_pos, - tpos->ram_saddr, tpos->remain_cnt); - devc->trigger_pos = tpos->real_pos; - g_free(tpos); - start_transfers(sdi); - } - libusb_free_transfer(transfer); -} - -static int trigger_request(const struct sr_dev_inst *sdi) -{ - struct sr_usb_dev_inst *usb; - struct libusb_transfer *transfer; - struct dslogic_trigger_pos *tpos; - struct dev_context *devc; - int ret; - - usb = sdi->conn; - devc = sdi->priv; - - if ((ret = dslogic_stop_acquisition(sdi)) != SR_OK) - return ret; - - if ((ret = dslogic_fpga_configure(sdi)) != SR_OK) - return ret; - - /* If this is a DSLogic Pro, set the voltage threshold. */ - if (!strcmp(devc->profile->model, "DSLogic Pro")){ - if (devc->voltage_threshold == DS_VOLTAGE_RANGE_18_33_V) { - dslogic_set_vth(sdi, 1.4); - } else { - dslogic_set_vth(sdi, 3.3); - } - } - - if ((ret = dslogic_start_acquisition(sdi)) != SR_OK) - return ret; - - sr_dbg("Getting trigger."); - tpos = g_malloc(sizeof(struct dslogic_trigger_pos)); - transfer = libusb_alloc_transfer(0); - libusb_fill_bulk_transfer(transfer, usb->devhdl, 6 | LIBUSB_ENDPOINT_IN, - (unsigned char *)tpos, sizeof(struct dslogic_trigger_pos), - trigger_receive, (void *)sdi, 0); - if ((ret = libusb_submit_transfer(transfer)) < 0) { - sr_err("Failed to request trigger: %s.", libusb_error_name(ret)); - libusb_free_transfer(transfer); - g_free(tpos); - return SR_ERR; - } - - devc->transfers = g_try_malloc0(sizeof(*devc->transfers)); - if (!devc->transfers) { - sr_err("USB trigger_pos transfer malloc failed."); - return SR_ERR_MALLOC; - } - devc->num_transfers = 1; - devc->submitted_transfers++; - devc->transfers[0] = transfer; - - return ret; -} - -static int dev_acquisition_start(const struct sr_dev_inst *sdi) -{ - struct sr_dev_driver *di; - struct drv_context *drvc; - struct dev_context *devc; - int timeout; - - if (sdi->status != SR_ST_ACTIVE) - return SR_ERR_DEV_CLOSED; - - di = sdi->driver; - drvc = di->context; - devc = sdi->priv; - - devc->ctx = drvc->sr_ctx; - devc->sent_samples = 0; - devc->empty_transfer_count = 0; - devc->acq_aborted = FALSE; - - timeout = dslogic_get_timeout(devc); - usb_source_add(sdi->session, devc->ctx, timeout, receive_data, drvc); - - trigger_request(sdi); - - return SR_OK; -} - -static int dev_acquisition_stop(struct sr_dev_inst *sdi) -{ - dslogic_stop_acquisition(sdi); - - dslogic_abort_acquisition(sdi->priv); - - return SR_OK; -} - static struct sr_dev_driver dslogic_driver_info = { .name = "dslogic", .longname = "DreamSourceLabs DSLogic", @@ -876,8 +652,8 @@ static struct sr_dev_driver dslogic_driver_info = { .config_list = config_list, .dev_open = dev_open, .dev_close = dev_close, - .dev_acquisition_start = dev_acquisition_start, - .dev_acquisition_stop = dev_acquisition_stop, + .dev_acquisition_start = dslogic_acquisition_start, + .dev_acquisition_stop = dslogic_acquisition_stop, .context = NULL, }; SR_REGISTER_DEV_DRIVER(dslogic_driver_info);