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

📄 am29lv64xdmtd.c

📁 Freescale MPC85xx BSP (8555/8541)。绝对可用的。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* am29lv64xdMtd.c - MTD for Am29Lv64Xd *//* * Copyright (c) 2003-2005 Wind River Systems, Inc. * * The right to copy, distribute or otherwise make use of this software * may be licensed only pursuant to the terms of an applicable Wind River * license agreement. No license to Wind River intellectual property rights * is granted herein. All rights not licensed by Wind River are reserved * by Wind River. */#include "copyright_wrs.h"/* FAT-FTL Lite Software Development Kit * Copyright (C) M-Systems Ltd. 1995-2001       *//*modification history--------------------01d,24mar05,mdo  Documentation changes for apigen01c,22mar05,dtr  Typo fixes.01b,18nov04,jln  fix compiler warning01a,22oct04,jln  modified from 01l/cfiamd.c *//*DESCRIPTIONThis library provides a MTD for Am29Lv641D on cds8541/cds8555 reference boards.It only supports 16 bit bus access to flash chips.  INCLUDE FILES: \NOMANUAL*/#include <stdio.h>#include "tffs/flflash.h"#include "tffs/backgrnd.h"#define 	MAXSECTORS	128	/* should work with any value */typedef enum    {    BOOTBLOCK_NONE,    BOOTBLOCK_TOP,    BOOTBLOCK_BOTTOM    }BOOTBLOCK;typedef union    {    UCHAR uchar[4];    UINT32 uint32;    } CFI_DWORD;typedef union    {    UCHAR uchar[2];    USHORT ushort;    } CFI_WORD;/* Instance specific CFI data so that a system may have more than one CFI * device. */typedef struct    {    unsigned         commandSetId;            /* id of a specific command set. */    unsigned         altCommandSetId;         /* id of alternate command set.  */    FLBoolean        wordMode;                /* TRUE - word mode.             */    /* FALSE - byte mode.            */    int              multiplier;              /* the number of bytes between   */    /* 1st Q and 1st R in query	     */    int          interleaveWidth;     /* 1 - byte 2 - word interleaved */     unsigned         maxBytesWrite;           /* maximum number of bytes       */    /* in multi-byte write.          */    FLBoolean        vpp;                     /* if = TRUE, need vpp.          */    long             optionalCommands;        /* optional commands supported   */    /* (1 = yes, 0 = no):            */    /* bit 0 - chip erase.           */    /* bit 1 - suspend erase.        */    /* bit 2 - suspend write         */    /* bit 3 - lock/unlock.          */    /* bit 4 - queued erase.         */    unsigned         afterSuspend;            /* functions supported after     */    /* suspend (1 = yes, 0 = no):    */    /* bit 0 - write after erase     */    /*         suspend.              */    int          sectorDefs;          /* Number of sector definitions  */    struct        {                  /* sector descriptions as found  */        long     secSize;         /* in CFI query. 		     */        int      numSecs;         /*				     */        }secDesc[8];                  /* assume 8 is enough	     */    struct        {                  /*				     */        long     sectorSize;          /* sector size 		     */        UINT32       sectorBaseAdrs;      /* base address of sector	     */        } secInfo[MAXSECTORS];            /* per sector info		     */    UINT32 unlockAddr1;               /* offset for first unlock	     */    UINT32 unlockAddr2;               /* offset for 2nd unlock	     */    int sectorsInCFI;             /* sector count for device	     */    int bootBlockSectors;             /* sectors that makeup boot block*/    BOOTBLOCK bootBlockType;          /* Top, Bottom or None	     */    } CFI;LOCAL CFI mtdVars[DRIVES];/* defines *//* Save the last erase block on each device discovered in the array  * for NVRAM */#undef SAVE_NVRAM_REGION/* disable debugging */#undef CFI_DEBUG#ifdef CFI_DEBUG    #define DEBUG_PRINT    printf#else    #undef DEBUG_PRINT#endif#ifndef _BYTE_ORDER    #error "Error: _BYTE_ORDER needs to be #define'd.  Try #include \"vxWorks.h\" "#endif#if (_BYTE_ORDER == _BIG_ENDIAN)    #define CFI_LONGSWAP(x)	LONGSWAP(x)	/* swap everything in a long word */    #define CFI_WORDSWAP(x) WORDSWAP(x)	/* swap the shorts in a long */    #define CFI_BYTESWAP(x) ( ( (x & 0xff) << 8) | ( (x >> 8) & 0xff) )  /* Swap bytes in a short */#else    #define CFI_LONGSWAP(x)	(x)		/* pass it as is */    #define CFI_WORDSWAP(x) (x)		/* pass it as is */    #define CFI_BYTESWAP(x) (x)		/* pass it as is */#endif /* _BYTE_ORDER == _BIG_ENDIAN */#define CFI_LONG_WRITE(addr, data)  (*(ULONG *)addr = (ULONG)(CFI_WORDSWAP(data)))#define CFI_WORD_WRITE(addr, data)  (*(USHORT *)addr = (USHORT)(CFI_BYTESWAP(data)))#define CFI_WORD_READ(addr)         (CFI_BYTESWAP(*(USHORT *)addr))#define CFI_LONG_READ(addr)         (CFI_WORDSWAP(*(ULONG *)addr))/* command set IDs */#define INTEL_COMMAND_SET      0x0001#define AMDFUJ_COMMAND_SET     0x0002#define INTEL_ALT_COMMAND_SET  0x0001#define AMDFUJ_ALT_COMMAND_SET 0x0004#define ALT_NOT_SUPPORTED      0x0000/* CFI identification strings */#define ID_STR_LENGTH      3#define QUERY_ID_STR       "QRY"#define PRIMARY_ID_STR     "PRI"#define ALTERNATE_ID_STR   "ALT"/* commands */#define AMD_SETUP_ERASE		0x80#define AMD_SETUP_WRITE		0xa0#define AMD_READ_ID 		0x90#define AMD_SUSPEND_ERASE	0xb0#define AMD_SECTOR_ERASE	0x30#define AMD_RESUME_ERASE	0x30#define AMD_READ_ARRAY		0xf0#define AMD_NO_UNLOCK_ADDR 0xffffffffL#define AMD_UNLOCK_1		0xaa#define	AMD_UNLOCK_2		0x55#define AMD_WW_UNLOCK_ADDR1	0x555u	/* Word wide devices */#define	AMD_WW_UNLOCK_ADDR2	0x2aau  /* Word wide devices */#define AMD_BW_UNLOCK_ADDR1	0xaaau  /* Byte wide devices */#define	AMD_BW_UNLOCK_ADDR2	0x555u  /* Byte wide devices */#define	AMD_D2		4	/* Toggles when erase suspended */#define AMD_D5		0x20	/* Set when programming timeout */#define	AMD_D6		0x40	/* Toggles when programming *//* optional commands support */#define CHIP_ERASE_SUPPORT           0x0001#define SUSPEND_ERASE_SUPPORT        0x0002#define SUSPEND_WRITE_SUPPORT        0x0004#define LOCK_SUPPORT                 0x0008#define QUEUED_ERASE_SUPPORT         0x0010#define QUERY	0x98/* supported functions after suspend */#define WRITE_AFTER_SUSPEND_SUPPORT  0x0001#define thisCFI   ((CFI *)vol.mtdVars)/******************************************************************************* cfiAmdChipCountGet - return the number of chips in this array** Leave the first chip (or set of interleaved chips) in READ_ARRAY* mode and move forward by chip size (or interleaved chip size) until* address wrap around is detected. The chip count is updated in * vol.noOfChips.** RETURNS:** ERRNO** \NOMANUAL*/LOCAL FLStatus cfiAmdChipCountGet    (    FLFlash vol    /* Pointer identifying drive */    )    {    UINT32 cmdBuffer;    int ix;    char queryIdStr[ID_STR_LENGTH + 1] = QUERY_ID_STR;    FlashPTR flashPtr = (FlashPTR) flMap(vol.socket, 0);    /* Switch first (interleaved) chip set to QUERY mode */    cmdBuffer = 0x0;    for (ix = 0; ix < thisCFI->multiplier; ix++)        cmdBuffer |= QUERY << (8 * ix);    flashPtr[0x55 * thisCFI->multiplier] = cmdBuffer;    /* NOTE: The address wrap around technique used here works only if the flash     * size was declared correctly in the socket driver. At some point the MTD     * should be discovering flash size and exporting it to the socket driver.      */    for (vol.noOfChips = 1 * vol.interleaving;       /* Scan the chips */        vol.noOfChips < 2000;  /* Big enough ? */        vol.noOfChips += vol.interleaving)        {#ifdef SAVE_NVRAM_REGION        /* Reinstate the NVRAM region */        flashPtr = (FlashPTR) flMap(vol.socket, vol.noOfChips *                                     (vol.chipSize + (vol.erasableBlockSize / vol.interleaving)));#else        flashPtr = (FlashPTR) flMap(vol.socket, vol.noOfChips * vol.chipSize);#endif#ifdef DEBUG_PRINT        DEBUG_PRINT("Debug: Looking for Flash device at base 0x%x\n", (UINT32) flashPtr);#endif        if ((flashPtr[0x10 * thisCFI->multiplier])             == (unsigned char)queryIdStr[0] &&            (flashPtr[0x11 * thisCFI->multiplier])             == (unsigned char)queryIdStr[1] &&            (flashPtr[0x12 * thisCFI->multiplier])             == (unsigned char)queryIdStr[2])            {            goto noMoreChips;      /* Wrapped around */            }        /* Confirm this is also a CFI part */        *(UCHAR *)(flashPtr + (0x55 * thisCFI->multiplier))        = (UCHAR)(QUERY);        if (flashPtr[0x10 * thisCFI->multiplier]            != (unsigned char)queryIdStr[0] ||            flashPtr[0x11 * thisCFI->multiplier]            != (unsigned char)queryIdStr[1] ||            flashPtr[0x12 * thisCFI->multiplier]            != (unsigned char)queryIdStr[2])            {            /* Should not happen !! */            goto noMoreChips;   /* Not a CFI Flash part */            }        flashPtr[0x55 * thisCFI->multiplier]         = (UCHAR)(AMD_READ_ARRAY);        }    /* We should never get here. */#ifdef DEBUG_PRINT    DEBUG_PRINT("Debug: Device count overflow\n");#endif  /* DEBUG_PRINT */    return flGeneralFailure;    noMoreChips:    flashPtr = (FlashPTR) flMap(vol.socket, 0);    /* Switch to READ_ARRAY mode */    cmdBuffer = 0x0;    for (ix = 0; ix < thisCFI->multiplier; ix++)        cmdBuffer |= AMD_READ_ARRAY << (8 * ix);    flashPtr[0x55 * thisCFI->multiplier] = cmdBuffer;    return flOK;    }/******************************************************************************* cfiAmdWrite - Write a block of bytes to Flash** This routine will be registered as the MTD vol.write routine. * Given a pointer to a buffer that must be written, the write width * determined from the identification process is used the stepping stone * to iterate through the buffer.*							                                                                    * RETURNS:                                                           *	FLStatus	: 0 on success, failed otherwise	** ERRNO*/LOCAL FLStatus cfiAmdWrite    (    FLFlash vol,                  /* Pointer identifying drive         */    CardAddress address,          /* Card address to write to          */    const void FAR1 *buffer,      /* Address of data to write          */    int length,                   /* Number of bytes to write          */    FLBoolean overwrite           /* Mode: TRUE overwrite;FALSE erased */    )    {    /* Set timeout to 5 seconds from now */    unsigned long writeTimeout = flMsecCounter + 5000;    int cLength;    CardAddress cAddr = address;    FlashPTR base;    FlashPTR flashPtr;    UINT32 unlock1 = 0;    UINT32 unlock2 = 0;    UINT32 setup_write = 0;    UINT32 read_array = 0;    int i;    CFI_WORD  tmpWord;#define bFlashPtr  flashPtr#define bBuffer ((const unsigned char FAR1 *) buffer)#define wFlashPtr ((FlashWPTR) flashPtr)#define wBuffer ((const unsigned short FAR1 *) buffer)#define dFlashPtr ((FlashDPTR) flashPtr)#define dBuffer ((const unsigned long FAR1 *) buffer)    /* Setup the commands first */    for (i = 0; i < thisCFI->multiplier; i++)        {        unlock1     |= AMD_UNLOCK_1 << (i * 8);        unlock2     |= AMD_UNLOCK_2 << (i * 8);        setup_write |= AMD_SETUP_WRITE << (i * 8);        read_array  |= AMD_READ_ARRAY << (i * 8);        }    if (flWriteProtected(vol.socket))        return flWriteProtect;    i = 0;     while ((thisCFI->secInfo[i].sectorBaseAdrs <= address) && (i < thisCFI->sectorsInCFI))        i++;    i--;    base = (FlashPTR)           vol.map(&vol, thisCFI->secInfo[i].sectorBaseAdrs,                   vol.interleaving * thisCFI->interleaveWidth);    flashPtr = (FlashPTR)               vol.map(&vol, address,                       vol.interleaving * thisCFI->interleaveWidth);    cLength = length;    if (vol.interleaving * thisCFI->interleaveWidth == 1)        {        while (cLength >= 2)            {            *(USHORT *)(base +                         (thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1;            *(USHORT *)(base +                         (thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2;            *(USHORT *)(base +                         (thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write;            *wFlashPtr = *wBuffer;            while ((wFlashPtr[0] != wBuffer[0]) &&                    (flMsecCounter < writeTimeout))                {                if (((wFlashPtr[0] & AMD_D5) &&                      ((wFlashPtr[0] ^ wBuffer[0]) &   0xff)))                    {                    wFlashPtr[0] = read_array;#ifdef DEBUG_PRINT                    DEBUG_PRINT("Debug: write failed in AMD MTD.\n");#endif                    return flWriteFault;                    }                }            cLength -= 2;            cAddr   += 2;            buffer  = (const void FAR1 *)((UINT32)buffer+2);            flashPtr += 2;            }        if (cLength > 0)            {            /* copy data from flash to tmpWord */            tmpWord.ushort = wFlashPtr[0];            /* now fill in the left over byte */            tmpWord.uchar[0] = *(char *)buffer;            *(USHORT *)(base +                         (thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1;            *(USHORT *)(base +                         (thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2;            *(USHORT *)(base +                         (thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write;            *wFlashPtr = tmpWord.ushort;

⌨️ 快捷键说明

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