X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fscpi%2Fscpi_usbtmc_libusb.c;h=a6eb922b9a67eb1e9aceb57b1a627747370f1657;hb=485a285abea07fa296ee56517cf95b4dbab69e29;hp=c4470b5db6dee0d98b4983a8a79b2627bf9e5f08;hpb=155b680da482cea2381becb73c51cfb838bff31e;p=libsigrok.git
diff --git a/src/scpi/scpi_usbtmc_libusb.c b/src/scpi/scpi_usbtmc_libusb.c
index c4470b5d..a6eb922b 100644
--- a/src/scpi/scpi_usbtmc_libusb.c
+++ b/src/scpi/scpi_usbtmc_libusb.c
@@ -17,9 +17,11 @@
* along with this program. If not, see .
*/
+#include
#include
-#include "libsigrok.h"
+#include
#include "libsigrok-internal.h"
+#include "scpi.h"
#define LOG_PREFIX "scpi_usbtmc"
@@ -68,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
@@ -92,7 +97,6 @@ enum {
#define EOM 0x01
#define TERM_CHAR_ENABLED 0x02
-
static GSList *scpi_usbtmc_libusb_scan(struct drv_context *drvc)
{
struct libusb_device **devlist;
@@ -184,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)
@@ -213,9 +217,8 @@ static int scpi_usbtmc_libusb_open(void *priv)
intfdes->bInterfaceProtocol != USBTMC_USB488)
continue;
uscpi->interface = intfdes->bInterfaceNumber;
- sr_dbg("Interface %d", uscpi->interface);
config = confdes->bConfigurationValue;
- sr_dbg("Configuration %d", config);
+ sr_dbg("Interface %d configuration %d.", uscpi->interface, config);
for (epidx = 0; epidx < intfdes->bNumEndpoints; epidx++) {
ep = &intfdes->endpoint[epidx];
if (ep->bmAttributes == LIBUSB_TRANSFER_TYPE_BULK &&
@@ -226,12 +229,12 @@ static int scpi_usbtmc_libusb_open(void *priv)
if (ep->bmAttributes == LIBUSB_TRANSFER_TYPE_BULK &&
ep->bEndpointAddress & (LIBUSB_ENDPOINT_DIR_MASK)) {
uscpi->bulk_in_ep = ep->bEndpointAddress;
- sr_dbg("Bulk IN EP %d", uscpi->bulk_in_ep);
+ sr_dbg("Bulk IN EP %d", uscpi->bulk_in_ep & 0x7f);
}
if (ep->bmAttributes == LIBUSB_TRANSFER_TYPE_INTERRUPT &&
ep->bEndpointAddress & (LIBUSB_ENDPOINT_DIR_MASK)) {
uscpi->interrupt_ep = ep->bEndpointAddress;
- sr_dbg("Interrupt EP %d", uscpi->interrupt_ep);
+ sr_dbg("Interrupt EP %d", uscpi->interrupt_ep & 0x7f);
}
}
found = 1;
@@ -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));
@@ -555,8 +599,7 @@ static int scpi_usbtmc_libusb_close(void *priv)
uscpi->detached_kernel_driver = 0;
}
- libusb_close(usb->devhdl);
- usb->devhdl = NULL;
+ sr_usb_close(usb);
return SR_OK;
}