]> git.zerfleddert.de Git - rigol/blob - rigol.c
Initial import of rew's USB control software for rigol scopes
[rigol] / rigol.c
1 /*
2 Sprite_tms hack to communicate with a Rigol DS1000-series scope using Linux.
3 This code is licensed under the GPL V3.
4
5 Warning: This code can in theory fubar the communications with the scope to a
6 point where the Linux USB-stack seems to get confused. Do a
7 rmmod uhci_hcd; modprobe uhci_hcd
8 (or alternately: use ohci_hcd) if that happens and you should be fine.
9 */
10
11 #include <usb.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18
19 #include <readline/readline.h>
20 #include <readline/history.h>
21
22
23 unsigned char seq=0;
24
25 //This routine locates a scope by VID/PID and returns an opened handle to it.
26 usb_dev_handle *find_scope() {
27 struct usb_bus *bus;
28 struct usb_device *dev=NULL;
29 usb_find_busses();
30 usb_find_devices();
31 for (bus=usb_busses; bus; bus=bus->next) {
32 for (dev=bus->devices; dev; dev=dev->next) {
33 // fprintf(stderr,"Prod/dev: %04X:%04X\n",dev->descriptor.idVendor,dev->descriptor.idProduct);
34 if (dev->descriptor.idVendor==0x400 && dev->descriptor.idProduct==0x5dc) {
35 return usb_open(dev);
36 }
37 }
38 }
39 return NULL;
40 }
41
42 //Helper-routine: Convert a little-endian 4-byte word to an int
43 void int2chars(unsigned char *buff,unsigned int a) {
44 buff[3]=(a>>24)&0xff;
45 buff[2]=(a>>16)&0xff;
46 buff[1]=(a>>8)&0xff;
47 buff[0]=(a)&0xff;
48 }
49
50 //Helper-routine: Convert an int to little-endian 4-byte word
51 unsigned int chars2int(unsigned char *buff) {
52 unsigned int a;
53 a=buff[3]<<24;
54 a+=buff[2]<<16;
55 a+=buff[1]<<8;
56 a+=buff[0];
57 return a;
58 }
59
60 #define MIN(a,b) (((a)<(b))?(a):(b))
61
62 inline char printable (char ch)
63 {
64 if (ch < ' ') return '.';
65 if (ch > '~') return '.';
66 return ch;
67 }
68
69 //Debugging: Print a buffers contents in hex
70 void printb (unsigned char *pkt, int len)
71 {
72 int i, j;
73
74 for (i=0;i<len;i+= 16) {
75 printf ("%04x: ", i);
76 for (j=0;j < MIN(len-i, 16);j++) {
77 printf (" %02x", pkt[i+j]);
78 if (j == 7) printf (" ");
79 }
80 if (j < 7) printf (" ");
81 for (;j<17;j++)
82 printf (" ");
83
84 for (j=0;j < MIN(len-i, 16);j++) {
85 printf ("%c", printable (pkt[i+j]));
86 }
87 printf ("\n");
88 }
89 }
90
91 //Send a scpi-command to the scope. The response goes into the buffer
92 //called resp, with a size of resplen. If resp==NULL, no response
93 //is requested.
94 int sendscpi(usb_dev_handle *dev, unsigned char* cmd,
95 unsigned char *resp, int resplen) {
96 char *buff;
97 int len,r,i;
98 buff=malloc(0x40);
99 seq++;
100 buff[0]=1; //func
101 buff[1]=seq; buff[2]=~seq; //nseq
102 buff[3]=0;
103 int2chars(buff+4,strlen(cmd));
104 buff[8]=1;
105 buff[9]=0x37;
106 buff[10]=0x39;
107 buff[11]=0x39;
108 // fprintf(stderr,"Writing header len=%d\n", strlen (cmd));
109 // printb(buff,12);
110 r=usb_bulk_write(dev,1,buff,12,1000);
111 // fprintf(stderr,"%i bytes written. Writing cmd\n",r);
112 // printb(cmd,strlen(cmd));
113 r=usb_bulk_write(dev,1,cmd,strlen(cmd),1000);
114 // fprintf(stderr,"%i bytes written.\n",r);
115 if (resp != NULL && resplen != 0) {
116 //send read command
117 buff[0]=2; //func
118 seq++;
119 buff[1]=seq; buff[2]=~seq; //nseq
120 int2chars(buff+4,0x40);
121 buff[8]=1;
122 buff[9]=0xA;
123 buff[10]=0;
124 buff[11]=0;
125 // fprintf(stderr,"Writing resp req header\n");
126 // printb(buff,12);
127 r=usb_bulk_write(dev,1,buff,12,1000);
128 // fprintf(stderr,"%i bytes written. Reading response hdr\n",r);
129 r=usb_bulk_read(dev,2,buff,0x40,1000);
130 // printb(buff,r);
131 len=chars2int(buff+4);
132 // fprintf(stderr,"%i bytes read. Resplen=%i\n",r,len);
133 for (i=0; i<(r-12); i++) {
134 if (i<resplen) resp[i] = buff[i+12];
135 }
136 // printb(resp,r-12);
137 if (len > 0x40-12) {
138 // fprintf(stderr," Reading response:\n");
139 if (resplen<len) len=resplen;
140 r=usb_bulk_read(dev,2,resp+(0x40-12),len-(0x40-12),1000);
141 // fprintf(stderr,"%i bytes read, wanted %i.\n", r, len-(0x40-12));
142 return r+(0x40-12);
143 }
144 return len;
145 }
146 return 0;
147 }
148
149 //Initialize the scope.
150 void initscope(usb_dev_handle *dev) {
151 int r;
152 char buff[10];
153 usb_claim_interface(dev,0);
154 //The following code isn't really necessary, the program works
155 //OK without it too.
156 r=usb_control_msg(dev, 0xC8, 9, 0, 0, buff, 4, 1000);
157 if (r < 0) {
158 fprintf (stderr, "Error %d sending init message: %s\n",
159 r, strerror (-r));
160 fprintf (stderr, "Do you have permission on the USB device?\n");
161 exit (1);
162 }
163 if (chars2int(buff)!=0x40004dc) {
164 fprintf(stderr,"Init: buff[%i]=%x\n",r,chars2int(buff));
165 }
166 return;
167 }
168
169 #define HAVE_READLINE
170 #ifndef HAVE_READLINE
171
172 char *readline (prompt)
173 {
174 char *buf;
175
176 printf (prompt);
177 fflush (stdout);
178 buf = malloc (1024);
179
180 if (fgets (buf, 1023, stdin) == NULL) {
181 free (buf);
182 return NULL;
183 }
184 l = strlen (buf);
185 if (buf[l-1] == '\n') {
186 buf[l] = 0;
187 }
188 return buf;
189 }
190
191 void add_history (char *buf)
192 {
193 }
194 #endif
195
196
197 void do_plot (struct usb_dev_handle *sc)
198 {
199 unsigned char ch1[1024], ch2[1024];
200 int i, l;
201
202 static FILE *gnuplot=NULL;
203 FILE *fp;
204
205 l = sendscpi(sc, ":WAV:DATA? CHANEL1", ch1, 1024);
206
207 if (l != 1024) {
208 printf ("hmm. didnt' get 1024 bytes. \n");
209 }
210
211 l = sendscpi(sc, ":WAV:DATA? CHANNEL2", ch2, 1024);
212
213 if (l != 1024) {
214 printf ("hmm. didnt' get 1024 bytes. \n");
215 }
216
217 if (!gnuplot) {
218 gnuplot = popen ("gnuplot", "w");
219 }
220
221 fp = fopen ("temp.dat", "w");
222 for (i=0xd4;i<0x32c;i++)
223 // for (i=0;i<0x400;i++)
224 fprintf (fp, "%d %d\n", 255 - ch1[i], 255 - ch2[i]);
225 fclose (fp);
226
227 fprintf (gnuplot, "plot 'temp.dat' using 1 with lines, 'temp.dat' using 2 with lines\n");
228 fflush (gnuplot);
229 }
230
231
232 #define ERROR -1e100
233
234 double get_float_from_scope (struct usb_dev_handle *sc, char *var)
235 {
236 unsigned char buf[1024];
237 double temp;
238 int l;
239
240 l = sendscpi(sc, var, buf, 1024);
241 if (l > 0) {
242 sscanf (buf, "%lf", &temp);
243 return temp;
244 }
245 return ERROR;
246 }
247
248
249 void do_get_buf (struct usb_dev_handle *sc)
250 {
251 FILE *fp;
252 int i, j, l, bp;
253 unsigned char buf[1024], ch1[1024];
254 unsigned char data[512*1024];
255 double sampfreq;
256
257 sendscpi (sc, ":STOP", NULL, 0);
258
259 sampfreq = get_float_from_scope (sc, ":ACQ:SAMP?");
260
261 printf ("Got sampling freq: %g\n", sampfreq);
262
263 sprintf (buf, ":TIM:SCAL %.15f", 50 / sampfreq);
264 printf ("sending scale cmd: %s\n", buf);
265 sendscpi (sc, buf, NULL, 0);
266
267 sleep (1);
268
269 bp=0;
270 for (i=-254*1024;i< 254*1024;i += 600) {
271 sprintf (buf, ":TIM:OFFSET %.15f", i / sampfreq);
272 printf ("Sending offset cmd: %s\n", buf);
273 sendscpi (sc, buf, NULL, 0);
274
275 l = sendscpi(sc, ":WAV:DATA? CHANEL1", ch1, 1024);
276
277 if (l != 1024) {
278 printf ("hmm. didnt' get 1024 bytes. \n");
279 }
280
281 for (j=0;j<600;j++)
282 data[bp++] = ch1[j+0xd4];
283 }
284 printf ("Got %d bytes of data. \n", bp);
285
286 fp = fopen ("ch1.dump", "w");
287 fwrite (data, bp, 1, fp);
288 fclose (fp);
289
290 sendscpi (sc, ":TIM:OFFSET 0", NULL, 0);
291 }
292
293
294
295 int main(int argc, char **argv)
296 {
297 struct usb_dev_handle *sc;
298 char *scpi, *buff;
299 int l;
300 //Init libusb
301 usb_init();
302 //Locate and open the scope
303 sc=find_scope();
304 if (!sc) {
305 printf("No scope found.\n");
306 exit(1);
307 } else {
308 printf("Scope found.\n");
309 }
310 //Initialize scope
311 initscope(sc);
312 buff = malloc (1024*1024);
313 while (1) {
314 scpi = readline ("> ");
315
316 if (!scpi) break;
317 if (strlen (scpi) == 0) {
318 free (scpi);
319 continue;
320 }
321
322 add_history (scpi);
323
324 if (strncmp (scpi, "quit", 4) == 0) break;
325 if (strncmp (scpi, "plot", 4) == 0) {
326 do_plot (sc);
327 continue;
328 }
329 if (strncmp (scpi, "databuf", 4) == 0) {
330 do_get_buf (sc);
331 continue;
332 }
333
334 l = strlen (scpi);
335 // printf ("got buf(%d): ", l);
336 // printb (scpi, l+2);
337 if (strchr (scpi, '?')) {
338 // printf ("Expecting reply\n");
339 l = sendscpi(sc, scpi, buff, 1024*1024);
340 // printf ("Got replylen = %d.\n", l);
341 buff[l] = 0; //zero-terminate
342 printb (buff, l);
343 } else {
344 // printf ("No reply expected\n");
345 l=sendscpi(sc,scpi,NULL,0);
346 }
347 free (scpi);
348 }
349 //Disable keylock, so the user doesn't have to press the 'force'-button
350 l=sendscpi(sc, ":KEY:LOCK DISABLE",NULL,0);
351
352 //Free up and exit
353 usb_release_interface(sc,0);
354 usb_close(sc);
355 return 0;
356 }
Impressum, Datenschutz