?? tffmtd.c
字號(hào):
*************************************************************************************************************************************************/ #ifdef __cplusplusextern "C"{#endif#include "tffs/flflash.h"#include "tffs/backgrnd.h"#include "stdio.h"#include "taskLib.h"#define TIME_OUT (2000000*100)#define AM29LV320_START_ADDR 0x51000000 /*flash base addr*//* Addresses */#define ADDR_MANUFACTURER_ID 0x0000#define ADDR_DEVICE_ID 0x0001#define ADDR_SECTOR_LOCK 0x0002#define ADDR_HANDSHAKE 0x0003#define ADDR_UNLOCK_1 0x0555#define ADDR_UNLOCK_2 0x02AA/* Commands */#define CMD_UNLOCK_DATA_1 0xAAAA#define CMD_UNLOCK_DATA_2 0x5555#define CMD_MANUFACTURER_UNLOCK_DATA 0x9090#define CMD_UNLOCK_BYPASS_MODE 0x2020#define CMD_PROGRAM_UNLOCK_DATA 0xA0A0#define CMD_RESET_DATA 0xF0F0#define CMD_SECTOR_ERASE_UNLOCK_DATA 0x8080#define CMD_SECTOR_ERASE_UNLOCK_DATA_2 0x3030#define CMD_CHIP_ERASE_UNLOCK_DATA_2 0x1010#define CMD_AUTOSELECT 0x9090#define AMD_READ_ARRAY 0xf0#define MANUFACTURER_ID 0x0001#define AM29LV320DB_ID 0x22F9#define AM29LV320MB_ID 0x227E/* Return codes from flash_status */#define STATUS_READY 0 /* ready for action */#define STATUS_BUSY 1 /* operation in progress */#define STATUS_ERSUSP 2 /* erase suspended */#define STATUS_TIMEOUT 3 /* operation timed out */#define STATUS_ERROR 4 /* unclassified but unhappy status */#undef MY_TFFS_DEBUG#ifdef MY_TFFS_DEBUG#define DEBUG_PRINT printf#endif/*var*//*function declare*/LOCAL UINT8 AFlashStatus(UINT16 *flashptr);/******************************************************************** Function Name : static void FAR0 * am29lv320MTDMap()* Description : A pointer to the flash memory map function,maps flash into an area of memory * Input : * Output : none* Returns : the only thing the map routine needs to do is to return a pointer to the specified address in flash memory* Options : none*******************************************************************/static void FAR0 * am29lv320MTDMap(FLFlash vol, CardAddress addr, int inter){ UINT32 ret; ret = AM29LV320_START_ADDR + addr;#ifdef MY_TFFS_DEBUG DEBUG_PRINT("Debug: in i28f320MTDMap ret=0x%x\n",ret);#endif vol.socket->remapped = TRUE; return (void FAR0 *)ret;}/******************************************************************** Function Name :LOCAL UINT8 AFlashStatus(UINT16 *flashptr)* Description : Flash_status utilizes the DQ6, DQ5, and DQ3 polling algorithms described * in the flash data book. It can quickly ascertain the operational status* of the flash device, and return an appropriate status code * Input : toggle address* Output :none* Returns :toggle satatus* Options : none*******************************************************************/ LOCAL UINT8 AFlashStatus(UINT16 *flashptr){ UINT16 data,temp; ULONG retry =0; taskDelay(0); while(retry++<TIME_OUT) { data = *flashptr; /* read data */ temp = data ^ *flashptr; /* read it again and see what toggled */ taskDelay(0); if (temp == 0) { /* no toggles, nothing's happening */ return STATUS_READY; } else if (temp == 0x04) { /* erase-suspend */ if(retry==TIME_OUT) return STATUS_ERSUSP; } else if (temp & 0x40) { if (data & 0x20) { /* timeout */ if(retry==TIME_OUT) return STATUS_TIMEOUT; } else { if(retry==TIME_OUT) return STATUS_BUSY; } } } /*cann't run here*/ return STATUS_ERROR;}/******************************************************************** Function Name : static FLStatus am29lv320Write(FLFlash vol,CardAddress address, const void FAR1 *buffer,int length,FLBoolean overwrite)* Description : Write a block of bytes to Flash* Input : vol : Pointer identifying drive * address : Card address to write to * buffer : Address of data to write * length : Number of bytes to write * overwrite : TRUE if overwriting old Flash contents * FALSE if old contents are known to be erased * Output : none* Returns : 0 on success, failed otherwise* Options : none*******************************************************************/static FLStatus am29lv320Write(FLFlash vol, CardAddress address, const void FAR1 *buffer, int length, FLBoolean overwrite){ int cLength; FLStatus status = flOK; FlashWPTR flashPtr,flashTmp; volatile UINT16 *gBuffer; if (flWriteProtected(vol.socket)) return flWriteProtect; if ((length & 1) || (address & 1)) /* Only write words on word-boundary */ return flBadParameter;#ifdef SOCKET_12_VOLTS checkStatus(flNeedVpp(vol.socket));#endif flashTmp = flashPtr = (FlashWPTR) vol.map(&vol, address, vol.interleaving); #ifdef MY_TFFS_DEBUG DEBUG_PRINT("Debug: entering i28f320Write,flashPtr=0x%x address=0x%x\n",(UINT32)flashPtr,(unsigned int)address);#endif cLength = length/2; gBuffer = (UINT16 *)buffer; while (cLength > 0) { *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_UNLOCK_DATA_1; /*解鎖.*/ *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_2) = CMD_UNLOCK_DATA_2; *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_PROGRAM_UNLOCK_DATA; *flashPtr = *gBuffer; /*寫入數(shù)據(jù).*/ if(AFlashStatus((UINT16 *)flashPtr)!=STATUS_READY) /*檢測(cè)寫入是否成功.*/ { printf("failed: write flash may failed at:0x%x.\n", (int)flashPtr); return(ERROR); } cLength--; flashPtr++; gBuffer++; } #ifdef SOCKET_12_VOLTS flDontNeedVpp(vol.socket);#endif /* verify the data */ if (status == flOK && tffscmpWords((void FAR0 *) flashTmp, (void FAR1 *) buffer,length)) { #ifdef MY_TFFS_DEBUG DEBUG_PRINT("Debug: write failed for 16-bit am29lv320 media in verification.\n"); #endif status = flWriteFault; } return status;}/******************************************************************** Function Name : static FLStatus am29lv320Erase(FLFlash vol, int firstErasableBlock,int numOfErasableBlocks)* Description : Erase one or more contiguous Flash erasable blocks* Input : vol : Pointer identifying drive * firstErasableBlock : Number of first block to erase * numOfErasableBlocks: Number of blocks to erase * Output : none* Returns : FLStatus : 0 on success, failed otherwise* Options : This routine will be registered as the MTD vol.erase routine*******************************************************************/static FLStatus am29lv320Erase(FLFlash vol, int firstErasableBlock, int numOfErasableBlocks){ FLStatus status = flOK; /* unless proven otherwise */ FlashWPTR flashPtr; UINT32 addr; int i,flag; if (flWriteProtected(vol.socket)) return flWriteProtect; #ifdef SOCKET_12_VOLTS checkStatus(flNeedVpp(vol.socket));#endif /*flashPtr = (FlashWPTR) flMap(vol.socket,(firstErasableBlock) * vol.erasableBlockSize);*/ flashPtr = (FlashWPTR) vol.map (&vol,(firstErasableBlock) * vol.erasableBlockSize,vol.interleaving);#ifdef MY_TFFS_DEBUG DEBUG_PRINT("Debug: entering i28f320Erase,flashPtr=0x%x firstErasableBlock=0x%x numOfErasableBlocks=0x%x\n",(UINT32)flashPtr, firstErasableBlock,numOfErasableBlocks);#endif for(i=0;i<numOfErasableBlocks;i++) { addr = (UINT32)flashPtr + (UINT32)(i * vol.erasableBlockSize); *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_UNLOCK_DATA_1; /*連續(xù)解鎖.*/ *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_2) = CMD_UNLOCK_DATA_2; *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_SECTOR_ERASE_UNLOCK_DATA; *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_UNLOCK_DATA_1; *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_2) = CMD_UNLOCK_DATA_2; flag=AFlashStatus((UINT16 *)flashPtr); *(volatile UINT16 *)flashPtr = CMD_SECTOR_ERASE_UNLOCK_DATA_2; /*寫入擦除命令.*/ if((flag=AFlashStatus((UINT16 *)flashPtr))!=STATUS_READY) { if(flag==STATUS_TIMEOUT) { printf("warning: Chip Erase time out!\n"); return ERROR; } else if(flag==STATUS_BUSY) { printf("warning: Chip Erase busy!\n"); return ERROR; } else if(flag==STATUS_ERSUSP) { printf("warning: Chip Erase suspended!\n"); return ERROR; } else { ; } } }#ifdef SOCKET_12_VOLTS flDontNeedVpp(vol.socket);#endif return status;}/******************************************************************** Function Name : FLStatus am29lv320Identify(FLFlash vol)* Description : Identifies media based on am29lv320Identify and registers as an MTD * Input : vol : Pointer identifying drive * Output : none* Returns : FLStatus : 0 on positive identificaion, failed otherwise* Options : This routine will be placed on the MTD list in custom.h. It must be * an extern routine.*******************************************************************/FLStatus am29lv320Identify(FLFlash vol){ FlashWPTR flashPtr; UINT16 manCode=0; UINT16 devCode=0;#ifdef MY_TFFS_DEBUG DEBUG_PRINT("Debug: entering 16-bit am29lv320 media identification routine.\n");#endif flSetWindowBusWidth(vol.socket,16);/* use 16-bits */ flSetWindowSpeed(vol.socket,120); /* 120 nsec. */ flSetWindowSize(vol.socket,2); /* KBytes */ /* flashPtr = (FlashWPTR) flMap(vol.socket,(CardAddress)0);*/ flashPtr = (FlashWPTR)vol.map (&vol, (CardAddress)0, vol.interleaving); *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_UNLOCK_DATA_1; /*解鎖.*/ *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_2) = CMD_UNLOCK_DATA_2;#ifdef MY_TFFS_DEBUG DEBUG_PRINT("Debug: in am29lv320Identify flashPtr=0x%x\n",(UINT32)flashPtr);#endif vol.noOfChips = 0; *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_AUTOSELECT; manCode=*((volatile UINT16*)(flashPtr+ADDR_MANUFACTURER_ID)); devCode=*((volatile UINT16*)(flashPtr+ADDR_DEVICE_ID)); #ifdef MY_TFFS_DEBUG DEBUG_PRINT("Debug: man_ID=0x%x device_ID=0x%x\n",manCode,devCode);#endif if (manCode == MANUFACTURER_ID && (devCode==AM29LV320DB_ID || devCode==AM29LV320MB_ID)) { /* Word mode */ vol.type = MANUFACTURER_ID; vol.interleaving = 1; flashPtr[0] = AMD_READ_ARRAY; } else { if (vol.interleaving == 1) vol.type = NOT_FLASH; /* We cannot handle byte-mode interleaving-1 */ } if (vol.type == MANUFACTURER_ID) { vol.chipSize = 0x400000L; vol.erasableBlockSize = 0x10000L * vol.interleaving; vol.noOfChips =0x1; /*one chip.*/ vol.write = am29lv320Write; vol.erase = am29lv320Erase; vol.map = am29lv320MTDMap; flashPtr[0] = AMD_READ_ARRAY; #ifdef MY_TFFS_DEBUG DEBUG_PRINT("Debug: identified 16-bit am29lv320 media.\n"); #endif return flOK; } else { #ifdef MY_TFFS_DEBUG DEBUG_PRINT("Debug: failed to identify 16-bit am29lv320 media.\n"); #endif return flUnknownMedia; /* not ours */ }}#if 1/*----------------------------------------------------------------------*//* f l R e g i s t e r 28f320 *//* *//* Registers this MTD for use *//* *//* Parameters: *//* None *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failure *//*----------------------------------------------------------------------*/FLStatus flRegisterAm29lv320(void){ if (noOfMTDs >= MTDS) return flTooManyComponents; mtdTable[noOfMTDs++] = am29lv320Identify; return flOK;}#endif /* FALSE */#ifdef __cplusplus}#endif /* end of __cplusplus */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -