#include "../main/SystemInclude.h" /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = USER_PARAMS_ADDR 参数数据保存区,对应EEPROM的 0x10-0x6C0 区间 参数页说明:将 u16 MBReg[336]; u16 WordReg[128]; u32 DWordReg[64]; 总共 1712bytes 依次连续存储到USER_PARAMS_ADDR为起始地址的页; CORRECT_DATA_ADDR 默认校准页保存区,对应EEPROM的 0x1000-及以后按照内码量设计的区间 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ //写参数数据保存区-临时缓冲区 u8 param_buffer[TOTAL_PARAM_SIZE] __attribute__((aligned(4))); //4字节对齐 void update_param_bufferFromFlash(void)// { memcpy(param_buffer, (void*)USER_PARAMS_ADDR, TOTAL_PARAM_SIZE); } //写参数数据保存区-将临时缓冲区param_buffer数据存入flash ------------------ static void WriteAllParamToFlash(void) { //擦除 Flash 页(USER_PARAMS_ADDR 是页起始) if(LHL_FLASH_Erase(USER_PARAMS_ADDR, USER_PARAMS_ADDR, LHL_LNG_TIMEOUT) != LHL_OK) { while(1); } //按 32-bit word 写入 必须 4-byte 对齐 u16 word_count = (TOTAL_PARAM_SIZE + 3)>>2; // 向上取整 转换为32位数据的个数 LHL_FLASH_Program( USER_PARAMS_ADDR, (uint32_t*)param_buffer, word_count, LHL_LNG_TIMEOUT ); } //写参数数据保存区-双字节保存区 u16 WriteShortParameterToFlash(u16 parameterAdr) { //访问双字节数据保存区------------------------------------------------------------------ // if((parameterAdr >=REG_MEM_ADDR_START) && (parameterAdr < REG_INT_DWORD_MEM_ADDR_START)) // {} u8 *p = param_buffer; tempL.Byte[2] = CRC8(tempL.Byte, 2);//计算新值校验码 p += parameterAdr; //更新变量 p[0] = tempL.Byte[0]; p[1] = tempL.Byte[1]; p[2] = tempL.Byte[2]; //写param_buffer到Flash WriteAllParamToFlash(); tempL.Word[0] = ReadShortParameterFromFlash(parameterAdr,WordDefault[ADR_WORD_IDX(parameterAdr)][DEFAULT]); tempL.Byte[2] = 0; // 注意:此时不用更新 WordReg[index] // 因为上层会用返回值来更新:*WRSource = 返回值; return tempL.Word[0]; //上层会用此值更新 WordReg[I] } //写参数数据保存区-四字节保存区 u32 WriteLongParameterToFlash(u16 parameterAdr) { // if( (parameterAdr >=REG_INT_DWORD_MEM_ADDR_START)&& parameterAdr <= REG_INT_DWORD_MEM_ADDR_END) // { } tempDev.Byte[4] = CRC8(tempDev.Byte, 4);//计算新值校验码 //更新变量 u8 *p = param_buffer; p += (parameterAdr ); p[0] = tempDev.Byte[0]; p[1] = tempDev.Byte[1]; p[2] = tempDev.Byte[2]; p[3] = tempDev.Byte[3]; p[4] = tempDev.Byte[4]; //写param_buffer到Flash WriteAllParamToFlash(); tempDev.DWord[0] = ReadLongParameterFromFlash(parameterAdr,WordDefault[ADR_DWORD_IDX(parameterAdr)][DEFAULT]); tempDev.Byte[4] = 0; return tempDev.DWord[0]; } //写校准页保存区 ,二次修正保存区 ,不定长参数数据保存区--------------------------------------------------- void WriteMultiByteToFlash(u16 address, u8 *wrtData, u16 dataLenth, u8 flashAdr) { (void)flashAdr; // 没有多个Flash //默认校准曲线--------------------------------------------------------------- if(address >= CALI_DATA1_ADDR)//要写入的地址为原eeprom的校准区 { //0.转换成Flash地址 u32 ADDR = (u32)(address - CALI_DATA1_ADDR); ADDR = ADDR + CORRECT_DATA_ADDR; //判断是否新一页,擦除新页准备写入 if((ADDR&0x0FFF) == 0x000) LHL_FLASH_Erase(ADDR,ADDR,LHL_LNG_TIMEOUT);//ADDR跨页即ADDR为页首地址 if(ADDR >(CORRECT_DATA_ADDR+ CALIB_STORED_SIZE) ) MBBuf.BusError = SLAVE_DEVICE_FAILURE;//溢出 //写校准进入Flash LHL_FLASH_Program(ADDR,(u32 *)wrtData,dataLenth>>2 ,LHL_LNG_TIMEOUT); } //校准曲线2--------------------------------------------------------------- //CALI_DATA2_ADDR CORRECT_DATA2_ADDR CALIB_STORED_SIZE2 //校准曲线3--------------------------------------------------------------- //CALI_DATA3_ADDR CORRECT_DATA3_ADDR CALIB_STORED_SIZE3 //二次修正区--------------------------------------------------------------- // else if() // { // USER_DCOEF_TAG_ADDR // } //写入多个到参数数据保存区------------------------------------------------------------------ else if((address >=REG_MEMORY_ADDR) && (address <= REG_INT_DWORD_MEM_ADDR_END)) { wrtData[dataLenth] = CRC8(wrtData, dataLenth);//计算新值校验码 //更新变量 u8 *p = param_buffer; p += address; /*for(u8 i = 0 ; i < dataLenth+1 ; i ++) { p[i] = wrtData[i]; }*/ //每两个字节交换 for (int i = 0; i < dataLenth; i += 2) { p[i] = wrtData[i + 1]; //低地址 p[i + 1] = wrtData[i]; //高地址 } p[dataLenth]= wrtData[dataLenth];//CRC直接复制 WriteAllParamToFlash(); } } //读双字节数据保存区------------------------------------------------------------------ u16 ReadShortParameterFromFlash(u16 parameterAdr , u16 parameterDefault) { // if(parameterAdr >=REG_MEM_ADDR_START && parameterAdr < REG_INT_DWORD_MEM_ADDR_START) // { } u32 ADDR = ((u32)parameterAdr + USER_PARAMS_ADDR);// 将EEPROM 参数地址(如 MEM_ADDR_REG_0X30 = 0x10)转为 Flash 物理地址 tempL.Word[0] = 0; memcpy(tempL.Byte,(const void*)ADDR, 3); if(tempL.Byte[2] != CRC8(tempL.Byte, 2)) { tempL.Word[0] = (u32)parameterDefault; isReadParameterOK = 0; } else { tempL.Byte[2] = 0; isReadParameterOK = 1; } return tempL.Word[0]; } //读四字节数据保存区------------------------------------------------------------------ u32 ReadLongParameterFromFlash(u16 parameterAdr , u16 parameterDefault) { // if( (parameterAdr >=REG_INT_DWORD_MEM_ADDR_START)&& parameterAdr <= REG_INT_DWORD_MEM_ADDR_END) // { } u32 ADDR = (u32)(parameterAdr + USER_PARAMS_ADDR); tempDev.DWord[0] = 0; memcpy(tempDev.Byte,(const void*)ADDR, 5); if(tempDev.Byte[4] != CRC8(tempDev.Byte, 4)) { tempDev.DWord[0] = (u32)parameterDefault; isReadParameterOK = 0; } else { isReadParameterOK = 1; } return tempDev.DWord[0]; } //读数据保存区,校准数据保存区------------------------------------------------------------------ void ReadMultiByteFromFlash(u16 address,u8 *wrtData, u16 dataLenth, u8 flashAdr) { (void)flashAdr; // 没有多个Flash,避免编译器 warning u32 ADDR; //读校准数据保存区-------------------------------------------------------- //由于校准数据地址基准为eeprom的地址,而所有的校准都在该地址后,因此只需要判断这一个即可 if(address >=CALI_DATA1_ADDR) { ADDR =(u32)(address-CALI_DATA1_ADDR ); ADDR += CORRECT_DATA_ADDR; //转换为Flash地址 memcpy(wrtData,(const void*)ADDR, dataLenth); } //读数据保存区---------------------------------------------------------- else if((address >=REG_MEMORY_ADDR) && (address <= REG_INT_DWORD_MEM_ADDR_END)) { ADDR =((u32)address + USER_PARAMS_ADDR); memcpy(wrtData,(const void*)ADDR, dataLenth); //不定长参数的校验位是存了的,若判断但是默认值=?未判断 } }