X-Git-Url: https://sigrok.org/gitweb/?p=libsigrok.git;a=blobdiff_plain;f=src%2Fhardware%2Fzeroplus-logic-cube%2Fapi.c;h=9d15fe6c97c13ec7e915e3036861ba348e228f30;hp=e606dba64ce07c80911088cfab436b419a78c92c;hb=HEAD;hpb=6605f1b9bb52f39b7d78a00cc6ba9caccfea9766 diff --git a/src/hardware/zeroplus-logic-cube/api.c b/src/hardware/zeroplus-logic-cube/api.c index e606dba6..49e0e1f9 100644 --- a/src/hardware/zeroplus-logic-cube/api.c +++ b/src/hardware/zeroplus-logic-cube/api.c @@ -42,6 +42,7 @@ struct zp_model { */ static const struct zp_model zeroplus_models[] = { {0x0c12, 0x7002, "LAP-16128U", 16, 128, 200}, + {0x0c12, 0x7007, "LAP-16032U", 16, 32, 200}, {0x0c12, 0x7009, "LAP-C(16064)", 16, 64, 100}, {0x0c12, 0x700a, "LAP-C(16128)", 16, 128, 200}, {0x0c12, 0x700b, "LAP-C(32128)", 32, 128, 200}, @@ -50,7 +51,8 @@ static const struct zp_model zeroplus_models[] = { {0x0c12, 0x700e, "LAP-C(16032)", 16, 32, 100}, {0x0c12, 0x7016, "LAP-C(162000)", 16, 2048, 200}, {0x0c12, 0x7025, "LAP-C(16128+)", 16, 128, 200}, - {0x0c12, 0x7100, "AKIP-9101", 16, 256, 200}, + {0x0c12, 0x7064, "Logian-16L", 16, 128, 200}, + {0x0c12, 0x7100, "AKIP-9101", 16, 256, 200}, ALL_ZERO }; @@ -69,6 +71,9 @@ static const uint32_t devopts[] = { static const int32_t trigger_matches[] = { SR_TRIGGER_ZERO, SR_TRIGGER_ONE, + SR_TRIGGER_RISING, + SR_TRIGGER_FALLING, + SR_TRIGGER_EDGE, }; /* @@ -164,7 +169,10 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) struct libusb_device_handle *hdl; libusb_device **devlist; GSList *devices; - int ret, i, j; + int ret; + size_t i, j; + uint8_t bus, addr; + const struct zp_model *check; char serial_num[64], connection_id[64]; (void)options; @@ -175,47 +183,69 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) /* Find all ZEROPLUS analyzers and add them to device list. */ libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); /* TODO: Errors. */ - for (i = 0; devlist[i]; i++) { libusb_get_device_descriptor(devlist[i], &des); - if ((ret = libusb_open(devlist[i], &hdl)) < 0) + /* + * Check for expected VID:PID first as soon as we got + * the descriptor's content. This avoids access to flaky + * unrelated devices which trouble the application even + * if they are unrelated to measurement purposes. + * + * See https://sigrok.org/bugzilla/show_bug.cgi?id=1115 + * and https://github.com/sigrokproject/libsigrok/pull/165 + * for a discussion. + */ + prof = NULL; + for (j = 0; zeroplus_models[j].vid; j++) { + check = &zeroplus_models[j]; + if (des.idVendor != check->vid) + continue; + if (des.idProduct != check->pid) + continue; + prof = check; + break; + } + if (!prof) continue; - if (des.iSerialNumber == 0) { - serial_num[0] = '\0'; - } else if ((ret = libusb_get_string_descriptor_ascii(hdl, - des.iSerialNumber, (unsigned char *) serial_num, - sizeof(serial_num))) < 0) { - sr_warn("Failed to get serial number string descriptor: %s.", - libusb_error_name(ret)); + /* Get the device's serial number from USB strings. */ + ret = libusb_open(devlist[i], &hdl); + if (ret < 0) continue; - } - - libusb_close(hdl); - - usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)); - prof = NULL; - for (j = 0; j < zeroplus_models[j].vid; j++) { - if (des.idVendor == zeroplus_models[j].vid && - des.idProduct == zeroplus_models[j].pid) { - prof = &zeroplus_models[j]; + serial_num[0] = '\0'; + if (des.iSerialNumber != 0) { + ret = libusb_get_string_descriptor_ascii(hdl, + des.iSerialNumber, + (uint8_t *)serial_num, sizeof(serial_num)); + if (ret < 0) { + sr_warn("Cannot get USB serial number: %s.", + libusb_error_name(ret)); + continue; } } - if (!prof) + libusb_close(hdl); + + if (usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)) < 0) continue; + sr_info("Found ZEROPLUS %s.", prof->model_name); - sdi = g_malloc0(sizeof(struct sr_dev_inst)); + sdi = g_malloc0(sizeof(*sdi)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("ZEROPLUS"); sdi->model = g_strdup(prof->model_name); sdi->serial_num = g_strdup(serial_num); sdi->connection_id = g_strdup(connection_id); - devc = g_malloc0(sizeof(struct dev_context)); + bus = libusb_get_bus_number(devlist[i]); + addr = libusb_get_device_address(devlist[i]); + sdi->inst_type = SR_INST_USB; + sdi->conn = sr_usb_dev_inst_new(bus, addr, NULL); + + devc = g_malloc0(sizeof(*devc)); sdi->priv = devc; devc->prof = prof; devc->num_channels = prof->channels; @@ -228,17 +258,13 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) #endif devc->max_samplerate *= SR_MHZ(1); devc->memory_size = MEMORY_SIZE_8K; - // memset(devc->trigger_buffer, 0, NUM_TRIGGER_STAGES); - for (j = 0; j < devc->num_channels; j++) + for (j = 0; j < devc->num_channels; j++) { sr_channel_new(sdi, j, SR_CHANNEL_LOGIC, TRUE, channel_names[j]); + } devices = g_slist_append(devices, sdi); - sdi->inst_type = SR_INST_USB; - sdi->conn = sr_usb_dev_inst_new( - libusb_get_bus_number(devlist[i]), - libusb_get_device_address(devlist[i]), NULL); } libusb_free_device_list(devlist, 1); @@ -392,7 +418,7 @@ static int config_list(uint32_t key, GVariant **data, switch (key) { case SR_CONF_DEVICE_OPTIONS: - return STD_CONFIG_LIST(key, data, sdi, cg, NULL, drvopts, devopts); + return STD_CONFIG_LIST(key, data, sdi, cg, NO_OPTS, drvopts, devopts); case SR_CONF_SAMPLERATE: devc = sdi->priv; if (devc->prof->max_sampling_freq == 100) @@ -544,8 +570,9 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) unsigned int buf_offset; res = analyzer_read_data(usb->devhdl, buf, PACKET_SIZE); - sr_info("Tried to read %d bytes, actually read %d bytes.", - PACKET_SIZE, res); + if (res != PACKET_SIZE) + sr_warn("Tried to read %d bytes, actually read %d.", + PACKET_SIZE, res); if (discard >= PACKET_SIZE / 4) { discard -= PACKET_SIZE / 4; @@ -576,12 +603,8 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) buf_offset += logic.length; } - if (samples_read == trigger_offset) { - /* Send out trigger */ - packet.type = SR_DF_TRIGGER; - packet.payload = NULL; - sr_session_send(sdi, &packet); - } + if (samples_read == trigger_offset) + std_session_send_df_trigger(sdi); /* Send out data (or data after trigger) */ packet.type = SR_DF_LOGIC;