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

📄 dataflashdev.c

📁 (1)基于部分u-boot代码自己调试的vxworks BSP (2)实现了nand/nor flash的tffs文件系统 (3)实现了对spi dataflash的访问 (4)实现了对启动参数
💻 C
📖 第 1 页 / 共 2 页
字号:
/* dataflashDrv.c - dataflash disk device driver *//* Copyright 1989-1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01p,30jul99,jkf  fixed SPR 9729, retryRW condition loses data.01o,11jan99,aeg  removed redundant semBInit () in dataflashInit ().01n,03mar97,dat  fixed SPR 8084, previous edit needed tweeking.01m,28feb97,dat  fixed SPR 8084, incorrect block number check01l,17dec96,dat  fixed SPR 3273, incorrect block count01k,14jun95,hdn  removed function declarations defined in sysLib.h.01j,24jan95,jdi  doc cleanup.01i,07dec94,rhp  man page cleanups to dataflashDrvCreate(), dataflashRawio() (SPR3734).01h,25oct94,hdn  cleaned up dataflashRawio().		 changed dataflashSemSec and dataflashWdSec back to 5.01g,06oct94,hdn  changed dataflashSemSec to 10, dataflashWdSec to 10.		 added dataflashRawio() to provdataflash physical IO.01f,03jun94,hdn  changed DESCRIPTION, 386 to 386/486.		 added an explanation of parameters for dataflashDevCreate().01e,18nov93,hdn  added watchdog to check dataflashInit() in dataflashDrv().01d,11nov93,hdn  added dataflashWait() in end of each primitive functions.		 implemented semaphore timeout and watchdog.01c,10nov93,hdn  separated dataflashDiagnose() from dataflashInit().01b,04nov93,hdn  cleaned up.01a,18oct93,hdn  written.*//*DESCRIPTIONThis is the driver for the dataflash used on the PC 386/486.USER-CALLABLE ROUTINESMost of the routines in this driver are accessible only through the I/Osystem.  However, two routines must be called directly:  dataflashDrv() toinitialize the driver, and dataflashDevCreate() to create devices.Before the driver can be used, it must be initialized by calling dataflashDrv().This routine should be called exactly once, before any reads, writes, orcalls to dataflashDevCreate().  Normally, it is called from usrRoot() inusrConfig.c.The routine dataflashRawio() provdataflashs physical I/O access.  Its firstargument is a drive number, 0 or 1; the second argument is a pointerto an DATAFLASH_RAW structure.NOTEFormat is not supported, because dataflash disks are already formatted, and badsectors are mapped.SEE ALSO:.pG "I/O System"*/#include "vxWorks.h"#include "taskLib.h"#include "ioLib.h"#include "iosLib.h"#include "memLib.h"#include "stdlib.h"#include "errnoLib.h"#include "stdio.h"#include "string.h"#include "private/semLibP.h"#include "intLib.h"#include "iv.h"#include "wdLib.h"#include "sysLib.h"#include "sys/fcntlcom.h"#include "h/drv/dataflash/dataflashdrv.h"#include "at91c_spi_dataflash.h"#define AT91C_DATAFLASH_TIMEOUT				10000   /* For AT91F_DataFlashWaitReady *//*/#define BUFFER_SIZE_DATAFLASH				1056 *//*/#define MASTER_CLOCK						60000000 *//* imports */#define CFG_MAX_DATAFLASH_BANKS 2/* global */BOOL dataflashDebug	 = FALSE;	/* debug flag */BOOL dataflashDebugErr = FALSE;	/* debug flag */int  dataflashIntCount = 0;		/* interrupt count */int  dataflashStatus	 = 0;		/* status register in interrupt level */int  dataflashDrives	 = 0;		/* number of dataflash drives */int  dataflashRetry	 = 3;		/* max retry count */int  dataflashSemSec	 = 5;		/* timeout seconds for semaphore */int  dataflashWdSec	 = 5;		/* timeout seconds for watchdog */BOOL dataflashWaitForever = TRUE;	/* watchdog: wait forever in dataflashInit() *//*/SEMAPHORE dataflashSyncSem;*/		/* binary semaphore for syncronization */SEMAPHORE dataflashMuteSem;		/* mutex  semaphore for mutual-exclusion */int cs[CFG_MAX_DATAFLASH_BANKS] = {	AT91C_SPI_PCS0_SERIAL_DATAFLASH,	/* Logical adress, CS */	AT91C_SPI_PCS3_DATAFLASH_CARD};/* local */LOCAL BOOL dataflashDrvInstalled = FALSE;   /* TRUE = facility installed */#include "dataflash.c"/* function prototypes */      void   dataflashShow	(int drive);LOCAL STATUS dataflashBlkRd	(AT91PS_DataFlash_Device pdataflashDev, int startBlk, int nBlks, char *pBuf);LOCAL STATUS dataflashBlkWrt	(AT91PS_DataFlash_Device pdataflashDev, int startBlk, int nBlks, char *pBuf);LOCAL STATUS dataflashReset	(AT91PS_DataFlash_Device pdataflashDev);LOCAL STATUS dataflashIoctl	(AT91PS_DataFlash_Device pdataflashDev, int function, int arg);LOCAL STATUS dataflashBlkRW	(AT91PS_DataFlash_Device pdataflashDev, int startBlk, int nBlks, char *pBuf,			 int direction);LOCAL void   dataflashIntr	(int ctrl);LOCAL void   dataflashWdog	(int ctrl);LOCAL void   dataflashWait	(int request);/*/LOCAL void   dataflashInit	(void);*/LOCAL STATUS dataflashDiagnose(void);LOCAL STATUS dataflashPinit	(AT91PS_DataFlash_Device pdataflashDev);LOCAL STATUS dataflashPread	(int drive, void *buffer);LOCAL STATUS dataflashRecalib	(int drive);LOCAL STATUS dataflashSeek	(int drive, int cylinder, int head);LOCAL STATUS dataflashRW	(int drive, int cylinder, int head, int sector, 	 		 void *pBuf, int nSecs, int direction);LOCAL STATUS dataflashFormat	(int drive, int cylinder, int head, int interleave);LOCAL STATUS dataflashStatusChk(AT91PS_DataFlash_Device pdataflashDev);LOCAL void AT91F_CfgDataFlash (AT91PS_DataFlash_Device pdataflashDev);LOCAL AT91S_DataflashFeatures			DeviceAT45DCB;LOCAL AT91S_DataflashFeatures			DeviceAT45DB;LOCAL AT91S_DataflashDesc			DataflashDesc;/*AT91S_DataFlash				DataFlash;*/LOCAL AT91PS_DataFlash_Device			pDataFlash_Device=0;LOCAL void  AT91F_SPI_CfgSPI(void){    /* Reset the SPI*/	AT91F_SPI_Reset(AT91C_BASE_SPI);    /* Configure SPI in Master Mode with No CS selected !!! */ 	AT91F_SPI_CfgMode(AT91C_BASE_SPI, AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS);#if 1    /* Configure SPI CS0 for Serial DataFlash AT45DBxx*/	AT91F_SPI_CfgCs(0, AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((MASTER_CLOCK / (2*DATAFLASH_CLK)) << 8));    /* Configure SPI CS3 for DataFlash Card AT45DCBxx*/	AT91F_SPI_CfgCs(3, AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((MASTER_CLOCK / (2*DATAFLASH_CLK)) << 8));#else	/* Configure CS0 and CS3 */	*(AT91C_SPI_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | (AT91C_SPI_DLYBCT &	DATAFLASH_TCHS) | ((MASTER_CLOCK / (2*DATAFLASH_CLK)) << 8);	*(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | (AT91C_SPI_DLYBCT &	DATAFLASH_TCHS) | ((MASTER_CLOCK / (2*DATAFLASH_CLK)) << 8);#endif    /* Enable the SPI */           AT91F_SPI_Enable(AT91C_BASE_SPI);}LOCAL void AT91F_CfgSPIForDataFlash(){    /* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard*/#if __DK__	AT91F_PIO_CfgOutput(AT91C_BASE_PIOB,AT91C_PIO_PB7);	AT91F_PIO_ClearOutput(AT91C_BASE_PIOB,AT91C_PIO_PB7);#else	AT91F_PIO_CfgOutput(AT91C_BASE_PIOB,AT91C_PIO_PB22);	AT91F_PIO_ClearOutput(AT91C_BASE_PIOB,AT91C_PIO_PB22);#endif		/* Init SPI for DataFlash interface*/	AT91F_SPI_CfgPIO();		AT91F_SPI_CfgPMC();	AT91F_SPI_CfgSPI();	AT91F_PDC_Open(AT91C_BASE_PDC_SPI);	 	AT91F_CfgDataFlash(pDataFlash_Device);	    intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (AT91C_ID_SPI),		       (VOIDFUNCPTR)dataflashIntr, 0);	    sysIntEnablePIC (AT91C_ID_SPI);	}LOCAL AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDesc, unsigned int timeout);LOCAL int  dataflashWaitReady(unsigned int timeout){/*/return semTake (&dataflashSyncSem, timeout);*/	return AT91F_DataFlashWaitReady(pDataFlash_Device->pDataFlashDesc,AT91C_DATAFLASH_TIMEOUT); 		}/********************************************************************************* dataFlashDrv - initialize the dataflash driver** This routine initializes the dataflash driver, sets up interrupt vectors,* and performs hardware initialization of the dataflash chip.** This routine should be called exactly once, before any reads, writes,* or calls to dataflashDevCreate().  Normally, it is called by usrRoot()* in usrConfig.c.** The dataflashDrv() call requires a configuration type, <manualConfig>.  If* this argument is 1, the driver will initialize drive parameters; if* the argument is 0, the driver will not initialize drive parameters.** The drive parameters are the number of sectors per track, the number of* heads, and the number of cylinders.  They are stored in the structure* table `dataflashTypes[]' in sysLib.c.  The table has two entries:  the first is* for drive 0; the second is for drive 1.  The table has two other members* which are used by the driver: the number of bytes per sector and* the precompensation cylinder.  These two members should be set properly.* Definitions of the structure members are:* .CS*     int cylinders;              /@ number of cylinders @/*     int heads;                  /@ number of heads @/*     int sectorsTrack;           /@ number of sectors per track @/*     int bytesSector;            /@ number of bytes per sector @/*     int precomp;                /@ precompensation cylinder @/* .CE** RETURNS: OK, or ERROR if initialization fails.** SEE ALSO: dataflashDevCreate()*/STATUS dataflashDrv    (    )    {    int drive;    if (!dataflashDrvInstalled)    {/*/        semBInit (&dataflashSyncSem, SEM_Q_FIFO, SEM_EMPTY);*/        semMInit (&dataflashMuteSem, SEM_Q_PRIORITY | SEM_DELETE_SAFE |		SEM_INVERSION_SAFE);	     /*/   dataflashInit ();*/	/*dataflashPinit (drive);*/        	dataflashDrvInstalled = TRUE;    }    return (OK);    }/********************************************************************************* dataflashDevCreate - create a device for a dataflash disk** This routine creates a device for a specified dataflash disk.** <drive> is a drive number for the hard drive: it must be 0 or 1.** The <nBlocks> parameter specifies the size of the device, in blocks.* If <nBlocks> is zero, the whole disk is used.** The <blkOffset> parameter specifies an offset, in blocks, from the start* of the device to be used when writing or reading the hard disk.  This* offset is added to the block numbers passed by the file system during* disk accesses.  (VxWorks file systems always use block numbers beginning* at zero for the start of a device.)*** RETURNS:* A pointer to a block device structure (BLK_DEV), or NULL if memory cannot* be allocated for the device structure.** SEE ALSO: dosFsMkfs(), dosFsDevInit(), rt11FsDevInit(), rt11FsMkfs(),* rawFsDevInit()*/int __get_Dataflash_block_size__(int size){    return 1;}LOCAL	char *databuf =0 ;#undef __TEST__#ifdef __TEST__LOCAL char* gpCache=0;#endifBLK_DEV *dataflashDevCreate    (    int drive,		/* drive number for hard drive (0 or 1) */    int nBlocks,	/* device size in blocks (0 = whole disk) */    int blkOffset	/* offset from start of device */    )    {    AT91PS_DataFlash_Device pdataflashDev;    BLK_DEV *pBlkDev;    if (!dataflashDrvInstalled)	return (NULL);    if(pDataFlash_Device)    { 	 if (nBlocks == 0)	nBlocks = (pDataFlash_Device->pDevice->pages_number)		  - blkOffset;    	pDataFlash_Device->blkDev.bd_nBlocks = nBlocks;   	 pDataFlash_Device->drive		= drive;   	 pDataFlash_Device->blkOffset		= blkOffset;	return (&pDataFlash_Device->blkDev);    }    if ((UINT)drive > dataflashDrives)	return (NULL);    if ((pdataflashDev = (AT91PS_DataFlash_Device )calloc(sizeof (AT91S_DataFlash_Device), 1)) == NULL)	return (NULL);    DataflashDesc.command = (char *) cacheDmaMalloc (8);    pBlkDev = &pdataflashDev->blkDev;    pDataFlash_Device = pdataflashDev;    AT91F_CfgSPIForDataFlash();     dataflashPinit (pdataflashDev);    if (nBlocks == 0)	nBlocks = (pdataflashDev->pDevice->pages_number)		  - blkOffset;    pBlkDev->bd_nBlocks		= nBlocks;    pBlkDev->bd_bytesPerBlk	= __get_Dataflash_block_size__(pdataflashDev->pDevice->pages_size);    pBlkDev->bd_blksPerTrack	= 1;    pBlkDev->bd_nHeads		= 1;    pBlkDev->bd_removable	= FALSE;    pBlkDev->bd_retry		= 1;    pBlkDev->bd_mode		= O_RDWR;    pBlkDev->bd_readyChanged	= FALSE;    pBlkDev->bd_blkRd		= dataflashBlkRd;    pBlkDev->bd_blkWrt		= dataflashBlkWrt;    pBlkDev->bd_ioctl		= dataflashIoctl;    pBlkDev->bd_reset		= dataflashReset;    pBlkDev->bd_statusChk	= dataflashStatusChk;    pdataflashDev->drive		= drive;    pdataflashDev->blkOffset		= blkOffset;#ifdef __TEST__        gpCache = malloc(0x210*nBlocks);#endif    databuf =(char *) cacheDmaMalloc (1200);    return (&pdataflashDev->blkDev);    }/********************************************************************************* dataflashShow - show dataflash disk parameters** Show dataflash disk parameters** RETURNS: N/A** NOMANUAL*/void dataflashShow    (    int drive    )    {    }/********************************************************************************* dataflashRawio - provide raw I/O access** This routine is called when the raw I/O access is necessary.** <drive> is a drive number for the hard drive: it must be 0 or 1.** The <pdataflashRaw> is a pointer to the structure DATAFLASH_RAW which is defined in * dataflashDrv.h** RETURNS: OK or ERROR.**/STATUS dataflashRawio    (    int        drive,	/* drive number for hard drive (0 or 1) */    DATAFLASH_RAW *  pdataflashRaw	/* pointer to DATAFLASH_RAW structure */    )    {     BLK_DEV *pBlkDev = 0 ;/*/	= &dataflashDev.blkDev;*/    int nBlocks = 0;    UINT startBlk;    STATUS err;    if (!dataflashDrvInstalled)	return (ERROR);    if ((UINT)drive > dataflashDrives)	return (ERROR);    if(pDataFlash_Device==0 )     {	pBlkDev=dataflashDevCreate(0,0,0);    }        AT91F_CfgDataFlash(pDataFlash_Device);    dataflashPinit(pDataFlash_Device);/*memcpy(&dataflashDev,pDataFlash_Device,sizeof(dataflashDev));*/     /*   nBlocks = (pDataFlash_Device->pDevice->pages_number)	  - 0;    pBlkDev->bd_nBlocks		= nBlocks;    pBlkDev->bd_bytesPerBlk	= __get_block_size__(pDataFlash_Device->pDevice->pages_size);    pBlkDev->bd_blksPerTrack	= 1;    pBlkDev->bd_nHeads		= 1;    pBlkDev->bd_removable	= FALSE;    pBlkDev->bd_retry		= 1;    pBlkDev->bd_mode		= O_RDWR;    pBlkDev->bd_readyChanged	= TRUE;    pBlkDev->bd_blkRd		= dataflashBlkRd;    pBlkDev->bd_blkWrt		= dataflashBlkWrt;    pBlkDev->bd_ioctl		= dataflashIoctl;    pBlkDev->bd_reset		= dataflashReset;    pBlkDev->bd_statusChk	= NULL;    pDataFlash_Device->drive		= drive;    pDataFlash_Device->blkOffset	= 0;*/    startBlk = 0;	AT91F_DataFlashWaitReady(pDataFlash_Device->pDataFlashDesc,AT91C_DATAFLASH_TIMEOUT);    err= (dataflashBlkRW (pDataFlash_Device, startBlk, pdataflashRaw->nSecs, pdataflashRaw->pBuf,		     pdataflashRaw->direction));        return err;    }/********************************************************************************* dataflashBlkRd - read one or more blocks from a dataflash disk** This routine reads one or more blocks from the specified device,* starting with the specified block number.** If any block offset was specified during dataflashDevCreate(), it is added* to <startBlk> before the transfer takes place.** RETURNS: OK, ERROR if the read command didn't succeed.*/LOCAL STATUS dataflashBlkRd    (    AT91PS_DataFlash_Device pdataflashDev,    int startBlk,    int nBlks,    char *pBuf    )    {    return (dataflashBlkRW (pdataflashDev, startBlk, nBlks, pBuf, O_RDONLY));    }/********************************************************************************* dataflashBlkWrt - write one or more blocks to a dataflash disk** This routine writes one or more blocks to the specified device,* starting with the specified block number.** If any block offset was specified during dataflashDevCreate(), it is added* to <startBlk> before the transfer takes place.** RETURNS: OK, ERROR if the write command didn't succeed.*/LOCAL STATUS dataflashBlkWrt    (    AT91PS_DataFlash_Device pdataflashDev,    int startBlk,    int nBlks,    char *pBuf    )    {    return (dataflashBlkRW (pdataflashDev, startBlk, nBlks, pBuf, O_WRONLY));    }/********************************************************************************* dataflashReset - reset a dataflash disk controller** This routine resets a dataflash disk controller.** RETURNS: OK, always.*/LOCAL STATUS dataflashReset    (    AT91PS_DataFlash_Device pdataflashDev    )    {        semTake (&dataflashMuteSem, WAIT_FOREVER); /*  dataflashInit ();*/    semGive (&dataflashMuteSem);

⌨️ 快捷键说明

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