?? flash.c
字號:
if(__macDFL_GetNVMStatus(cNVMBit))
return TRUE;
OS_ENTER_CRITICAL()
{
__macDFL_SetFMCNForNVM();
AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_SET_GP_NVM | (cNVMBit << 8);
__macDFL_WaitFlashReady(__unStatus);
}
OS_EXIT_CRITICAL()
return __macDFL_GetNVMStatus(cNVMBit);
}
//*------------------------------------------------------------------------------------------------
//* 函數(shù)名稱 : DFL_ClearNVM
//* 功能描述 : 清除NVM位
//* 入口參數(shù) : <cNVMBit>[in] 要設(shè)置的NVM位(0-2)
//* 出口參數(shù) : 指令執(zhí)行成功返回TRUE,否則返回FLASE
//*------------------------------------------------------------------------------------------------
int DFL_ClearNVM(char cNVMBit)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
unsigned int __unStatus;
if(cNVMBit > 2)
return FALSE;
if(!__macDFL_GetNVMStatus(cNVMBit))
return TRUE;
OS_ENTER_CRITICAL()
{
__macDFL_SetFMCNForNVM();
AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_CLR_GP_NVM | (cNVMBit << 8);
__macDFL_WaitFlashReady(__unStatus);
}
OS_EXIT_CRITICAL()
return !__macDFL_GetNVMStatus(cNVMBit);
}
//*------------------------------------------------------------------------------------------------
//* 函數(shù)名稱 : __ilIsDataCorrect
//* 功能描述 : 在軟件層面對數(shù)據(jù)作做一次判斷,看其是否正確
//* 入口參數(shù) : <punFrom>[in] 指向原始數(shù)據(jù)的指針
//* : <punTo>[in] 指向目標(biāo)數(shù)據(jù)的指針
//* : <unSize>[in] 進(jìn)行比較的數(shù)據(jù)長度
//* 出口參數(shù) : 無
//*------------------------------------------------------------------------------------------------
__inline unsigned int __ilIsDataCorrect(unsigned int *punFrom, unsigned int* punTo, unsigned int unSize)
{
while(unSize > 0)
{
if(*punFrom != *punTo)
return ((unsigned int)punTo);
unSize-=4;
punFrom++;
punTo++;
}
return 0x00000000;
}
//*------------------------------------------------------------------------------------------------
//* 函數(shù)名稱 : __DFL_WritePage
//* 功能描述 : 把數(shù)據(jù)寫入指定的頁面。該函數(shù)具備容錯(cuò)能力,它會檢查檢查寫入的數(shù)據(jù)是否正確,如果不正確它會嘗試
//* : 重新寫入直至正確或者到達(dá)指定的嘗試次數(shù)--3次。
//* 入口參數(shù) : <sPageIdx>[in] 要寫入的頁面序號
//* : <cIsLocked>[in] 是否鎖定相關(guān)頁面
//* : <punFrom>[in] 指向原始數(shù)據(jù)的指針
//* : <unLen>[in] 原始數(shù)據(jù)長度
//* 出口參數(shù) : - ERR_WFLASH_OK : 編程成功
//* : - ERR_WFLASH_PROG : 編程失敗
//* : - ERR_WFLASH_UNLOCK : 解鎖失敗。參數(shù)cIsLocked為TRUE時(shí),該返回值有效
//*------------------------------------------------------------------------------------------------
static char __DFL_WritePage(short sPageIdx, char cIsLocked, unsigned int *punFrom, unsigned int unLen)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
unsigned int __unStatus, *__punTo, *__punNextTo, *__punNextFrom, __unCurLenToWrite;
char i = 0;
__punTo = (unsigned int*)((unsigned int)AT91C_IFLASH + sPageIdx * FLASH_PAGE_SIZE);
for(i=0; i<3; i++)
{
OS_ENTER_CRITICAL()
{
__macDFL_SetFMCNForFlash();
__punNextTo = __punTo;
__punNextFrom = punFrom;
__unCurLenToWrite = unLen;
do{
*__punNextTo = *__punNextFrom;
__punNextTo++;
__punNextFrom++;
}while(__unCurLenToWrite -= 4);
AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_START_PROG | (sPageIdx << 8);
//* 等待編程成功
__macDFL_WaitFlashReady(__unStatus);
}
OS_EXIT_CRITICAL()
if(__unStatus & AT91C_MC_LOCKE)
return ERR_WFLASH_LOCK;
if(__ilIsDataCorrect(punFrom, __punTo, unLen) == 0x00000000)
return ERR_WFLASH_OK;
}
return ERR_WFLASH_PROG;
}
//*------------------------------------------------------------------------------------------------
//* 函數(shù)名稱 : __DFL_WriteFlash
//* 功能描述 : 把數(shù)據(jù)寫入FLASH,并根據(jù)參數(shù)cIsLocked判斷是否鎖定
//* 入口參數(shù) : <punFrom>[in] 指向?qū)懭霐?shù)據(jù)的指針
//* : <unTo>[in] 要寫入的地址
//* : <nSize>[in] 要寫入的數(shù)據(jù)長度
//* : <cIsLocked>[in] 是否鎖定相關(guān)頁面
//* 出口參數(shù) : 返回?cái)?shù)據(jù)寫入的開始地址,如果寫入失敗則返回一個(gè)小于AT91C_IFLASH的值,分別為:
//* : - ERR_WFLASH_INVALID_ADDR : 指定寫入的地址無效
//* : - ERR_WFLASH_LOCK : 正在編程的頁面已被鎖定
//* : - ERR_WFLASH_PROG : 編程出錯(cuò)
//* : - ERR_WFLASH_UNLOCK : 解鎖出錯(cuò)
//*------------------------------------------------------------------------------------------------
static unsigned int __DFL_WriteFlash(unsigned int *punFrom, unsigned int unTo, int nSize, char cIsLocked)
{
unsigned int *__punTo, *__punNextTo, *__punNextFrom;
int __nSize, __nCurSizeToWrite, __nTotalSizeToWrite = 0, __nTotalSizeNotToWrite;
short __sCurPage;
char __cResult, __cBitNum;
unsigned short __usLockRegions = 0x0000;
//* 先將數(shù)據(jù)寫入FLASH鎖存緩沖器。因?yàn)閿?shù)據(jù)手冊表明不允許寫入8位或16位數(shù)據(jù),所以這里必須按照32位進(jìn)行數(shù)據(jù)
//* 寫入。在寫入鎖存緩沖器之前先對據(jù)大小進(jìn)行32位對齊運(yùn)算。
__nSize = (int)ALIGN32(nSize);
__punTo = (unsigned int*)unTo;
//* 如果指定的寫入地址超出了FLASH的結(jié)束地址或者寫入的數(shù)據(jù)超出了FLASH存儲容量,函數(shù)立即返回,不再繼續(xù)寫入。
//* 如果指定的FLASH地址并不是頁面起始地址,同樣視為無效地址
if((__punTo > (unsigned int*)AT91C_IFLASH_ENDADDR)
|| (__punTo < (unsigned int*)AT91C_IFLASH)
|| (((unsigned int*)AT91C_IFLASH_ENDADDR - __punTo) < __nSize)
|| (unTo & FLASG_PAGE_SIZE_MASK))
return ERR_WFLASH_INVALID_ADDR;
//* 開始頁編程
__punNextFrom = punFrom;
__sCurPage = ((unsigned int)__punNextTo - (unsigned int)AT91C_IFLASH) / FLASH_PAGE_SIZE;
do{
__nTotalSizeNotToWrite = __nSize - __nTotalSizeToWrite;
__nCurSizeToWrite = (FLASH_PAGE_SIZE < __nTotalSizeNotToWrite) ? FLASH_PAGE_SIZE:__nTotalSizeNotToWrite;
//* 解鎖當(dāng)前頁面
if(!DFL_PageUnlock(__sCurPage))
return ERR_WFLASH_UNLOCK;
if((__cResult = __DFL_WritePage(__sCurPage, cIsLocked, __punNextFrom, __nCurSizeToWrite)) != ERR_WFLASH_OK)
return __cResult;
__punNextFrom = (unsigned int*)((unsigned int)__punNextFrom + __nCurSizeToWrite);
//* 設(shè)置鎖定區(qū)域位
if(cIsLocked)
{
__cBitNum = __sCurPage / PAGES_PER_LOCK_REGION;
__usLockRegions |= 1 << __cBitNum;
}
__nTotalSizeToWrite += __nCurSizeToWrite;
__sCurPage++;
}while(__nTotalSizeToWrite < __nSize);
//* 鎖定頁面
if(cIsLocked)
{
for(__cBitNum=0; __cBitNum<FLASH_LOCK_REGIONS_NB; __cBitNum++)
{
if(__usLockRegions & (1 << __cBitNum))
DFL_PageLock(__cBitNum * PAGES_PER_LOCK_REGION);
}
}
return (unsigned int)__punTo;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -