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