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