#define EXTERN #define MAIN 1 /*-------------------------- ** include files **-------------------------- */ #include #include #include #include #include #include #include #include #include #include #include #include #include /*----------------------------- ** Non-standard include files **----------------------------- */ #include "parint.h" /*--------------------------- ** function prototypes **--------------------------- */ int cmd_execute( char * cmd_buf); int do_get_time( char * par ); int do_flush( char * par ); int do_select( char * par ); int do_pulse( char *par ); int do_osq( char * par ); int do_osc( char * par ); int do_help( char *par ); int do_quit( char *par ); int do_test( char *par ); int do_t1( char *par ); int do_t2( char *par ); ulong get_ulong( char *prompt, ulong cur_val, ulong min, ulong max ); long get_long ( char *prompt, long cur_val, long min, long max ); double get_dbl( char *prompt, double cur_val, double min, double max ); void show_mem( void * mem, int nbytes, char * desc ); int sc_clrscr( int p ); int sc_clrln( int p ); int sc_gotoxy( int x, int y); int sc_home(void ); char * strxcpy ( char * dest, const char * src, int maxlen ); char *unpad ( char * s, int c ); char *str_rws( char * s, int maxlen ); double elapse_sec( struct timeval *start, struct timeval *end); /*------------------------------------- * defines *------------------------------------- */ #define PASS 0 #define FAIL (-1) #ifndef INRANGE #define INRANGE(a,x,b) ((a) <= (x) && (x) <= (b)) #endif #ifndef MAX #define MAX( a, b ) ((a) < (b) ? (b) : (a)) #define MIN( a, b ) ((a) < (b) ? (a) : (b)) #endif /*------------------------------------- * Global variables *------------------------------------- */ int Quit; int Fd; struct PARSE_TABLE { char * kw; /* The opcode string */ int (* pfi)(char*); /* pfi is pointer to function returning an integer */ char * desc; /* command description */ }; struct PARSE_TABLE parse_table[] = { /* BASIC DRIVER COMMANDS */ { "get.time", do_get_time, "get.time - get time info " }, { "flush", do_flush, "flush - flush any driver data" }, { "select", do_select, "select - using select & get_time " }, { "pulse", do_pulse, "pulse - command to test driver" }, { "p", do_pulse, "pulse - command to test driver" }, { "onq", do_osq, "onq - query one shot data in a loop" }, { "onc", do_osc, "onc - query one clear" }, { "t1", do_t1, "t1 - call ioctl_t1" }, { "t2", do_t2, "t2 - call ioctl_t2" }, /* MISC COMMANDS */ { "help", do_help, "Help - List commands" }, { "Quit", do_quit, "Quit - quits app" }, { "Test", do_test, "Test - test code" }, }; int num_parse_item = { sizeof(parse_table) / sizeof(struct PARSE_TABLE) }; /*--------------------------------- ** main() **--------------------------------- */ int main( int argc, char * argv[]) { char buf[80]; /*-------------------------------------- ** open device driver */ if( (Fd = open("/dev/parint", O_RDWR, 0x666)) < 0) { printf("Error opening pmac device driver \n"); exit(0); } printf("opened /dev/parint fd=%d \n", Fd ); /* main loop for commands */ Quit = FALSE; while( !Quit ) { /* Get command */ printf("Enter Command: "); fgets( buf, sizeof(buf), stdin ); str_rws( buf, sizeof(buf)); cmd_execute( buf ); } close( Fd ); return 0; } /*------------------------------------------------------------- ** cmd_execute() - Executes a command line instruction **------------------------------------------------------------- */ int cmd_execute( cmd_buf ) char * cmd_buf; { char copy_buf[80]; int error, found, i; char * kw, * par; /* ** Search table for keyword */ strxcpy( copy_buf, cmd_buf, sizeof(copy_buf)); kw = strtok(copy_buf, " "); if( (kw == NULL) || (*kw=='#') ) return( PASS ); if( (par = strtok( (char*)NULL, "")) != NULL ) unpad( par, ' ' ); /* ** Search table for keyword. If found call function. */ error = FAIL; for(i=0, found = FALSE; itm_hour, t->tm_min, t->tm_sec, tv[i].tv_usec, esec); memcpy( &tv_last, &tv[i], sizeof(tv_last)); } usleep(100000); } return 0; } /*---------------------------------------------------------------------- ** do_flush() - call parint_flush() to delete any time data in the driver. **---------------------------------------------------------------------- */ int do_flush( char * par ) { int rc; rc = parint_flush( Fd ); if( rc ) printf("parint_flush() return with error\n"); return 0; } /*---------------------------------------------------------------------- ** do_select() - demonstrates how to use select() to wait for data, ** then get_time to read it. **---------------------------------------------------------------------- */ int do_select( char * par ) { int rc, n, i; double esec; struct timeval tv_now; struct tm * t; fd_set fds; struct timeval tv_wait; while( 1 ) { // setup selection paramters FD_ZERO( &fds ); FD_SET( Fd, &fds ); tv_wait.tv_sec = 20; tv_wait.tv_usec = 0; //printf("select() waits ... %ld.%06ld \n", tv_wait.tv_sec, tv_wait.tv_usec); n = select( Fd+1, &fds, NULL, NULL, &tv_wait ); if( n > 0 ) { // new data is ready unsigned int i_cnt; int num_tv; struct timeval tv[100]; rc = parint_get_time( Fd, &i_cnt, &num_tv, &tv[0], sizeof(tv)/sizeof(struct timeval)); if( rc ) { printf("ERR get_time() error %d \n", rc); } else if ( num_tv < 1 ) { printf("ERR get_time no data. num_tv=%d \n", num_tv); } else { for( i=0; itm_hour, t->tm_min, t->tm_sec, tv[i].tv_usec, esec); } } } else if ( n == 0 ) { gettimeofday( &tv_now, NULL ); t = localtime( &tv_now.tv_sec ); printf("select() timed out. %02d:%02d:%02d \n", t->tm_hour, t->tm_min, t->tm_sec); return 0; /* return, as we are done? */ } else { printf("select() error.\n"); return 0; } } return 0; } /*---------------------------------------------------------------------- ** do_pulse() - The driver has an IOCTL_PULSE command that ** timestamps and toggles the data bits. I used this to test ** the driver, as I could connect pin10 to a data out and generate ** interrupts. **---------------------------------------------------------------------- */ int do_pulse( char * par ) { int i; double esec; struct timeval tv; struct timeval tv_last; struct tm * t; static long rep = 10; static long usec = 1000000; rep = get_long( "rep", rep, 1, 1000000); usec = get_long( "usec", usec, 1000, 2000000); printf("\n"); gettimeofday( &tv_last, NULL); for( i=0; itm_hour, t->tm_min, t->tm_sec, tv.tv_usec, esec); memcpy( &tv_last, &tv, sizeof(tv_last)); usleep( usec ); } return 0; } /*---------------------------------------------------------------------- ** do_osq() - query one shot data in a loop **---------------------------------------------------------------------- */ int do_osq( char * par ) { int rc; int has_data; struct timeval tv; while( 1 ) { rc=parint_oneshot_get( Fd, &has_data, &tv ); printf("rc=%d has_data=%d tv %10ld.%06ld \n", rc, has_data, tv.tv_sec, tv.tv_usec); sleep( 1 ); } return 0; } /*---------------------------------------------------------------------- ** do_osc() - calls clear one shot **---------------------------------------------------------------------- */ int do_osc( char * par ) { parint_oneshot_clear( Fd ); return 0; } /*---------------------------------------------------------------------- ** do_t1() - call ioctl_t1 **---------------------------------------------------------------------- */ int do_t1( char * par ) { parint_t1( Fd ); return 0; } /*---------------------------------------------------------------------- ** do_t2() - call ioctl_t2 **---------------------------------------------------------------------- */ int do_t2( char * par ) { unsigned char uc[3]; while( 1 ) { parint_t2( Fd, uc ); printf(" iop: 0x%02x 0x%02x 0x%02x \n", uc[0], uc[1], uc[2]); usleep(200000); } return 0; } /******************************************************************** ** T3 APPLICATION specific COMMANDS ** ********************************************************************/ /******************************************************************** ** MISC COMMANDS ** ********************************************************************/ /*---------------------------------------------------------------------- ** do_help() - set Quit flag to TRUE. **---------------------------------------------------------------------- */ int do_help( char * par ) { int i; printf("\n" "This program communicate with the PARINT driver. \n" "Summary of commands:\n"); for( i=0; i= 1 ) sscanf( buf, "%lx", &cur_val); if( INRANGE(min, cur_val, max)) { return cur_val; } else printf("\007INVALID Input. Range is %lu to %lu.\n", min, max); } } /*---------------------------------------------------------------------- ** get_long() - prompt the user and reads a long from the keyboard. **---------------------------------------------------------------------- */ long get_long ( char *prompt, long cur_val, long min, long max ) { char buf[80]; while( 1 ) { printf( "%s (%ld): ", prompt, cur_val ); fgets( buf, sizeof(buf), stdin ); str_rws( buf, sizeof(buf)); unpad( buf, ' ' ); if( strlen(buf) >= 1 ) cur_val = atol(buf); if( INRANGE(min, cur_val, max)) { return cur_val; } else printf("\007INVALID Input. Range is %ld to %ld.\n", min, max); } } /*---------------------------------------------------------------------- ** get_dbl() - prompt the user and reads a double from the keyboard. **---------------------------------------------------------------------- */ double get_dbl( char *prompt, double cur_val, double min, double max ) { char buf[80]; while( 1 ) { printf( "%s (%f): ", prompt, cur_val ); fgets( buf, sizeof(buf), stdin ); str_rws( buf, sizeof(buf)); unpad( buf, ' ' ); if( strlen( buf) >= 1 ) sscanf( buf, "%lf", &cur_val); if( INRANGE( min, cur_val, max)) return cur_val; else printf("\007INVALID Input. Range is %g to %g.\n", min, max); } } /*-------------------------------------------------------------- ** show_mem() - print a dump of RAM to stdout. **-------------------------------------------------------------- */ void show_mem( void * mem, int nbytes, char * desc ) { int i; unsigned char *c; c = (unsigned char*) mem; // heading printf("\n "); for( i=0; i<16; i++ ) printf("%02x ", i); printf("\n-- %s -nbytes=%d ---------------------", desc, nbytes); for( i=0; i=0) && (s[i]==c) ) s[i--] = 0; for( i=0; s[i]==c; i++); if( i > 0 ) memmove(s, s+i, l-i+1); return(s); } /*--------------------------------------------------------- ** str_rws() - changes white space characters in a string to ' '. **--------------------------------------------------------- */ char *str_rws( char * s, int maxlen ) { char *cptr = s; while( maxlen && (*cptr!=0)) { if( isspace( (int)*cptr ) ) *cptr = ' '; maxlen--; cptr++; } return s; } /*------------------------------------------------------ ** elapse_sec() - returns the elapse seconds as a float ** from start to end (timeval). **------------------------------------------------------ */ double elapse_sec( struct timeval *start, struct timeval *end) { long sec, usec; sec = end->tv_sec - start->tv_sec; usec = end->tv_usec - start->tv_usec; return (double)sec + (usec/1000000.0); }