⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m5i20cfg.c

📁 Source code for an Numeric Cmputer
💻 C
📖 第 1 页 / 共 2 页
字号:
*/static int programdunq(void){	return (inl(P_5I20PRGMDUN) & M_5I20PRGMDUN) == M_5I20PRGMDUNNOW ;}/*---------------------------------------------------------------------------*//* Function: wait4dun   Purpose: Wait for the FPGA to finish programming.   Used by: Local functions.   Returns: Done/timeout status.   Notes:	 -Failure to become DONE may be caused by an attempt to load an invalid		FPGA code image, or an I/O address conflict.   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static signed wait4dun(void){	clock_t then ;	unsigned waitcount ;	/* Wait at least long enough for the FPGA to finish its post-programming		 tomfoolery.  This time is generally masked by software overhead, but the		 programmer needs to be aware of it.	*/	then = (clock() + ((CLOCKS_PER_SEC / 10000) + 1)) ; /* 100 uS. should be enough. */	while(clock() < then)	{		;	}	/* The DONE bit should now indicate end of programming.	*/	if(programdunq())	{		/* Programming seems to be complete; make sure the state sticks and we're not			 seeing some sort of I/O conflict-related foo.		*/		for(waitcount = 100 ; waitcount != 0 ; --waitcount)		{			if(!programdunq())			{				return -1 ; /* (Shouldn't.) */			}		}		return 0 ; /* Success. */	}	else	{		return -1 ; /* Failure -- didn't become DONE. */	}}/*---------------------------------------------------------------------------*//* Function: delay100us   Purpose: Wait for 100 uS.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void delay100us(void){	clock_t then ;	then = (clock() + ((CLOCKS_PER_SEC / 10000) + 1)) ;	while(clock() < then)	{		;	}}/*---------------------------------------------------------------------------*//* Function: filelengthq   Purpose: Determine the length of the specified file.   Used by: Local functions.   Returns: The file length, or -1 on failure.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.	 2) Thursday February 24, 2005 -- 12:12:48.	    -We now return unsigned long instead of off_t.*/static unsigned long filelengthq(FILE *f){	struct stat fileinfo ;	fstat(fileno(f), &fileinfo) ;	return fileinfo.st_size ;}/*---------------------------------------------------------------------------*//* Function: saybytesfromfile   Purpose: Send the bytes from the specified offset in the specified open     file to standard out.   Used by: Local functions.   Returns: The number of bytes read.   Notes:     -It is assumed that numbytes includes the trailing '\0'.     -The file position is not restored to its original value.     -Don't try to output 0 bytes.   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static size_t saybytesfromfile(FILE *f, long fromoffset, size_t numbytes, FILE *str){	int c ;	size_t len = 0 ;	if(fseek(f, fromoffset, SEEK_SET) != 0)	{		return 0 ;	}	while(numbytes-- != 0)	{		if((c = getc(f)) == EOF)		{			break ;		}		++len ;		if(c == '\0')		{			break ;		}		fputc(c, str) ;	}	return len ;}/*---------------------------------------------------------------------------*//* Function: readbytesfromfile   Purpose: Read the specified number of bytes from the specified offset in	 the specified open file to the specified address.   Used by: Local functions.   Returns: The number of bytes read.   Notes:     -The file position is not restored to its original value.     -Don't try to read 0 bytes.   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static size_t readbytesfromfile(FILE *f, long fromoffset, size_t numbytes, ubyte *bufptr){	if(fseek(f, fromoffset, SEEK_SET) != 0)	{		return 0 ;	}	return fread(bufptr, 1, numbytes, f) ;}/*---------------------------------------------------------------------------*//* Function: sayfileinfo   Purpose: Display some bytes from our configuration file on standard out.   Used by: Local functions.   Returns: Nothing.   Notes:     -It is assumed that numbytes includes the trailing '\0'.     -The file position is not restored to its original value.     -Don't try to output 0 bytes.   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void sayfileinfo(signed long *infobaseptr, FILE *str){	size_t len ;	ubyte b[2] ;	if(readbytesfromfile(ConfigFile, *infobaseptr, sizeof(b), b) != sizeof(b))	{		ioerror:		fatalerror(EC_FILE, "File I/O error.  Unexpected end of file?") ;	}	len = ((b[0] << 8) | b[1]) ; /* (Bigendian.) */	if(saybytesfromfile(ConfigFile, (*infobaseptr + sizeof(b)), len, str) != len)	{		goto ioerror ;	}	*infobaseptr += (sizeof(b) + (signed long)len + 1) ; /* Skip over length field, text field, and tag. */}/*---------------------------------------------------------------------------*//* Function: selectfiletype   Purpose: Set up for processing the input file.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void selectfiletype(void){	ubyte b[14] ;	FILE *bitstr;	bitstr = (PrintConfig)? OutStr: InfoStr;	/* Read in the interesting parts of the file header.	*/	if(readbytesfromfile(ConfigFile, 0, sizeof(b), b) != sizeof(b))	{		ioerror:		fatalerror(EC_FILE, "File I/O error.  Unexpected end of file?") ;	}	/* Figure out what kind of file we have.	*/	if((b[0] == 0x00) && (b[1] == 0x09) && (b[11] == 0x00) && (b[12] == 0x01) && (b[13] == 'a'))	{		/* Looks like a .BIT file.		*/		signed long base ;		fprintf(InfoStr, "\nLooks like a .BIT file:") ;		base = 14 ; /* Offset of design name length field. */		/* Display file particulars.		*/		if(PrintConfig) fprintf(bitstr, "/*");		fprintf(bitstr, "\n  Design name:          ") ; sayfileinfo(&base, bitstr) ;		fprintf(bitstr, "\n  Part I.D.:            ") ; sayfileinfo(&base, bitstr) ;		fprintf(bitstr, "\n  Design date:          ") ; sayfileinfo(&base, bitstr) ;		fprintf(bitstr, "\n  Design time:          ") ; sayfileinfo(&base, bitstr) ;		if(readbytesfromfile(ConfigFile, base, 4, b) != 4)		{			goto ioerror ;		}		ImageLen = (((unsigned long)b[0] << 24) |					((unsigned long)b[1] << 16) |					((unsigned long)b[2] << 8) |					(unsigned long)b[3]) ;		fprintf(bitstr, "\n  Configuration length: %lu bytes", ImageLen) ;		if(PrintConfig) fprintf(bitstr, "\n*/\n");		DataOutFuncPtr = outdata8wswap ; /* We have to swap bits in .BIT files. */		/* We leave the file position set to the next byte in the file, which should		     be the first byte of the body of the data image.		*/	}	else if((b[0] == 0xFF) && (b[4] == 0x55) && (b[5] == 0x99) && (b[6] == 0xAA) && (b[7] == 0x66))	{		/* Looks like a PROM file.		*/		fprintf(InfoStr, "\nLooks like a PROM file:") ;		DataOutFuncPtr = outdata8noswap ; /* No bit swap in PROM files. */		ImageLen = filelengthq(ConfigFile); ;		if(ImageLen < 0)		{			seekerror:			fatalerror(EC_SYS, "File seek error.") ;		}		fprintf(InfoStr, "\n  Configuration length: %lu bytes", ImageLen) ;		/* PROM file data starts at offset 0, so we have to back up.		*/		if(fseek(ConfigFile, 0, SEEK_SET) != 0)		{			goto seekerror ;		}	}	else	{		/* It isn't something we know about.		*/		fatalerror(EC_FILE, "Unknown file type.") ;	}	fputc('\n', InfoStr) ;	fflush(InfoStr) ; /* (Make sure the user can see all output to date.) */}/*---------------------------------------------------------------------------*//* Function: signon   Purpose: Display the signon message.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void signon(void){	fprintf(InfoStr, "%s", SIGNONMESSAGE) ;	fprintf(InfoStr, "Mesa Electronics 5I20 configuration utility for Linux.\n") ;	fflush(InfoStr) ;}/*---------------------------------------------------------------------------*//* Function: pcl   Purpose: Collect parameters from the command line.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static const char FileNameInfo[] = "\n""filename.ext specifies the name of the configuration file to be loaded." ;static const char CardInfo[] = "\n""card is the number of the PCI card.  (For use with multiple 5I20 cards.)" ;static const char PurposeInfo[] = "\n""Purpose: 5I20 configuration upload." ;static void pcl(unsigned argc, char *argv[]){	unsigned cardnum = 0 ;	if((argc != 2) && (argc != 3))	{		fprintf(InfoStr, "\n%s program usage:\n%s filename.ext [<card>]", ProgNameMsg, ProgNameMsg) ;		fprintf(InfoStr, "\nWhere:") ;		fprintf(InfoStr, "%s", FileNameInfo) ;		fprintf(InfoStr, "%s", CardInfo) ;		fprintf(InfoStr, "%s", PurposeInfo) ;		fputc('\n', InfoStr) ;		fflush(InfoStr) ;		exit(EC_BADCL) ;	}	if((ConfigFile = fopen(argv[1], "rb")) == 0) /* (Binary mode.) */	{		fatalerror(EC_USER, "File not found: %s", argv[1]) ;	}	if(argc == 2)	{	    PrintConfig = 1;	}	else	{	    if(sscanf(argv[2], "%u", &cardnum) != 1)	    {		    badcardnum:		    fatalerror(EC_USER, "Invalid card number: %s", argv[2]) ;	    }	    if(cardnum > 15)	    {		    goto badcardnum ;	    }	    findpcicard(cardnum) ;	}	selectfiletype() ;}/*---------------------------------------------------------------------------*//* Function: programfpga   Purpose: Initialize the FPGA with the contents of file ConfigFile.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/#define FORMATSTRING "%-6lu"static void programfpga(void){	signed long bytesleft ;	unsigned long numbytes ;	size_t count ;	static ubyte filebuffer[16384] ;	ubyte *bptr ;	/* Enable programming.	*/	fprintf(InfoStr, "\nProgramming...\n") ;	fflush(InfoStr) ;	if(PrintConfig)	{	    fprintf(OutStr, "\nstatic hal_u8_t\n");	    fprintf(OutStr, "fpgaConfig[] = {");	}	else	{	    programdisable() ; /* Reset the FPGA. */	    if(programdunq())	    {		    /* Note that if we see DONE at the start of programming, it's most likely due			     to an attempt to access the FPGA at the wrong I/O location.		    */		    fatalerror(EC_HDW, "<DONE> status bit indicates busy at start of programming.") ;	    }	    programenable() ;	    /* Delay for at least 100 uS. to allow the FPGA to finish its reset		     sequencing.  (In reality, the time taken for the initial file access		     makes this this delay redundant.)	    */	    delay100us() ;	}	/* Program the card.	*/	numbytes = 0 ;	bytesleft = ImageLen ;	for( ; ; )	{		/* Write the file to the FPGA.		*/		errno = 0 ;		count = fread(filebuffer, 1, sizeof(filebuffer), ConfigFile) ;		if(count == 0)		{			/* 0 bytes could be end of file or error; must check.			*/			if(errno != 0)			{				if(!PrintConfig) programdisable() ;				fatalerror(EC_SYS, "File I/O error.") ;			}			else			{				fprintf(InfoStr, FORMATSTRING, 0L) ; fflush(InfoStr) ;				break ; /* Done. */			}		}		else		{			/* Write the block to the FPGA data port.			*/			fprintf(InfoStr, FORMATSTRING "\r", bytesleft) ; fflush(InfoStr) ;			bytesleft -= (signed long)count ;			bptr = filebuffer ;			do			{				if(PrintConfig && ((numbytes & 0x7) == 0)) fprintf(OutStr, "\n    ");				DataOutFuncPtr(*bptr++) ;				numbytes++;			} while(--count != 0) ;		}	}	fclose(ConfigFile) ;	/* Wait for completion of programming.	*/	if(!PrintConfig && (wait4dun() < 0))	{		fatalerror(EC_HDW, "Error: Not <DONE>; programming not completed.") ;	}	if(PrintConfig)	{	    fprintf(OutStr, "\n};\n");	    fflush(OutStr);	}	else	{	    /* Send configuration completion clocks.	    */	    sendcompletionclocks() ;	}	fprintf(InfoStr, "\nSuccessfully programmed %lu bytes.", numbytes) ;	fflush(InfoStr) ;}/*---------------------------------------------------------------------------*//* Function: main   Purpose: Program entry point.   Used by: Program launcher.   Returns: Exit status.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/int main(int argc, char *argv[]){	InfoStr = stderr;	ErrStr = stderr;	OutStr = stdout;	signon() ;	pcl(argc, argv) ;	programfpga() ;	cleanup() ;	fprintf(InfoStr, "\n\nFunction complete.\n") ; fflush(InfoStr) ;	return 0 ;}/*---------------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -