6 #include <libusb-1.0/libusb.h>
12 #define USB_TIMEOUT 10000
13 #define USBTMC_IN_TRANSFERSIZE 0x800
15 #define ID_VENDOR 0x400
16 #define ID_PRODUCT 0x5dc
18 #if BYTE_ORDER == LITTLE_ENDIAN
20 #elif BYTE_ORDER == BIG_ENDIAN
21 #define LE32(x) ((uint32_t)((((uint32_t)x)>>24) | ((((uint32_t)x)>>8) & 0xff00) | ((((uint32_t)x)<<8) & 0xff0000) | (((uint32_t)x)<<24)))
23 #error BYTE_ORDER not defined/known!
26 /* TODO: fix memory leak here: */
27 #define USB_ERROR(s, x) do { if (x < 0) { fprintf(stderr, "usb %s: %s\n", s, usb_strerror(x)); usbtmc_clear(sc); return 0; } } while(0)
29 /* Not in all libusb-1.0 versions, so we have to roll our own :-( */
30 static char * usb_strerror(int e
)
32 static char unknerr
[256];
38 return "Input/output error";
39 case LIBUSB_ERROR_INVALID_PARAM
:
40 return "Invalid parameter";
41 case LIBUSB_ERROR_ACCESS
:
42 return "Access denied (insufficient permissions)";
43 case LIBUSB_ERROR_NO_DEVICE
:
44 return "No such device (it may have been disconnected)";
45 case LIBUSB_ERROR_NOT_FOUND
:
46 return "Entity not found";
47 case LIBUSB_ERROR_BUSY
:
48 return "Resource busy";
49 case LIBUSB_ERROR_TIMEOUT
:
50 return "Operation timed out";
51 case LIBUSB_ERROR_OVERFLOW
:
53 case LIBUSB_ERROR_PIPE
:
55 case LIBUSB_ERROR_INTERRUPTED
:
56 return "System call interrupted (perhaps due to signal)";
57 case LIBUSB_ERROR_NO_MEM
:
58 return "Insufficient memory";
59 case LIBUSB_ERROR_NOT_SUPPORTED
:
60 return "Operation not supported or unimplemented on this platform";
61 case LIBUSB_ERROR_OTHER
:
64 snprintf(unknerr
, sizeof(unknerr
), "Unknown error code %d / 0x%02x", e
, e
);
68 /* This routine locates a scope by VID/PID and returns a struct scope* for it */
69 static struct scope
* usbtmc_find_scope() {
70 libusb_device_handle
*devh
= NULL
;
77 cnt
= libusb_get_device_list(NULL
, &list
);
79 fprintf(stderr
, "Can't get USB device list: %d\n", (int)cnt
);
83 for (i
= 0; i
< cnt
; i
++){
84 struct libusb_device_descriptor desc
;
86 err
= libusb_get_device_descriptor(list
[i
], &desc
);
90 if ((desc
.idVendor
== ID_VENDOR
) && (desc
.idProduct
== ID_PRODUCT
)) {
91 libusb_device
*dev
= list
[i
];
93 err
= libusb_open(dev
, &devh
);
95 fprintf(stderr
, "Can't open device: %d\n", err
);
99 sc
= calloc(1, sizeof(struct scope
));
108 sc
->usb
.brokenRigol
= 1;
109 sc
->usb
.ep_bulk_out
= 0x01;
110 sc
->usb
.ep_bulk_in
= 0x82;
111 sc
->usb
.wMaxPacketSize_in
= 0x40;
121 static unsigned char usb488_status(struct scope
*sc
)
124 unsigned char status
[3];
128 r
= libusb_control_transfer(sc
->usb
.dev
, 0xA1,
129 USB488_CTL_READ_STATUS_BYTE
,
130 (sc
->usb
.bTag
& 0x7f), 0, status
, 3,
133 if ((r
!= 3) || (status
[0] != USBTMC_STATUS_SUCCESS
) || (status
[1] != (sc
->usb
.bTag
& 0x7f))) {
134 printf("READ_STATUS_BYTE failed: %d 0x%x 0x%x 0x%x\n", r
, status
[0], status
[1], status
[2]);
141 static struct usbtmc_capabilities
* usbtmc_get_capabilities(struct scope
*sc
)
144 static struct usbtmc_capabilities res
;
146 r
= libusb_control_transfer(sc
->usb
.dev
, 0xA1,
147 USBTMC_CTL_GET_CAPABILITIES
,
148 0, 0, (unsigned char*)&res
, sizeof(struct usbtmc_capabilities
),
150 if (r
!= sizeof(struct usbtmc_capabilities
)) {
151 printf("GET_CAPABILITIES failed: %s\n", usb_strerror(r
));
155 printf("USBTMC Version %02x.%02x Capabilities:\n", res
.bcdUSBTMC
[0], res
.bcdUSBTMC
[1]);
156 if (res
.USBTMCIFcapabilities
& USBTMC_CAP_IF_INDICATOR_PULSE
)
157 printf("\tInterface supports indicator pulse\n");
159 if (res
.USBTMCIFcapabilities
& USBTMC_CAP_IF_TALKONLY
)
160 printf("\tInterface is talk only\n");
162 if (res
.USBTMCIFcapabilities
& USBTMC_CAP_IF_LISTENONLY
)
163 printf("\tInterface is listen only\n");
165 if (res
.USBTMCDEVcapabilities
& USBTMC_CAP_DEV_TERMCHAR_SUPP
)
166 printf("\tDevice supports Termchar\n");
168 printf("USB488 Version %02x.%02x Capabilities:\n", res
.bcdUSB488
[0], res
.bcdUSB488
[1]);
170 if (res
.USB488IFcapabilities
& USB488_CAP_IF_4882
)
171 printf("\tInterface is 488.2 compliant\n");
173 if (res
.USB488IFcapabilities
& USB488_CAP_IF_LOCKOUT
)
174 printf("\tInterface supports local lockout\n");
176 if (res
.USB488IFcapabilities
& USB488_CAP_IF_TRIGGER
)
177 printf("\tInterface supports TRIGGER\n");
179 if (res
.USB488DEVcapabilities
& USB488_CAP_DEV_SCPI
)
180 printf("\tDevice is SCPI compliant\n");
182 if (res
.USB488DEVcapabilities
& USB488_CAP_DEV_SR1
)
183 printf("\tDevice is SR1 capable\n");
185 if (res
.USB488DEVcapabilities
& USB488_CAP_DEV_RL1
)
186 printf("\tDevice is RL1 capable\n");
188 if (res
.USB488DEVcapabilities
& USB488_CAP_DEV_DT1
)
189 printf("\tDevice is DT1 capable\n");
194 void usbtmc_reset(struct scope
*sc
)
196 libusb_reset_device(sc
->usb
.dev
);
200 static void usbtmc_clear(struct scope
*sc
)
203 unsigned char status
[2];
205 printf("Initiating clear...\n");
206 r
= libusb_control_transfer(sc
->usb
.dev
, 0xA1,
207 USBTMC_CTL_INITIATE_CLEAR
,
211 if ((r
!= 1) || status
[0] != USBTMC_STATUS_SUCCESS
) {
212 printf("INITIATE_CLEAR failed (0x%x): %s\n", status
[0], usb_strerror(r
));
219 printf("Waiting for clear to complete...\n");
221 r
= libusb_control_transfer(sc
->usb
.dev
, 0xA1,
222 USBTMC_CTL_CHECK_CLEAR_STAT
,
227 printf("CHECK_CLEAR failed: %s\n", usb_strerror(r
));
231 if (USBTMC_STATUS_FAIL(status
[0])) {
232 printf("CHECK_CLEAR failed: 0x%x\n", status
[0]);
236 if ((status
[0] == USBTMC_STATUS_SUCCESS
) && (status
[1] == 0)) {
237 printf("Success!\n");
244 * Send a scpi-command to the scope. The response goes into the buffer
245 * called resp, with a size of resplen. If resp==NULL, no response
248 int usbtmc_sendscpi(struct scope
*sc
, char* cmd
,
249 unsigned char *resp
, int resplen
) {
252 int cmdlen
= strlen(cmd
);
254 struct usbtmc_header
*req
;
258 len
= sizeof(struct usbtmc_header
) + cmdlen
;
262 req
= calloc(1, len
);
268 req
->MsgID
= USBTMC_DEV_DEP_MSG_OUT
;
269 req
->bTag
= sc
->usb
.bTag
;
270 req
->bTagInverse
= ~sc
->usb
.bTag
;
271 req
->TransferSize
= LE32(cmdlen
);
272 req
->bmTransferAttributes
= USBTMC_TRANSFERATTRIB_EOM
;
273 memcpy(req
->msg
, cmd
, cmdlen
);
275 if (sc
->usb
.brokenRigol
) {
276 r
=libusb_bulk_transfer(sc
->usb
.dev
, sc
->usb
.ep_bulk_out
,
277 (unsigned char*)req
, sizeof(struct usbtmc_header
),
280 USB_ERROR("USBTMC_DEV_DEP_MSG_OUT1", r
);
282 r
=libusb_bulk_transfer(sc
->usb
.dev
, sc
->usb
.ep_bulk_out
,
283 (unsigned char*)&(req
->msg
), len
- sizeof(struct usbtmc_header
),
286 USB_ERROR("USBTMC_DEV_DEP_MSG_OUT2", r
);
288 r
=libusb_bulk_transfer(sc
->usb
.dev
, sc
->usb
.ep_bulk_out
,
289 (unsigned char*)req
, len
, &transferred
, USB_TIMEOUT
);
290 USB_ERROR("USBTMC_DEV_DEP_MSG_OUT", r
);
295 if (resp
!= NULL
&& resplen
!= 0) {
296 unsigned char *buff
= NULL
;
297 unsigned char rxbuff
[USBTMC_IN_TRANSFERSIZE
];
298 struct usbtmc_header
*res
;
300 unsigned int read_size
= USBTMC_IN_TRANSFERSIZE
;
301 unsigned int headerlen
;
303 req
= calloc(1, sizeof(struct usbtmc_header
));
309 if (sc
->usb
.brokenRigol
== 1) {
310 read_size
= sc
->usb
.wMaxPacketSize_in
;
317 if ((sc
->usb
.brokenRigol
== 0) || (bytes_read
== 0)) {
320 req
->MsgID
= USBTMC_REQUEST_DEV_DEP_MSG_IN
;
321 req
->bTag
= sc
->usb
.bTag
;
322 req
->bTagInverse
= ~sc
->usb
.bTag
;
323 req
->TransferSize
= LE32(USBTMC_IN_TRANSFERSIZE
);
324 req
->bmTransferAttributes
= 0;
327 /* send read command */
328 r
=libusb_bulk_transfer(sc
->usb
.dev
, sc
->usb
.ep_bulk_out
,
329 (unsigned char*)req
, sizeof(struct usbtmc_header
), &transferred
, USB_TIMEOUT
);
330 USB_ERROR("USBTMC_REQUEST_DEV_DEP_MSG_IN", r
);
332 headerlen
= sizeof(struct usbtmc_header
);
335 err
=libusb_bulk_transfer(sc
->usb
.dev
, sc
->usb
.ep_bulk_in
,
336 (unsigned char*)rxbuff
, read_size
, &r
, USB_TIMEOUT
);
337 USB_ERROR("USBTMC_DEV_DEP_MSG_IN", err
);
340 fprintf(stderr
, "Short read!\n");
345 res
= (struct usbtmc_header
*)rxbuff
;
347 if ((res
->bTag
!= sc
->usb
.bTag
) ||
348 (res
->bTagInverse
!= (unsigned char)(~sc
->usb
.bTag
))) {
349 fprintf(stderr
, "Wrong TAG received! We: 0x%02x, Scope: 0x%02x\n", sc
->usb
.bTag
, res
->bTag
);
350 if (sc
->usb
.brokenRigol
== 1) {
351 fprintf(stderr
, "Tying to restart transfer...\n");
359 len
= LE32(res
->TransferSize
);
368 if ((r
- headerlen
) > 0) {
369 memcpy(buff
+ bytes_read
, rxbuff
+ headerlen
, r
- headerlen
);
370 bytes_read
+= r
- headerlen
;
373 read_size
= USBTMC_IN_TRANSFERSIZE
;
374 } while(bytes_read
< len
);
379 if (bytes_read
> resplen
) {
380 fprintf(stderr
, "Response buffer to small: %d instead of %d bytes!\n",
381 resplen
, bytes_read
);
382 bytes_read
= resplen
;
385 memcpy(resp
, buff
, bytes_read
);
393 void usbtmc_claim(struct scope
*sc
)
395 libusb_claim_interface(sc
->usb
.dev
, 0);
398 void usbtmc_release(struct scope
*sc
)
400 libusb_release_interface(sc
->usb
.dev
, 0);
403 /* Initialize the scope. */
404 struct scope
* usbtmc_initscope(void) {
411 /* Locate and open the scope */
412 sc
= usbtmc_find_scope();
418 sc
->usb
.cap
= usbtmc_get_capabilities(sc
);
419 printf("Device status: 0x%x\n", usb488_status(sc
));
420 /* The following code isn't really necessary, the program works
421 OK without it too. */
422 r
=libusb_control_transfer(sc
->usb
.dev
, 0xC8, 9, 0, 0, (unsigned char*)&vidpid
, 4, USB_TIMEOUT
);
425 fprintf (stderr
, "Error %d sending init message: %s\n",
427 fprintf (stderr
, "Do you have permission on the USB device?\n");
430 if (LE32(vidpid
)!=0x40005dc) {
431 fprintf(stderr
,"Init: buff[%i]=%x\n",r
,LE32(vidpid
));
436 void usbtmc_close(struct scope
*sc
)
438 /* Free up and exit */
439 libusb_close(sc
->usb
.dev
);