10 #define USB_TIMEOUT 10000
11 #define USBTMC_IN_TRANSFERSIZE 0x800
13 #if BYTE_ORDER == LITTLE_ENDIAN
15 #elif BYTE_ORDER == BIG_ENDIAN
16 #define LE32(x) ((uint32_t)((((uint32_t)x)>>24) | ((((uint32_t)x)>>8) & 0xff00) | ((((uint32_t)x)<<8) & 0xff0000) | (((uint32_t)x)<<24)))
18 #error BYTE_ORDER not defined/known!
21 /* TODO: fix memory leak here: */
22 #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)
24 /* This routine locates a scope by VID/PID and returns a struct scope* for it */
25 static struct scope
* usbtmc_find_scope() {
27 struct usb_device
*dev
=NULL
;
28 struct usb_dev_handle
*devh
;
35 for (bus
=usb_busses
; bus
; bus
=bus
->next
) {
36 for (dev
=bus
->devices
; dev
; dev
=dev
->next
) {
37 if (dev
->descriptor
.idVendor
== 0x400 && dev
->descriptor
.idProduct
== 0x5dc) {
42 sc
= calloc(1, sizeof(struct scope
));
51 sc
->usb
.brokenRigol
= 1;
52 sc
->usb
.ep_bulk_out
= 0x01;
53 sc
->usb
.ep_bulk_in
= 0x82;
54 sc
->usb
.wMaxPacketSize_in
= 0x40;
64 static unsigned char usb488_status(struct scope
*sc
)
67 unsigned char status
[3];
71 r
= usb_control_msg(sc
->usb
.dev
, 0xA1,
72 USB488_CTL_READ_STATUS_BYTE
,
73 (sc
->usb
.bTag
& 0x7f), 0, (char*)status
, 3,
76 if ((r
!= 3) || (status
[0] != USBTMC_STATUS_SUCCESS
) || (status
[1] != (sc
->usb
.bTag
& 0x7f))) {
77 printf("READ_STATUS_BYTE failed: %d 0x%x 0x%x 0x%x\n", r
, status
[0], status
[1], status
[2]);
84 static struct usbtmc_capabilities
* usbtmc_get_capabilities(struct scope
*sc
)
87 static struct usbtmc_capabilities res
;
89 r
= usb_control_msg(sc
->usb
.dev
, 0xA1,
90 USBTMC_CTL_GET_CAPABILITIES
,
91 0, 0, (char*)&res
, sizeof(struct usbtmc_capabilities
),
93 if (r
!= sizeof(struct usbtmc_capabilities
)) {
94 printf("GET_CAPABILITIES failed: %s\n", usb_strerror());
98 printf("USBTMC Version %02x.%02x Capabilities:\n", res
.bcdUSBTMC
[0], res
.bcdUSBTMC
[1]);
99 if (res
.USBTMCIFcapabilities
& USBTMC_CAP_IF_INDICATOR_PULSE
)
100 printf("\tInterface supports indicator pulse\n");
102 if (res
.USBTMCIFcapabilities
& USBTMC_CAP_IF_TALKONLY
)
103 printf("\tInterface is talk only\n");
105 if (res
.USBTMCIFcapabilities
& USBTMC_CAP_IF_LISTENONLY
)
106 printf("\tInterface is listen only\n");
108 if (res
.USBTMCDEVcapabilities
& USBTMC_CAP_DEV_TERMCHAR_SUPP
)
109 printf("\tDevice supports Termchar\n");
111 printf("USB488 Version %02x.%02x Capabilities:\n", res
.bcdUSB488
[0], res
.bcdUSB488
[1]);
113 if (res
.USB488IFcapabilities
& USB488_CAP_IF_4882
)
114 printf("\tInterface is 488.2 compliant\n");
116 if (res
.USB488IFcapabilities
& USB488_CAP_IF_LOCKOUT
)
117 printf("\tInterface supports local lockout\n");
119 if (res
.USB488IFcapabilities
& USB488_CAP_IF_TRIGGER
)
120 printf("\tInterface supports TRIGGER\n");
122 if (res
.USB488DEVcapabilities
& USB488_CAP_DEV_SCPI
)
123 printf("\tDevice is SCPI compliant\n");
125 if (res
.USB488DEVcapabilities
& USB488_CAP_DEV_SR1
)
126 printf("\tDevice is SR1 capable\n");
128 if (res
.USB488DEVcapabilities
& USB488_CAP_DEV_RL1
)
129 printf("\tDevice is RL1 capable\n");
131 if (res
.USB488DEVcapabilities
& USB488_CAP_DEV_DT1
)
132 printf("\tDevice is DT1 capable\n");
137 static void usbtmc_clear(struct scope
*sc
)
140 unsigned char status
[2];
142 printf("Initiating clear...\n");
143 r
= usb_control_msg(sc
->usb
.dev
, 0xA1,
144 USBTMC_CTL_INITIATE_CLEAR
,
145 0, 0, (char*)status
, 1,
148 if ((r
!= 1) || status
[0] != USBTMC_STATUS_SUCCESS
) {
149 printf("INITIATE_CLEAR failed (0x%x): %s\n", status
[0], usb_strerror());
150 usb_reset(sc
->usb
.dev
);
157 printf("Waiting for clear to complete...\n");
159 r
= usb_control_msg(sc
->usb
.dev
, 0xA1,
160 USBTMC_CTL_CHECK_CLEAR_STAT
,
161 0, 0, (char*)status
, 2,
165 printf("CHECK_CLEAR failed: %s\n", usb_strerror());
169 if (USBTMC_STATUS_FAIL(status
[0])) {
170 printf("CHECK_CLEAR failed: 0x%x\n", status
[0]);
174 if ((status
[0] == USBTMC_STATUS_SUCCESS
) && (status
[1] == 0)) {
175 printf("Success!\n");
182 * Send a scpi-command to the scope. The response goes into the buffer
183 * called resp, with a size of resplen. If resp==NULL, no response
186 int usbtmc_sendscpi(struct scope
*sc
, char* cmd
,
187 unsigned char *resp
, int resplen
) {
189 int cmdlen
= strlen(cmd
);
190 struct usbtmc_header
*req
;
194 len
= sizeof(struct usbtmc_header
) + cmdlen
;
198 req
= calloc(1, len
);
204 req
->MsgID
= USBTMC_DEV_DEP_MSG_OUT
;
205 req
->bTag
= sc
->usb
.bTag
;
206 req
->bTagInverse
= ~sc
->usb
.bTag
;
207 req
->TransferSize
= LE32(cmdlen
);
208 req
->bmTransferAttributes
= USBTMC_TRANSFERATTRIB_EOM
;
209 memcpy(req
->msg
, cmd
, cmdlen
);
211 if (sc
->usb
.brokenRigol
) {
212 r
=usb_bulk_write(sc
->usb
.dev
, sc
->usb
.ep_bulk_out
,
213 (char*)req
, sizeof(struct usbtmc_header
),
215 USB_ERROR("USBTMC_DEV_DEP_MSG_OUT1", r
);
217 r
=usb_bulk_write(sc
->usb
.dev
, sc
->usb
.ep_bulk_out
,
218 (char*)&(req
->msg
), len
- sizeof(struct usbtmc_header
),
220 USB_ERROR("USBTMC_DEV_DEP_MSG_OUT2", r
);
222 r
=usb_bulk_write(sc
->usb
.dev
, sc
->usb
.ep_bulk_out
,
223 (char*)req
, len
, USB_TIMEOUT
);
224 USB_ERROR("USBTMC_DEV_DEP_MSG_OUT", r
);
229 if (resp
!= NULL
&& resplen
!= 0) {
230 unsigned char *buff
= NULL
;
231 unsigned char rxbuff
[USBTMC_IN_TRANSFERSIZE
];
232 struct usbtmc_header
*res
;
234 unsigned int transfer_size
= USBTMC_IN_TRANSFERSIZE
;
235 unsigned int headerlen
;
237 req
= calloc(1, sizeof(struct usbtmc_header
));
243 if (sc
->usb
.brokenRigol
== 1) {
244 transfer_size
= sc
->usb
.wMaxPacketSize_in
;
251 if ((sc
->usb
.brokenRigol
== 0) || (bytes_read
== 0)) {
254 req
->MsgID
= USBTMC_REQUEST_DEV_DEP_MSG_IN
;
255 req
->bTag
= sc
->usb
.bTag
;
256 req
->bTagInverse
= ~sc
->usb
.bTag
;
257 req
->TransferSize
= LE32(transfer_size
);
258 req
->bmTransferAttributes
= 0;
261 /* send read command */
262 r
=usb_bulk_write(sc
->usb
.dev
, sc
->usb
.ep_bulk_out
,
263 (char*)req
, sizeof(struct usbtmc_header
), USB_TIMEOUT
);
264 USB_ERROR("USBTMC_REQUEST_DEV_DEP_MSG_IN", r
);
266 headerlen
= sizeof(struct usbtmc_header
);
269 r
=usb_bulk_read(sc
->usb
.dev
, sc
->usb
.ep_bulk_in
,
270 (char*)rxbuff
, transfer_size
, USB_TIMEOUT
);
271 USB_ERROR("USBTMC_DEV_DEP_MSG_IN", r
);
274 fprintf(stderr
, "Short read!\n");
280 res
= (struct usbtmc_header
*)rxbuff
;
282 if ((res
->bTag
!= sc
->usb
.bTag
) ||
283 (res
->bTagInverse
!= (unsigned char)(~sc
->usb
.bTag
))) {
284 fprintf(stderr
, "Wrong TAG received! We: 0x%02x, Scope: 0x%02x\n", sc
->usb
.bTag
, res
->bTag
);
285 if (sc
->usb
.brokenRigol
== 1) {
286 fprintf(stderr
, "Tying to restart transfer...\n");
294 len
= LE32(res
->TransferSize
);
303 if ((sc
->usb
.brokenRigol
== 0) || (transfer_size
== USBTMC_IN_TRANSFERSIZE
) ||
304 ((r
- sizeof(struct usbtmc_header
) >= len
))) {
305 memcpy(buff
+ bytes_read
, rxbuff
+ headerlen
, r
- headerlen
);
306 bytes_read
+= r
- headerlen
;
309 transfer_size
= USBTMC_IN_TRANSFERSIZE
;
310 } while(bytes_read
< len
);
315 if (bytes_read
> resplen
) {
316 fprintf(stderr
, "Response buffer to small: %d instead of %d bytes!\n",
317 resplen
, bytes_read
);
318 bytes_read
= resplen
;
321 memcpy(resp
, buff
, bytes_read
);
329 void usbtmc_claim(struct scope
*sc
)
331 usb_claim_interface(sc
->usb
.dev
, 0);
334 void usbtmc_release(struct scope
*sc
)
336 usb_release_interface(sc
->usb
.dev
, 0);
339 /* Initialize the scope. */
340 struct scope
* usbtmc_initscope(void) {
347 /* Locate and open the scope */
348 sc
= usbtmc_find_scope();
354 sc
->usb
.cap
= usbtmc_get_capabilities(sc
);
355 printf("Device status: 0x%x\n", usb488_status(sc
));
356 /* The following code isn't really necessary, the program works
357 OK without it too. */
358 r
=usb_control_msg(sc
->usb
.dev
, 0xC8, 9, 0, 0, (char*)&vidpid
, 4, USB_TIMEOUT
);
361 fprintf (stderr
, "Error %d sending init message: %s\n",
363 fprintf (stderr
, "Do you have permission on the USB device?\n");
366 if (LE32(vidpid
)!=0x40005dc) {
367 fprintf(stderr
,"Init: buff[%i]=%x\n",r
,LE32(vidpid
));
372 void usbtmc_close(struct scope
*sc
)
374 /* Free up and exit */
375 usb_close(sc
->usb
.dev
);