📄 flash.c
字号:
//*------------------------------------------------------------------------------------------------
//* 文件名 : flash.c
//* 功能描述 : flash驱动函数
//* 作者 : 焦海波
//* 版本 : 0.2
//* 建立日期、时间 : 2006/06/26 09:30
//* 修改日期、时间 : 2006/06/28 15:03
//* 修改原因 : 原来的写入函数在页面编程完毕后没有对编程结果进行容错,这次修改增加了容错代码。
//*------------------------------------------------------------------------------------------------
//*------------------------------------------ 头文件 -----------------------------------------------
#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)
{
OS_CPU_SR cpu_sr = 0;
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)
{
OS_CPU_SR cpu_sr = 0;
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)
{
OS_CPU_SR cpu_sr = 0;
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)
{
OS_CPU_SR cpu_sr = 0;
unsigned int __unStatus;
if(cNVMBit > 2)
return FALSE;
if(__macDFL_GetNVMStatus(cNVMBit))
return TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -