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

📄 amd29lv64mtd.c

📁 型号为AMD29Lv64M的闪存烧写源码
💻 C
字号:
/* amd29LvMtd.c - TrueFFS MTD for AMD AM29LV64DLdevices */ /* Copyright 2006 cetc. *//*modification history--------------------06a,21apr00,add  Created.*//*DESCRIPTIONThis module implements an TrueFFS MTD for the AMD AM29LV6400DL . *//* includes */#include <vxWorks.h>#include <taskLib.h>#include <logLib.h>#include <stdio.h>#include <cacheLib.h>#include "tffs/flflash.h"#include "tffs/backgrnd.h"#include "config.h"IMPORT int sysClkRateGet();/* defines *//* FLASH_SIZE , FLASH_TFFS_RESERVED  define in config.h*/#define AMD29LV_MTD_SECTOR_SIZE         (0x20000) /*128KB*/#define AMD29LV_640_CHIP_SIZE               (FLASH_SIZE - FLASH_TFFS_RESERVED)   /*  14MB. first 1M and last 1M use to save user paramater */#define AMD29LV_640_LAST_SECTOR_NUM     (AMD29LV_640_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#define DEBUG#ifdef  DEBUG    LOCAL UINT32 debug;    #define DEBUG_PRINT(mask, string) \                if ((debug & mask) || (mask == DEBUG_ALWAYS)) \                printf string#else    #define DEBUG_PRINT(mask, string)#endif/* local routines */LOCAL FLStatus amd29lv64SectorRangeErase(FLFlash* pVol, int, int);LOCAL FLStatus amd29lv64Program(FLFlash*, CardAddress, const void FAR1*, int,                             FLBoolean);LOCAL void FAR0* amd29lv64Map(FLFlash*, CardAddress, int);LOCAL void flashReset(FLFlash*);LOCAL void flashIdGet(FLFlash*, UINT16*, UINT16*);LOCAL void flashUnlock(FLFlash*);LOCAL STATUS flashProgram32Bits(FLFlash*, volatile UINT32*, UINT32);LOCAL void flashRegWrite32Bits(FLFlash*, UINT32, UINT32);LOCAL UINT16 flashRegRead16Bits(FLFlash*, UINT32);LOCAL STATUS amd29lv64FlashSectorErase(FLFlash*, int);/******************************************************************************** amd29lv64MTDIdentify - MTD identify routine (see TrueFFS Programmer's Guide)** RETURNS: FLStatus**/FLStatus amd29lv64MTDIdentify    (    FLFlash* pVol    )    {    UINT16 manCode;    UINT16 devCode;	    flashIdGet(pVol, &manCode, &devCode);    if (manCode != 0x0001)        {        DEBUG_PRINT(DEBUG_ALWAYS,                    ("amd29lv64MTDIdentify Manufacturer unknown: 0x%02x\n",                    manCode));        return(flUnknownMedia);        }    if (devCode == 0x22D7)	/* amd29LV640 */   	{	pVol->type = 0x01D7;	pVol->erasableBlockSize = AMD29LV_MTD_SECTOR_SIZE;	pVol->chipSize = AMD29LV_640_CHIP_SIZE;	pVol->noOfChips = AMD29LV_MTD_CHIP_CNT;	pVol->interleaving = AMD29LV_MTD_INTERLEAVE;	pVol->write = amd29lv64Program;	pVol->erase = amd29lv64SectorRangeErase;	pVol->map = amd29lv64Map;	}       else        {        DEBUG_PRINT(DEBUG_ALWAYS,                    ("amd29lv64MTDIdentify Device unknown: 0x%02x\n",                    devCode));        return(flUnknownMedia);        }      debug=DEBUG_ID;     DEBUG_PRINT(DEBUG_ID, ("amd29lv64MTDIdentify succeeds!\n"));    return(flOK);    }/******************************************************************************** amd29lvProgram - MTD write routine (see TrueFFS Programmer's Guide)** RETURNS: FLStatus**/LOCAL FLStatus amd29lv64Program    (    FLFlash*          pVol,    CardAddress       address,    const void FAR1*  buffer,    int               length,    FLBoolean         overwrite    )    {    volatile UINT32* pFlash;    UINT32* pBuffer;    STATUS rc = OK;    int i;    BOOL doFree = FALSE;    DEBUG_PRINT(DEBUG_PROGRAM,                ("Program: 0x%08x, 0x%08x, %d\n", (unsigned int) address,                 length, overwrite));    if (flWriteProtected(vol.socket))        {        return(flWriteProtect);        }    /* Check 4 bytes alignment */    if (((address & 0x03) != 0) || (((UINT32) buffer) &  0x03))        {        DEBUG_PRINT(DEBUG_ALWAYS, ("amd29lv64Program: Alignment error\n"));        return(flBadParameter);        }    if (overwrite && length == 2)        {        int sector;        int offset;        pFlash = (volatile UINT32*) pVol->map(pVol, address, length);        pBuffer = (UINT32*) malloc(AMD29LV_MTD_SECTOR_SIZE);        if (pBuffer == 0)            {            DEBUG_PRINT(DEBUG_ALWAYS, ("amd29lv64Program: No memory\n"));            return(flBadParameter);            }        /* Determine sector and offset */        sector = address / AMD29LV_MTD_SECTOR_SIZE;        offset = address % AMD29LV_MTD_SECTOR_SIZE;        DEBUG_PRINT(DEBUG_PROGRAM,("Overwrite sector: 0x%08x, offset: 0x%08x\n",                    sector,offset));        /* Get a pointer to the flash sector */        pFlash = (volatile UINT32*) pVol->map(pVol,                                              sector * AMD29LV_MTD_SECTOR_SIZE,                                              AMD29LV_MTD_SECTOR_SIZE);        /* Copy the sector from flash to memory */        memcpy(pBuffer, (void*) pFlash, AMD29LV_MTD_SECTOR_SIZE);        /* Overwrite the sector in memory */       memcpy(((UINT8*) pBuffer) + offset, buffer, length);        /* Erase sector */        rc = amd29lv64SectorRangeErase(pVol, sector, 1);        if (rc != flOK)            {            free(pBuffer);            return(rc);            }        length = AMD29LV_MTD_SECTOR_SIZE;        doFree = TRUE;        }    else        {        if ((length & 0x03) != 0)            {            DEBUG_PRINT(DEBUG_ALWAYS, ("amd29lv64Program: length: %d\n", length));            return(flBadParameter);            }        pBuffer = (UINT32*) buffer;        pFlash = (volatile UINT32*) pVol->map(pVol, address, length);        }    /* Program 'length' bytes (4 bytes each iterations) */   /* upper = ((((UINT32) pFlash) & 0x04) != 0);*/    for (i = 0; i < (length / 4); i++, pFlash++)        {        /* Don't bother programming if buffer data == format value */        if (pBuffer[i] == 0xffffffff)            continue;        /* Program 32 bits */        rc = flashProgram32Bits(pVol, pFlash, pBuffer[i]);        if (rc != OK)            break;        }    if (doFree)        {        free(pBuffer);        }    return((rc == OK) ? flOK : flTimedOut);    }/******************************************************************************** amd29lvSectorRangeErase - MTD erase routine (see TrueFFS Programmer's Guide)** RETURNS: FLStatus**/LOCAL FLStatus amd29lv64SectorRangeErase    (    FLFlash* pVol,    int sectorNum,    int sectorCount    )    {    int i;    STATUS rc;	if (sectorNum + sectorCount >  AMD29LV_640_LAST_SECTOR_NUM + 1)	    {	      DEBUG_PRINT(DEBUG_ALWAYS, ("Invalid sector range: %d , %d\n",	                sectorNum, sectorCount));	    }/*      DEBUG_PRINT(DEBUG_ALWAYS, (" Erasing sector range: %d , %d\n",	                sectorNum, sectorCount));*/        for (i = 0; i < sectorCount; i++)        {        /* Erase sector*/        rc = amd29lv64FlashSectorErase(pVol, sectorNum + i);        if (rc != OK)            return(flTimedOut);        }         return(flOK);    }/******************************************************************************** amd29lvMap - MTD map routine (see TrueFFS Programmer's Guide)** RETURNS: FLStatus**/LOCAL void FAR0* amd29lv64Map    (    FLFlash* pVol,    CardAddress address,    int length    )    {    UINT32 flashBaseAddr = (pVol->socket->window.baseAddress << 12);    void FAR0* pFlash = (void FAR0*) (flashBaseAddr + address);    DEBUG_PRINT(DEBUG_MAP, ("Mapping 0x%08x bytes at 0x%08x to %p\n", length,                (unsigned int) address, pFlash));    return(pFlash);    }/******************************************************************************** flashProgram32Bits - Program 32 bits at 4 byte aligned address.** RETURNS: OK or ERROR**/LOCAL STATUS flashProgram32Bits    (    FLFlash* pVol,    volatile UINT32* pData,    UINT32 data    )    {    BOOL programmed = FALSE;    int timeout;    flashUnlock(pVol);    flashRegWrite32Bits(pVol, 0x555, 0x00a000a0);    DEBUG_PRINT(DEBUG_PROG32, ("Programming 0x%08x to %p\n",                data, pData));    *pData = data;    CACHE_PIPE_FLUSH();    for (timeout = flMsecCounter + 3000; flMsecCounter < timeout;)        {        if (*pData == data)            {            programmed = TRUE;            break;            }        taskDelay(0);        }    if (!programmed)        {        DEBUG_PRINT(DEBUG_ALWAYS, ("Timeout\n"));        return(ERROR);        }    return(OK);    }/******************************************************************************** flashHalfSectorErase - Erase lower or upper half of sector.** RETURNS: OK or ERROR**/LOCAL STATUS amd29lv64FlashSectorErase    (    FLFlash* pVol,    int sectorNum    )    {    BOOL erased = FALSE;    int timeout = sysClkRateGet() * 5;    UINT32 offset;    UINT32 size;    volatile UINT32* pFlash;    UINT32 sectorAddr;    offset     = sectorNum * AMD29LV_MTD_SECTOR_SIZE;    size       = AMD29LV_MTD_SECTOR_SIZE;    sectorAddr = (sectorNum << 15);       DEBUG_PRINT(DEBUG_ERASE, ("Erasing sector %d, 0x%02x\n",                sectorNum, sectorAddr));    /* Erase the sector half */    flashUnlock(pVol);    flashRegWrite32Bits(pVol, 0x555, 0x00800080);    flashUnlock(&vol);    flashRegWrite32Bits(pVol, sectorAddr, 0x00300030);    pFlash = (volatile UINT32*) pVol->map(pVol, offset, size);       for (timeout = flMsecCounter + 5000; flMsecCounter < timeout;)        {        if (*pFlash == 0xffffffff)            {            erased = TRUE;            break;            }        }    if (!erased)        {        DEBUG_PRINT(DEBUG_ALWAYS, ("Sector erase timeout, %p\n", pFlash));        return(ERROR);        }    return(OK);    }/******************************************************************************** flashRegWrite32Bits - Write 32 bits to 4 byte aligned address.** RETURNS: N/A**/LOCAL void flashRegWrite32Bits    (    FLFlash* pVol,    UINT32 addr,    UINT32 data     )    {    UINT32 flashBaseAddr = (pVol->socket->window.baseAddress << 12);    addr = flashBaseAddr + 4* addr;  /*modified by MCL*/    /*if (upper)        addr += 4;modified by MCL*//* debug=DEBUG_WRITE; */    DEBUG_PRINT(DEBUG_WRITE, ("Writing 0x%08x to 0x%08x\n", data, addr));    /* Write */    *((volatile UINT32*) addr) = data;    CACHE_PIPE_FLUSH();    }/******************************************************************************** flashRegRead16Bits - Read 16 bits from 2 byte aligned address.** RETURNS: data at specified address**/LOCAL UINT16 flashRegRead16Bits    (    FLFlash* pVol,    UINT32 addr       )    {    UINT16 data;    UINT32 flashBaseAddr = (pVol->socket->window.baseAddress << 12);    addr = flashBaseAddr + 4 * addr;  /*modified by MCL*/       data = *((volatile UINT16*) addr);    DEBUG_PRINT(DEBUG_READ, ("Read 0x%08x from 0x%08x\n", data, addr));    CACHE_PIPE_FLUSH();    return(data);    }/******************************************************************************** flashIdGet - Get flash man. and device codes.** RETURNS: N/A**/LOCAL void flashIdGet    (    FLFlash* pVol,    UINT16* manCode,    UINT16* devCode    )    {    flashUnlock(pVol);    flashRegWrite32Bits(pVol, 0x555, 0x00900090);    *manCode = flashRegRead16Bits(pVol, 0x00);    *devCode = flashRegRead16Bits(pVol, 0x01);    flashReset(pVol);    }/******************************************************************************** flashUnlock - Write unlock sequence to upper or lower flash section.** RETURNS: N/A**/LOCAL void flashUnlock    (    FLFlash* pVol    )    {    flashRegWrite32Bits(pVol, 0x555, 0x00aa00aa);    flashRegWrite32Bits(pVol, 0x2aa, 0x00550055);    }/******************************************************************************** flashReset - Write reset sequence to upper or lower flash section.** RETURNS: N/A**/LOCAL void flashReset    (    FLFlash* pVol    )    {    flashRegWrite32Bits(pVol, 0, 0x00f000f0);    }#define FLASH_TEST#undef FLASH_TEST#ifdef FLASH_TEST#include "tffs/flsocket.h"LOCAL FLFlash testVol;LOCAL FLSocket testSocket;/* Make sure this functions are NOT static (LOCAL) in sysTffs.c */IMPORT void rfaSetWindow (FLSocket vol);IMPORT void rfaSetMappingContext (FLSocket vol, unsigned page);IMPORT FLBoolean rfaWriteProtected (FLSocket vol);/* Initialize */LOCAL void FAR0 *flashMap(FLFlash vol, CardAddress address, int length){  return flMap(vol.socket,address);}void fsinit()    {    FLStatus rc;    testSocket.window.baseAddress = tffsFlashBaseAdrs >> 12;    testSocket.window.currentPage = UNDEFINED_MAPPING;    testSocket.setWindow = rfaSetWindow;    testSocket.setMappingContext = rfaSetMappingContext;    testSocket.setMappingContext = rfaSetMappingContext;    testSocket.writeProtected = rfaWriteProtected;    testVol.socket = &testSocket;    testVol.map = flashMap;    rc = amd29lv64MTDIdentify(&testVol);    if (rc != flOK)        {        printf("identify fails\n");        }    }/* Show */void fsshow()    {    printf("Type 0x%04x\n", testVol.type);    printf("Eraseable block size 0x%08lx\n", testVol.erasableBlockSize);    }/* Erase */STATUS fse    (    UINT8 sectorNum,    UINT8 numSectors    )    {    FLStatus rc;    if (sectorNum <= 3)        {        printf("Sector contains bootrom!\n");        return(ERROR);        }    rc = testVol.erase(&testVol, sectorNum, numSectors);    return(rc);    }/* Program */STATUS fprog    (    UINT32 offset,    UINT32 bufSize,    UINT8  pattern    )    {    FLStatus rc;    UINT32* pBuf;    UINT32 sectorNum = offset / AMD29LV_MTD_SECTOR_SIZE;    if (sectorNum <= 3)        {        printf("Sector contains bootrom!\n");        return(ERROR);        }    if (bufSize == 0)        bufSize = 4;    if ((bufSize & 0x03) != 0)        bufSize += 4 - (bufSize & 0x03);    pBuf = memalign(4, bufSize);    if (pBuf == 0)        return(ERROR);    memset(pBuf, pattern, bufSize);    rc = testVol.write(&testVol, offset, pBuf, bufSize, FALSE);    free(pBuf);    return(rc == flOK ? OK : ERROR);    }#endif

⌨️ 快捷键说明

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