jianghuai/SYSTEM/bsp_cpu_flash.c
2024-05-07 09:36:09 +08:00

223 lines
5.3 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
*********************************************************************************************************
*
* 模块名称 : 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) *********************************/