?? flash.c
字號:
//*------------------------------------------------------------------------------------------------
//* 文件名 : flash.c
//* 功能描述 : flash驅動函數
//* 作者 : 焦海波
//* 版本 : 0.2
//* 建立日期、時間 : 2006/06/26 09:30
//* 修改日期、時間 : 2006/06/28 15:03
//* 修改原因 : 原來的寫入函數在頁面編程完畢后沒有對編程結果進行容錯,這次修改增加了容錯代碼。
//*------------------------------------------------------------------------------------------------
//*------------------------------------------ 頭文件 -----------------------------------------------
#include "/uCOS_II/os_cpu.h"
#include "/at91sam7x256/include/AT91SAM7X256.h"
#include "flash.h"
//*------------------------------------- 常量、變量、宏 --------------------------------------------
#define FLASG_PAGE_SIZE_MASK 0x000000FF
#define FLASH_PAGE_SIZE 256
#define FLASH_PAGE_NB 1024
//* AT91C_IFLASH + FLASH_PAGE_NB * FLASH_PAGE_SIZE
#define AT91C_IFLASH_ENDADDR 0x00140000
#define FLASH_LOCK_REGIONS_NB 16
#define PAGES_PER_LOCK_REGION 64
#define FSR_LOCK_BIT_OFFSET 16
#define AT91C_MC_CORRECT_KEY ((unsigned int) 0x5A << 24)
//* 對32位數據進行32位對齊,實際運算結果將得到一個能被4整除的數據
#define ALIGN32(unData) ((unData + 3) & ~3)
//* 等待FLASH指令執行成功
#define __macDFL_WaitFlashReady(unStatus) while(!((unStatus = AT91C_BASE_MC->MC_FSR) & AT91C_MC_FRDY))
//* 設置對FLASH進行擦寫操作時的正確的FMCN值。擦寫FLASH時需要將FMCN設置為1.5微妙的主時鐘周期數。
#define __macDFL_SetFMCNForFlash() AT91C_BASE_MC->MC_FMR = (AT91C_BASE_MC->MC_FMR & ~AT91C_MC_FMCN) | (72 << 16)
//* 設置對NVM位進行操作時的正確的FMCN值。其值設置為1微妙的主時鐘周期數。
#define __macDFL_SetFMCNForNVM() AT91C_BASE_MC->MC_FMR = (AT91C_BASE_MC->MC_FMR & ~AT91C_MC_FMCN) | (48 << 16)
//* 讀取鎖定位狀態
#define __macDFL_GetLockStatus() (AT91C_BASE_MC->MC_FSR & ((unsigned int)0xFFFF << 16))
#define __macDFL_GetNVMStatus(cNVMBit) (AT91C_BASE_MC->MC_FSR & ((unsigned int)0x01 << (8 + cNVMBit)))
//*------------------------------------- 函數原型聲明 ----------------------------------------------
static unsigned int __DFL_WriteFlash(unsigned int *punFrom, unsigned int unTo, int nSize, char cIsLocked);
static char __DFL_WritePage(short sPageIdx, char cIsLocked, unsigned int *punFrom, unsigned int unLen);
//*================================================================================================
//* 函 數 區
//*================================================================================================
//*------------------------------------------------------------------------------------------------
//* 函數名稱 : DFL_IsLockedPage
//* 功能描述 : 指定頁面是否已被鎖定
//* 入口參數 : <sPageIdx>[in] 指定要鎖定的頁面,范圍為0-1023
//* 出口參數 : - TRUE : 該頁被鎖定
//* : - FALSE: 該頁未被鎖定
//*------------------------------------------------------------------------------------------------
int DFL_IsLockedPage(short sPageIdx)
{
unsigned int __unLockStatus;
char __cBitNum;
if(sPageIdx < 0 || sPageIdx > 1023)
return FALSE;
__cBitNum = sPageIdx / PAGES_PER_LOCK_REGION;
__unLockStatus = __macDFL_GetLockStatus();
return (__unLockStatus & ((unsigned int)(0x01 << (__cBitNum + FSR_LOCK_BIT_OFFSET))));
}
//*------------------------------------------------------------------------------------------------
//* 函數名稱 : DFL_PageLock
//* 功能描述 : 將指定的FLASH頁面鎖定以禁止編程
//* 入口參數 : <sPageIdx>[in] 指定要鎖定的頁面,范圍為0-1023
//* 出口參數 : 成功則返回TRUE,否則返回FALSE
//*------------------------------------------------------------------------------------------------
int DFL_PageLock(short sPageIdx)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
unsigned int __unStatus;
if(sPageIdx < 0 || sPageIdx > 1023)
return FALSE;
if(DFL_IsLockedPage(sPageIdx))
return TRUE;
OS_ENTER_CRITICAL()
{
__macDFL_SetFMCNForNVM();
AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_LOCK | (sPageIdx << 8);
__macDFL_WaitFlashReady(__unStatus);
}
OS_EXIT_CRITICAL()
return DFL_IsLockedPage(sPageIdx);
}
//*------------------------------------------------------------------------------------------------
//* 函數名稱 : DFL_PageUnlock
//* 功能描述 : 解鎖指定的FLASH頁面
//* 入口參數 : <sPageIdx>[in] 指定要解鎖的頁面,范圍為0-1023
//* 出口參數 : 成功則返回TRUE,否則返回FALSE
//*------------------------------------------------------------------------------------------------
int DFL_PageUnlock(short sPageIdx)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
unsigned int __unStatus;
if(sPageIdx < 0 || sPageIdx > 1023)
return FALSE;
if(!DFL_IsLockedPage(sPageIdx))
return TRUE;
OS_ENTER_CRITICAL()
{
__macDFL_SetFMCNForNVM();
AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_UNLOCK | (sPageIdx << 8);
__macDFL_WaitFlashReady(__unStatus);
}
OS_EXIT_CRITICAL()
return !DFL_IsLockedPage(sPageIdx);
}
//*------------------------------------------------------------------------------------------------
//* 函數名稱 : DFL_WriteFlash
//* 功能描述 : 通過調用__DFL_WriteFlash()完成把數據寫入FLASH的工作。
//* 入口參數 : <punFrom>[in] 指向寫入數據的指針
//* : <unTo>[in] 要寫入的地址
//* : <nSize>[in] 要寫入的數據長度
//* 出口參數 : 參見__DFL_WriteFlash()函數返回值說明
//*------------------------------------------------------------------------------------------------
unsigned int DFL_WriteFlash(unsigned int *punFrom, unsigned int unTo, int nSize)
{
return __DFL_WriteFlash(punFrom, unTo, nSize, FALSE);
}
//*------------------------------------------------------------------------------------------------
//* 函數名稱 : DFL_WriteAndLockFlash
//* 功能描述 : 通過調用__DFL_WriteFlash()完成把數據寫入FLASH并鎖定相關頁面的工作,
//* 入口參數 : <punFrom>[in] 指向寫入數據的指針
//* : <unTo>[in] 要寫入的地址
//* : <nSize>[in] 要寫入的數據長度
//* 出口參數 : 參見__DFL_WriteFlash()函數返回值說明
//*------------------------------------------------------------------------------------------------
unsigned int DFL_WriteAndLockFlash(unsigned int *punFrom, unsigned int unTo, int nSize)
{
return __DFL_WriteFlash(punFrom, unTo, nSize, TRUE);
}
//*------------------------------------------------------------------------------------------------
//* 函數名稱 : DFL_EraseAllFlash
//* 功能描述 : 擦除整個FLASH
//* 入口參數 : 無
//* 出口參數 : 指令執行成功返回TRUE,否則返回FLASE
//*------------------------------------------------------------------------------------------------
int DFL_EraseAllFlash(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
unsigned int __unStatus;
OS_ENTER_CRITICAL()
{
__macDFL_SetFMCNForFlash();
AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_ERASE_ALL;
__macDFL_WaitFlashReady(__unStatus);
}
OS_EXIT_CRITICAL()
return !(__unStatus & (AT91C_MC_PROGE | AT91C_MC_LOCKE));
}
//*------------------------------------------------------------------------------------------------
//* 函數名稱 : DFL_SetNVM
//* 功能描述 : 設置NVM位
//* 入口參數 : <cNVMBit>[in] 要設置的NVM位(0-2)
//* 出口參數 : 指令執行成功返回TRUE,否則返回FLASE
//*------------------------------------------------------------------------------------------------
int DFL_SetNVM(char cNVMBit)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
unsigned int __unStatus;
if(cNVMBit > 2)
return FALSE;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -