Request USBTMC capabilities from device
authorMichael Gernoth <michael@gernoth.net>
Tue, 8 Jun 2010 07:40:24 +0000 (09:40 +0200)
committerMichael Gernoth <michael@gernoth.net>
Tue, 8 Jun 2010 07:40:24 +0000 (09:40 +0200)
usbtmc.c
usbtmc.h

index 85842ec8ceac550599f8ae46ff6e9b4b43a3f2cc..332cbda8f192f85a4b1ec5f5dad88b4db5bb6d41 100644 (file)
--- 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);
index 519012e04da9aeda12cd8a38cbd9286526be6dca..1fa1046009aa2f791e6019983b6e339a9d001966 100644 (file)
--- 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);
Impressum, Datenschutz