scpi/usbtmc: Support RL1 feature.

This automatically locks out local controls when a USBTMC device is
opened, and returns local control on close.
This commit is contained in:
Bert Vermeulen 2015-09-17 23:31:04 +02:00 committed by Uwe Hermann
parent b41bbfdbe2
commit baed0211a1
1 changed files with 45 additions and 1 deletions

View 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));