/* * Name: 1bitla (one bit logic analyzer) * * Description: A program to drive the one-bit data acquisition circuit * and to perform post processing (logic analysis) on the * data stream. Please see http://www.linuxtoys.com for * the schematic of the data acquisition circuit. * * Syntax: 1bitla [options] tty_port * Options: -r raw data * -c value,count output (default) * -t value,seconds output * * Example: 1bitla -c /dev/ttyS1 * 0,44 * 1,45 * 0,45 * .......... * */ #include #include #include #include #include #include #include #include #include #define NREAD 512 void proc_cmdline(int, char *[], char *, char *); int setup_port(char *); void display_smpl(unsigned char *, int, char); void logic_analysis(int, int, char); static float period=(1.0/46080.0); int main (int argc, char *argv[]) { char portname[FILENAME_MAX]; /* serial port as a string */ int fd_serial; /* file descriptor to serial port */ char mode; /* output mode:raw,count,time -r,-c,-t */ int count; /* count of bytes read */ unsigned char inbuf[NREAD]; /* the array of bytes read */ /* Process command line arguments. Get the name of the serial port */ proc_cmdline(argc, argv, portname, &mode); /* Open the serial port at 8,N,1,57600. */ fd_serial = setup_port(portname); /* Loop forever reading data bytes */ while (1) { /* There is no background processing, so we use a blocking read */ count = read(fd_serial, inbuf, NREAD); if (count < 0) { /* we've encountered an error of some kind. Just exit for now. */ exit(0); } display_smpl(inbuf, count, mode); } return(0); } /****************************************************************** * proc_cmdline() * Get and process the command line arguments. Get the serial port. ******************************************************************/ void proc_cmdline( int argc, /* count of command line arguments */ char *argv[], /* strings of command line arguments */ char *portname, /* where to copy the name of the serial port */ char *mode) /* r,c,t: raw, count, or time mode */ { if (argc == 2) *mode = 'c'; else *mode = getopt(argc, argv, "rct"); if (*mode == '?') { printf("Usage:\n%s [option] serial_port\noption -r : ", argv[0]); printf("raw\n -c : value,count\n -t : value,time\n"); exit(0); } strncpy(portname, argv[argc-1], FILENAME_MAX); } /****************************************************************** * setup_port() * Open the serial port specified and return the file descriptor. * Use 8,N,1,57600 and exit() on any errors. ******************************************************************/ int setup_port( char *portname) /* the name of the port */ { int fd_dev; struct termios tbuf; if (( fd_dev = open(portname, O_RDWR,0)) < 0 ) { printf("Unable to open port '%s'.\n", portname); exit(1); } tbuf.c_cflag = CS8|CREAD|B57600|CLOCAL; tbuf.c_iflag = IGNBRK; tbuf.c_oflag = 0; tbuf.c_lflag = 0; tbuf.c_cc[VMIN] = 1; /* character-by-character input */ tbuf.c_cc[VTIME]= 0; /* no delay waiting for characters */ if (tcsetattr(fd_dev, TCSANOW, &tbuf) < 0) { printf("Unable to set device '%s' parameters\n", portname); exit(1); } return(fd_dev); } /****************************************************************** * display_smpl() * Display the samples in the appropriate mode ******************************************************************/ void display_smpl( unsigned char *inbuf, /* array of input samples */ int count, /* count of samples in inbuf */ char mode) /* mode of display = r,c,t */ { static int value=0; /* the "current" value */ static int vcnt=0; /* the sample count at value */ unsigned char smpl; /* the 8 bit sample */ int i; /* loop counter */ int bitmask; /* used to detect value of individual bit */ /* if raw mode, just display the values in hex */ if (mode == 'r') { for (i=0; i> 1; } } } } /****************************************************************** * logic_analysis() * Perform state machine evaluation of input ******************************************************************/ void logic_analysis( int value, /* 0 or 1 */ int count, /* count of samples with value */ char mode) /* mode of output display */ { /* This is where we perform all of the "logic analysis" to */ /* relate the input stream to the output stream. */ /* In the simple case, just output the data. */ if (mode == 'c') printf("%1d, %d\n", value, count); else printf("%1d, %f\n", value, (float)count * period); }