// loader.cpp : Defines the entry point for the console application. // #include "stdafx.h" /*** defines ***/ #undef LINUX /* activate linux compatibility stuff */ #define DOS 1 /*** includes ***/ #include #include "pport.h" #include #include #define SSTEP 0 #define RHPDEBUG 0 #define WAIT 50 /*** typedefs ***/ /*** globals ***/ /*** func protos ***/ static int flip_byte(int byte); void init_ports(); void frob_cclk(); void one_byte(unsigned char c); void print_banner(); void init_ports() { /* init_ports */ /* locals */ /* body */ #ifdef LINUX ioperm((unsigned long) LP1_BASE, (unsigned long) 0x3, 0x2 ); #endif } /* init_ports */ static int flip_byte(int byte) { /* flip_byte */ int bit=0, result = 0; for (bit = 0; bit < 8; bit++) if (byte & (1 << bit)) result |= (1 << (7 - bit)); return (result); } /* flip_bypte */ void frob_cclk() { /* frob_cclk */ /* locals */ long wait; /* body */ outb( (char) (inb( LP1_CR ) & ~CR_STB) & 0xFF, LP1_CR ); #if SSTEP printf( "strobe is now high\n" ); getchar(); #endif for( wait = 0; wait < WAIT; wait++ ) ; outb( (char) (inb( LP1_CR ) | CR_STB) & 0xFF, LP1_CR ); #if SSTEP printf( "strobe is now low\n" ); getchar(); #endif for( wait = 0; wait < WAIT; wait++ ) ; outb( (char) (inb( LP1_CR ) & ~CR_STB) & 0xFF, LP1_CR ); #if SSTEP printf( "strobe is now high\n" ); getchar(); #endif for( wait = 0; wait < WAIT; wait++ ) ; } /* frob_cclk */ void one_byte(unsigned char c) { /* one_byte */ /* locals */ int i; /* body */ for( i = 0 ; i < 8; i++ ) { outb( (char) c, LP1_DR ); frob_cclk(); c >>= 1; } } /* one_byte */ int main( int argc, char *argv[] ) { /* main */ /* locals */ unsigned int count, j; unsigned long i; long wait; FILE *bitstream = NULL; char c; int verbose = 0; char *fname; char data; /* body */ #if LINUX scanargv( argc, argv, "%s [-v] [-f filename]", "[-v %+|-f %r]", &verbose, &bitstream ); #else /* dos mode substitute...hack hack */ fname = argv[1]; if( NULL IS (bitstream = fopen( fname, "r" ) ) ) { printf( "Can't open %s...\n", fname ); return(0); } /* if */ verbose = 0; #endif if( verbose ) print_banner(); /***** * init any machine-specific stuph *****/ init_ports(); /* for(;;) { frob_cclk(); } */ /***** * open the bitfile for reading *****/ if( bitstream IS NULL ) { if( verbose ) printf( "using crypt.bit\n" ); if( NULL IS (bitstream = fopen( "exp1.bit", "r" )) ) { printf("Can't open crypt.bit for reading.\n"); return(0); } /* if */ } /* if */ data = inb( LP1_BASE + 0x402 ); printf( "ECR mode: %02X\n", data & 0xFF ); outb( (data & 0x1F) | 0x00, LP1_BASE + 0x402 ); outb( 0x0, LP1_CR ); /***** * perform a low-level init and clear of the logic cell array *****/ /* set strobe to inactive value */ outb( (char) (inb( LP1_CR ) | CR_STB) & 0xFF, LP1_CR ); /* clear strobe */ /* initialize the LCA */ /* this is done by slamming program low and holding it there */ /* then returning it to the high value */ outb( (char) inb( LP1_CR ) | CR_SEL, LP1_CR ); for( wait = 0; wait < 40000; wait++ ) ; /* wait for LCA to reset */ #if RHPDEBUG printf( "Initialize array\n" ); getchar(); #endif outb( (char) inb( LP1_CR ) & ~CR_SEL, LP1_CR ); /* wait for /init to go high */ /* this allows us to determine if the device is connected */ count = 0; while( !(inb( LP1_SR ) & SR_SEL) ) { count++; if( count > TIMEOUT ) { printf( "Init did not go high; is it plugged in?\n" ); return(0); } /* if */ } /* while */ /***** * upload the bitstream *****/ /* scan past the bitfile header */ c = 0; count = 0; while( (unsigned char) c AINT 0xFF ) { fread( &c, 1, 1, bitstream ); count++; } /* while */ /* set the data output to all 1's to handle weird parallel ports */ outb( (char) 0xFF, LP1_DR ); /* from cclk once to get the FPGA in the proper state */ for(wait = 0; wait < 40000; wait++ ) ; frob_cclk(); for(wait = 0; wait < 40000; wait++ ) ; #if RHPDEBUG printf( "Entering main loop.\n" ); getchar(); #endif /***** * main upload loop *****/ while( !feof( bitstream ) ) { fread( &c, 1, 1, bitstream ); count++; /* keep a running count of bytes processed, incl header */ /* check for error by INIT going low */ if(!( inb(LP1_SR) & SR_SEL)) { printf( "Got error while downloading on byte %d.\n", count ); return(0); } /* if */ /* bizarrity #2935: MSB and LSB are mixed up in Xilinx world */ /* outb( (char) flip_byte(c) & 0xFF, LP1_DR ); */ /* outb( (char) c & 0xFF, LP1_DR ); */ /* printf( "data now available: %X.\n", c & 0xFF ); getchar(); */ #if SSTEP printf( "Data now available: %X.\n", c & 0xFF ); getchar(); #endif /* send the byte to the FPGA */ one_byte( (unsigned char) flip_byte( (int) c) ); /* martching .'s to monitor progress */ if( !(count % 1024) ) { /* printf( "count: %d\n", count ); */ printf( "." ); fflush(stdout); /* in case of buffered I/O */ } /* if */ } /* while */ one_byte(0xFF); one_byte(0xFF); frob_cclk(); frob_cclk(); outb( (char) (inb( LP1_CR ) | CR_STB) & 0xFF, LP1_CR ); outb( (char) inb( LP1_CR ) & ~CR_SEL, LP1_CR ); printf( "\nuploaded %d bytes\n", count ); #if 0 printf( "hit return to frob data bits\n" ); getchar(); j = 0; while( 1 ) { outb( (char) j++, LP1_DR ); for( i = 0; i < 5000000; i++ ) ; printf( "%ld\n", i ); } #endif return(0); } /* main */ void print_banner() { /* print_banner */ /* locals */ /* body */ printf( "loader v0.8 (11/1/99)\n" ); } /* print_banner */ /***** * misc development notes *****/ /* to fix: move WS from 7404 to latch; disconnect cclk. fix M0-2. wire rdy/bsy again -- 8/1/97 */ /* cclk uses negative logic in this prototype -- 7/30/97 */