completely rewritten usbtmc_sendscpi
[rigol] / usbtmc.c
CommitLineData
58a9e276
MG
1#include <string.h>
2#include <stdio.h>
3#include <stdint.h>
4#include <usb.h>
5#include <arpa/inet.h>
6
7906b395 7#include "scope.h"
58a9e276
MG
8#include "usbtmc.h"
9
7a226bb8 10#define USB_TIMEOUT 50000
165abe62 11
ddf9f28b
MG
12#if BYTE_ORDER == LITTLE_ENDIAN
13#define LE32(x) x
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)))
16#else
17#error BYTE_ORDER not defined/known!
18#endif
19
7b575069 20#define USB_ERROR(x) do { if (x < 0) { fprintf(stderr, "usb: %s\n", usb_strerror()); exit(EXIT_FAILURE); } } while(0)
58a9e276 21
7b575069
MG
22/* This routine locates a scope by VID/PID and returns a struct scope* for it */
23static struct scope* usbtmc_find_scope() {
58a9e276
MG
24 struct usb_bus *bus;
25 struct usb_device *dev=NULL;
7b575069
MG
26 struct usb_dev_handle *devh;
27
28 struct scope *sc;
29
58a9e276
MG
30 usb_find_busses();
31 usb_find_devices();
7b575069 32
58a9e276
MG
33 for (bus=usb_busses; bus; bus=bus->next) {
34 for (dev=bus->devices; dev; dev=dev->next) {
7b575069
MG
35 if (dev->descriptor.idVendor == 0x400 && dev->descriptor.idProduct == 0x5dc) {
36 devh = usb_open(dev);
37 if (devh == NULL)
38 return NULL;
39
40 sc = calloc(1, sizeof(struct scope));
41 if (sc == NULL) {
42 perror("calloc");
43 exit(EXIT_FAILURE);
44 }
45
46 sc->usb.dev = devh;
47
48 /* TODO: FIXME */
49 sc->usb.brokenRigol = 1;
50 sc->usb.ep_bulk_out = 1;
51 sc->usb.ep_bulk_in = 2;
52 sc->usb.wMaxPacketSize_in = 0x40;
53
54 return sc;
58a9e276
MG
55 }
56 }
57 }
7b575069 58
58a9e276
MG
59 return NULL;
60}
61
7b575069
MG
62/*
63 * Send a scpi-command to the scope. The response goes into the buffer
64 * called resp, with a size of resplen. If resp==NULL, no response
65 * is requested.
66 */
7906b395 67int usbtmc_sendscpi(struct scope *sc, char* cmd,
58a9e276 68 unsigned char *resp, int resplen) {
7b575069 69 int len,r;
58a9e276 70 int cmdlen = strlen(cmd);
7b575069
MG
71 struct usbtmc_header *req;
72
73 sc->usb.bTag++;
74
75 len = sizeof(struct usbtmc_header) + cmdlen;
76 if (len%4)
77 len += 4 - (len%4);
78
79 req = calloc(1, len);
80 if (req == NULL) {
81 perror("calloc");
82 exit(EXIT_FAILURE);
83 }
84
85 req->MsgID = USBTMC_DEV_DEP_MSG_OUT;
86 req->bTag = sc->usb.bTag;
87 req->bTagInverse = ~sc->usb.bTag;
88 req->TransferSize = LE32(cmdlen);
89 req->bmTransferAttributes = USBTMC_TRANSFERATTRIB_EOM;
90 memcpy(req->msg, cmd, cmdlen);
91
92 if (sc->usb.brokenRigol) {
93 r=usb_bulk_write(sc->usb.dev, sc->usb.ep_bulk_out,
94 (char*)req, sizeof(struct usbtmc_header),
95 USB_TIMEOUT);
96 USB_ERROR(r);
97
98 r=usb_bulk_write(sc->usb.dev, sc->usb.ep_bulk_out,
99 (char*)&(req->msg), len - sizeof(struct usbtmc_header),
100 USB_TIMEOUT);
101 USB_ERROR(r);
102 } else {
103 r=usb_bulk_write(sc->usb.dev, sc->usb.ep_bulk_out,
104 (char*)req, len, USB_TIMEOUT);
105 USB_ERROR(r);
106 }
107
108 free(req);
109
58a9e276 110 if (resp != NULL && resplen != 0) {
7b575069
MG
111 unsigned char *buff;
112 struct usbtmc_header *res;
113 int bytes_read;
114
115 sc->usb.bTag++;
116
117 req = calloc(1, sizeof(struct usbtmc_header));
118 if (req == NULL) {
119 perror("calloc");
120 exit(EXIT_FAILURE);
121 }
122
123 req->MsgID = USBTMC_REQUEST_DEV_DEP_MSG_IN;
124 req->bTag = sc->usb.bTag;
125 req->bTagInverse = ~sc->usb.bTag;
126 req->TransferSize = LE32(sc->usb.wMaxPacketSize_in);
127 req->bmTransferAttributes = 0;
128 req->TermChar = 0;
129
130 /* send read command */
131 r=usb_bulk_write(sc->usb.dev, sc->usb.ep_bulk_out,
132 (char*)req, sizeof(struct usbtmc_header), USB_TIMEOUT);
133 USB_ERROR(r);
134
135 free(req);
136
137 buff=malloc(sc->usb.wMaxPacketSize_in);
138 if (buff == NULL) {
139 perror("malloc");
140 exit(EXIT_FAILURE);
58a9e276 141 }
7b575069
MG
142
143 r=usb_bulk_read(sc->usb.dev, sc->usb.ep_bulk_in,
144 (char*)buff, sc->usb.wMaxPacketSize_in, USB_TIMEOUT);
145 USB_ERROR(r);
146
147 if (r < sizeof(struct usbtmc_header)) {
148 fprintf(stderr, "Short read!\n");
149 return 0;
58a9e276 150 }
7b575069
MG
151
152 bytes_read = r - sizeof(struct usbtmc_header);
153
154 res = (struct usbtmc_header*)buff;
155 len = LE32(res->TransferSize);
156
157 memmove(buff, buff + sizeof(struct usbtmc_header), bytes_read);
158
159 buff = realloc(buff, len);
160 if (buff == NULL) {
161 perror("realloc");
162 exit(EXIT_FAILURE);
163 }
164
165 while ((len - bytes_read) > 0) {
166 r=usb_bulk_read(sc->usb.dev, sc->usb.ep_bulk_in,
167 (char*)buff + bytes_read, len - bytes_read,
168 USB_TIMEOUT);
169 USB_ERROR(r);
170
171 bytes_read += r;
172 }
173
174 /* TODO: FIXME */
175 if (bytes_read > resplen) {
176 fprintf(stderr, "Response buffer to small: %d instead of %d bytes!\n",
177 resplen, bytes_read);
178 bytes_read = resplen;
179 }
180
181 memcpy(resp, buff, bytes_read);
182 free(buff);
183
184 return bytes_read;
58a9e276
MG
185 }
186 return 0;
187}
188
7906b395 189void usbtmc_claim(struct scope *sc)
ad9fbc05 190{
7906b395 191 usb_claim_interface(sc->usb.dev, 0);
ad9fbc05
MG
192}
193
7906b395 194void usbtmc_release(struct scope *sc)
ad9fbc05 195{
7906b395 196 usb_release_interface(sc->usb.dev, 0);
ad9fbc05
MG
197}
198
58a9e276 199//Initialize the scope.
7906b395 200struct scope* usbtmc_initscope(void) {
58a9e276
MG
201 int r;
202 unsigned char buff[10];
7906b395 203 struct scope *sc;
58a9e276 204
7b575069 205 /* Init libusb */
58a9e276 206 usb_init();
7b575069
MG
207 /* Locate and open the scope */
208 sc = usbtmc_find_scope();
209 if (!sc) {
2999345d 210 return NULL;
58a9e276 211 }
7906b395 212
7906b395 213 usbtmc_claim(sc);
7b575069
MG
214 /* The following code isn't really necessary, the program works
215 OK without it too. */
7906b395
MG
216 r=usb_control_msg(sc->usb.dev, 0xC8, 9, 0, 0, (char*)buff, 4, USB_TIMEOUT);
217 usbtmc_release(sc);
58a9e276
MG
218 if (r < 0) {
219 fprintf (stderr, "Error %d sending init message: %s\n",
220 r, strerror (-r));
221 fprintf (stderr, "Do you have permission on the USB device?\n");
222 exit (1);
223 }
7b575069
MG
224 if (LE32((*(uint32_t*)buff))!=0x40005dc) {
225 fprintf(stderr,"Init: buff[%i]=%x\n",r,LE32((*(uint32_t*)buff)));
58a9e276 226 }
7906b395 227 return sc;
58a9e276 228}
b74fea90 229
7906b395 230void usbtmc_close(struct scope *sc)
b74fea90 231{
7b575069 232 /* Free up and exit */
7906b395 233 usb_close(sc->usb.dev);
b74fea90 234}
Impressum, Datenschutz