📄 sst39vf160.c
字号:
#include "tffs/flflash.h"#include "tffs/backgrnd.h"#include "stdio.h"#include "config.h"/*需与sysTffs.c中相同定义一致*/#define FLASH_BASE_ADRS (0x04000000)#define FLASH_SIZE (0x00400000)#define FLASH_BOOT_ADRS (0x04000000)#define FLASH_BOOT_SIZE (0x00050000)typedef struct { FlashWPTR unlockAddr1; FlashWPTR unlockAddr2;} Vars;static Vars mtdVars[DRIVES];#define thisVars ((Vars *) vol.mtdVars)#define SETUP_ERASE 0x80#define SETUP_WRITE 0xa0#define READ_ID 0x90#define SECTOR_ERASE 0x30#define BLOCK_ERASE 0x50 /*块擦除*/#define READ_ARRAY 0xf0 /*软件ID读模式退出*/#define UNLOCK_1 0xaa /*解锁写入值*/#define UNLOCK_2 0x55#define UNLOCK_ADDR1 0x5555 /*解锁偏移地址[字]*/#define UNLOCK_ADDR2 0x2aaa/* JEDEC ids for this MTD */#define AM29LV160D_DEID 0x2782 /*设备ID*/#define DEBUG_PRINT printErrstatic STATUS lv160OpOverDetect(void * ptr, int timeCounter);/*------------------------------------------------------------------------ Procedure: lv160MTDMap ID:1 Purpose: 映射Flash片内地址为CPU全局地址 Input: addr-相对地址 Output: Errors:------------------------------------------------------------------------*/static void FAR0 * lv160MTDMap0(FLFlash *vol, CardAddress addr, int length){ UINT32 ret; /*???baseAddress可能系统启动读时未初始化*/ ret = FLASH_BASE_ADRS + addr; return (void FAR0 *)ret;}static void FAR0 * lv160MTDMap1(FLFlash *vol, CardAddress addr, int length){ UINT32 ret; /*???不能根据vol->socket->serialNo来分支判断*/ ret = FLASH_BOOT_ADRS + addr; return (void FAR0 *)ret;}/*------------------------------------------------------------------------ Procedure: lv160OpOverDetect ID:1 Purpose: 探测write,erase操作是否结束,超时错误 Input: Output: Errors:------------------------------------------------------------------------*/static STATUS lv160OpOverDetect(void * ptr, int timeCounter){ FlashWPTR pFlash = ptr; INT16 buf1,buf2; buf1 = *pFlash & 0x40; while(1) { buf2 = *pFlash & 0x40; if(buf1 == buf2) break; else buf1 = buf2; if(timeCounter-- <= 0) { return ERROR; } } return OK;}/*------------------------------------------------------------------------ Procedure: lv160MTDWrite ID:1 Purpose: MTD写Flash函数 Input: Output: Errors:------------------------------------------------------------------------*/static FLStatus lv160MTDWrite(FLFlash vol, CardAddress address, const void FAR1 *buffer, int length, FLBoolean overwrite){ int cLength; FlashWPTR flashPtr, flashTmp; volatile UINT16 *gBuffer; flashTmp = flashPtr = (FlashWPTR) vol.map(&vol, address, length); if(length&1) { printf("warning! the data length can not divided by 2."); } cLength = length/2; gBuffer = (UINT16 *)buffer; //printf("$$$$$$Entering MTD write.\n"); while (cLength >= 1) { *thisVars->unlockAddr1 = UNLOCK_1; *thisVars->unlockAddr2 = UNLOCK_2; *thisVars->unlockAddr1 = SETUP_WRITE; *flashPtr = *gBuffer; if(lv160OpOverDetect((void *)flashPtr, 0x1000000)); if(*flashPtr != *gBuffer) { *flashPtr = READ_ARRAY; #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: lv160MTDWrite timeout.\n"); #endif return flWriteFault; } cLength--; flashPtr++; gBuffer++; //printf("Write %d.",cLength); } if (tffscmp((void FAR0 *) flashTmp, buffer,length)) { /* verify the data */ #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: lv160MTDWrite fail.\n"); #endif return flWriteFault; } return flOK;}/*------------------------------------------------------------------------ Procedure: lv160MTDWrite ID:1 Purpose: MTD擦除Flash函数 Input: Output: Errors:------------------------------------------------------------------------*/static FLStatus lv160MTDErase(FLFlash vol, int firstErasableBlock, int numOfErasableBlocks){ int iBlock; FlashWPTR flashPtr; unsigned int offset; if(numOfErasableBlocks <= 0) return ERROR; printf("*** EraseBlock = %d***\n", firstErasableBlock); for (iBlock = 0; iBlock < numOfErasableBlocks; iBlock++) { int i; offset = (firstErasableBlock + iBlock) * vol.erasableBlockSize; flashPtr = (FlashWPTR) vol.map(&vol, offset, vol.interleaving); *thisVars->unlockAddr1 = UNLOCK_1; *thisVars->unlockAddr2 = UNLOCK_2; *thisVars->unlockAddr1 = SETUP_ERASE; *thisVars->unlockAddr1 = UNLOCK_1; *thisVars->unlockAddr2 = UNLOCK_2; *flashPtr = SECTOR_ERASE; lv160OpOverDetect((void *)flashPtr, 0x2000000); for(i=0; i<vol.erasableBlockSize/2; i++,flashPtr++) { if(*flashPtr != 0xffff) break; } *flashPtr = READ_ARRAY; if(i < vol.erasableBlockSize/2) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: lv160MTDErase fail.\n"); #endif return flWriteFault; } //printf("iBlock%d ok.",iBlock+5); } return flOK;}/*------------------------------------------------------------------------ Procedure: fllv160Identify ID:1 Purpose: MTD读Flash标识 Input: Output: Errors:------------------------------------------------------------------------*/static FLStatus fllv160Identify(FLFlash vol, UINT32 offset){ FlashWPTR flashPtr; flashPtr = (FlashWPTR) vol.map(&vol, 0, vol.interleaving); //printf("\nenter the fllv160Identify\n"); *thisVars->unlockAddr1 = UNLOCK_1; *thisVars->unlockAddr2 = UNLOCK_2; *thisVars->unlockAddr1 = READ_ID; //printf("\nthisVars->unlockAddr1 %x,*thisVars->unlockAddr2 %x\n", thisVars->unlockAddr1, thisVars->unlockAddr2); /* 0X01 read device Id, 0X00 manufacture Id.*/ flashPtr = (FlashWPTR) vol.map(&vol, offset, vol.interleaving); printf("the flashPtr is %x\n",flashPtr); vol.type = *flashPtr; flashPtr = (FlashWPTR)vol.map(&vol, 0, vol.interleaving) ; *flashPtr = READ_ARRAY; /*回到读状态*/ return flOK;}/*------------------------------------------------------------------------ Procedure: lv160MTDIdentify ID:1 Purpose: MTD读Flash标识[extern] Input: Output: Errors:------------------------------------------------------------------------*/FLStatus lv160MTDIdentify(FLFlash vol){ FlashWPTR baseFlashPtr; vol.interleaving = 1; flSetWindowBusWidth(vol.socket,16);/* use 16-bits */ flSetWindowSpeed(vol.socket,120); /* 120 nsec. */ if (vol.socket->serialNo == 0){ flSetWindowSize(vol.socket, FLASH_SIZE>>12); vol.chipSize = FLASH_SIZE; vol.map = lv160MTDMap0; } else if(vol.socket->serialNo == 1){ flSetWindowSize(vol.socket, FLASH_BOOT_SIZE>>12); vol.chipSize = FLASH_BOOT_SIZE; vol.map = lv160MTDMap1; } vol.mtdVars = &mtdVars[flSocketNoOf(vol.socket)]; baseFlashPtr = (FlashWPTR)vol.map (&vol, (CardAddress)0, vol.interleaving); printf("\n\n******** FLASH MTD Identify ********\n"); printf("The baseFlashPtr is %x\n",baseFlashPtr); /*UNLOCK_ADDR为字地址, 赋值转换x2*/ thisVars->unlockAddr1 = (FlashWPTR)((long)baseFlashPtr) + UNLOCK_ADDR1; thisVars->unlockAddr2 = (FlashWPTR)((long)baseFlashPtr) + UNLOCK_ADDR2; fllv160Identify(&vol, 2); /*get flash device ID.*/ //printf("\nthe thisVars->unlockAddr1 is %x, thisVars->unlockAddr2 is %x\n",thisVars->unlockAddr1,thisVars->unlockAddr2); printf("The FLASH type is 0x%x\n",vol.type); #if 0 if (vol.type != AM29LV160D_DEID) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: can not identify SST39VF160 media.\n"); #endif return flUnknownMedia; } #endif vol.noOfChips =0x1; /*one chip.*/ vol.erasableBlockSize = 0x10000; /* 64k bytes.*/ vol.flags |= SUSPEND_FOR_WRITE; /* Register our flash handlers */ vol.write = lv160MTDWrite; vol.erase = lv160MTDErase; printf("MTDIdentify ok.\n\n"); return flOK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -