]> git.zerfleddert.de Git - rigol/blob - usbtmc.c
4a23a4fad953da902da62f41ea6d8563e9137a53
[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 = 1;
51 sc->usb.ep_bulk_in = 2;
52 sc->usb.wMaxPacketSize_in = 0x40;
53
54 return sc;
55 }
56 }
57 }
58
59 return NULL;
60 }
61
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 */
67 int usbtmc_sendscpi(struct scope *sc, char* cmd,
68 unsigned char *resp, int resplen) {
69 int len,r;
70 int cmdlen = strlen(cmd);
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("USBTMC_DEV_DEP_MSG_OUT1", 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("USBTMC_DEV_DEP_MSG_OUT2", 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("USBTMC_DEV_DEP_MSG_OUT", r);
106 }
107
108 free(req);
109
110 if (resp != NULL && resplen != 0) {
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 = USBTMC_TRANSFERATTRIB_EOM;
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("USBTMC_REQUEST_DEV_DEP_MSG_IN", r);
134
135 free(req);
136
137 buff=malloc(sc->usb.wMaxPacketSize_in);
138 if (buff == NULL) {
139 perror("malloc");
140 exit(EXIT_FAILURE);
141 }
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("USBTMC_DEV_DEP_MSG_IN1", r);
146
147 if (r < sizeof(struct usbtmc_header)) {
148 fprintf(stderr, "Short read!\n");
149 return 0;
150 }
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("USBTMC_DEV_DEP_MSG_INx", 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;
185 }
186 return 0;
187 }
188
189 void usbtmc_claim(struct scope *sc)
190 {
191 usb_claim_interface(sc->usb.dev, 0);
192 }
193
194 void usbtmc_release(struct scope *sc)
195 {
196 usb_release_interface(sc->usb.dev, 0);
197 }
198
199 //Initialize the scope.
200 struct scope* usbtmc_initscope(void) {
201 int r;
202 unsigned char buff[10];
203 struct scope *sc;
204
205 /* Init libusb */
206 usb_init();
207 /* Locate and open the scope */
208 sc = usbtmc_find_scope();
209 if (!sc) {
210 return NULL;
211 }
212
213 usbtmc_claim(sc);
214 /* The following code isn't really necessary, the program works
215 OK without it too. */
216 r=usb_control_msg(sc->usb.dev, 0xC8, 9, 0, 0, (char*)buff, 4, USB_TIMEOUT);
217 usbtmc_release(sc);
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 }
224 if (LE32((*(uint32_t*)buff))!=0x40005dc) {
225 fprintf(stderr,"Init: buff[%i]=%x\n",r,LE32((*(uint32_t*)buff)));
226 }
227 return sc;
228 }
229
230 void usbtmc_close(struct scope *sc)
231 {
232 /* Free up and exit */
233 usb_close(sc->usb.dev);
234 }
Impressum, Datenschutz