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

📄 nordriver.c

📁 (1)基于部分u-boot代码自己调试的vxworks BSP (2)实现了nand/nor flash的tffs文件系统 (3)实现了对spi dataflash的访问 (4)实现了对启动参数
💻 C
📖 第 1 页 / 共 3 页
字号:
/* amd29LvMtd.c - TrueFFS MTD for AMD AM29LV devices */ /* Copyright 2000 Wind River, Inc. *//*modification history--------------------01h,27oct01,mil  Removed inline eieio and replaced with CACHE_PIPE_FLUSH().01g,11oct01,mil  Merged from post T2.1 release into T2.2.01f,22aug01,mil  Decoupled this MTD from BSP by using tffsFlashBaseAdrs from                 sysTffs.c.01e,21aug01,mil  Created in mcpn765 for TFFS until merged back to                 target/src/drv/tffs/amdmtd.c.01d,06aug00,srr  Modified amd29lv323CT support for 16 MB.01c,31jul00,cak  Renamed from mv2400mtd to amd29lvmtd.                 Added support for the amd29lv323. 01b,09may00,add  Fixed erase bug (last 4 sectors are odd sizes)01a,21apr00,add  Created.*//*DESCRIPTIONThis module implements an TrueFFS MTD for the AMD AM29LV160D andAM29LV323 flash devices. *//* includes */#include "config.h"#ifdef INCLUDE_TFFS #include <vxWorks.h>#include <taskLib.h>#include <logLib.h>#include <stdio.h>#include <cacheLib.h>#include "tffs/flflash.h"#include "tffs/backgrnd.h"IMPORT int sysClkRateGet();#define AT91C_A24_NC/* defines */#define S29GL_N_256_MTD_SECTOR_SIZE  NOR_FLASH_SECTOR_SIZE_IN_BYTES#define S29GL_N_256_CHIP_SIZE  NOR_FLASH_TFFS_SIZE_IN_BYTES#define S29GL_N_256_LAST_SECTOR_NUM  (S29GL_N_256_CHIP_SIZE / S29GL_N_256_MTD_SECTOR_SIZE - 1)#define AMD29LV_MTD_SECTOR_SIZE         (0x40000)#define AMD29LV_160_CHIP_SIZE           (0x80000)	/*  8MB */#define AMD29LV_160_LAST_SECTOR_NUM     (AMD29LV_160_CHIP_SIZE / AMD29LV_MTD_SECTOR_SIZE - 1)/* specific 160 chip defines */#define AMD29LV_160_D_MTD_SECTOR_SIZE 	(NOR_FLASH_SECTOR_SIZE_IN_BYTES)#define AMD29LV_160_D_CHIP_SIZE           		(NOR_FLASH_TFFS_SIZE_IN_BYTES)	#define AMD29LV_160_D_LAST_SECTOR_NUM     (AMD29LV_160_D_CHIP_SIZE / AMD29LV_160_D_MTD_SECTOR_SIZE - 1)#define AMD29LV_323_CHIP_SIZE           (0x1000000)	/* 16MB */#define AMD29LV_323_LAST_SECTOR_SIZE    (0x8000)#define AMD29LV_323_LAST_SECTOR_NUM     (AMD29LV_323_CHIP_SIZE / AMD29LV_MTD_SECTOR_SIZE - 1)#define AMD29LV_MTD_CHIP_CNT            (1)#define AMD29LV_MTD_INTERLEAVE          (1)#define DEBUG_READ     0x00000001#define DEBUG_WRITE    0x00000002#define DEBUG_PROGRAM  0x00000004#define DEBUG_ERASE    0x00000008#define DEBUG_ID       0x00000010#define DEBUG_MAP      0x00000020#define DEBUG_PROG32   0x00000040#define DEBUG_ALWAYS   0xffffffff#undef TFFS_NOR_DEBUG#ifdef  TFFS_NOR_DEBUG    LOCAL UINT32 tffs_nor_debug_switch = DEBUG_ALWAYS;    #define TFFS_NOR_DEBUG_PRINT(mask, string) \                if ((tffs_nor_debug_switch & mask) || (mask == DEBUG_ALWAYS)) \                printf string#else    #define TFFS_NOR_DEBUG_PRINT(mask, string)#endif/* local routines */LOCAL FLStatus amd29lvSectorRangeErase(FLFlash* pVol, int, int);LOCAL FLStatus amd29lvProgram(FLFlash*, CardAddress, const void FAR1*, int,                             FLBoolean);LOCAL void FAR0* amd29lvMap(FLFlash*, CardAddress, int);LOCAL void flashReset(FLFlash*, BOOL);LOCAL void flashIdGet(FLFlash*, UINT16*, UINT16*);LOCAL void flashUnlock(FLFlash*, BOOL);LOCAL STATUS flashProgram16Bits(FLFlash*, volatile UINT16*, UINT16, BOOL);LOCAL void flashRegWrite16Bits(FLFlash*, UINT32, UINT32, BOOL);LOCAL UINT16 flashRegRead16Bits(FLFlash*, UINT32, BOOL);LOCAL STATUS flashSectorErase(FLFlash*, int , BOOL);/******************************************************************************** amd29lvMTDIdentify - MTD identify routine (see TrueFFS Programmer's Guide)** RETURNS: FLStatus**/FLStatus amd29lvMTDIdentify    (    FLFlash* pVol    ){    UINT16 manCode;    UINT16 devCode;    if (pVol->socket->window.baseAddress != (NOR_FLASH_TFFS_BASE >> 12))    {        TFFS_NOR_DEBUG_PRINT(DEBUG_ID, ("%s: base address (0x%x) mismatch. \n", __FUNCTION__, (vol.socket->window.baseAddress <<12)));            printf("window.baseAddress = 0x%x\n", (pVol->socket->window.baseAddress <<12));            return flUnknownMedia;    }	#if 1    flashIdGet(pVol, &manCode, &devCode);#else    *((volatile UINT16 *)NOR_FLASH_TFFS_BASE + 0x555) = 0xAA;    *((volatile UINT16 *)NOR_FLASH_TFFS_BASE + 0x2AA) = 0x55;    *((volatile UINT16 *)NOR_FLASH_TFFS_BASE + 0x555) = 0x90;    *manCode = *((volatile UINT16 *)NOR_FLASH_TFFS_BASE + 0x000);    *((volatile UINT16 *)NOR_FLASH_TFFS_BASE + 0x555) = 0xAA;    *((volatile UINT16 *)NOR_FLASH_TFFS_BASE + 0x2AA) = 0x55;    *((volatile UINT16 *)NOR_FLASH_TFFS_BASE + 0x555) = 0x90;    *devCode = *((volatile UINT16 *)NOR_FLASH_TFFS_BASE + 0x001);    /* Issue reset command to exit autoselect mode */	    *((volatile UINT16 *)ROM_BASE_ADRS + 0x000) = 0xF0;#endif    if (manCode != 0x0001)        {        TFFS_NOR_DEBUG_PRINT(DEBUG_ALWAYS,                    ("amd29lvMTDIdentify Manufacturer unknown: 0x%02x\n",                    manCode));        return(flUnknownMedia);        }    if (devCode == 0x227e)		/* amd29LV160BT */	{	pVol->type = 0x017e;	pVol->erasableBlockSize = S29GL_N_256_MTD_SECTOR_SIZE;	pVol->chipSize = S29GL_N_256_CHIP_SIZE;	pVol->noOfChips = AMD29LV_MTD_CHIP_CNT;	pVol->interleaving = AMD29LV_MTD_INTERLEAVE;	pVol->write = amd29lvProgram;	pVol->erase = amd29lvSectorRangeErase;	pVol->map = amd29lvMap;	}    else if (devCode == 0x22C4)		/* amd29LV160BT */	{	pVol->type = 0x01C4;	pVol->erasableBlockSize = AMD29LV_MTD_SECTOR_SIZE;	pVol->chipSize = AMD29LV_160_CHIP_SIZE;	pVol->noOfChips = AMD29LV_MTD_CHIP_CNT;	pVol->interleaving = AMD29LV_MTD_INTERLEAVE;	pVol->write = amd29lvProgram;	pVol->erase = amd29lvSectorRangeErase;	pVol->map = amd29lvMap;	}    else if (devCode == 0x2249)	    	{	pVol->type = 0x0149;	pVol->erasableBlockSize = AMD29LV_160_D_MTD_SECTOR_SIZE;	pVol->chipSize = AMD29LV_160_D_CHIP_SIZE;	pVol->noOfChips = AMD29LV_MTD_CHIP_CNT;	pVol->interleaving = AMD29LV_MTD_INTERLEAVE;	pVol->write = amd29lvProgram;	pVol->erase = amd29lvSectorRangeErase;	pVol->map = amd29lvMap;    	    	}    else if (devCode == 0x2250)		/* amd29LV323CT */	{	pVol->type = 0x0150;	pVol->erasableBlockSize = AMD29LV_MTD_SECTOR_SIZE;	pVol->chipSize = AMD29LV_323_CHIP_SIZE;	pVol->noOfChips = AMD29LV_MTD_CHIP_CNT;	pVol->interleaving = AMD29LV_MTD_INTERLEAVE;	pVol->write = amd29lvProgram;	pVol->erase = amd29lvSectorRangeErase;	pVol->map = amd29lvMap;	}    else    {        TFFS_NOR_DEBUG_PRINT(DEBUG_ALWAYS,                    ("amd29lvMTDIdentify Device unknown: 0x%02x\n",                    devCode));        return(flUnknownMedia);    }        TFFS_NOR_DEBUG_PRINT(DEBUG_ID, ("amd29lvMTDIdentify succeeds!\n"));    return(flOK);    }/******************************************************************************** amd29lvProgram - MTD write routine (see TrueFFS Programmer's Guide)** RETURNS: FLStatus**/LOCAL FLStatus amd29lvProgram    (    FLFlash*          pVol,    CardAddress       address,    const void FAR1*  buffer,    int               length,    FLBoolean         overwrite    ){    volatile UINT16* pFlash = NULL;    UINT16* pBuffer = NULL;    STATUS rc = OK;    int i;    BOOL doFree = FALSE;    TFFS_NOR_DEBUG_PRINT(DEBUG_PROGRAM,                ("Program: 0x%08x, 0x%08x, %d\n", (unsigned int) address,                 length, overwrite));    if (flWriteProtected(vol.socket))    {        return(flWriteProtect);    }    /* Check alignment */    if (((address & 0x01) != 0) || (((UINT32) buffer) &  0x01))    {        TFFS_NOR_DEBUG_PRINT(DEBUG_ALWAYS, ("amd29lvProgram: Alignment error\n"));        return(flBadParameter);    }    if (overwrite && length == 2)    {        int sector = 0;        int offset = 0;        pFlash = (volatile UINT16*) pVol->map(pVol, address, length);        pBuffer = (UINT16*) malloc(S29GL_N_256_MTD_SECTOR_SIZE);        if (pBuffer == 0)        {            TFFS_NOR_DEBUG_PRINT(DEBUG_ALWAYS, ("amd29lvProgram: No memory\n"));            return(flBadParameter);        }        /* Determine sector and offset */        sector = address / S29GL_N_256_MTD_SECTOR_SIZE;        offset = address % S29GL_N_256_MTD_SECTOR_SIZE;        TFFS_NOR_DEBUG_PRINT(DEBUG_PROGRAM,("Overwrite sector: 0x%08x, offset: 0x%08x\n",                    sector,offset));        /* Get a pointer to the flash sector */        pFlash = (volatile UINT16*) pVol->map(pVol,                                              sector * S29GL_N_256_MTD_SECTOR_SIZE,                                              S29GL_N_256_MTD_SECTOR_SIZE);        /* Copy the sector from flash to memory */        memcpy(pBuffer, (void*) pFlash, S29GL_N_256_MTD_SECTOR_SIZE);        /* Overwrite the sector in memory */       memcpy(((UINT8*) pBuffer) + offset, buffer, length);        /* Erase sector */        rc = amd29lvSectorRangeErase(pVol, sector, 1);        if (rc != flOK)        {            printf("Erase sector failed.\r\n");            free(pBuffer);            return(rc);        }        length = S29GL_N_256_MTD_SECTOR_SIZE;        doFree = TRUE;    }    else    {        if ((length & 0x01) != 0)            {            TFFS_NOR_DEBUG_PRINT(DEBUG_ALWAYS, ("amd29lvProgram: length: %d\n", length));            return(flBadParameter);            }        pBuffer = (UINT16*) buffer;        pFlash = (volatile UINT16*) pVol->map(pVol, address, length);    }    /* Program 'length' bytes (4 bytes each iterations) */    for (i = 0; i < (length / 2); i++, pFlash++)    {        /* Don't bother programming if buffer data == format value */        if (pBuffer[i] == (UINT16)0xffff)            continue;        /* Program 16 bits */        rc = flashProgram16Bits(pVol, pFlash, pBuffer[i], FALSE);        if (rc != OK)            break;    }    if (doFree)    {        free(pBuffer);    }	    if (rc != OK)    {        TFFS_NOR_DEBUG_PRINT(DEBUG_ALWAYS, ("amd29lvProgram: TimedOut.\r\n"));	 return (flTimedOut);    }	    return(flOK);    }/******************************************************************************** amd29lvSectorRangeErase - MTD erase routine (see TrueFFS Programmer's Guide)** RETURNS: FLStatus**/LOCAL FLStatus amd29lvSectorRangeErase    (    FLFlash* pVol,    int sectorNum,    int sectorCount    ){    int i;    STATUS rc;    /* Check for valid range */    if (pVol->type == 0x017e)			/* amd29LV160BT */    {        if (sectorNum + sectorCount >  S29GL_N_256_LAST_SECTOR_NUM + 1)        {            TFFS_NOR_DEBUG_PRINT(DEBUG_ALWAYS, ("Invalid sector range: %d - %d\n",	                sectorNum, sectorCount));        }    }    else if (pVol->type == 0x1C4)			/* amd29LV160BT */	{	if (sectorNum + sectorCount >  AMD29LV_160_LAST_SECTOR_NUM + 1)	    {	    TFFS_NOR_DEBUG_PRINT(DEBUG_ALWAYS, ("Invalid sector range: %d - %d\n",	                sectorNum, sectorCount));	    }	/* Last sector is really 4 seperately erasable sectors */	if (sectorNum + sectorCount == AMD29LV_160_LAST_SECTOR_NUM + 1)	    {	    sectorCount += 3;	    }	}    else if (pVol->type == 0x149)	/* amd29LV160D */    	{	if (sectorNum + sectorCount >  AMD29LV_160_D_LAST_SECTOR_NUM + 1)	    {	    TFFS_NOR_DEBUG_PRINT(DEBUG_ALWAYS, ("Invalid sector range: %d - %d\n",	                sectorNum, sectorCount));	    }	}    else					 /* amd29LV323CT */	{	if (sectorNum + sectorCount >  AMD29LV_323_LAST_SECTOR_NUM + 1)	    {	    TFFS_NOR_DEBUG_PRINT(DEBUG_ALWAYS, ("Invalid sector range: %d - %d\n",	                sectorNum, sectorCount));	    }	/* Last sector is really 8 seperately erasable sectors */	if (sectorNum + sectorCount == AMD29LV_323_LAST_SECTOR_NUM + 1)	    {	    sectorCount += 7;	    }	}    for (i = 0; i < sectorCount; i++)        {#if 0        /* Erase lower half */        rc = flashHalfSectorErase(pVol, sectorNum + i, FALSE);        if (rc != OK)            return(flTimedOut);        /* Erase upper half */        rc = flashHalfSectorErase(pVol, sectorNum + i, TRUE);        if (rc != OK)            return(flTimedOut);#else        rc = flashSectorErase(pVol, sectorNum + i, FALSE);        if (rc != OK)        {            return(flTimedOut);        }		#endif        }    return(flOK);    }/******************************************************************************** amd29lvMap - MTD map routine (see TrueFFS Programmer's Guide)** RETURNS: FLStatus**/LOCAL void FAR0* amd29lvMap    (    FLFlash* pVol,    CardAddress address,    int length    )    {#if 0    #if 0    UINT32 flashBaseAddr = (pVol->socket->window.baseAddress << 12);    void FAR0* pFlash = (void FAR0*) (flashBaseAddr + address);    TFFS_NOR_DEBUG_PRINT(DEBUG_MAP, ("Mapping 0x%08x bytes at 0x%08x to %p\n", length,                (unsigned int) address, pFlash));    return(pFlash);	    #else	    #ifdef AT91_NOR_FLASH_16M_TO_32M	    printf("\namd29lvMap() address:0x%x\n",address);/*add by wurj*/    if (address >= 0xf00000)    {	printf("\namd29lvMap() address:0x%x > 0xf00000\n",address);/*add by wurj*/    	address += 0x1100000;	    }	#endif /* AT91_NOR_FLASH_16M_TO_32M */	    return ((void FAR0*)((pVol->socket->window.baseAddress << 12) + address));    #endif#endif/*  base = 10100000; size = 1f00000  tempaddress : 10100000 -- 12000000   

⌨️ 快捷键说明

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