?? am29lv160.c
字號:
#include "typeDef.h"
#define AM_START_ADDR 0x1100000
#define AM_CHIP_HWORD_SIZE 0x100000 /*1M HWords*/
#define AM_ADDR_UNLOCK1 0x555
#define AM_ADDR_UNLOCK2 0x2aa
#define AM_DATA_UNLOCK1 0xaaaa
#define AM_DATA_UNLOCK2 0x5555
#define AM_SETUP_WRITE 0xa0a0
#define AM_SETUP_ERASE 0x8080
#define AM_CHIP_ERASE 0x1010
#define AM_SECTOR_ERASE 0x3030
/******************************************************
函數名稱: amOpOverDetect()
函數功能: 采用poll方式檢測flash擦寫是否完成.
入口參數: ptr 數據寫入地址/擦除扇區首址.
trueData 要寫入的值.
timeCounter 超時計數.
返 回 值: OK 操作成功.
ERROR 操作失敗.
備 注: 在預定時間內如果d7,d6仍不是truedata,則返回
ERROR.
*******************************************************/
STATUS amOpOverDetect(UINT16 *ptr, UINT16 trueData, int timeCounter)
{
int timeTmp = timeCounter;
volatile UINT16 *pFlash = ptr;
UINT16 buf1, buf2,curTrueData;
curTrueData = trueData & 0x8080; //先檢測d7位.
while((*pFlash & 0x8080) != curTrueData)
{
if(timeTmp-- <= 0) break;
}
timeTmp = timeCounter;
buf1 = *pFlash & 0x4040; //(為保險)再檢測d6位.
while(1)
{
buf2 = *pFlash & 0x4040;
if(buf1 == buf2)
break;
else
buf1 = buf2;
if(timeTmp-- <= 0)
{
return ERROR;
}
}
return OK;
}
/********************************************************
函數名稱: sstWrite()
函數功能: 讀取緩沖區數據根據給定的長度寫入指定地址.
入口參數: flashAddr 數據目標地址(flash).
buffer 數據源地址.
length 要寫入的字節數.
返 回 值: NULL 寫失敗.
flashPtr flash的下一個地址.
備 注: 由于sst39vf160只能按半字(16bit)操作,所以
如果要多次調用這個函數來寫入一個文件,則應
每次讀取偶數個字節,以保證連續性.
*********************************************************/
UINT16 *amWrite(UINT16 *flashAddr, UINT8 *buffer, int length)
{
int i, cLength;
volatile UINT16 *flashPtr;
volatile UINT16 *gBuffer;
flashPtr = flashAddr;
cLength = (length + 1)/2; //計算半字長度.
gBuffer = (UINT16 *)buffer;
while (cLength > 0)
{
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_DATA_UNLOCK1; //解鎖.
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK2) = AM_DATA_UNLOCK2;
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_SETUP_WRITE;
*flashPtr = *gBuffer; //寫入數據.
if(amOpOverDetect((UINT16 *)flashPtr, *gBuffer, 0x100000)) //檢測寫入是否成功.
{
//printf("warning: write flash may failed at:0x%x.\n", (int)flashPtr);
}
cLength--;
flashPtr++;
gBuffer++;
}
flashPtr = flashAddr;
gBuffer = (UINT16 *)buffer;
cLength = length/2;
for(i=0; i<cLength; i++) //寫入的數據全部校驗一次.
{
if(*flashPtr++ != *gBuffer++)
{
//printf("Error: write failed in SST39vf160 at 0x%x on verification.\n", (int)flashPtr);
return NULL;
}
}
if(length%2)
{
if((*flashPtr++ & 0x00ff) != (*gBuffer++ & 0x00ff)) /*奇數長度的最后一個字節.*/
{
//printf("Error: write failed in SST39vf160 at 0x%x on verification.\n", (int)flashPtr);
return NULL;
}
}
return (UINT16 *)flashPtr;
}
/********************************************************
函數名稱: amChipErase()
函數功能: 擦除整個flash芯片.
入口參數: 無.
返 回 值: OK 擦除完全正確.
ERROR 有單元不能正確擦除.
備 注: datasheet上說典型時間為26s,實際大約15秒,
所以盡量用amSectorErase().
*********************************************************/
STATUS amChipErase(void)
{
int i;
volatile UINT16 *flashPtr = NULL;
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_DATA_UNLOCK1; //連續解鎖.
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK2) = AM_DATA_UNLOCK2;
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_SETUP_ERASE;
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_DATA_UNLOCK1;
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK2) = AM_DATA_UNLOCK2;
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_CHIP_ERASE; //寫入擦除命令.
flashPtr = (volatile UINT16 *)AM_START_ADDR;
if(amOpOverDetect((UINT16 *)flashPtr, 0xffff, 0x800000) != OK)
{
//printf("warning: Chip Erase time out!\n");
}
flashPtr = (volatile UINT16 *)AM_START_ADDR;
for(i=0; i<AM_CHIP_HWORD_SIZE; i++,flashPtr++) //校驗是否全為0xffff.
{
if(*flashPtr != 0xffff)
{
//printf("Debug: Erase failed at 0x%x in SST39VF160 on verification.\n", (int)flashPtr);
return ERROR;
}
}
return OK;
}
/********************************************************
函數名稱: amSectorErase()
函數功能: 擦除指定的flash扇區.
入口參數: 扇區地址.
返 回 值: OK 擦除完全正確.
ERROR 有單元不能正確擦除.
備 注:
*********************************************************/
STATUS amSectorErase(UINT16 *pSector)
{
//int i;
volatile UINT16 *flashPtr = pSector;
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_DATA_UNLOCK1; //連續解鎖.
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK2) = AM_DATA_UNLOCK2;
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_SETUP_ERASE;
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_DATA_UNLOCK1;
*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK2) = AM_DATA_UNLOCK2;
*flashPtr = AM_SECTOR_ERASE; //寫入擦除命令.
if(amOpOverDetect((UINT16 *)flashPtr, 0xffff, 0x20000) != OK)
{
return ERROR;
//printf("warning: Chip Erase time out!\n");
}
return OK;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -