Files
CHJ/user/MCU/lhl_flash.c
2026-03-20 21:19:04 +08:00

181 lines
6.1 KiB
C
Raw 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.

#include "../main/SystemInclude.h"
//擦除一页扇区(只操作需要操作的扇区)如果仅擦除1个页面则Endpage与Startpage相同。
void FLASH_Erase_Data_Page(u8 UserPage)
{
u32 flashAddr = FLASH_PAGE_29;
switch(UserPage)
{
case USER_DCOEF_TAG_PAGE:flashAddr= USER_DCOEF_TAG_ADDR; break;
case USER_PARAMS_PAGE :flashAddr= USER_PARAMS_ADDR ; break;
case VENDER_PARAMS_PAGE :flashAddr= VENDER_PARAMS_ADDR ; break;
default : return;
}
if(LHL_FLASH_Erase(flashAddr, flashAddr, LHL_LNG_TIMEOUT) != LHL_OK)
{
while(1);
}
}
//按整页写入
void FLASH_Write_Data_Page(u8 UserPage, void *pBuffer, u32 byteSize)
{
//1 地址映射
uint32_t flashAddr = 0;
switch(UserPage)
{
case USER_DCOEF_TAG_PAGE: flashAddr = USER_DCOEF_TAG_ADDR ; break;
case USER_PARAMS_PAGE : flashAddr = USER_PARAMS_ADDR ; break;
case VENDER_PARAMS_PAGE : flashAddr = VENDER_PARAMS_ADDR ; break;
default : return;
}
//2 向上对齐到 4 字节
u32 wordCount = (byteSize + 3U)/4U; // 等价于 ((byteSize + 3) & ~3) / 4
//3 限制不超过一页word 数)
if (wordCount > FLASH_PAGE_SIZE/4U) wordCount = FLASH_PAGE_SIZE/4U;
//4 写入
if(LHL_FLASH_Program(flashAddr ,(u32 *)pBuffer, (u16)wordCount, LHL_LNG_TIMEOUT) != LHL_OK)
{
while(1);
}
}
//Application ******************************************************************
//API
// 定义指向固定地址的指针
volatile u8 * const USER_PARAMS = (u8*)USER_PARAMS_ADDR;
volatile u8 * const VENDER_PARAMS = (u8*)VENDER_PARAMS_ADDR;
volatile u8 * const CORRECT_DATA = (u8 *)CORRECT_DATA_ADDR;
volatile u8 * const CORRECT2_DATA = (u8 *)CORRECT2_DATA_ADDR;
// 通用参数读取函数
void ReadParameterFromFlash( void *value,u16 offset, u8 size ,u8 UserPage )
{
if(offset + size <= FLASH_PAGE_BYTE_SIZE) //不超过一页大小
{
switch(UserPage)
{
case USER_PARAMS_PAGE :memcpy(value,(void*)&USER_PARAMS[offset] , size);break; //读用户数据页
case VENDER_PARAMS_PAGE :memcpy(value,(void*)&VENDER_PARAMS[offset], size);break; //读厂家数据页
default : break ;
}
}
}
//APP
u8 mucSaveParams; //Flash状态标志
u8 munWriteParams;//Flash写寄存器参数标志
#define ParamsBufSize FLASH_PAGE_BYTE_SIZE/4u //4K大小(缓冲区不够了用的1K)
u8 unParamsBuf[ParamsBufSize]; //用于按byte存储flash页中间缓冲
/* 保存系统参数(整合到一起批量传入) */
void SaveSysParams(void)
{
if(munWriteParams == WP_NOT) return;//不写寄存器
//0- 是否恢复默认值
if(munWriteParams == WP_DEF)//寄存器恢复默认值
{
mucSaveParams = PARAMS_ING;//写入中
memcpy(unParamsBuf, (void*)VENDER_PARAMS, ParamsBufSize);//从Flash出厂数据页装填unParamsBuf
FLASH_Erase_Data_Page(USER_PARAMS_PAGE);//擦除用户数据页
FLASH_Write_Data_Page(USER_PARAMS_PAGE, unParamsBuf, ParamsBufSize);//将unParamsBuf写入用户数据页
munWriteParams = WP_NOT; //恢复无写入状态
mucSaveParams = PARAMS_COMPL;//Flash写入完成
}
//1- 准备需要写入的FLASH数据
//1-1 从Flash更新一下历史参数
memcpy(unParamsBuf, (void*)USER_PARAMS, ParamsBufSize);
//1-2 为unParamsBuf传入可修改部分的新值
memcpy((void *)&unParamsBuf[OFFSET_AIR], &offsetAir, OFFSET_AIR_WIDTH);
memcpy((void *)&unParamsBuf[OFFSET_GAS], &offsetGas, OFFSET_GAS_WIDTH);
memcpy((void *)&unParamsBuf[SERIES_BASE+SENSOR_SN_WIDTH*1],&meterSN1,SENSOR_SN_WIDTH);
memcpy((void *)&unParamsBuf[SERIES_BASE+SENSOR_SN_WIDTH*2],&meterSN2,SENSOR_SN_WIDTH);
memcpy((void *)&unParamsBuf[SERIES_BASE+SENSOR_SN_WIDTH*3],&meterSN3,SENSOR_SN_WIDTH);
memcpy((void *)&unParamsBuf[SERIES_BASE+SENSOR_SN_WIDTH*4],&meterSN4,SENSOR_SN_WIDTH);
memcpy((void *)&unParamsBuf[SERIES_BASE+SENSOR_SN_WIDTH*5],&meterSN5,SENSOR_SN_WIDTH);
memcpy((void *)&unParamsBuf[SERIES_BASE+SENSOR_SN_WIDTH*6],&meterSN6,SENSOR_SN_WIDTH);
//......
//2- 开始写入Flash
//写厂家及用户区
if(munWriteParams == WP_VENDER)
{
FLASH_Erase_Data_Page(USER_PARAMS_PAGE);//擦除指定页
FLASH_Write_Data_Page(USER_PARAMS_PAGE,unParamsBuf, ParamsBufSize);//按页写入
FLASH_Erase_Data_Page(VENDER_PARAMS_PAGE);//擦除指定页
FLASH_Write_Data_Page(VENDER_PARAMS_PAGE,unParamsBuf, ParamsBufSize);//按页写入
}
//写用户区
else if(munWriteParams == WP_USER)
{
FLASH_Erase_Data_Page(USER_PARAMS_PAGE);//擦除指定页
FLASH_Write_Data_Page(USER_PARAMS_PAGE,unParamsBuf, ParamsBufSize);//按页写入
}
//写二次修正区
else if(munWriteParams == WP_DCOEF_TAG)
{
}
munWriteParams = WP_NOT;//恢复无写入状态
mucSaveParams = PARAMS_COMPL;//Flash写入完成
}
/******************************************************************************/
/* 写校准到指定页的FLASH数据每次传输一帧内的数量 */
void FLASH_Write_Calib_Data_ToFlash(u16 FrameN, u8 *pBuffer )
{
u32 ADDR;
ADDR = FrameN * CALIB_WIDTH + CORRECT_DATA_ADDR;
if((ADDR&0x0FFF) == 0x000)LHL_FLASH_Erase(ADDR,ADDR,LHL_LNG_TIMEOUT);//ADDR跨页即ADDR为页首地址
if(ADDR >(CORRECT_DATA_ADDR+CALIB_REAL_SIZE)) MBBuf.BusError = SLAVE_DEVICE_FAILURE;
LHL_FLASH_Program(ADDR,(u32 *)pBuffer,CALIB_WIDTH/4u ,LHL_LNG_TIMEOUT);
}
/* 写校准到指定页的FLASH数据每次传输一帧内的数量*/
void FLASH_Write_Calib2_Data_ToFlash(u16 FrameN, u8 *pBuffer )
{
u32 ADDR;
ADDR = FrameN * CALIB_WIDTH + CORRECT2_DATA_ADDR;
if((ADDR&0x0FFF) == 0x000)LHL_FLASH_Erase(ADDR,ADDR,LHL_LNG_TIMEOUT);//ADDR跨页即ADDR为页首地址
if(ADDR >(CORRECT2_DATA_ADDR+CALIB_REAL_SIZE))MBBuf.BusError = SLAVE_DEVICE_FAILURE;
LHL_FLASH_Program(ADDR,(u32*)pBuffer ,CALIB_WIDTH/4u ,LHL_LNG_TIMEOUT );
}
/******************************************************************************/
/* 按页读校准区域数据*/
void ReadCalibDataFromFlash(u32 frameN , u8 *data ,u16 size )
{
memcpy(data,(void*)&CORRECT_DATA[frameN*size], size);
}
void ReadCalib2DataFromFlash(u32 frameN , u8 *data ,u16 size )
{
memcpy(data,(void*)&CORRECT2_DATA[frameN*size], size);
}
/******************************************************************************/
/* 按索引读取校准区域数据*/
void ReadDataFromFlash(u32 offset , u8 *data ,u16 size )
{
memcpy(data,(void*)&CORRECT_DATA[offset], size);
// if(offsetAir)memcpy(data,(void*)&CORRECT_DATA[offset], size);
// else memcpy(data,(void*)&CORRECT2_DATA[offset], size);
}