]>
cvs.zerfleddert.de Git - rigol/blob - rigol.c
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>
29 //This routine locates a scope by VID/PID and returns an opened handle to it.
30 usb_dev_handle
*find_scope() {
32 struct usb_device
*dev
=NULL
;
35 for (bus
=usb_busses
; bus
; bus
=bus
->next
) {
36 for (dev
=bus
->devices
; dev
; dev
=dev
->next
) {
37 //fprintf(stderr,"Prod/dev: %04X:%04X\n",dev->descriptor.idVendor,dev->descriptor.idProduct);
38 if (dev
->descriptor
.idVendor
==0x400 && dev
->descriptor
.idProduct
==0x5dc) {
46 //Helper-routine: Convert a little-endian 4-byte word to an int
47 void int2chars(unsigned char *buff
,unsigned int a
) {
54 //Helper-routine: Convert an int to little-endian 4-byte word
55 unsigned int chars2int(unsigned char *buff
) {
64 #define MIN(a,b) (((a)<(b))?(a):(b))
66 inline char printable (char ch
)
68 if (ch
< ' ') return '.';
69 if (ch
> '~') return '.';
73 //Debugging: Print a buffers contents in hex
74 void printb (unsigned char *pkt
, int len
)
78 for (i
=0;i
<len
;i
+= 16) {
80 for (j
=0;j
< MIN(len
-i
, 16);j
++) {
81 printf (" %02x", pkt
[i
+j
]);
82 if (j
== 7) printf (" ");
84 if (j
< 7) printf (" ");
88 for (j
=0;j
< MIN(len
-i
, 16);j
++) {
89 printf ("%c", printable (pkt
[i
+j
]));
95 //Send a scpi-command to the scope. The response goes into the buffer
96 //called resp, with a size of resplen. If resp==NULL, no response
98 int sendscpi(usb_dev_handle
*dev
, char* cmd
,
99 unsigned char *resp
, int resplen
) {
102 int cmdlen
= strlen(cmd
);
103 static unsigned char seq
=0;
109 buff
[1]=seq
; buff
[2]=~seq
; //nseq
111 int2chars(buff
+4, cmdlen
);
116 //fprintf(stderr,"Writing header len=%d\n", cmdlen);
118 r
=usb_bulk_write(dev
, 1, (char*)buff
, 12, 1000);
119 //fprintf(stderr,"%i bytes written. Writing cmd\n",r);
120 //printb(cmd, cmdlen);
121 r
=usb_bulk_write(dev
, 1, cmd
, cmdlen
, 1000);
122 //fprintf(stderr,"%i bytes written.\n",r);
123 if (resp
!= NULL
&& resplen
!= 0) {
127 buff
[1]=seq
; buff
[2]=~seq
; //nseq
128 int2chars(buff
+4,0x40);
133 //fprintf(stderr,"Writing resp req header\n");
135 r
=usb_bulk_write(dev
, 1, (char*)buff
, 12, 1000);
136 //fprintf(stderr,"%i bytes written. Reading response hdr\n",r);
137 r
=usb_bulk_read(dev
, 2, (char*)buff
, 0x40, 1000);
139 len
=chars2int(buff
+4);
140 //fprintf(stderr,"%i bytes read. Resplen=%i\n",r,len);
141 for (i
=0; i
<(r
-12); i
++) {
142 if (i
<resplen
) resp
[i
] = buff
[i
+12];
146 //fprintf(stderr," Reading response:\n");
147 if (resplen
<len
) len
=resplen
;
148 r
=usb_bulk_read(dev
, 2, (char*)resp
+(0x40-12), len
-(0x40-12),1000);
149 //fprintf(stderr,"%i bytes read, wanted %i.\n", r, len-(0x40-12));
157 //Initialize the scope.
158 void initscope(usb_dev_handle
*dev
) {
160 unsigned char buff
[10];
161 usb_claim_interface(dev
,0);
162 //The following code isn't really necessary, the program works
164 r
=usb_control_msg(dev
, 0xC8, 9, 0, 0, (char*)buff
, 4, 1000);
166 fprintf (stderr
, "Error %d sending init message: %s\n",
168 fprintf (stderr
, "Do you have permission on the USB device?\n");
171 if (chars2int(buff
)!=0x40004dc) {
172 fprintf(stderr
,"Init: buff[%i]=%x\n",r
,chars2int(buff
));
177 #define HAVE_READLINE
178 #ifndef HAVE_READLINE
180 char *readline (prompt
)
188 if (fgets (buf
, 1023, stdin
) == NULL
) {
193 if (buf
[l
-1] == '\n') {
199 void add_history (char *buf
)
205 void do_plot (struct usb_dev_handle
*sc
)
207 unsigned char ch1
[1024], ch2
[1024];
210 static FILE *gnuplot
=NULL
;
213 l
= sendscpi(sc
, ":WAV:DATA? CHANEL1", ch1
, 1024);
216 printf ("hmm. didnt' get 1024 bytes. \n");
219 l
= sendscpi(sc
, ":WAV:DATA? CHANNEL2", ch2
, 1024);
222 printf ("hmm. didnt' get 1024 bytes. \n");
226 gnuplot
= popen ("gnuplot", "w");
229 fp
= fopen ("temp.dat", "w");
230 for (i
=0xd4;i
<0x32c;i
++)
231 //for (i=0;i<0x400;i++)
232 fprintf (fp
, "%d %d\n", 255 - ch1
[i
], 255 - ch2
[i
]);
235 fprintf (gnuplot
, "plot 'temp.dat' using 1 with lines, 'temp.dat' using 2 with lines\n");
242 double get_float_from_scope (struct usb_dev_handle
*sc
, char *var
)
244 unsigned char buf
[1024];
248 l
= sendscpi(sc
, var
, buf
, 1024);
250 sscanf ((char*)buf
, "%lf", &temp
);
257 void do_get_buf (struct usb_dev_handle
*sc
)
262 unsigned char ch1
[1024];
263 unsigned char data
[512*1024];
266 sendscpi (sc
, ":STOP", NULL
, 0);
268 sampfreq
= get_float_from_scope (sc
, ":ACQ:SAMP?");
270 printf ("Got sampling freq: %g\n", sampfreq
);
272 sprintf (buf
, ":TIM:SCAL %.15f", 50 / sampfreq
);
273 printf ("sending scale cmd: %s\n", buf
);
274 sendscpi (sc
, buf
, NULL
, 0);
279 for (i
=-254*1024;i
< 254*1024;i
+= 600) {
280 sprintf (buf
, ":TIM:OFFSET %.15f", i
/ sampfreq
);
281 printf ("Sending offset cmd: %s\n", buf
);
282 sendscpi (sc
, buf
, NULL
, 0);
284 l
= sendscpi(sc
, ":WAV:DATA? CHANEL1", ch1
, 1024);
287 printf ("hmm. didnt' get 1024 bytes. \n");
291 data
[bp
++] = ch1
[j
+0xd4];
293 printf ("Got %d bytes of data. \n", bp
);
295 fp
= fopen ("ch1.dump", "w");
296 fwrite (data
, bp
, 1, fp
);
299 sendscpi (sc
, ":TIM:OFFSET 0", NULL
, 0);
302 void do_get_screen(struct usb_dev_handle
*sc
)
304 unsigned char screen
[320*234];
305 unsigned char screen_conv
[320*234*3];
306 unsigned char lut
[256][3];
316 /* Hide "RMT" from screen */
317 l
= sendscpi(sc
, ":KEY:LOCK DISABLE", NULL
, 0);
320 l
= sendscpi(sc
, ":LCD:DATA?", screen
, sizeof(screen
));
322 if (l
!= sizeof(screen
)) {
323 printf ("hmm. didnt' get %d bytes, but %d\n\n", sizeof(screen
), l
);
326 for(i
= 0; i
< 256; i
++) {
327 lut
[i
][0] = ((i
>> 6) * 0x55);
328 lut
[i
][1] = ((((i
>> 3) & 7) * 0x49) >> 1);
329 lut
[i
][2] = (((i
& 7) * 0x49) >> 1);
332 for(i
= 0; i
< sizeof(screen_conv
); i
+= 3) {
333 screen_conv
[i
] = lut
[screen
[i
/3]][0];
334 screen_conv
[i
+1] = lut
[screen
[i
/3]][1];
335 screen_conv
[i
+2] = lut
[screen
[i
/3]][2];
339 strftime(filename
, sizeof(filename
), "screen_%Y%m%d-%H%M%S.ppm", localtime(<
));
341 fp
= fopen (filename
, "w");
342 fprintf(fp
, "P6\n320 234\n255\n");
343 fwrite(screen_conv
, sizeof(screen_conv
), 1, fp
);
346 printf("Waveform saved as %s\n", filename
);
351 execlp("display", "display", filename
, NULL
);
361 strftime(filename
, sizeof(filename
), "screen_%Y%m%d-%H%M%S.png", localtime(<
));
362 fd
=open(filename
, O_CREAT
|O_WRONLY
, 0644);
363 png
= lcd2png(screen
, &i
);
368 void child_reaper(int sig
)
373 child
= waitpid(-1, NULL
, WNOHANG
);
378 int main(int argc
, char **argv
)
380 struct usb_dev_handle
*sc
;
384 struct sigaction act
;
388 //Locate and open the scope
391 printf("No scope found.\n");
394 printf("Scope found.\n");
398 buff
= malloc (1024*1024);
404 bzero(&act
, sizeof(act
));
405 act
.sa_handler
= child_reaper
;
406 act
.sa_flags
= SA_NOCLDSTOP
|SA_RESTART
;
407 if (sigaction(SIGCHLD
, &act
, NULL
) == -1) {
413 scpi
= readline ("> ");
416 if (strlen (scpi
) == 0) {
423 if (strncmp (scpi
, "quit", 4) == 0) break;
424 if (strncmp (scpi
, "plot", 4) == 0) {
428 if (strncmp (scpi
, "databuf", 7) == 0) {
432 if (strncmp (scpi
, "screen", 6) == 0) {
438 //printf ("got buf(%d): ", l);
439 //printb (scpi, l+2);
440 if (strchr (scpi
, '?')) {
441 //printf ("Expecting reply\n");
442 l
= sendscpi(sc
, scpi
, buff
, 1024*1024);
443 //printf ("Got replylen = %d.\n", l);
444 buff
[l
] = 0; //zero-terminate
447 //printf ("No reply expected\n");
448 l
=sendscpi(sc
,scpi
,NULL
,0);
452 //Disable keylock, so the user doesn't have to press the 'force'-button
453 l
=sendscpi(sc
, ":KEY:LOCK DISABLE",NULL
,0);
456 usb_release_interface(sc
,0);