10 #define USB_TIMEOUT 10000
12 #if BYTE_ORDER == LITTLE_ENDIAN
14 #elif BYTE_ORDER == BIG_ENDIAN
15 #define LE32(x) ((uint32_t)((((uint32_t)x)>>24) | ((((uint32_t)x)>>8) & 0xff00) | ((((uint32_t)x)<<8) & 0xff0000) | (((uint32_t)x)<<24)))
17 #error BYTE_ORDER not defined/known!
20 /* TODO: fix memory leak here: */
21 #define USB_ERROR(s, x) do { if (x < 0) { fprintf(stderr, "usb %s: %s\n", s, usb_strerror()); usbtmc_clear(sc); return 0; } } while(0)
23 /* This routine locates a scope by VID/PID and returns a struct scope* for it */
24 static struct scope
* usbtmc_find_scope() {
26 struct usb_device
*dev
=NULL
;
27 struct usb_dev_handle
*devh
;
34 for (bus
=usb_busses
; bus
; bus
=bus
->next
) {
35 for (dev
=bus
->devices
; dev
; dev
=dev
->next
) {
36 if (dev
->descriptor
.idVendor
== 0x400 && dev
->descriptor
.idProduct
== 0x5dc) {
41 sc
= calloc(1, sizeof(struct scope
));
50 sc
->usb
.brokenRigol
= 1;
51 sc
->usb
.ep_bulk_out
= 0x01;
52 sc
->usb
.ep_bulk_in
= 0x82;
53 sc
->usb
.wMaxPacketSize_in
= 0x40;
63 static unsigned char usbtmc_status(struct scope
*sc
)
66 unsigned char status
[3];
70 r
= usb_control_msg(sc
->usb
.dev
, 0xA1,
71 USB488_CTL_READ_STATUS_BYTE
,
72 (sc
->usb
.bTag
& 0x7f), 0, (char*)status
, 3,
75 if ((r
!= 3) || (status
[0] != 0x01) || (status
[1] != (sc
->usb
.bTag
& 0x7f))) {
76 printf("READ_STATUS_BYTE failed: %d 0x%x 0x%x 0x%x\n", r
, status
[0], status
[1], status
[2]);
83 static struct usbtmc_capabilities
* usbtmc_get_capabilities(struct scope
*sc
)
86 static struct usbtmc_capabilities res
;
88 r
= usb_control_msg(sc
->usb
.dev
, 0xA1,
89 USBTMC_CTL_GET_CAPABILITIES
,
90 0, 0, (char*)&res
, sizeof(struct usbtmc_capabilities
),
92 if (r
!= sizeof(struct usbtmc_capabilities
)) {
93 printf("GET_CAPABILITIES failed: %s\n", usb_strerror());
97 printf("USBTMC Version %x.%x Capabilities:\n", res
.bcdUSBTMC
[0], res
.bcdUSBTMC
[1]);
98 if (res
.USBTMCIFcapabilities
& USBTMC_CAP_IF_INDICATOR_PULSE
)
99 printf("\tInterface supports indicator pulse\n");
101 if (res
.USBTMCIFcapabilities
& USBTMC_CAP_IF_TALKONLY
)
102 printf("\tInterface is talk only\n");
104 if (res
.USBTMCIFcapabilities
& USBTMC_CAP_IF_LISTENONLY
)
105 printf("\tInterface is listen only\n");
107 if (res
.USBTMCDEVcapabilities
& USBTMC_CAP_DEV_TERMCHAR_SUPP
)
108 printf("\tDevice supports Termchar\n");
110 printf("USB488 Version %x.%x Capabilities:\n", res
.bcdUSB488
[0], res
.bcdUSB488
[1]);
112 if (res
.USB488IFcapabilities
& USB488_CAP_IF_4882
)
113 printf("\tInterface is 488.2 compliant\n");
115 if (res
.USB488IFcapabilities
& USB488_CAP_IF_LOCKOUT
)
116 printf("\tInterface supports local lockout\n");
118 if (res
.USB488IFcapabilities
& USB488_CAP_IF_TRIGGER
)
119 printf("\tInterface supports TRIGGER\n");
121 if (res
.USB488DEVcapabilities
& USB488_CAP_DEV_SCPI
)
122 printf("\tDevice is SCPI compliant\n");
124 if (res
.USB488DEVcapabilities
& USB488_CAP_DEV_SR1
)
125 printf("\tDevice is SR1 capable\n");
127 if (res
.USB488DEVcapabilities
& USB488_CAP_DEV_RL1
)
128 printf("\tDevice is RL1 capable\n");
130 if (res
.USB488DEVcapabilities
& USB488_CAP_DEV_DT1
)
131 printf("\tDevice is DT1 capable\n");
136 static void usbtmc_clear(struct scope
*sc
)
139 unsigned char status
[2];
141 printf("Initiating clear...\n");
142 r
= usb_control_msg(sc
->usb
.dev
, 0xA1,
143 USBTMC_CTL_INITIATE_CLEAR
,
144 0, 0, (char*)status
, 1,
147 if ((r
!= 1) || status
[0] != 0x01) {
148 printf("INITIATE_CLEAR failed: %s\n", usb_strerror());
154 printf("Waiting for clear to complete...\n");
156 r
= usb_control_msg(sc
->usb
.dev
, 0xA1,
157 USBTMC_CTL_CHECK_CLEAR_STAT
,
158 0, 0, (char*)status
, 2,
161 if ((r
!= 2) || status
[0] != 0x01) {
162 printf("CHECK_CLEAR failed: %s\n", usb_strerror());
166 if (status
[1] & (1<<0)) {
167 printf("Success!\n");
174 * Send a scpi-command to the scope. The response goes into the buffer
175 * called resp, with a size of resplen. If resp==NULL, no response
178 int usbtmc_sendscpi(struct scope
*sc
, char* cmd
,
179 unsigned char *resp
, int resplen
) {
181 int cmdlen
= strlen(cmd
);
182 struct usbtmc_header
*req
;
186 len
= sizeof(struct usbtmc_header
) + cmdlen
;
190 req
= calloc(1, len
);
196 req
->MsgID
= USBTMC_DEV_DEP_MSG_OUT
;
197 req
->bTag
= sc
->usb
.bTag
;
198 req
->bTagInverse
= ~sc
->usb
.bTag
;
199 req
->TransferSize
= LE32(cmdlen
);
200 req
->bmTransferAttributes
= USBTMC_TRANSFERATTRIB_EOM
;
201 memcpy(req
->msg
, cmd
, cmdlen
);
203 if (sc
->usb
.brokenRigol
) {
204 r
=usb_bulk_write(sc
->usb
.dev
, sc
->usb
.ep_bulk_out
,
205 (char*)req
, sizeof(struct usbtmc_header
),
207 USB_ERROR("USBTMC_DEV_DEP_MSG_OUT1", r
);
209 r
=usb_bulk_write(sc
->usb
.dev
, sc
->usb
.ep_bulk_out
,
210 (char*)&(req
->msg
), len
- sizeof(struct usbtmc_header
),
212 USB_ERROR("USBTMC_DEV_DEP_MSG_OUT2", r
);
214 r
=usb_bulk_write(sc
->usb
.dev
, sc
->usb
.ep_bulk_out
,
215 (char*)req
, len
, USB_TIMEOUT
);
216 USB_ERROR("USBTMC_DEV_DEP_MSG_OUT", r
);
221 if (resp
!= NULL
&& resplen
!= 0) {
223 struct usbtmc_header
*res
;
228 req
= calloc(1, sizeof(struct usbtmc_header
));
234 req
->MsgID
= USBTMC_REQUEST_DEV_DEP_MSG_IN
;
235 req
->bTag
= sc
->usb
.bTag
;
236 req
->bTagInverse
= ~sc
->usb
.bTag
;
237 req
->TransferSize
= LE32(sc
->usb
.wMaxPacketSize_in
);
238 req
->bmTransferAttributes
= 0;
241 /* send read command */
242 r
=usb_bulk_write(sc
->usb
.dev
, sc
->usb
.ep_bulk_out
,
243 (char*)req
, sizeof(struct usbtmc_header
), USB_TIMEOUT
);
244 USB_ERROR("USBTMC_REQUEST_DEV_DEP_MSG_IN", r
);
248 buff
=malloc(sc
->usb
.wMaxPacketSize_in
);
254 r
=usb_bulk_read(sc
->usb
.dev
, sc
->usb
.ep_bulk_in
,
255 (char*)buff
, sc
->usb
.wMaxPacketSize_in
, USB_TIMEOUT
);
256 USB_ERROR("USBTMC_DEV_DEP_MSG_IN1", r
);
258 if (r
< sizeof(struct usbtmc_header
)) {
259 fprintf(stderr
, "Short read!\n");
263 bytes_read
= r
- sizeof(struct usbtmc_header
);
265 res
= (struct usbtmc_header
*)buff
;
266 len
= LE32(res
->TransferSize
);
268 memmove(buff
, buff
+ sizeof(struct usbtmc_header
), bytes_read
);
270 buff
= realloc(buff
, len
);
276 while ((len
- bytes_read
) > 0) {
277 r
=usb_bulk_read(sc
->usb
.dev
, sc
->usb
.ep_bulk_in
,
278 (char*)buff
+ bytes_read
, len
- bytes_read
,
280 USB_ERROR("USBTMC_DEV_DEP_MSG_INx", r
);
286 if (bytes_read
> resplen
) {
287 fprintf(stderr
, "Response buffer to small: %d instead of %d bytes!\n",
288 resplen
, bytes_read
);
289 bytes_read
= resplen
;
292 memcpy(resp
, buff
, bytes_read
);
300 void usbtmc_claim(struct scope
*sc
)
302 usb_claim_interface(sc
->usb
.dev
, 0);
305 void usbtmc_release(struct scope
*sc
)
307 usb_release_interface(sc
->usb
.dev
, 0);
310 /* Initialize the scope. */
311 struct scope
* usbtmc_initscope(void) {
318 /* Locate and open the scope */
319 sc
= usbtmc_find_scope();
325 sc
->usb
.cap
= usbtmc_get_capabilities(sc
);
326 printf("Device status: 0x%x\n", usbtmc_status(sc
));
327 /* The following code isn't really necessary, the program works
328 OK without it too. */
329 r
=usb_control_msg(sc
->usb
.dev
, 0xC8, 9, 0, 0, (char*)&vidpid
, 4, USB_TIMEOUT
);
332 fprintf (stderr
, "Error %d sending init message: %s\n",
334 fprintf (stderr
, "Do you have permission on the USB device?\n");
337 if (LE32(vidpid
)!=0x40005dc) {
338 fprintf(stderr
,"Init: buff[%i]=%x\n",r
,LE32(vidpid
));
343 void usbtmc_close(struct scope
*sc
)
345 /* Free up and exit */
346 usb_close(sc
->usb
.dev
);