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

📄 amd29lvmtd.c.svn-base

📁 realtek的8186芯片ADSL路由AP源代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/* amd29LvMtd.c - AMD AM29LV devices */
 

/* includes */
#include "board.h"

/* defines */
#define OK	0
#define ERROR -1
#define flOK	OK
#define LOCAL	static
#define FALSE	0
#define flTimedOut	-1
#define flSectorNotFound	-2
#define CACHE_PIPE_FLUSH	sysWbFlush
#define DEBUGIT
typedef int	BOOL;
typedef char INT8;
typedef short INT16;
typedef long INT32;
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned long UINT32;
typedef int	STATUS;
typedef int FLStatus;
typedef int	FLBoolean;
typedef unsigned long	CardAddress;
typedef struct tFlash FLFlash;		/* Forward definition */

struct tFlash {
	unsigned int	type;
	unsigned short	flags;
	unsigned long	erasableBlockSize;
	unsigned long	chipSize;
	unsigned int	noOfChips;
	unsigned int	interleaving;
	unsigned long	baseAddress;
	void * 		(*map)(FLFlash *, CardAddress, int);
	FLStatus 	(*erase)(FLFlash *, int, int);
	FLStatus 	(*write)(FLFlash *, CardAddress, const void *, int, int);

};	

//#define FLASH_BASE_ADDR					0xbfc00000
#define AMD29LV_MTD_SECTOR_SIZE         (0x10000)	/* 64k */

#define AMD29LV_800_CHIP_SIZE           (0x100000)	/* 1MB */
#define AMD29LV_800_LAST_SECTOR_NUM     (AMD29LV_800_CHIP_SIZE / AMD29LV_MTD_SECTOR_SIZE - 1)

#define AMD29LV_160_CHIP_SIZE           (0x200000)	/* 2MB */
#define AMD29LV_160_LAST_SECTOR_NUM     (AMD29LV_160_CHIP_SIZE / AMD29LV_MTD_SECTOR_SIZE - 1)
#define AMD29LV_320_CHIP_SIZE           (0x400000)	/* 4MB */
#define AMD29LV_320_LAST_SECTOR_NUM     (AMD29LV_320_CHIP_SIZE / AMD29LV_MTD_SECTOR_SIZE - 1)
#define AMD29LV_640_CHIP_SIZE           (0x800000)	/* 8MB */
#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)


// definition to support SST flash
#define FLASH_SST_SUPPORT		1
#define SST39VF_MTD_SECTOR_SIZE         (0x1000)	/* 64k */
#define SST39VF_400_CHIP_SIZE           (0x80000)	/* 512KB */
#define SST39VF_400_LAST_SECTOR_NUM     (SST39VF_400_CHIP_SIZE / SST39VF_MTD_SECTOR_SIZE - 1)
#define SST39VF_800_CHIP_SIZE           (0x100000)	/* 1MB */
#define SST39VF_800_LAST_SECTOR_NUM     (SST39VF_800_CHIP_SIZE / SST39VF_MTD_SECTOR_SIZE - 1)
#define SST39VF_1601_CHIP_SIZE           (0x200000)	/* 2MB */
#define SST39VF_1601_LAST_SECTOR_NUM     (SST39VF_1601_CHIP_SIZE / SST39VF_MTD_SECTOR_SIZE - 1)
#define SST39VF_3201_CHIP_SIZE           (0x400000)	/* 4MB */
#define SST39VF_3201_LAST_SECTOR_NUM     (SST39VF_3201_CHIP_SIZE / SST39VF_MTD_SECTOR_SIZE - 1)
#define SST39VF_MTD_CHIP_CNT            (1)
#define SST39VF_MTD_INTERLEAVE          (1)


/* Save the last erase block on each device discovered in the array 
 * for NVRAM */
#undef SAVE_NVRAM_REGION


#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_PROG16   0x00000040
#define DEBUG_ALWAYS   0xffffffff

#define DEBUG
#ifdef  DEBUG
    LOCAL UINT32 debug = 0;
    #define DEBUG_PRINT(mask, string) \
                if ((debug & mask) || (mask == DEBUG_ALWAYS)) \
                printf string
#else
    #define DEBUG_PRINT(mask, string)
#endif

/* local routines */

LOCAL FLStatus amd29lvSectorRangeErase(FLFlash* pVol, int, int);

LOCAL FLStatus amd29lvProgram(FLFlash*, CardAddress, const void *, int,
                             FLBoolean);

LOCAL void * amd29lvMap(FLFlash*, CardAddress, int);

LOCAL void flashReset(FLFlash*);
LOCAL void flashIdGet(FLFlash*, UINT16*, UINT16*);
LOCAL void flashUnlock(FLFlash*);
LOCAL STATUS flashCheck16Bits(FLFlash*, UINT32);
LOCAL inline STATUS flashProgram16Bits(FLFlash*, volatile UINT16*, UINT16);
LOCAL inline void flashRegWrite16Bits(FLFlash*, UINT32, UINT16);
LOCAL UINT16 flashRegRead16Bits(FLFlash*, UINT32);
LOCAL UINT16 flashRegRead8Bits(FLFlash*, UINT32);
LOCAL STATUS flashSectorErase(FLFlash*, int);

UINT16 DeviceID_cycle2, DeviceID_cycle3;	//added for verify mx29LV640M T/B
/******************************************************************************
*
* amd29lvMTDIdentify - MTD identify routine (see TrueFFS Programmer's Guide)
*
* RETURNS: FLStatus
*
*/

FLStatus amd29lvMTDIdentify(FLFlash* pVol)
{
    UINT16 manCode;
    UINT16 devCode;

    flashIdGet(pVol, &manCode, &devCode);

	DEBUG_PRINT(DEBUG_ID,
                    ("amd29lvMTDIdentify Manufacturer: 0x%02x\n\r",
                    manCode));
	DEBUG_PRINT(DEBUG_ID,
                    ("amd29lvMTDIdentify Device: 0x%02x\n\r",
                    devCode));


    if (devCode == 0x22DA || 	/* amd29LV800BT */
    	devCode == 0x225B)		/* amd29LV800BB */
	{
		pVol->type = (manCode<<16)| (devCode&0xffff);
		pVol->erasableBlockSize = AMD29LV_MTD_SECTOR_SIZE;
		#ifdef SAVE_NVRAM_REGION
		pVol->chipSize = AMD29LV_800_CHIP_SIZE - AMD29LV_MTD_SECTOR_SIZE;
		#else
		pVol->chipSize = AMD29LV_800_CHIP_SIZE;
		#endif
		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 */
    	devCode == 0x2249)		/* amd29LV160BB */
	{
		pVol->type = (manCode<<16)| (devCode&0xffff);
		pVol->erasableBlockSize = AMD29LV_MTD_SECTOR_SIZE;
		#ifdef SAVE_NVRAM_REGION
		pVol->chipSize = AMD29LV_160_CHIP_SIZE - AMD29LV_MTD_SECTOR_SIZE;
		#else
		pVol->chipSize = AMD29LV_160_CHIP_SIZE;
		#endif
		pVol->noOfChips = AMD29LV_MTD_CHIP_CNT;
		pVol->interleaving = AMD29LV_MTD_INTERLEAVE;
		pVol->write = amd29lvProgram;
		pVol->erase = amd29lvSectorRangeErase;
		pVol->map = amd29lvMap;
	}
	else
    if (devCode == 0x22A7 || 	/* amd29LV320BT */
    	devCode == 0x22A8 ||		/* amd29LV320BB */
	devCode == 0x22F6 ||            /* SpansionS29AL032DT */
	devCode == 0x22F9 )             /* SpansionS29AL032DB */
	{
		pVol->type = (manCode<<16)| (devCode&0xffff);
		pVol->erasableBlockSize = AMD29LV_MTD_SECTOR_SIZE;
		#ifdef SAVE_NVRAM_REGION
		pVol->chipSize = AMD29LV_320_CHIP_SIZE - AMD29LV_MTD_SECTOR_SIZE;
		#else
		pVol->chipSize = AMD29LV_320_CHIP_SIZE;
		#endif
		pVol->noOfChips = AMD29LV_MTD_CHIP_CNT;
		pVol->interleaving = AMD29LV_MTD_INTERLEAVE;
		pVol->write = amd29lvProgram;
		pVol->erase = amd29lvSectorRangeErase;
		pVol->map = amd29lvMap;
	}
    else
    if (devCode == 0x227E  		/* amd29LV640BT */
    	||devCode == 0x22CB)	/* mx29lv640 bb */
	{
		pVol->type = (manCode<<16)| (devCode&0xffff);
		pVol->erasableBlockSize = AMD29LV_MTD_SECTOR_SIZE;
		#ifdef SAVE_NVRAM_REGION
		pVol->chipSize = AMD29LV_640_CHIP_SIZE - AMD29LV_MTD_SECTOR_SIZE;
		#else
		pVol->chipSize = AMD29LV_640_CHIP_SIZE;
		#endif
		pVol->noOfChips = AMD29LV_MTD_CHIP_CNT;
		pVol->interleaving = AMD29LV_MTD_INTERLEAVE;
		pVol->write = amd29lvProgram;
		pVol->erase = amd29lvSectorRangeErase;
		pVol->map = amd29lvMap;
	}
    else
    	
#if FLASH_SST_SUPPORT
	if (0x2780 == devCode) { /* SST39VF400 */
		pVol->type = (manCode<<16)| (devCode&0xffff);
		pVol->erasableBlockSize = SST39VF_MTD_SECTOR_SIZE;
		#ifdef SAVE_NVRAM_REGION
		pVol->chipSize = SST39VF_400_CHIP_SIZE - SST39VF_MTD_SECTOR_SIZE;
		#else
		pVol->chipSize = SST39VF_400_CHIP_SIZE;
		#endif
		pVol->noOfChips = SST39VF_MTD_CHIP_CNT;
		pVol->interleaving = SST39VF_MTD_INTERLEAVE;
		pVol->write = amd29lvProgram;
		pVol->erase = amd29lvSectorRangeErase;
		pVol->map = amd29lvMap;		
	} else
	if (0x2781 == devCode) { /* SST39VF800 */
		pVol->type = (manCode<<16)| (devCode&0xffff);
		pVol->erasableBlockSize = SST39VF_MTD_SECTOR_SIZE;
		#ifdef SAVE_NVRAM_REGION
		pVol->chipSize = SST39VF_800_CHIP_SIZE - SST39VF_MTD_SECTOR_SIZE;
		#else
		pVol->chipSize = SST39VF_800_CHIP_SIZE;
		#endif
		pVol->noOfChips = SST39VF_MTD_CHIP_CNT;
		pVol->interleaving = SST39VF_MTD_INTERLEAVE;
		pVol->write = amd29lvProgram;
		pVol->erase = amd29lvSectorRangeErase;
		pVol->map = amd29lvMap;
	} else
	if (0x234B == devCode) {
		pVol->type = (manCode<<16)| (devCode&0xffff);
		pVol->erasableBlockSize = SST39VF_MTD_SECTOR_SIZE;
		#ifdef SAVE_NVRAM_REGION
		pVol->chipSize = SST39VF_1601_CHIP_SIZE - SST39VF_MTD_SECTOR_SIZE;
		#else
		pVol->chipSize = SST39VF_1601_CHIP_SIZE;
		#endif
		pVol->noOfChips = SST39VF_MTD_CHIP_CNT;
		pVol->interleaving = SST39VF_MTD_INTERLEAVE;
		pVol->write = amd29lvProgram;
		pVol->erase = amd29lvSectorRangeErase;
		pVol->map = amd29lvMap;
	} else
	if (0x235B == devCode) {
		pVol->type = (manCode<<16)| (devCode&0xffff);
		pVol->erasableBlockSize = SST39VF_MTD_SECTOR_SIZE;
		#ifdef SAVE_NVRAM_REGION
		pVol->chipSize = SST39VF_3201_CHIP_SIZE - SST39VF_MTD_SECTOR_SIZE;
		#else
		pVol->chipSize = SST39VF_3201_CHIP_SIZE;
		#endif
		pVol->noOfChips = SST39VF_MTD_CHIP_CNT;
		pVol->interleaving = SST39VF_MTD_INTERLEAVE;
		pVol->write = amd29lvProgram;
		pVol->erase = amd29lvSectorRangeErase;
		pVol->map = amd29lvMap;
	} else
#endif
	{
        DEBUG_PRINT(DEBUG_ALWAYS,
                    ("amd29lvMTDIdentify Device unknown: 0x%02x\n\r",
                    devCode));
        return(ERROR);
	}    

    DEBUG_PRINT(DEBUG_ID, ("amd29lvMTDIdentify succeeds!\n\r"));
    return(flOK);
}


/******************************************************************************
* flashCheck16Bits - Wait for a flash operation to complete and determine the result
*
* Result:              0 = operation completed successfully
*                      1 = timeout during operation
*                      2 = error detected
*/

static STATUS flashCheck16Bits(FLFlash* pVol, UINT32 addr)
{
    volatile UINT8      initialData;
    volatile UINT8      nextData;
	int start = get_sys_time();    

    /* Read the 'initial' value of the status register */
    initialData = flashRegRead16Bits(pVol, addr);

    while(!timeout(start, 30000))
    {
        nextData = flashRegRead16Bits(pVol, addr);

        /* See if the toggle bit toggled. 
         * If it has not then the operation has completed successfully
         */
        if ((initialData & (1<<6)) == (nextData & (1<<6)))
        {
            /* D6 has stopped toggling Operation complete */
            return 0;
        }

        /* If still toggling then check D5 to see if an error was detected */
        if (initialData & (1<<5))
        {
            volatile UINT8 value1 = flashRegRead16Bits(pVol, addr);
            volatile UINT8 value2 = flashRegRead16Bits(pVol, addr);

            if ((value1 & (1<<6)) == (value2 & (1<<6)))
            {
                /* DQ6 is not toggling, so ignore the error bit */
                return 0;
            }
            else
            {
                /* DQ6 is still toggling so return the error */
				if(value2 & (1<<2))
					return 0;
            }
        }

        /* Update the initial data for the next pass */
        initialData = nextData;
        //delay_msec(1);
    }

    /* Operation timed out before completion */
    return 1;
}


/******************************************************************************
*
* amd29lvProgram - MTD write routine (see TrueFFS Programmer's Guide)
*
* RETURNS: FLStatus
*
*/

LOCAL FLStatus amd29lvProgram(FLFlash *pVol, CardAddress address, 
		const void *  buffer, int length, FLBoolean overwrite)
{
    volatile UINT16* pFlash;
    UINT8* pBuffer;
    UINT16 data;
    STATUS rc = OK;
    int i;

    DEBUG_PRINT(DEBUG_PROGRAM,
                ("Program: 0x%08x, 0x%08x, %d\n\r", (unsigned int) address,
                 length, overwrite));

    /* Check alignment */
	pBuffer = (UINT8*)buffer;

#if 0
	DEBUG_PRINT(DEBUG_PROGRAM,("\n\r"));
	for(i=0;i<length;i++)
		DEBUG_PRINT(DEBUG_PROGRAM, ("%02X", pBuffer[i]));
	DEBUG_PRINT(DEBUG_PROGRAM, ("\n\r"));
#endif

⌨️ 快捷键说明

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