223 lines
5.3 KiB
C
223 lines
5.3 KiB
C
/*
|
||
*********************************************************************************************************
|
||
*
|
||
* 模块名称 : cpu内部falsh操作模块
|
||
* 文件名称 : bsp_cpu_flash.c
|
||
* 版 本 : V1.0
|
||
* 说 明 : 提供读写CPU内部Flash的函数
|
||
* 修改记录 :
|
||
* 版本号 日期 作者 说明
|
||
*
|
||
*********************************************************************************************************
|
||
*/
|
||
#include "Sys.h"
|
||
#include "misc.h"
|
||
#include "stm32f10x_flash.h"
|
||
#include "bsp_cpu_flash.h"
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: bsp_GetSector
|
||
* 功能说明: 根据地址计算扇区首地址
|
||
* 形 参:无
|
||
* 返 回 值: 扇区首地址
|
||
*********************************************************************************************************
|
||
*/
|
||
uint32_t bsp_GetSector(uint32_t _ulWrAddr)
|
||
{
|
||
uint32_t sector = 0;
|
||
|
||
sector = _ulWrAddr & SECTOR_MASK;
|
||
|
||
return sector;
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: bsp_ReadCpuFlash
|
||
* 功能说明: 读取CPU Flash的内容
|
||
* 形 参:_ucpDst : 目标缓冲区
|
||
* _ulFlashAddr : 起始地址
|
||
* _ulSize : 数据大小(单位是字节)
|
||
* 返 回 值: 0=成功,1=失败
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t bsp_ReadCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpDst, uint32_t _ulSize)
|
||
{
|
||
uint32_t i;
|
||
|
||
/* 如果偏移地址超过芯片容量,则不改写输出缓冲区 */
|
||
if (_ulFlashAddr + _ulSize > FLASH_BASE_ADDR + FLASH_SIZE)
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
/* 长度为0时不继续操作,否则起始地址为奇地址会出错 */
|
||
if (_ulSize == 0)
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
for (i = 0; i < _ulSize; i++)
|
||
{
|
||
*_ucpDst++ = *(uint8_t *)_ulFlashAddr++;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: bsp_CmpCpuFlash
|
||
* 功能说明: 比较Flash指定地址的数据.
|
||
* 形 参: _ulFlashAddr : Flash地址
|
||
* _ucpBuf : 数据缓冲区
|
||
* _ulSize : 数据大小(单位是字节)
|
||
* 返 回 值:
|
||
* FLASH_IS_EQU 0 Flash内容和待写入的数据相等,不需要擦除和写操作
|
||
* FLASH_REQ_WRITE 1 Flash不需要擦除,直接写
|
||
* FLASH_REQ_ERASE 2 Flash需要先擦除,再写
|
||
* FLASH_PARAM_ERR 3 函数参数错误
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t bsp_CmpCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpBuf, uint32_t _ulSize)
|
||
{
|
||
uint32_t i;
|
||
uint8_t ucIsEqu; /* 相等标志 */
|
||
uint8_t ucByte;
|
||
|
||
/* 如果偏移地址超过芯片容量,则不改写输出缓冲区 */
|
||
if (_ulFlashAddr + _ulSize > FLASH_BASE_ADDR + FLASH_SIZE)
|
||
{
|
||
return FLASH_PARAM_ERR; /* 函数参数错误 */
|
||
}
|
||
|
||
/* 长度为0时返回正确 */
|
||
if (_ulSize == 0)
|
||
{
|
||
return FLASH_IS_EQU; /* Flash内容和待写入的数据相等 */
|
||
}
|
||
|
||
ucIsEqu = 1; /* 先假设所有字节和待写入的数据相等,如果遇到任何一个不相等,则设置为 0 */
|
||
for (i = 0; i < _ulSize; i++)
|
||
{
|
||
ucByte = *(uint8_t *)_ulFlashAddr;
|
||
|
||
if (ucByte != *_ucpBuf)
|
||
{
|
||
if (ucByte != 0xFF)
|
||
{
|
||
return FLASH_REQ_ERASE; /* 需要擦除后再写 */
|
||
}
|
||
else
|
||
{
|
||
ucIsEqu = 0; /* 不相等,需要写 */
|
||
}
|
||
}
|
||
|
||
_ulFlashAddr++;
|
||
_ucpBuf++;
|
||
}
|
||
|
||
if (ucIsEqu == 1)
|
||
{
|
||
return FLASH_IS_EQU; /* Flash内容和待写入的数据相等,不需要擦除和写操作 */
|
||
}
|
||
else
|
||
{
|
||
return FLASH_REQ_WRITE; /* Flash不需要擦除,直接写 */
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: bsp_WriteCpuFlash
|
||
* 功能说明: 写数据到CPU 内部Flash。
|
||
* 形 参: _ulFlashAddr : Flash地址
|
||
* _ucpSrc : 数据缓冲区
|
||
* _ulSize : 数据大小(单位是字节)
|
||
* 返 回 值: 0-成功,1-数据长度或地址溢出,2-写Flash出错(估计Flash寿命到)
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t bsp_WriteCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpSrc, uint32_t _ulSize)
|
||
{
|
||
uint32_t i;
|
||
uint8_t ucRet;
|
||
uint16_t usTemp,j;
|
||
FLASH_Status status = FLASH_COMPLETE;
|
||
|
||
/* 如果偏移地址超过芯片容量,则不改写输出缓冲区 */
|
||
if (_ulFlashAddr + _ulSize > FLASH_BASE_ADDR + FLASH_SIZE)
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
/* 长度为0 时不继续操作 */
|
||
if (_ulSize == 0)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
/* 长度为奇数时不继续操作 */
|
||
// if ((_ulSize % 2) != 0)
|
||
// {
|
||
// return 1;
|
||
// }
|
||
if ((_ulSize % 2) != 0)
|
||
{
|
||
_ulSize= _ulSize+1;
|
||
}
|
||
ucRet = bsp_CmpCpuFlash(_ulFlashAddr, _ucpSrc, _ulSize);
|
||
|
||
if (ucRet == FLASH_IS_EQU)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
__set_PRIMASK(1); /* 关中断 */
|
||
|
||
/* FLASH 解锁 */
|
||
FLASH_Unlock();
|
||
|
||
/* Clear pending flags (if any) */
|
||
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
|
||
|
||
/* 需要擦除 */
|
||
// if (ucRet == FLASH_REQ_ERASE)
|
||
{
|
||
status = FLASH_ErasePage(bsp_GetSector(_ulFlashAddr));
|
||
// if (status != FLASH_COMPLETE)
|
||
// {
|
||
// return 2;
|
||
// }
|
||
}
|
||
j=1000;
|
||
while(j--);
|
||
/* 按字节模式编程(为提高效率,可以按字编程,一次写入4字节) */
|
||
for (i = 0; i < _ulSize / 2; i++)
|
||
{
|
||
//FLASH_ProgramByte(_ulFlashAddr++, *_ucpSrc++);
|
||
usTemp = _ucpSrc[2 * i];
|
||
usTemp |= (_ucpSrc[2 * i + 1] << 8);
|
||
status = FLASH_ProgramHalfWord(_ulFlashAddr, usTemp);
|
||
if (status != FLASH_COMPLETE)
|
||
{
|
||
break;
|
||
}
|
||
|
||
_ulFlashAddr += 2;
|
||
}
|
||
|
||
/* Flash 加锁,禁止写Flash控制寄存器 */
|
||
FLASH_Lock();
|
||
|
||
__set_PRIMASK(0); /* 开中断 */
|
||
|
||
if (status == FLASH_COMPLETE)
|
||
{
|
||
return 0;
|
||
}
|
||
return 2;
|
||
}
|
||
|
||
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|