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

📄 s29glmtd.c

📁 flash文件系统的驱动
💻 C
字号:
/* s29glMtd.c - TrueFFS MTD for Spansion s29gl×××N devices */ /* Copyright 2007 HUST juntong *//* includes */#include <vxWorks.h>#include <taskLib.h>#include <logLib.h>#include <stdio.h>#include <cacheLib.h>#include "tffs/flflash.h"#include "tffs/backgrnd.h"/* defines */#define S29GL_MTD_SECTOR_SIZE           (0x80000)/* 128KB */#define S29GL_128_CHIP_SIZE             (0x1000000)	/* 16MB */#define S29GL_128_LAST_SECTOR_NUM       (S29GL_128_CHIP_SIZE / S29GL_MTD_SECTOR_SIZE - 1) /* 127 */#define S29GL_256_CHIP_SIZE             (0x2000000)	/* 32MB */#define S29GL_256_LAST_SECTOR_NUM       (S29GL_256_CHIP_SIZE / S29GL_MTD_SECTOR_SIZE - 1) /* 255 */#define S29GL_512_CHIP_SIZE             (0x2000000)	/* 32MB */#define S29GL_512_LAST_SECTOR_NUM       (S29GL_512_CHIP_SIZE / S29GL_MTD_SECTOR_SIZE - 1) /* 511 */#define S29GL_RSV_FOR_BOOTROM           (0x100000)/* 1MB */#define S29GL_FIRST_SECTOR_NUM          (S29GL_RSV_FOR_BOOTROM / S29GL_MTD_SECTOR_SIZE ) /* 8 */#define S29GL_MTD_CHIP_CNT              (1)#define S29GL_MTD_INTERLEAVE            (1)#define FLASH_REGISTER_WR(addr,data)	  *((volatile UINT16 *)(addr<<1))=(UINT16)data#define FLASH_REGISTER_RD(addr)	        (*((UINT16 *)(addr<<1)))UINT16 awBuffForOneSector[S29GL_MTD_SECTOR_SIZE];/* local routines */LOCAL FLStatus s29glSectorRangeErase(FLFlash* pVol, int, int);LOCAL FLStatus s29glProgram(FLFlash*, CardAddress, const void FAR1*, int,                             FLBoolean);LOCAL void FAR0* s29glMap(FLFlash*, CardAddress, int);LOCAL void flashIdGet(FLFlash*, UINT16*, UINT16*);/******************************************************************************** amd29lvMTDIdentify - MTD identify routine (see TrueFFS Programmer's Guide)** RETURNS: FLStatus**/FLStatus s29glMTDIdentify    (    FLFlash* pVol    ){    UINT16 manCode;    UINT16 devCode;    flashIdGet ( pVol, &manCode, &devCode );    if (( manCode & 0xff ) != 0x0001 )    {        return ( flUnknownMedia );    }    if ( devCode == 0x227E )		/* s29GL128N Just Process this kind of chip */	  {        pVol->type = 0x017E;        pVol->erasableBlockSize = S29GL_MTD_SECTOR_SIZE;        pVol->chipSize = S29GL_128_CHIP_SIZE - S29GL_RSV_FOR_BOOTROM;/* Not sure  ?????????*/        pVol->noOfChips = S29GL_MTD_CHIP_CNT;        pVol->interleaving = S29GL_MTD_INTERLEAVE;        pVol->write = s29glProgram;        pVol->erase = s29glSectorRangeErase;        pVol->map = s29glMap;	  }    else    {        return ( flUnknownMedia );    }            return(flOK);}/******************************************************************************** s29glProgram - MTD write routine (see TrueFFS Programmer's Guide)** RETURNS: FLStatus**/LOCAL FLStatus s29glProgram    (    FLFlash*          pVol,    CardAddress       address,    const void FAR1*  buffer,    int               length,    FLBoolean         overwrite    ){    volatile UINT16* pFlash;    UINT16* pBuffer, *pTemp, *pTemp2;    UINT16  wTemp1, wTemp2;    int  ii, sector, offset, timeout, dwLength ;    STATUS rc;    /* Check alignment */    if ( ( ( address & 0x01 ) != 0 ) ) /* Maybe do something here */    {        ;    }        if ( ( length > pVol->chipSize ) || ( length <= 0 ) )    {        logMsg("s29glProgram() length Error =0x %x.\n",length,0,0,0,0,0);				return flWriteFault;    }        pTemp2 = (UINT16 *)buffer;        while ( length > 0 )    {        pFlash = (volatile UINT16*) pVol->map(pVol, address, length);            /* Determine sector and offset */            sector = ( (UINT32)pFlash ) / pVol->erasableBlockSize ;/* Not sure ????? */        if ( ( sector < S29GL_FIRST_SECTOR_NUM ) || ( sector > S29GL_128_LAST_SECTOR_NUM ) )        {            logMsg("s29glProgram() sector Error = %x.\n",sector,0,0,0,0,0);				    return flWriteFault;        }                    offset = address % pVol->erasableBlockSize;/* the offset address in this sector */            /* Get a pointer to the flash sector */            pFlash = (volatile UINT16*) ( sector * ( pVol->erasableBlockSize ) );            pBuffer = (UINT16*) &awBuffForOneSector;/* Donnot use malloc() */        /* Copy all the sector from flash to memory */            memcpy(pBuffer, (void*) pFlash, pVol->erasableBlockSize);            /* Overwrite the sector in memory */                if ( length <= pVol->erasableBlockSize - offset )/* the length is in this sector, once is enough */        {            dwLength = length;            length = 0;                }        else        {            dwLength = pVol->erasableBlockSize - offset;                   length  -= dwLength;             pTemp2  += dwLength;            address += dwLength;        }        memcpy(((UINT8*) pBuffer) + offset, pTemp2, dwLength );                /* Erase sector */            rc = pVol->erase(pVol, sector, 1);         if ( rc != flOK )        {            return ( rc );        }            pTemp = ( UINT16 *)pFlash; /* point to the sector start address */                /* Program 'length' bytes (2 bytes each iterations) */                for ( ii = 0; ii < pVol->erasableBlockSize/2; ii++ )         {            FLASH_REGISTER_WR(0x555,0xaaaa);            FLASH_REGISTER_WR(0x2aa,0x5555);            FLASH_REGISTER_WR(0x555,0xa0a0);            *pFlash = *pBuffer;                        wTemp1 = *pFlash & 0x40;            timeout = 0x1000000;            while ( 1 )            {		            wTemp2  = *pFlash & 0x40;		            if ( wTemp1 == wTemp2 ) 		    		        break;		            else		    	          wTemp1 = wTemp2;		            if ( timeout-- <= 0 ) 		            {                    logMsg("s29glProgram() return flTimedOut.\n",0,0,0,0,0,0);		    		        return flWriteFault;		            }            }                    if ( *pFlash != *pBuffer )            {                logMsg("s29glProgram() return *pFlash != *pBuffer.\n",0,0,0,0,0,0);                return flWriteFault;            }            pFlash  ++;            pBuffer ++;        }                pBuffer = (UINT16 *)&awBuffForOneSector;        if ( memcmp( (void *) pTemp, (void *)pBuffer, pVol->erasableBlockSize) )/* check the entire sector */        {            logMsg("s29glProgram()  memcmp fail.\n",0,0,0,0,0,0);            return flWriteFault;        }    }            return flOK ;}/******************************************************************************** s29glSectorRangeErase - MTD erase routine (see TrueFFS Programmer's Guide)** RETURNS: FLStatus**/LOCAL FLStatus s29glSectorRangeErase    (    FLFlash* pVol,    int sectorNum,    int sectorCount    ){    int ii,jj;    UINT16 wTemp1,wTemp2;    volatile UINT16* pFlash;    int timeout;        /* Check for valid range */    if ( pVol->type == 0x017E )			/* s29gl128N */    {	      if ( sectorNum < S29GL_FIRST_SECTOR_NUM )	      {            logMsg("s29glSectorRangeErase() sectorNum too little = %x\n", sectorNum ,0,0,0,0,0);            return ( flBadParameter );	      }        if ( sectorNum + sectorCount >  S29GL_128_LAST_SECTOR_NUM + 1 )	      {            logMsg("s29glSectorRangeErase() sectorNum too large = %x\n",sectorNum + sectorCount,0,0,0,0,0);            return ( flBadParameter );	      }    }    else    {        logMsg("s29glSectorRangeErase() Error pVol->type =%x\n",pVol->type,0,0,0,0,0);        return ( flBadParameter );    }    for ( ii = 0; ii < sectorCount; ii++ )    {        pFlash = ( UINT16 * ) ( ( sectorNum + ii ) * ( pVol->erasableBlockSize ) );        FLASH_REGISTER_WR(0x00, 0xf0f0);/* RESET ????*/                FLASH_REGISTER_WR(0x555,0xaaaa);        FLASH_REGISTER_WR(0x2aa,0x5555);        FLASH_REGISTER_WR(0x555,0x8080);        FLASH_REGISTER_WR(0x555,0xaaaa);        FLASH_REGISTER_WR(0x2aa,0x5555);        FLASH_REGISTER_WR((((UINT32)pFlash)>>1),0x3030);                wTemp1 = *pFlash & 0x40;        timeout = 0x1000000;        while ( 1 )        {		        wTemp2  = *pFlash & 0x40;		        if ( wTemp1 == wTemp2 ) 				        break;		        else			          wTemp1 = wTemp2;		        if ( timeout-- <= 0 ) 		        {                logMsg("s29glSectorRangeErase() return flTimedOut.\n",0,0,0,0,0,0);				        return ( flWriteFault );		        }        }                FLASH_REGISTER_WR(0x00, 0xf0f0);/* RESET ????*/                for ( jj = 0; jj < pVol->erasableBlockSize/2; jj++ )/* Maybe too long time */        {            if ( *pFlash != 0xffff )            {                logMsg("s29glSectorRangeErase() *pFlash not 0xffff.\n",0,0,0,0,0,0);				        return ( flWriteFault );				    }				    pFlash ++;        }    }        return(flOK);   }/******************************************************************************** s29glMap - MTD map routine (see TrueFFS Programmer's Guide)** RETURNS: FLStatus**/LOCAL void FAR0* s29glMap    (    FLFlash* pVol,    CardAddress address,    int length    )    {    UINT32 flashBaseAddr = (pVol->socket->window.baseAddress << 12);    void FAR0* pFlash = (void FAR0*) (flashBaseAddr + address);    return(pFlash);    }    /******************************************************************************** flashIdGet - Get flash man. and device codes.** RETURNS: N/A**/LOCAL void flashIdGet    (    FLFlash* pVol,    UINT16* manCode,    UINT16* devCode    ){    FLASH_REGISTER_WR(0x00, 0xf0f0);/* RESET ????*/        FLASH_REGISTER_WR(0x555,0xaaaa);    FLASH_REGISTER_WR(0x2aa,0x5555);    FLASH_REGISTER_WR(0x555,0x9090);    *manCode = FLASH_REGISTER_RD(0x00);    FLASH_REGISTER_WR(0x00, 0xf0f0);/* RESET ????*/    FLASH_REGISTER_WR(0x555,0xaaaa);    FLASH_REGISTER_WR(0x2aa,0x5555);    FLASH_REGISTER_WR(0x555,0x9090);    *devCode = FLASH_REGISTER_RD(0x01);    FLASH_REGISTER_WR(0x00, 0xf0f0);/* RESET ?????*/    logMsg("Manufacture ID(0x0001)=%4x, Device ID(0x22xx)=%4x\n",*manCode, *devCode, 0, 0, 0, 0 );}

⌨️ 快捷键说明

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