]>
cvs.zerfleddert.de Git - rigol/blob - rigol.c
e7497ac65444fa4b9c10eaaf99e09ceced8968a8
2 Sprite_tms hack to communicate with a Rigol DS1000-series scope using Linux.
3 This code is licensed under the GPL V3.
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.
16 #include <sys/types.h>
23 #include <readline/readline.h>
24 #include <readline/history.h>
27 //This routine locates a scope by VID/PID and returns an opened handle to it.
28 usb_dev_handle
*find_scope() {
30 struct usb_device
*dev
=NULL
;
33 for (bus
=usb_busses
; bus
; bus
=bus
->next
) {
34 for (dev
=bus
->devices
; dev
; dev
=dev
->next
) {
35 //fprintf(stderr,"Prod/dev: %04X:%04X\n",dev->descriptor.idVendor,dev->descriptor.idProduct);
36 if (dev
->descriptor
.idVendor
==0x400 && dev
->descriptor
.idProduct
==0x5dc) {
44 //Helper-routine: Convert a little-endian 4-byte word to an int
45 void int2chars(unsigned char *buff
,unsigned int a
) {
52 //Helper-routine: Convert an int to little-endian 4-byte word
53 unsigned int chars2int(unsigned char *buff
) {
62 #define MIN(a,b) (((a)<(b))?(a):(b))
64 inline char printable (char ch
)
66 if (ch
< ' ') return '.';
67 if (ch
> '~') return '.';
71 //Debugging: Print a buffers contents in hex
72 void printb (unsigned char *pkt
, int len
)
76 for (i
=0;i
<len
;i
+= 16) {
78 for (j
=0;j
< MIN(len
-i
, 16);j
++) {
79 printf (" %02x", pkt
[i
+j
]);
80 if (j
== 7) printf (" ");
82 if (j
< 7) printf (" ");
86 for (j
=0;j
< MIN(len
-i
, 16);j
++) {
87 printf ("%c", printable (pkt
[i
+j
]));
93 //Send a scpi-command to the scope. The response goes into the buffer
94 //called resp, with a size of resplen. If resp==NULL, no response
96 int sendscpi(usb_dev_handle
*dev
, char* cmd
,
97 unsigned char *resp
, int resplen
) {
100 int cmdlen
= strlen(cmd
);
101 static unsigned char seq
=0;
107 buff
[1]=seq
; buff
[2]=~seq
; //nseq
109 int2chars(buff
+4, cmdlen
);
114 //fprintf(stderr,"Writing header len=%d\n", cmdlen);
116 r
=usb_bulk_write(dev
, 1, (char*)buff
, 12, 1000);
117 //fprintf(stderr,"%i bytes written. Writing cmd\n",r);
118 //printb(cmd, cmdlen);
119 r
=usb_bulk_write(dev
, 1, cmd
, cmdlen
, 1000);
120 //fprintf(stderr,"%i bytes written.\n",r);
121 if (resp
!= NULL
&& resplen
!= 0) {
125 buff
[1]=seq
; buff
[2]=~seq
; //nseq
126 int2chars(buff
+4,0x40);
131 //fprintf(stderr,"Writing resp req header\n");
133 r
=usb_bulk_write(dev
, 1, (char*)buff
, 12, 1000);
134 //fprintf(stderr,"%i bytes written. Reading response hdr\n",r);
135 r
=usb_bulk_read(dev
, 2, (char*)buff
, 0x40, 1000);
137 len
=chars2int(buff
+4);
138 //fprintf(stderr,"%i bytes read. Resplen=%i\n",r,len);
139 for (i
=0; i
<(r
-12); i
++) {
140 if (i
<resplen
) resp
[i
] = buff
[i
+12];
144 //fprintf(stderr," Reading response:\n");
145 if (resplen
<len
) len
=resplen
;
146 r
=usb_bulk_read(dev
, 2, (char*)resp
+(0x40-12), len
-(0x40-12),1000);
147 //fprintf(stderr,"%i bytes read, wanted %i.\n", r, len-(0x40-12));
155 //Initialize the scope.
156 void initscope(usb_dev_handle
*dev
) {
158 unsigned char buff
[10];
159 usb_claim_interface(dev
,0);
160 //The following code isn't really necessary, the program works
162 r
=usb_control_msg(dev
, 0xC8, 9, 0, 0, (char*)buff
, 4, 1000);
164 fprintf (stderr
, "Error %d sending init message: %s\n",
166 fprintf (stderr
, "Do you have permission on the USB device?\n");
169 if (chars2int(buff
)!=0x40004dc) {
170 fprintf(stderr
,"Init: buff[%i]=%x\n",r
,chars2int(buff
));
175 #define HAVE_READLINE
176 #ifndef HAVE_READLINE
178 char *readline (prompt
)
186 if (fgets (buf
, 1023, stdin
) == NULL
) {
191 if (buf
[l
-1] == '\n') {
197 void add_history (char *buf
)
203 void do_plot (struct usb_dev_handle
*sc
)
205 unsigned char ch1
[1024], ch2
[1024];
208 static FILE *gnuplot
=NULL
;
211 l
= sendscpi(sc
, ":WAV:DATA? CHANEL1", ch1
, 1024);
214 printf ("hmm. didnt' get 1024 bytes. \n");
217 l
= sendscpi(sc
, ":WAV:DATA? CHANNEL2", ch2
, 1024);
220 printf ("hmm. didnt' get 1024 bytes. \n");
224 gnuplot
= popen ("gnuplot", "w");
227 fp
= fopen ("temp.dat", "w");
228 for (i
=0xd4;i
<0x32c;i
++)
229 //for (i=0;i<0x400;i++)
230 fprintf (fp
, "%d %d\n", 255 - ch1
[i
], 255 - ch2
[i
]);
233 fprintf (gnuplot
, "plot 'temp.dat' using 1 with lines, 'temp.dat' using 2 with lines\n");
240 double get_float_from_scope (struct usb_dev_handle
*sc
, char *var
)
242 unsigned char buf
[1024];
246 l
= sendscpi(sc
, var
, buf
, 1024);
248 sscanf ((char*)buf
, "%lf", &temp
);
255 void do_get_buf (struct usb_dev_handle
*sc
)
260 unsigned char ch1
[1024];
261 unsigned char data
[512*1024];
264 sendscpi (sc
, ":STOP", NULL
, 0);
266 sampfreq
= get_float_from_scope (sc
, ":ACQ:SAMP?");
268 printf ("Got sampling freq: %g\n", sampfreq
);
270 sprintf (buf
, ":TIM:SCAL %.15f", 50 / sampfreq
);
271 printf ("sending scale cmd: %s\n", buf
);
272 sendscpi (sc
, buf
, NULL
, 0);
277 for (i
=-254*1024;i
< 254*1024;i
+= 600) {
278 sprintf (buf
, ":TIM:OFFSET %.15f", i
/ sampfreq
);
279 printf ("Sending offset cmd: %s\n", buf
);
280 sendscpi (sc
, buf
, NULL
, 0);
282 l
= sendscpi(sc
, ":WAV:DATA? CHANEL1", ch1
, 1024);
285 printf ("hmm. didnt' get 1024 bytes. \n");
289 data
[bp
++] = ch1
[j
+0xd4];
291 printf ("Got %d bytes of data. \n", bp
);
293 fp
= fopen ("ch1.dump", "w");
294 fwrite (data
, bp
, 1, fp
);
297 sendscpi (sc
, ":TIM:OFFSET 0", NULL
, 0);
300 void do_get_screen(struct usb_dev_handle
*sc
)
302 unsigned char screen
[320*234];
303 unsigned char screen_conv
[320*234*3];
304 unsigned char lut
[256][3];
312 /* Hide "RMT" from screen */
313 l
= sendscpi(sc
, ":KEY:LOCK DISABLE", NULL
, 0);
316 l
= sendscpi(sc
, ":LCD:DATA?", screen
, sizeof(screen
));
318 if (l
!= sizeof(screen
)) {
319 printf ("hmm. didnt' get %d bytes, but %d\n\n", sizeof(screen
), l
);
322 for(i
= 0; i
< 256; i
++) {
323 lut
[i
][0] = ((i
>> 6) * 0x55);
324 lut
[i
][1] = ((((i
>> 3) & 7) * 0x49) >> 1);
325 lut
[i
][2] = (((i
& 7) * 0x49) >> 1);
328 for(i
= 0; i
< sizeof(screen_conv
); i
+= 3) {
329 screen_conv
[i
] = lut
[screen
[i
/3]][0];
330 screen_conv
[i
+1] = lut
[screen
[i
/3]][1];
331 screen_conv
[i
+2] = lut
[screen
[i
/3]][2];
335 strftime(filename
, sizeof(filename
), "screen_%Y%m%d-%H%M%S.ppm", localtime(<
));
337 fp
= fopen (filename
, "w");
338 fprintf(fp
, "P6\n320 234\n255\n");
339 fwrite(screen_conv
, sizeof(screen_conv
), 1, fp
);
342 printf("Waveform saved as %s\n", filename
);
347 execlp("display", "display", filename
, NULL
);
358 void child_reaper(int sig
)
363 child
= waitpid(-1, NULL
, WNOHANG
);
368 int main(int argc
, char **argv
)
370 struct usb_dev_handle
*sc
;
374 struct sigaction act
;
378 //Locate and open the scope
381 printf("No scope found.\n");
384 printf("Scope found.\n");
388 buff
= malloc (1024*1024);
394 bzero(&act
, sizeof(act
));
395 act
.sa_handler
= child_reaper
;
396 act
.sa_flags
= SA_NOCLDSTOP
|SA_RESTART
;
397 if (sigaction(SIGCHLD
, &act
, NULL
) == -1) {
403 scpi
= readline ("> ");
406 if (strlen (scpi
) == 0) {
413 if (strncmp (scpi
, "quit", 4) == 0) break;
414 if (strncmp (scpi
, "plot", 4) == 0) {
418 if (strncmp (scpi
, "databuf", 7) == 0) {
422 if (strncmp (scpi
, "screen", 6) == 0) {
428 //printf ("got buf(%d): ", l);
429 //printb (scpi, l+2);
430 if (strchr (scpi
, '?')) {
431 //printf ("Expecting reply\n");
432 l
= sendscpi(sc
, scpi
, buff
, 1024*1024);
433 //printf ("Got replylen = %d.\n", l);
434 buff
[l
] = 0; //zero-terminate
437 //printf ("No reply expected\n");
438 l
=sendscpi(sc
,scpi
,NULL
,0);
442 //Disable keylock, so the user doesn't have to press the 'force'-button
443 l
=sendscpi(sc
, ":KEY:LOCK DISABLE",NULL
,0);
446 usb_release_interface(sc
,0);