From 483a564bf0578b64b25c68ffabdfdc0fb9f0f2b7 Mon Sep 17 00:00:00 2001 From: Michael Gernoth Date: Tue, 8 Jun 2010 09:40:24 +0200 Subject: [PATCH] Request USBTMC capabilities from device --- usbtmc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- usbtmc.h | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 3 deletions(-) diff --git a/usbtmc.c b/usbtmc.c index 85842ec..332cbda 100644 --- a/usbtmc.c +++ b/usbtmc.c @@ -17,6 +17,7 @@ #error BYTE_ORDER not defined/known! #endif +/* TODO: fix memory leak here: */ #define USB_ERROR(s, x) do { if (x < 0) { fprintf(stderr, "usb %s: %s\n", s, usb_strerror()); usb_reset(sc->usb.dev); return 0; } } while(0) /* This routine locates a scope by VID/PID and returns a struct scope* for it */ @@ -59,14 +60,18 @@ static struct scope* usbtmc_find_scope() { return NULL; } -unsigned char usbtmc_status(struct scope *sc) +static unsigned char usbtmc_status(struct scope *sc) { int r; unsigned char status[3]; sc->usb.bTag++; - r = usb_control_msg(sc->usb.dev, 0xA1, 128, (sc->usb.bTag & 0x7f), 0, (char*)status, 3, USB_TIMEOUT); + r = usb_control_msg(sc->usb.dev, 0xA1, + USB488_CTL_READ_STATUS_BYTE, + (sc->usb.bTag & 0x7f), 0, (char*)status, 3, + USB_TIMEOUT); + if ((r != 3) || (status[0] != 0x01) || (status[1] != (sc->usb.bTag & 0x7f))) { printf("READ_STATUS_BYTE failed: %d 0x%x 0x%x 0x%x\n", r, status[0], status[1], status[2]); return 0xff; @@ -75,6 +80,59 @@ unsigned char usbtmc_status(struct scope *sc) return status[2]; } +static struct usbtmc_capabilities* usbtmc_get_capabilities(struct scope *sc) +{ + int r; + static struct usbtmc_capabilities res; + + r = usb_control_msg(sc->usb.dev, 0xA1, + USBTMC_CTL_GET_CAPABILITIES, + 0, 0, (char*)&res, sizeof(struct usbtmc_capabilities), + USB_TIMEOUT); + if (r != sizeof(struct usbtmc_capabilities)) { + printf("GET_CAPABILITIES failed: %s\n", usb_strerror()); + return NULL; + } + + printf("USBTMC Version %x.%x Capabilities:\n", res.bcdUSBTMC[0], res.bcdUSBTMC[1]); + if (res.USBTMCIFcapabilities & USBTMC_CAP_IF_INDICATOR_PULSE) + printf("\tInterface supports indicator pulse\n"); + + if (res.USBTMCIFcapabilities & USBTMC_CAP_IF_TALKONLY) + printf("\tInterface is talk only\n"); + + if (res.USBTMCIFcapabilities & USBTMC_CAP_IF_LISTENONLY) + printf("\tInterface is listen only\n"); + + if (res.USBTMCDEVcapabilities & USBTMC_CAP_DEV_TERMCHAR_SUPP) + printf("\tDevice supports Termchar\n"); + + printf("USB488 Version %x.%x Capabilities:\n", res.bcdUSB488[0], res.bcdUSB488[1]); + + if (res.USB488IFcapabilities & USB488_CAP_IF_4882) + printf("\tInterface is 488.2 compliant\n"); + + if (res.USB488IFcapabilities & USB488_CAP_IF_LOCKOUT) + printf("\tInterface supports local lockout\n"); + + if (res.USB488IFcapabilities & USB488_CAP_IF_TRIGGER) + printf("\tInterface supports TRIGGER\n"); + + if (res.USB488DEVcapabilities & USB488_CAP_DEV_SCPI) + printf("\tDevice is SCPI compliant\n"); + + if (res.USB488DEVcapabilities & USB488_CAP_DEV_SR1) + printf("\tDevice is SR1 capable\n"); + + if (res.USB488DEVcapabilities & USB488_CAP_DEV_RL1) + printf("\tDevice is RL1 capable\n"); + + if (res.USB488DEVcapabilities & USB488_CAP_DEV_DT1) + printf("\tDevice is DT1 capable\n"); + + return &res; +} + /* * Send a scpi-command to the scope. The response goes into the buffer * called resp, with a size of resplen. If resp==NULL, no response @@ -212,7 +270,7 @@ void usbtmc_release(struct scope *sc) usb_release_interface(sc->usb.dev, 0); } -//Initialize the scope. +/* Initialize the scope. */ struct scope* usbtmc_initscope(void) { int r; uint32_t vidpid; @@ -227,6 +285,8 @@ struct scope* usbtmc_initscope(void) { } usbtmc_claim(sc); + usbtmc_get_capabilities(sc); + printf("Device status: 0x%x\n", usbtmc_status(sc)); /* The following code isn't really necessary, the program works OK without it too. */ r=usb_control_msg(sc->usb.dev, 0xC8, 9, 0, 0, (char*)&vidpid, 4, USB_TIMEOUT); diff --git a/usbtmc.h b/usbtmc.h index 519012e..1fa1046 100644 --- a/usbtmc.h +++ b/usbtmc.h @@ -11,6 +11,19 @@ struct usbtmc_header { unsigned char msg[]; } __attribute__ ((__packed__)); +struct usbtmc_capabilities { + unsigned char USBTMC_status; + unsigned char Reserved1; + unsigned char bcdUSBTMC[2]; + unsigned char USBTMCIFcapabilities; + unsigned char USBTMCDEVcapabilities; + unsigned char Reserved6[6]; + unsigned char bcdUSB488[2]; + unsigned char USB488IFcapabilities; + unsigned char USB488DEVcapabilities; + unsigned char Reserved16[8]; +} __attribute__ ((__packed__)); + #define USBTMC_DEV_DEP_MSG_OUT 0x1 #define USBTMC_REQUEST_DEV_DEP_MSG_IN 0x2 #define USBTMC_DEV_DEP_MSG_IN 0x2 @@ -18,6 +31,31 @@ struct usbtmc_header { #define USBTMC_TRANSFERATTRIB_EOM (1<<0) #define USBTMC_TRANSFERATTRIB_TERMCHAR (1<<1) +#define USBTMC_CTL_INITIATE_ABORT_BO 0x01 +#define USBTMC_CTL_CHECK_ABORT_BO_STAT 0x02 +#define USBTMC_CTL_INITIATE_ABORT_BI 0x03 +#define USBTMC_CTL_CHECK_ABORT_BI_STAT 0x04 +#define USBTMC_CTL_INITIATE_CLEAR 0x05 +#define USBTMC_CTL_CHECK_CLEAR_STAT 0x06 +#define USBTMC_CTL_GET_CAPABILITIES 0x07 +#define USBTMC_CTL_INDICATOR_PULSE 0x40 +#define USB488_CTL_READ_STATUS_BYTE 0x80 +#define USB488_CTL_REN_CONTROL 0xa0 +#define USB488_CTL_GO_TO_LOCAL 0xa1 +#define USB488_CTL_LOCAL_LOCKOUT 0xa2 + +#define USBTMC_CAP_IF_INDICATOR_PULSE (1<<2) +#define USBTMC_CAP_IF_TALKONLY (1<<1) +#define USBTMC_CAP_IF_LISTENONLY (1<<0) +#define USBTMC_CAP_DEV_TERMCHAR_SUPP (1<<0) +#define USB488_CAP_IF_4882 (1<<2) +#define USB488_CAP_IF_LOCKOUT (1<<1) +#define USB488_CAP_IF_TRIGGER (1<<0) +#define USB488_CAP_DEV_SCPI (1<<3) +#define USB488_CAP_DEV_SR1 (1<<2) +#define USB488_CAP_DEV_RL1 (1<<1) +#define USB488_CAP_DEV_DT1 (1<<0) + int usbtmc_sendscpi(struct scope *sc, char* cmd, unsigned char *resp, int resplen); struct scope * usbtmc_initscope(void); void usbtmc_close(struct scope *sc); -- 2.39.2