]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/fx2lafw/api.c
soft-trigger: Add support for pre-triggering.
[libsigrok.git] / src / hardware / fx2lafw / api.c
index dead6dca8bf90ebcb74680e9df6247032581c6ca..796749a34dbd0d3f004c7111654b6aa4e604f77f 100644 (file)
@@ -73,18 +73,20 @@ static const struct fx2lafw_profile supported_fx2[] = {
        { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
 };
 
-static const uint32_t hwopts[] = {
+static const uint32_t drvopts[] = {
+       SR_CONF_LOGIC_ANALYZER,
+};
+
+static const uint32_t scanopts[] = {
        SR_CONF_CONN,
 };
 
 static const uint32_t devopts[] = {
-       SR_CONF_LOGIC_ANALYZER,
-       SR_CONF_TRIGGER_MATCH,
-       SR_CONF_SAMPLERATE,
-
-       /* These are really implemented in the driver, not the hardware. */
-       SR_CONF_LIMIT_SAMPLES,
-       SR_CONF_CONTINUOUS,
+       SR_CONF_CONTINUOUS | SR_CONF_SET,
+       SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
+       SR_CONF_CONN | SR_CONF_GET,
+       SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
+       SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
 };
 
 static const char *channel_names[] = {
@@ -141,9 +143,9 @@ static GSList *scan(GSList *options)
        struct libusb_device_descriptor des;
        libusb_device **devlist;
        struct libusb_device_handle *hdl;
-       int devcnt, num_logic_channels, ret, i, j;
+       int num_logic_channels, ret, i, j;
        const char *conn;
-       char manufacturer[64], product[64];
+       char manufacturer[64], product[64], serial_num[64], connection_id[64];
 
        drvc = di->priv;
 
@@ -208,6 +210,18 @@ static GSList *scan(GSList *options)
                        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));
+                       continue;
+               }
+
+               usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));
+
                libusb_close(hdl);
 
                prof = NULL;
@@ -227,24 +241,26 @@ static GSList *scan(GSList *options)
                if (!prof)
                        continue;
 
-               devcnt = g_slist_length(drvc->instances);
-               sdi = sr_dev_inst_new(devcnt, SR_ST_INITIALIZING,
-                       prof->vendor, prof->model, prof->model_version);
-               if (!sdi)
-                       return NULL;
+               sdi = g_malloc0(sizeof(struct sr_dev_inst));
+               sdi->status = SR_ST_INITIALIZING;
+               sdi->vendor = g_strdup(prof->vendor);
+               sdi->model = g_strdup(prof->model);
+               sdi->version = g_strdup(prof->model_version);
                sdi->driver = di;
+               sdi->serial_num = g_strdup(serial_num);
+               sdi->connection_id = g_strdup(connection_id);
 
                /* Fill in channellist according to this device's profile. */
                num_logic_channels = prof->dev_caps & DEV_CAPS_16BIT ? 16 : 8;
                for (j = 0; j < num_logic_channels; j++) {
-                       if (!(ch = sr_channel_new(j, SR_CHANNEL_LOGIC, TRUE,
-                                       channel_names[j])))
-                               return NULL;
+                       ch = sr_channel_new(j, SR_CHANNEL_LOGIC, TRUE,
+                                       channel_names[j]);
                        sdi->channels = g_slist_append(sdi->channels, ch);
                }
 
                devc = fx2lafw_dev_new();
                devc->profile = prof;
+               devc->sample_wide = (prof->dev_caps & DEV_CAPS_16BIT) != 0;
                sdi->priv = devc;
                drvc->instances = g_slist_append(drvc->instances, sdi);
                devices = g_slist_append(devices, sdi);
@@ -263,7 +279,9 @@ static GSList *scan(GSList *options)
                                devc->fw_updated = g_get_monotonic_time();
                        else
                                sr_err("Firmware upload failed for "
-                                      "device %d.", devcnt);
+                                      "device %d.%d (logical).",
+                                      libusb_get_bus_number(devlist[i]),
+                                      libusb_get_device_address(devlist[i]));
                        sdi->inst_type = SR_INST_USB;
                        sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
                                        0xff, NULL);
@@ -359,8 +377,8 @@ static int dev_close(struct sr_dev_inst *sdi)
        if (usb->devhdl == NULL)
                return SR_ERR;
 
-       sr_info("fx2lafw: Closing device %d on %d.%d interface %d.",
-               sdi->index, usb->bus, usb->address, USB_INTERFACE);
+       sr_info("fx2lafw: Closing device on %d.%d (logical) / %s (physical) interface %d.",
+               usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
        libusb_release_interface(usb->devhdl, USB_INTERFACE);
        libusb_close(usb->devhdl);
        usb->devhdl = NULL;
@@ -478,11 +496,15 @@ static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *
        switch (key) {
        case SR_CONF_SCAN_OPTIONS:
                *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
-                               hwopts, ARRAY_SIZE(hwopts), sizeof(uint32_t));
+                               scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
                break;
        case SR_CONF_DEVICE_OPTIONS:
-               *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
-                               devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
+               if (!sdi)
+                       *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
+                                       drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
+               else
+                       *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
+                                       devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
                break;
        case SR_CONF_SAMPLERATE:
                g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
@@ -545,7 +567,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
        devc->empty_transfer_count = 0;
 
        if ((trigger = sr_session_trigger_get(sdi->session))) {
-               devc->stl = soft_trigger_logic_new(sdi, trigger);
+               devc->stl = soft_trigger_logic_new(sdi, trigger, 0);
                devc->trigger_fired = FALSE;
        } else
                devc->trigger_fired = TRUE;