oscillo.c

00001 /****************************************************************
00002  *  program name / version
00003  *   oscillo.c      wave data transfer from oscilloscope to WS
00004  *---------------------------------------------------------------
00005  *  2003.03.12 by SCH. remove compile warnnings.
00006  *  1999.03.05 by GRA. for Lynix and AS network corrected.
00007  *  1998.02.21 by TEL.
00008  *                 copyright reserved by designers & YMBC project    
00009  ****************************************************************
00010  * NOTE:
00011  * 
00012  * device name : LT etc.: /dev/ttya Max baourate is 9600.
00013  *               PC/AT etc.: /dev/ttyS0 (Upper one is ttyS1 at robolin1)
00014  *                           Max baurate is 19200.   
00015  *
00016 -- succeeded set up of the terminal --
00017 
00018 % stty -a > /dev/ttya
00019 input speed 9600 baudoutput speed 19200 baud, 0 rows, 0 columns
00020 eucw 1:2:1:2, scrw 1:2:1:2
00021 -parenb -parodd cs8 -cstopb -hupcl cread clocal -crtscts 
00022 -ignbrk brkint -ignpar -parmrk inpck istrip -inlcr igncr icrnl -iuclc 
00023 -ixon -ixany -ixoff -imaxbel 
00024 -isig iexten -icanon -xcase -echo -echoe -echok -echonl -noflsh -tostop 
00025 -echoctl -echoprt -echoke 
00026 -opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel -tabs 
00027 min 255, time 5
00028 erase  kill   werase rprnt  flush  lnext  susp   intr   quit   stop   eof
00029 ^?     ^U     ^W     ^R     ^O     ^V     ^Z/^Y  ^C     ^\     ^S/^Q  
00030 %
00031  ****************************************************************/
00032 
00033 #include <unistd.h>
00034 #include <math.h>
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <ctype.h>
00038 #include <fcntl.h>
00039 #include <sys/termios.h> 
00040 #include <sys/file.h>
00041 #include <signal.h>
00042 #include <string.h>
00043 #include <signal.h>
00044 #include <sys/time.h>
00045 #include <sys/types.h>
00046 #include <sys/ioctl.h>
00047 
00048 #define STX 0x2
00049 #define ETX 0x3
00050 #define ENQ 0x5
00051 #define ACK 0x6
00052 #define NAK 0x15
00053 #define ACK_STRING "\006"
00054 #define BELL 0x7
00055 #define LF 0xa
00056 #define NL LF
00057 #define CR 0xd
00058 #define SI  0x0f
00059 #define SO  0x0e
00060 
00061 #define HIGH( val ) ((val>>4) & 0xf) /* high nibble */
00062 #define LOW( val ) (val & 0xf)  /* low nibble */
00063 #define FALSEP( cond ) (cond==FALSE)
00064 #define TRUEP( cond ) (cond==TRUE)
00065 
00066 typedef unsigned char Uchar;
00067 typedef unsigned short Ushort;
00068 typedef unsigned int Uint;
00069 typedef Uchar * UniversalPointer;
00070 typedef enum {
00071     FALSE,
00072     TRUE
00073 } Bool;
00074 
00075 #define BAUD      9600
00076 #define DATA       256
00077 #define LENGTH    1024
00078 #define LENGTH2   2048
00079 #define LENGTH16 16384
00080 #define LENGTH32 32768
00081 /* #define STDERR 2 */
00082 
00083 struct termios ytm,old_ytm;   
00084 int sw_old_ytm = 0;
00085 
00086 typedef struct point {
00087     double x, y;
00088 } Point;
00089 
00090 void finishDev(void);
00091 void exit_mode(int);
00092 void setup(int, char *[]);
00093 void get_length(void);
00094 void read_wave(void);
00095 void exit_mode(int);
00096 void Command_output(char *);
00097 int Read_command(char *, char);
00098 void ErrorCheck(int retv);
00099 void get_info(void);
00100 void save_data(Point *);
00101 void Nak_err(void);
00102 void Other_err(void);
00103 void uWrite(int fd, char *buff, int nwrite);
00104 void options(int argc, char *argv[]);
00105 void crlf(void);
00106 int calcBaudChar(Uint baud);
00107 int hog(int ttyfd, int w, int print);
00108 
00109 
00110 extern int errno;
00111 int ttyfd;
00112 char BlockTransferChar;
00113 char progName[80];
00114 int channel = 0;         /* channel number */
00115 int data_len;            /* data length */
00116 char sfile[20];          /* output filename */
00117 char TermDev[32];        /* terminal device */
00118 int no_ad_gnd = 0;       /* adjust GND level ON/OFF */
00119 int save_format = 0;     /* saving the data DOUBLE/BINARY */
00120 double volt,timediv,gnd; /* volt/div, time/div, GND level   !!! 'time'->'timediv' */
00121 int baudrate = BAUD;     /* baudrate */
00122 
00123 
00124 int main(int argc, char *argv[])
00125 {
00126     setup(argc, argv);
00127     get_length();
00128     read_wave();
00129     exit_mode(0);
00130     
00131     return 0;
00132 }
00133 
00134 
00135 void usage(void)
00136 {
00137     fprintf(stderr, "\n%s : %s [-p port] [-c channel] [-h] [-v] [-b] [-g] [filename]\n", progName, progName);
00138 }
00139 
00140 
00141 void version(void)
00142 {
00143     printf("\n%s version 2.3.1  1994/08/07\n\n",progName);
00144 }
00145 
00146 
00147 void help(void)
00148 {
00149     printf("\n-p port    : RS232C device port [/dev/ttya,/dev/ttyb]");
00150     printf("\n-b baudrate: baudrate [300,600,1200,2400,4800,9600,19200]");
00151     printf("\n-c channel : wave channel [1,2,3,4,calc,calc2,REF1,REF3]");
00152     printf("\n             REF1 : take data from channel 1  ");
00153     printf("\n                    In case of taking 2k data, put upper 1k in REF1 ");
00154     printf("\n                    and lower 1k in REF2.     ");
00155     printf("\n             REF3 : take data from channel 2  ");
00156     printf("\n                    In case of taking 2k data, put upper 1k in REF3 ");
00157     printf("\n                    and lower 1k in REF4.     ");
00158     printf("\n-f         : save the data in binary (faster) ");
00159     printf("\n-g         : no-adjust GND level");
00160     printf("\n-h         : display this help");
00161     printf("\n-v         : display version");
00162     printf("\nfilename   : wave data file name\n");
00163     printf("\n    %s tansfers wave data from DS-8613 & DS-8617 to WS.",progName);    
00164     printf("\n    data length is choosen automatically [1k,2k,16k,32k].");
00165     printf("\n    GND level is adjusted (expect -g option)."); 
00166     printf("\n    channel CALC[1|2] is supprted only for DS-8617.\n\n");
00167 }
00168 
00169 
00170 void get_length(void)
00171 {
00172     int retv;
00173     char *len,*len1,*len2,*len16,*len32;
00174     
00175     len1="1K\n"; len2="2K\n"; len16="16K\n"; len32="32K\n";
00176     if ((len = malloc(sizeof(char)*DATA)) == NULL){
00177         fprintf(stderr,"malloc error:\n");
00178         exit_mode(1);
00179     }
00180     Command_output("LGTH?");   
00181     retv = Read_command(len,LF);
00182     ErrorCheck(retv);
00183     if (strcmp(len+1,len1)==0) data_len = LENGTH;
00184     else if (strcmp(len+1,len2)==0) data_len = LENGTH2;
00185     else if (strcmp(len+1,len16)==0) data_len = LENGTH16;
00186     else if (strcmp(len+1,len32)==0) data_len = LENGTH32;
00187     else{
00188         fprintf(stderr,"data length error\n");
00189         exit_mode(1);
00190     }
00191     free(len);
00192 }
00193 
00194 
00195 void set_channel(void)
00196 {
00197     char *rch,u[10];
00198     int retv;
00199 
00200     if (channel == 0){
00201         printf("Input channel\n");
00202         printf(" CH1->1 CH2->2 CH3->3 CH4->4 CALC1->5 CALC2->6 \n");
00203         printf(" REF1>7 REF3>8                                 \n");
00204         scanf("%d%*c",&channel);
00205     }
00206     if ((rch = malloc(sizeof(char)*DATA)) == NULL){
00207         fprintf(stderr,"malloc error:\n");
00208         exit_mode(1);
00209     }
00210     if (channel < 5) sprintf(u, "DIRV CH%1d", channel);
00211     else if (channel == 5) sprintf(u, "DIRV CH1");
00212     else if (channel == 6) sprintf(u, "DIRV CH3");
00213     else if (channel == 7) sprintf(u, "DIRV CH1");
00214     else if (channel == 8) sprintf(u, "DIRV CH2");
00215     else{
00216         fprintf(stderr,"wrong channel.\n");
00217         exit_mode(1);
00218     }
00219     Command_output(u);
00220     retv = Read_command(rch,ACK);
00221     ErrorCheck(retv);
00222     if (channel < 5) printf("channel No.%1d\n",channel);
00223     else if (channel < 7) printf("channel CALC%1d\n",channel-4);
00224     else printf("channel REF%1d\r\n",channel-6);
00225     free(rch);
00226 }
00227 
00228 
00229 void read_wave(void)
00230 {
00231     int i,retv;       /* i:counter, c:input character */
00232     char u[50],*rch;
00233     Point *p;
00234 
00235     set_channel();
00236     get_info();
00237     if ((rch = malloc(sizeof(char)*data_len*7+3)) == NULL){
00238         fprintf(stderr,"malloc error:\n");
00239         exit_mode(1);
00240     }
00241     if (channel < 5) sprintf(u, "MEMR CH%1d, 0, 0, %d",channel,data_len);
00242     else if (channel == 5) sprintf(u, "MEMR CALC, 0, 0, %d", data_len);
00243     else if (channel == 6) sprintf(u, "MEMR CALC2, 0, 0, %d", data_len);
00244     else if (channel == 7) sprintf(u, "MEMR REF1, 0, 0, %d", data_len);
00245     else sprintf(u, "MEMR REF3, 0, 0, %d", data_len);
00246     Command_output(u);
00247     retv = Read_command(rch,LF);
00248     ErrorCheck(retv);
00249     printf("\nDone.\n");
00250 
00251     if ((p = (Point *)malloc(sizeof(Point)*data_len)) == NULL){
00252         fprintf(stderr,"malloc error:\n");
00253         exit_mode(1);
00254     }
00255     for (i=0; i<data_len; i++){
00256         p[i].x = (double)i/1024.0 * timediv * 10.0;
00257         if (no_ad_gnd == 1){
00258             p[i].y = (double)(atoi(rch+1+i*7) / 256) / 256.0 * 8.0 * volt; 
00259         }
00260         else 
00261             p[i].y = ((double)(atoi(rch+1+i*7)/256)/256.0*8.0 - gnd) * volt;
00262         /* 16bit -> 8bit -> div */    
00263     }
00264     free(rch);
00265     save_data(p);
00266     free(p);
00267 }
00268 
00269 
00270 void get_info(void)
00271 {
00272     char *t,*v,*g,u[10];
00273     int retv;
00274 
00275     if ((v = malloc(sizeof(char)*DATA)) == NULL){
00276         fprintf(stderr,"malloc error:\n");
00277         exit_mode(1);
00278     }
00279     sprintf(u,"VDIV?");
00280     Command_output(u);
00281     retv = Read_command(v,LF);
00282     ErrorCheck(retv);
00283     volt = atof(v+1);
00284     printf("volt/dev = %g, ",volt);
00285     free(v);
00286 
00287     if ((t = malloc(sizeof(char)*DATA)) == NULL){
00288         fprintf(stderr,"malloc error:\n");
00289         exit_mode(1);
00290     }
00291     sprintf(u,"TMDV?");
00292     Command_output(u);
00293     retv = Read_command(t,LF);
00294     ErrorCheck(retv);
00295     timediv = atof(t+1);
00296     printf("time/dev = %g, ",timediv);
00297     free(t);
00298 
00299     if ((g = malloc(sizeof(char)*DATA)) == NULL){
00300         fprintf(stderr,"malloc error:\n");
00301         exit_mode(1);
00302     }
00303     sprintf(u,"VPOS?");
00304     Command_output(u);
00305     retv = Read_command(g,LF);
00306     ErrorCheck(retv);
00307     gnd = atof(g+1);
00308     printf("GND level = %g div\n",gnd);
00309     free(g);
00310 }
00311 
00312 
00313 void save_data(Point *p)
00314 {
00315     FILE *fp;
00316     char check[5];
00317     int i;
00318 
00319     if ('\0' == sfile[0]){
00320         printf("Input file name for saving: ");
00321         scanf("%s%*c",sfile);
00322     }
00323     if (NULL != (fp = fopen(sfile,"r"))){
00324         fprintf(stderr,"%s is already exist. Overwrite (y/n) ?  ",sfile);
00325         scanf("%s",check);
00326         if (check[0] == 'n'){
00327             fprintf(stderr,"Input file name for saving :  ");
00328             scanf("%s",sfile);
00329         }
00330     }
00331     if (NULL == (fp = fopen(sfile,"wb"))){
00332         printf("Cannot open FILE : %s\n",sfile);
00333     }
00334     fprintf(stderr, "Now writing...");
00335 
00336     
00337     if(save_format == 1) /* data is written in BINARY. */
00338         fwrite(p,sizeof(Point),data_len,fp);
00339 
00340     else { /* data is written in DOUBLE.*/
00341         fprintf(fp, "# Volt/dev  %g\n", volt);
00342         fprintf(fp, "# Time/dev  %g\n", timediv);
00343         fprintf(fp, "# GND level %g\n", gnd);
00344         for (i=0; i<data_len; i++){
00345             fprintf(fp, "%g ", p[i].x);
00346             fprintf(fp, "%g\n", p[i].y);
00347         }
00348     }
00349         
00350     fclose(fp);
00351     printf("Done.\n");
00352 }
00353 
00354 
00355 void ErrorCheck(int retv)
00356 {
00357     if (retv == NAK) Nak_err();
00358     else if (retv != ACK) Other_err();
00359 }
00360 
00361 
00362 void Nak_err(void)
00363 {
00364     char *sch,u[10];
00365     int retv;
00366 
00367     if ((sch = malloc(sizeof(char)*DATA)) == NULL){
00368         fprintf(stderr,"malloc error:\n");
00369         exit_mode(1);
00370     }
00371     fprintf(stderr, "NAK received.\n");
00372     sprintf(u, "ERRN?");
00373     Command_output(u);
00374     retv = Read_command(sch,LF);
00375     ErrorCheck(retv);
00376     fprintf(stderr,"ERROR number : %s\n",sch);
00377     exit_mode(1);
00378 }
00379   
00380 
00381 void Other_err(void)
00382 {
00383     fprintf(stderr, "Transfer error!!!\n");
00384     exit_mode(1);
00385 }
00386 
00387 
00388 void Command_output(char *sch)
00389 {
00390     int writew;
00391     char *p;
00392 
00393     p = malloc(strlen(sch) + 2 + 1);
00394     strcpy(p,sch);
00395     writew = strlen(p) + 2; 
00396     if (writew == 2) exit_mode(1);
00397     p[writew-2] = '\r';
00398     p[writew-1] = '\n';
00399     p[writew] = '\0';
00400     uWrite(ttyfd, p, writew);
00401     free(p);
00402 }
00403 
00404 
00405 int Read_command(char *ch, char delim)
00406 {
00407     int readw;
00408     char *start;
00409     int count = 0;
00410     start = ch;
00411     for(;;){
00412         readw = read(ttyfd, ch, DATA-1);
00413         if (start[0]!=ACK){
00414             return((int)ch[0]); /* something wrong for communication */
00415         }
00416         if ( readw > 0){
00417             if (ch[readw-1] == delim) {
00418                 ch[readw] = '\0';
00419                 break;          
00420             }
00421             else {
00422                 count += readw;
00423                 if(count >= 1024) {
00424                     fprintf(stderr,"\r%5d", data_len*7+3-((int)ch-(int)start));
00425                     count %= 1024;
00426                 }
00427                 ch=ch+readw;
00428                 continue;
00429             }
00430         }
00431     }
00432     if(count > 0) fprintf(stderr,"\r%5d",0);
00433     return((int)start[0]);
00434 }
00435 
00436 
00437 void exit_mode(int st)
00438 {
00439     finishDev();
00440     if(!st) ; //fprintf(stderr, "%s is normally ended\n", progName);
00441     else fprintf(stderr, "\n%s is ABNORMALLY exited\n", progName);
00442     exit(st);
00443 }
00444 
00445 
00446 void uWrite(int fd, char *buff, int nwrite)
00447 {
00448     int writew;
00449     writew = write(fd, buff, nwrite);
00450     if ( writew < 0  && errno ) {
00451         perror("write:");
00452         exit_mode(1);
00453     }
00454 }
00455 
00456 
00457 void setup(int argc, char *argv[])
00458 {
00459     Bool initDev();
00460 
00461     strcpy(progName, argv[0]);   /* copy program name. */
00462     BlockTransferChar = 't';
00463 
00464     options(argc,argv);
00465     if ( TermDev[0] == '\0' ) {
00466         fprintf(stderr, "device for communication : ");
00467         fflush(stderr);          /* flush. */
00468         scanf("%s", TermDev);
00469     }
00470 
00471     if FALSEP(initDev(TermDev, baudrate) ) {    /* initialize the device */
00472         fprintf(stderr, "something is wrong in initialization of devices.\n");
00473         crlf();
00474         exit_mode(1);
00475     }
00476 
00477     signal(SIGINT,exit_mode);
00478 }
00479 
00480 
00481 void options(int argc, char *argv[])
00482 {
00483     int i;
00484     char *ch1,*ch2;
00485 
00486     ch1="calc"; ch2="calc2";
00487     for ( i = 1; i < argc; i++ ){
00488         if (argv[i][0] == '-'){
00489             switch (argv[i][1]){
00490             case 'p':
00491                 i++;
00492                 if (argv[i][0] == '-'){
00493                     usage();
00494                     exit_mode(1);
00495                 }
00496                 strcpy(TermDev, argv[i]);
00497                 break;
00498             case 'c':
00499                 i++;
00500                 if (argv[i][0] == '-'){
00501                     usage();
00502                     exit_mode(1);
00503                 }
00504                 if (isdigit(argv[i][0])) channel = atoi(argv[i]);
00505                 else if (strcmp(argv[i],ch1)==0) channel = 5;
00506                 else if (strcmp(argv[i],ch2)==0) channel = 6;
00507                 break;
00508             case 'f':
00509                 save_format = 1;
00510                 break;
00511             case 'g':
00512                 no_ad_gnd = 1;
00513                 break;
00514             case 'h':
00515                 usage();
00516                 help();
00517                 exit_mode(0);
00518             case 'v':
00519                 version();
00520                 exit_mode(0);
00521             case 'b':
00522                 i++;
00523                 if (argv[i][0] == '-'){
00524                     usage();
00525                     exit_mode(1);
00526                 }
00527                 baudrate = atoi(argv[i]);
00528                 break;
00529             default:
00530                 fprintf(stderr, "illegal option %s.\n", argv[i]);
00531                 exit_mode(0);
00532             }
00533         }
00534         else strcpy(sfile,argv[i]);
00535     }
00536 }
00537 
00538 
00539 void crlf(void)
00540 {
00541     fprintf(stderr,"\r\n");
00542     return;
00543 }
00544 
00545 
00546 void finishDev()
00547 {
00548     if(sw_old_ytm) ioctl(ttyfd, TCSETS, &old_ytm);
00549     close(ttyfd);
00550 }
00551 
00552 
00553 Bool initDev(char *term, Uint baud)
00554 {
00555     if ( (ttyfd=open(term, O_RDWR)) < 0 ) {
00556         perror("open");
00557         return FALSE;
00558     }
00559 
00560     if ( ioctl(ttyfd, TCGETS, &old_ytm) ) {
00561         perror("ioctl(TCGETS:communication)");
00562         return FALSE;
00563     };
00564 
00565     sw_old_ytm = 1;
00566     ytm = old_ytm;
00567 
00568     /* for desplaying initial sets, REMAIN  this part.
00569        fprintf(stderr, "ytm.c_iflag=0x%6x\n", ytm.c_iflag);
00570        fprintf(stderr, "ytm.c_oflag=0x%6x\n", ytm.c_oflag);
00571        fprintf(stderr, "ytm.c_cflag=0x%6x\n", ytm.c_cflag);
00572        fprintf(stderr, "ytm.c_lflag=0x%6x\n", ytm.c_lflag); */
00573 
00574     ytm.c_iflag &= ~( IXON );
00575     ytm.c_iflag |= ( IGNCR | INPCK ); 
00576     /* ytm.c_iflag |= ( /IXOFF | IGNBRK | IGNPAR | /IGNCR | INPCK ); */
00577     ytm.c_oflag &= ~( OPOST );
00578     ytm.c_cflag &= ~( CBAUD | CSIZE | PARENB | CSTOPB );
00579     ytm.c_cflag |= ( calcBaudChar(baud) | CLOCAL | CS8 );
00580     ytm.c_lflag &= ~( ICANON |  ISIG |  ECHO );
00581     /*ytm.c_lflag &= ~( ICANON |  ISIG |  ECHO  /| IEXTEN /);*/
00582     ytm.c_cc[4]=255;      /* MIN  */
00583     ytm.c_cc[5]=5;      /* TIME */
00584 
00585 
00586     if ( ioctl(ttyfd, TCSETS, &ytm) ) {
00587         perror("ioctl(TCSETS:communication)");
00588         return FALSE;
00589     };
00590 
00591     if ( ioctl(ttyfd, TCGETS, &ytm) ) {
00592         perror("ioctl(TCGETS:communication)");
00593         return FALSE;
00594     };
00595 
00596     /*
00597       fprintf(stderr, "ytm.c_iflag=0x%6x\n", ytm.c_iflag);
00598       fprintf(stderr, "ytm.c_oflag=0x%6x\n", ytm.c_oflag);
00599       fprintf(stderr, "ytm.c_cflag=0x%6x\n", ytm.c_cflag);
00600       fprintf(stderr, "ytm.c_lflag=0x%6x\n", ytm.c_lflag); */
00601 
00602     /* !!! Inserted here. Please use one of them as you like. */
00603     write(ttyfd,"\r\n",2);
00604     printf("Discarding data from '%s' ...",term);
00605     hog(ttyfd,1,0);
00606     printf(" Done.\n");
00607 
00608     return TRUE;
00609 }
00610 
00611 
00612 int hog(int ttyfd, int w, int print) /* GRA's function */
00613 {
00614     fd_set r;
00615     struct timeval tv;
00616     char n[257];
00617     int len;
00618     while(1) {
00619         FD_ZERO(&r);  FD_SET(ttyfd,&r);  tv.tv_sec = w;  tv.tv_usec = 0;
00620         select(ttyfd+1,&r,NULL,NULL,&tv);
00621         if(!FD_ISSET(ttyfd,&r)) break;
00622         if((len = read(ttyfd,n,256))<=0) break;
00623         n[len] = '\0';
00624         if(print) fputs(n,stdout);
00625     }
00626     return 0;
00627 }
00628 
00629 
00630 int calcBaudChar(Uint baud)
00631 {
00632     int retv;
00633   
00634     switch ( (int)baud ) {
00635     case 300:
00636         retv = B300;
00637         break;
00638     case 600:
00639         retv = B600;
00640         break;
00641     case 1200:
00642         retv = B1200;
00643         break;
00644     case 2400:
00645         retv = B2400;
00646         break;
00647     case 4800:
00648         retv = B4800;
00649         break;
00650     case 9600:
00651     default:
00652         retv = B9600;
00653         break;
00654     case 19200:
00655         retv = B19200;
00656         break;
00657     }
00658     return retv;
00659 }
00660 

Generated on Mon Apr 13 22:52:01 2009 by  doxygen 1.5.7.1