]> sigrok.org Git - libsigrok.git/commitdiff
scpi/usbtmc: Support RL1 feature.
authorBert Vermeulen <redacted>
Thu, 17 Sep 2015 21:31:04 +0000 (23:31 +0200)
committerUwe Hermann <redacted>
Fri, 18 Sep 2015 23:26:45 +0000 (01:26 +0200)
This automatically locks out local controls when a USBTMC device is
opened, and returns local control on close.

src/scpi/scpi_usbtmc_libusb.c

index 36ff316bcef30fc94dd469d2da21c1b10336eea5..a6eb922b9a67eb1e9aceb57b1a627747370f1657 100644 (file)
@@ -70,6 +70,9 @@ enum {
        LOCAL_LOCKOUT               = 162,
 };
 
+/* USBTMC status codes */
+#define USBTMC_STATUS_SUCCESS      0x01
+
 /* USBTMC capabilities */
 #define USBTMC_INT_CAP_LISTEN_ONLY 0x01
 #define USBTMC_INT_CAP_TALK_ONLY   0x02
@@ -185,7 +188,7 @@ static int scpi_usbtmc_libusb_open(void *priv)
        const struct libusb_interface_descriptor *intfdes;
        const struct libusb_endpoint_descriptor *ep;
        int confidx, intfidx, epidx, config = 0;
-       uint8_t capabilities[24];
+       uint8_t capabilities[24], status;
        int ret, found = 0;
 
        if (usb->devhdl)
@@ -313,6 +316,32 @@ static int scpi_usbtmc_libusb_open(void *priv)
               uscpi->usb488_dev_cap & USB488_DEV_CAP_RL1        ? "RL1"  : "RL0",
               uscpi->usb488_dev_cap & USB488_DEV_CAP_DT1        ? "DT1"  : "DT0");
 
+       if (uscpi->usb488_dev_cap & USB488_DEV_CAP_RL1) {
+               sr_dbg("Locking out local control.");
+               ret = libusb_control_transfer(usb->devhdl,
+                               LIBUSB_ENDPOINT_IN         |
+                               LIBUSB_REQUEST_TYPE_CLASS  |
+                               LIBUSB_RECIPIENT_INTERFACE,
+                               REN_CONTROL, 1,
+                               uscpi->interface,
+                               &status, 1,
+                               TRANSFER_TIMEOUT);
+               if (ret < 0 || status != USBTMC_STATUS_SUCCESS) {
+                       sr_dbg("Failed to enter REN state.");
+                       return SR_OK;
+               }
+               ret = libusb_control_transfer(usb->devhdl,
+                               LIBUSB_ENDPOINT_IN         |
+                               LIBUSB_REQUEST_TYPE_CLASS  |
+                               LIBUSB_RECIPIENT_INTERFACE,
+                               LOCAL_LOCKOUT, 1,
+                               uscpi->interface,
+                               &status, 1,
+                               TRANSFER_TIMEOUT);
+               if (ret < 0 || status != USBTMC_STATUS_SUCCESS)
+                       sr_dbg("Failed to enter local lockout state.");
+       }
+
        return SR_OK;
 }
 
@@ -527,6 +556,7 @@ static int scpi_usbtmc_libusb_close(void *priv)
        int ret;
        struct scpi_usbtmc_libusb *uscpi = priv;
        struct sr_usb_dev_inst *usb = uscpi->usb;
+       uint8_t status;
 
        if (!usb->devhdl)
                return SR_ERR;
@@ -543,6 +573,20 @@ static int scpi_usbtmc_libusb_close(void *priv)
                       uscpi->interrupt_ep, libusb_error_name(ret));
        }
 
+       if (uscpi->usb488_dev_cap & USB488_DEV_CAP_RL1) {
+               sr_dbg("Returning local control.");
+               ret = libusb_control_transfer(usb->devhdl,
+                               LIBUSB_ENDPOINT_IN         |
+                               LIBUSB_REQUEST_TYPE_CLASS  |
+                               LIBUSB_RECIPIENT_INTERFACE,
+                               GO_TO_LOCAL, 1,
+                               uscpi->interface,
+                               &status, 1,
+                               TRANSFER_TIMEOUT);
+               if (ret < 0 || status != USBTMC_STATUS_SUCCESS)
+                       sr_dbg("Failed to clear local lockout state.");
+       }
+
        if ((ret = libusb_release_interface(usb->devhdl, uscpi->interface)) < 0)
                sr_err("Failed to release interface: %s.",
                       libusb_error_name(ret));