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

📄 m5i20cfg.c

📁 Source code for an Numeric Cmputer
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * * Copyright (C) 2005 Peter C. Wallace <pcw AT mesanet DOT com> * * $RCSfile: m5i20cfg.c,v $ * $Author: petev $ * $Locker:  $ * $Revision: 1.4 $ * $State: Exp $ * $Date: 2005/11/20 02:39:36 $ * ****************************************************************************** * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2.1 of the GNU General * Public License as published by the Free Software Foundation. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111 USA * * THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR * ANY HARM OR LOSS RESULTING FROM ITS USE.  IT IS _EXTREMELY_ UNWISE * TO RELY ON SOFTWARE ALONE FOR SAFETY.  Any machinery capable of * harming persons must have provisions for completely removing power * from all motors, etc, before persons enter any danger area.  All * machinery must be designed to comply with local and national safety * codes, and the authors of this software can not, and do not, take * any responsibility for such compliance. * * This code was written as part of the EMC HAL project.  For more * information, go to www.linuxcnc.org. * ******************************************************************************//*---------------------------------------------------------------------------*//*   sc5i20l.c   Demonstration program for configuration of the Mesa Electronics 5I20 I/O	 card/Linux.   Version 0.2, Thursday February 24, 2005 -- 12:12:48.   Note: This program must be run as root, as it accesses system I/O ports	 directly.  (No device driver is used.)  Ugly.  Dangerous.  X86-only.*//*---------------------------------------------------------------------------*//*   Compiler: gcc   Tabs: 4   Compile with "gcc -O2 sc5i20l.c -o sc5i20"*//*---------------------------------------------------------------------------*//*   Revision history.   1) Version 0.1, Monday February 21, 2005 -- 20:12:17.	  Code frozen for version 0.1.   2) Version 0.2, Thursday February 24, 2005 -- 12:12:48.      Changes from version 0.1:	  1) Uses of off_t replaced with unsigned long for consistency.	  2) <sys/types.h> is no longer included.*//*---------------------------------------------------------------------------*/#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <time.h>#include <errno.h>#include <sys/io.h>#include <sys/stat.h>/*---------------------------------------------------------------------------*//* Assorted #defines.*/#define PROGNAME      "SC5I20L"#define SIGNONMESSAGE "\n"PROGNAME" version "PROGVERSION"\n"#define PROGVERSION   "0.2"/* I/O registers.*/#define R_5I20CONTROLNSTATUS 0x0054 /* 32-bit control/status register. *//* PCI base register indices.*/#define BRNUM_5I20LCLCFGIO 1 /* Local configuration I/O base address register number. */#define BRNUM_5I20IO16     2 /* 16-bit I/O window to FPGA. (Base address register 2.) */#define BRNUM_5I20IO32     3 /* 32-bit I/O window to FPGA. (Base address register 3.) */#define BRNUM_5I20CFGMEM   4 /* Configuration memory window. *//* Masks for R_5I20CONTROLNSTATUS.*/#define P_5I20CFGPRGM         P_FPGAIOControlnStatus32#define B_5I20CFGPRGM         26 /* Program enable. (Output.) */#define M_5I20CFGPRGM         (0x1 << B_5I20CFGPRGM)#define M_5I20CFGPRGMDEASSERT (0x0 << B_5I20CFGPRGM) /* Reset the FPGA. */#define M_5I20CFGPRGMASSERT   (0x1 << B_5I20CFGPRGM) /* Begin programming. */#define P_5I20CFGRW           P_FPGAIOControlnStatus32#define B_5I20CFGRW           23 /* Data direction control. (Output.) */#define M_5I20CFGRW           (0x1 << B_5I20CFGRW)#define M_5I20CFGWRITEENABLE  (0x0 << B_5I20CFGRW) /* From CPU. */#define M_5I20CFGWRITEDISABLE (0x1 << B_5I20CFGRW) /* To CPU. */#define P_5I20LEDONOFF        P_FPGAIOControlnStatus32#define B_5I20LEDONOFF        17 /* Red LED control. (Output.) */#define M_5I20LEDONOFF        (0x1 << B_5I20LEDONOFF)#define M_5I20LEDON           (0x0 << B_5I20LEDONOFF)#define M_5I20LEDOFF          (0x1 << B_5I20LEDONOFF)#define P_5I20PRGMDUN         P_FPGAIOControlnStatus32#define B_5I20PRGMDUN         11 /* Programming-done flag. (Input.) */#define M_5I20PRGMDUN         (0x1 << B_5I20PRGMDUN)#define M_5I20PRGMDUNNOW      (0x1 << B_5I20PRGMDUN)/* Paths.*/#define PATH_PROC_BUS_PCI "/proc/bus/pci"/* Card I.D.*/#define VENDORID5I20 0x10B5 /* PCI vendor I.D. */#define DEVICEID5I20 0x9030 /* PCI device I.D. *//* Exit codes.*/#define EC_OK    0   /* Exit OK. */#define EC_BADCL 100 /* Bad command line. */#define EC_USER  101 /* Invalid input. */#define EC_HDW   102 /* Some sort of hardware failure on the 5I20. */#define EC_FILE  103 /* File error of some sort. */#define EC_SYS   104 /* Beyond our scope. */#define EC_NTRNL 105 /* Internal error. *//*---------------------------------------------------------------------------*//* Assorted typedefs.*/typedef unsigned char  unsigned8,  ubyte ;typedef unsigned short unsigned16, uword ;typedef unsigned long unsigned32, udword ;/*---------------------------------------------------------------------------*//* Local external variables.*/static unsigned long ImageLen ; /* Number of bytes in device image portion of file. */static uword P_FPGAData, P_FPGAIOControlnStatus32 ;static void (*DataOutFuncPtr)(unsigned thebyte) ;static FILE *ConfigFile ;static int PrintConfig = 0;static const char ProgNameMsg[] = { PROGNAME } ;static FILE *InfoStr;static FILE *ErrStr;static FILE *OutStr;/*---------------------------------------------------------------------------*//* Function: cleanup   Purpose: Release external resources, etc.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void cleanup(void){	iopl(0) ;}/*---------------------------------------------------------------------------*//* Function: fatalerror   Purpose: Display a fatal error message and exit.   Used by: Local functions.   Returns: Never.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void fatalerror(int exitcode, const char *fmt, ...){	va_list vp ;	cleanup() ; /* Maybe free up allocated system resources. */	fflush(InfoStr) ; /* Make sure we don't get normal informational messages mixed in with error messages. */	fflush(OutStr) ;	va_start(vp, fmt) ;	fprintf(ErrStr, "\n\n\a%s:\n", ProgNameMsg) ;	vfprintf(ErrStr, fmt, vp) ;	putc('\n', ErrStr) ;	fflush(ErrStr) ;	exit(exitcode) ;}/*---------------------------------------------------------------------------*//* Function: ledon   Purpose: Turn on the 5I20's programming LED.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void ledon(void){	outl(((inl(P_5I20LEDONOFF) & ~M_5I20LEDONOFF) | M_5I20LEDON), P_5I20LEDONOFF) ;}/*---------------------------------------------------------------------------*//* Function: ledoff   Purpose: Turn off the 5I20's programming LED.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void ledoff(void){	outl(((inl(P_5I20LEDONOFF) & ~M_5I20LEDONOFF) | M_5I20LEDOFF), P_5I20LEDONOFF) ;}/*---------------------------------------------------------------------------*//* Function: writeenable   Purpose: Enable configuration data transfer from the CPU to the 5I20.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void writeenable(void){	outl(((inl(P_5I20CFGRW) & ~M_5I20CFGRW) | M_5I20CFGWRITEENABLE), P_5I20CFGRW) ;	ledon() ;}/*---------------------------------------------------------------------------*//* Function: writedisable   Purpose: Disable configuration data transfer from the CPU to the 5I20.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void writedisable(void){	outl(((inl(P_5I20CFGRW) & ~M_5I20CFGRW) | M_5I20CFGWRITEDISABLE), P_5I20CFGRW) ;	ledoff() ;}/*---------------------------------------------------------------------------*//* Function: programenable   Purpose: Enable 5I20 programming.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void programenable(void){	outl(((inl(P_5I20CFGPRGM) & ~M_5I20CFGPRGM) | M_5I20CFGPRGMASSERT), P_5I20CFGPRGM) ;	writeenable() ;}/*---------------------------------------------------------------------------*//* Function: programdisable   Purpose: Disable 5I20 programming/reset the FPGA.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void programdisable(void){	outl(((inl(P_5I20CFGPRGM) & ~M_5I20CFGPRGM) | M_5I20CFGPRGMDEASSERT), P_5I20CFGPRGM) ;	writedisable() ;}/*---------------------------------------------------------------------------*//* Function: outdata8wswap   Purpose: Send a byte to the 5I20 data port with bits swapped.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void outdata8wswap(unsigned thebyte){	static const unsigned char swaptab[256] =	{		0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,		0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,		0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,		0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,		0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,		0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,		0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,		0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,		0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,		0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,		0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,		0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,		0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,		0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,		0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,		0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF	} ;	if(PrintConfig)	{	    fprintf(OutStr, "0x%02x, ", swaptab[thebyte]); 	}	else	{	    outb(swaptab[thebyte], P_FPGAData) ;	}}/*---------------------------------------------------------------------------*//* Function: outdata8noswap   Purpose: Send a byte to the 5I20 data port with no bit swapping.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void outdata8noswap(unsigned thebyte){    if(PrintConfig)    {	fprintf(OutStr, "0x%02x, ", thebyte);     }    else    {	outb(thebyte, P_FPGAData) ;    }}/*---------------------------------------------------------------------------*//* Function: findpcicard   Purpose: Try to find the specified PCI card.  If found set parameters.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void findpcicard(unsigned cardnum){	udword vendordev, busdevfunc ;	udword bases[6] ;	int numfields ;	unsigned		i, numlines ;	size_t linelen ;	FILE *f ;	char namebuf[256 + 1] ;	char *lineptr ;	if(snprintf(namebuf, sizeof(namebuf), "%s/devices", PATH_PROC_BUS_PCI) >= sizeof(namebuf))	{		fatalerror(EC_NTRNL, "File name too long: %s...", PATH_PROC_BUS_PCI) ;	}	if((f = fopen(namebuf, "r")) == 0)	{		/* (Shouldn't happen.)		*/		fatalerror(EC_SYS, "File not found: %s", namebuf) ;	}	lineptr = 0 ;	linelen = 0 ;	numlines = 0 ;	i = cardnum ;	for( ; ; )	{		if(getline(&lineptr, &linelen, f) < 0)		{			free(lineptr) ;			if(numlines == 0)			{				fatalerror(EC_SYS, "Unexpected end of file in %s", namebuf) ;			}			else			{				break ;			}		}		++numlines ;		/* Bus/dev/func vendor/device IRQ base0 base1 base2 base3 base4 base5...		*/		numfields = sscanf(lineptr, "%lx %lx %*x  %lx %lx %lx %lx %lx %lx",						   &busdevfunc, &vendordev,						   &bases[0], &bases[1], &bases[2], &bases[3], &bases[4], &bases[5]) ;		if(numfields < 8)		{			free(lineptr) ;			fatalerror(EC_SYS, "Incomplete PCI device information found: %s", namebuf) ;		}		if(vendordev == ((VENDORID5I20 << 16) | DEVICEID5I20))		{			if(i++ != cardnum)			{				continue ;			}			fclose(f) ;			free(lineptr) ;			fprintf(InfoStr, "\nUsing PCI device at bus %lu/device %lu/function %lu.",				   (busdevfunc >> 8), ((busdevfunc >> 3) & 0x1F), (busdevfunc & 0x07)) ;			P_FPGAIOControlnStatus32 = ((uword)bases[BRNUM_5I20LCLCFGIO] & ~0x3) ;			fprintf(InfoStr, "\n\nPLX 9030 configuration I/O base port: 0x%04hX", P_FPGAIOControlnStatus32) ;			P_FPGAIOControlnStatus32 += R_5I20CONTROLNSTATUS ;			fprintf(InfoStr, "\nPLX 9030 control/status port:         0x%04hX", P_FPGAIOControlnStatus32) ;			P_FPGAData = ((uword)bases[BRNUM_5I20IO16] & ~0x3) ;			fprintf(InfoStr, "\nPLX 9030 16-bit I/O base:             0x%04hX", P_FPGAData) ;			fprintf(InfoStr, "\nPLX 9030 32-bit I/O base:             0x%04hX", ((uword)bases[BRNUM_5I20IO32] & ~0x3)) ;			fputc('\n', InfoStr) ;			fflush(InfoStr) ;			/* Enable direct access to the I/O port range.			   Don't try this without adult supervision!			*/			if(iopl(3) < 0) /* Danger, Will Robinson!  Danger!  Danger! */			{				fatalerror(EC_SYS, "Can't enable direct port access.") ;			}			return ;		}	}	fatalerror(EC_USER, "Can't find 5I20 card number %u.", cardnum) ;}/*---------------------------------------------------------------------------*//* Function: sendcompletionclocks   Purpose: Send completion clocks to finish up programming.   Used by: Local functions.   Returns: Nothing.   Notes:   Revision history:	 1) Monday February 21, 2005 -- 20:12:17.*/static void sendcompletionclocks(void){	unsigned count ;	writedisable() ;	/* Send configuration completion clocks.  (6 should be enough, but we send		 lots for good measure.)	*/	for(count = 24 ; count != 0 ; --count)	{		outb(-1, P_FPGAData) ;	}}/*---------------------------------------------------------------------------*//* Function: programdunq   Purpose: Return whether or not the FPGA is done programming.   Used by: Local functions.   Returns: Yes/no 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.

⌨️ 快捷键说明

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