123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- #include "eeprom.h"
- FLASH_EraseInitTypeDef EEPROM_AreaEraseInitStruct;
- TrueOrFalse_Flag_Struct_t IsFirstPowerOn;
- static void EEPROM_Erase(void)
- {
- uint32_t PageError;
-
- EEPROM_AreaEraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
- EEPROM_AreaEraseInitStruct.PageAddress = EEPROM_BEGIN_ADDRESS;
- EEPROM_AreaEraseInitStruct.NbPages = 1;
-
- HAL_FLASH_Unlock();
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
- HAL_FLASHEx_Erase(&EEPROM_AreaEraseInitStruct, &PageError);
- HAL_FLASH_Lock();
- HAL_Delay(100);
- }
- static void FLASH_Write(uint32_t FlashAddress, uint32_t* Data, uint16_t DataLength)
- {
- uint32_t i = 0;
-
- HAL_FLASH_Unlock();
- for (i = 0; (i < DataLength) && (FlashAddress <= (EEPROM_END_ADDRESS-4)); i++)
- {
- if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FlashAddress, *(uint32_t*)(Data + i)) == HAL_OK)
- {
- FlashAddress += 4;
- }
- else
- {
- // Error occurred while writing data in Flash memory
- return;
- }
- }
- HAL_FLASH_Lock();
- return;
- }
- static void SaveDataToEEPROM(uint32_t FlashAddress, uint8_t* Data, uint8_t Length) // Length必须为4的倍数
- {
- #if 0
- uint32_t CRC_Result, DataBuf[64];
- uint8_t PakageNum, LastPakageNum, i;
-
- LastPakageNum = Length % 4;//组合成32bit数据,最后一包数据个数
-
- //数据组包成32bit
- if(LastPakageNum == 0)
- {
- PakageNum = Length / 4;
- for(i=0; i<PakageNum; i++)
- {
- DataBuf[i] = (Data[4 * i + 0] << 24) + (Data[4 * i + 1] << 16) + (Data[4 * i + 2] << 8) + Data[4 * i + 3];
- }
- CRC_Result = CRC32_Calculate(Data, Length);
- }
- else
- {
- PakageNum = Length / 4 + 1;
- PakageNum = Length / 4;
- for(i=0; i<(PakageNum - 1); i++)
- {
- DataBuf[i] = (Data[4 * i + 0] << 24) + (Data[4 * i + 1] << 16) + (Data[4 * i + 2] << 8) + Data[4 * i + 3];
- }
- switch(LastPakageNum)
- {
- case 1:
- {
- DataBuf[PakageNum - 1] = (DataBuf[Length - 1] << 24) & 0xFF000000;
- break;
- }
- case 2:
- {
- DataBuf[PakageNum - 1] = ((DataBuf[Length - 2] << 24) + (DataBuf[Length - 1] << 16)) & 0xFFFF0000;
- break;
- }
- case 3:
- {
- DataBuf[PakageNum - 1] = ((DataBuf[Length - 3] << 24) + (DataBuf[Length - 2] << 16) + (DataBuf[Length - 1] << 8)) & 0xFFFFFF00;
- break;
- }
- default:break;
- }
- }
- #elif 1
- uint32_t CRC_Result, DataBuf[65];
- uint8_t PakageNum, i;
-
- PakageNum = Length / 4;
- //数据组包成32bit,最后一包存储CRC校验结果
- for(i=0; i<PakageNum; i++)
- {
- DataBuf[i] = (Data[4 * i + 0] << 24) + (Data[4 * i + 1] << 16) + (Data[4 * i + 2] << 8) + Data[4 * i + 3];
- }
- CRC_Result = CRC32_Calculate(Data, Length);
- DataBuf[PakageNum] = CRC_Result;
- #endif
-
- //存储数据
- FLASH_Write(FlashAddress, DataBuf, PakageNum + 1);
- }
- static void CopyDataToEEPROM(TrueOrFalse_Flag_Struct_t Flag_FirstPowerOn)
- {
- uint8_t Flag[4] = {0x55,0xAA,0x55,0xAA};
- uint32_t Flag_32[2];
- //Flash页擦除
- EEPROM_Erase();
-
- //默认值初始化,未初始化部分存储随机值
- if(Flag_FirstPowerOn == TRUE)
- {
- PBU_ConfigParam.GearsNum = 4; //PBU配置参数
- PBU_ConfigParam.RatedVoltage = 1; //0-24 1-36 2-48
- PBU_ConfigParam.NoHMI_Flag = 0xAA;
- strcpy(PBU_VerInfo.Mode, (char*)"CN300 & CN301. "); //型号
- strcpy(PBU_VerInfo.SN_Num, (char*)"0000000000. ");//序列号
- strcpy(PBU_MacInfo.Manufacturer, (char*)"TTIUM. "); //生产信息
- strcpy(PBU_MacInfo.MacAddr, (char*)"WUHAN. ");
- strcpy(PBU_MacInfo.MacDate, (char*)"20191016");
- PBU_RunLog.PowerOnCnt = 0; //历史信息
- PBU_RunLog.RunTime = 0;
- }
-
- //写入数据
- SaveDataToEEPROM(EEPROM_CHECK_CODE_ADDR_OFFSET, PBU_CheckInfo.CheckCode, 12);//存储校验码
- SaveDataToEEPROM(EEPROM_USER_PARAM_ADDR_OFFSET, &(PBU_ConfigParam.RatedVoltage),16);//存储出厂参数
- SaveDataToEEPROM(EEPROM_MODE_ADDR_OFFSET, (uint8_t*)PBU_VerInfo.Mode, 16);//存储型号信息
- SaveDataToEEPROM(EEPROM_SN_ADDR_OFFSET, (uint8_t*)PBU_VerInfo.SN_Num,16);//存储序列号
- SaveDataToEEPROM(EEPROM_MAC_INFO_ADDR_OFFSET, (uint8_t*)PBU_MacInfo.Manufacturer, 32);//存储生产信息
- SaveDataToEEPROM(EEPROM_LOG_INFO_ADDR_OFFSET, (uint8_t*)&PBU_RunLog.RunTime, 16);//存储历史信息
- SaveDataToEEPROM(EEPROM_USER_INFO1_ADDR_OFFSET,(uint8_t*)UserString1, 16);//用户自定义字符串1
- SaveDataToEEPROM(EEPROM_USER_INFO2_ADDR_OFFSET,(uint8_t*)UserString2, 16);//用户自定义字符串1
- SaveDataToEEPROM(EEPROM_USER_INFO3_ADDR_OFFSET,(uint8_t*)UserString3, 16);//用户自定义字符串1
- //写入标志
- Flag_32[0] = (Flag[0] << 24) + (Flag[1] << 16) + (Flag[2] << 8) + Flag[3];
- Flag_32[1] = CRC32_Calculate(Flag, 4);
- FLASH_Write(EEPROM_FLAG_ADDR_OFFSET, Flag_32, 2);
- }
- static int8_t ReadDataFromEEPROM(uint32_t FlashAddress, uint8_t* Data, uint8_t Length) // Length必须为4的倍数
- {
- uint32_t DataTemp32[8], CRC_Data, CRC_Result;
- uint8_t CRC_Buf[40], i;
-
- Length = Length >> 2;//按照32bit读取
- for(i=0; i<Length; i++)
- {
- DataTemp32[i] = *(__IO uint32_t*)(FlashAddress + i * 4);
- CRC_Buf[4 * i] = (uint8_t)((DataTemp32[i] >> 24) & 0xFF);
- CRC_Buf[4 * i + 1] = (uint8_t)((DataTemp32[i] >> 16) & 0xFF);
- CRC_Buf[4 * i + 2] = (uint8_t)((DataTemp32[i] >> 8) & 0xFF);
- CRC_Buf[4 * i + 3] = (uint8_t)(DataTemp32[i] & 0xFF);
- }
- CRC_Data = *(__IO uint32_t*)(FlashAddress + Length * 4);
- CRC_Result = CRC32_Calculate(CRC_Buf, i * 4);
-
- if((CRC_Data - CRC_Result) == 0)
- {
- memcpy(Data, CRC_Buf, Length * 4);
- return 0;
- }
- else
- {
- return -1;
- }
- }
- static void CopyDataFromEEPROM(void)
- {
- uint8_t Data_Buf[40];
- int8_t Error_OK;
-
- //读取校验码
- Error_OK = ReadDataFromEEPROM(EEPROM_CHECK_CODE_ADDR_OFFSET, Data_Buf, 12);
- if(Error_OK == 0)
- {
- memcpy(PBU_CheckInfo.CheckCode, Data_Buf, 12);
- }
- //读取出厂参数
- Error_OK = ReadDataFromEEPROM(EEPROM_USER_PARAM_ADDR_OFFSET, Data_Buf, 16);
- if(Error_OK == 0)
- {
- memcpy(&(PBU_ConfigParam.RatedVoltage), Data_Buf, 16);
- }
- else
- {
- PBU_ConfigParam.RatedVoltage = 1; //0-24 1-36 2-48
- PBU_ConfigParam.GearsNum = 4;
- }
- //读取型号
- Error_OK = ReadDataFromEEPROM(EEPROM_MODE_ADDR_OFFSET, Data_Buf, 16);
- if(Error_OK == 0)
- {
- memcpy(PBU_VerInfo.Mode, Data_Buf, 16);
- }
- //读取序列号
- Error_OK = ReadDataFromEEPROM(EEPROM_SN_ADDR_OFFSET, Data_Buf, 16);
- if(Error_OK == 0)
- {
- memcpy(PBU_VerInfo.SN_Num, Data_Buf, 16);
- }
- //读取生产信息
- Error_OK = ReadDataFromEEPROM(EEPROM_MAC_INFO_ADDR_OFFSET, Data_Buf, 32);
- if(Error_OK == 0)
- {
- memcpy(PBU_MacInfo.Manufacturer, Data_Buf, 32);
- }
- //读取历史信息
- Error_OK = ReadDataFromEEPROM(EEPROM_LOG_INFO_ADDR_OFFSET, Data_Buf, 16);
- if(Error_OK == 0)
- {
- #if 0 //Flash存储低位在前,不能直接赋值
- memcpy(&(PBU_RunLog.RunTime), Data_Buf, 16);
- #elif 1
- PBU_RunLog.RunTime = Data_Buf[0] + (Data_Buf[1] << 8 ) + (Data_Buf[2] << 16 ) + (Data_Buf[3] << 24 );
- PBU_RunLog.PowerOnCnt = Data_Buf[4] + (Data_Buf[5] << 8 ) + (Data_Buf[6] << 16 ) + (Data_Buf[7] << 24 );
- #endif
- }
- //读取自定义字符串1
- Error_OK = ReadDataFromEEPROM(EEPROM_USER_INFO1_ADDR_OFFSET, Data_Buf, 16);
- if(Error_OK == 0)
- {
- memcpy(&UserString1, Data_Buf, 16);
- }
- //读取自定义字符串2
- Error_OK = ReadDataFromEEPROM(EEPROM_USER_INFO2_ADDR_OFFSET, Data_Buf, 16);
- if(Error_OK == 0)
- {
- memcpy(&UserString2, Data_Buf, 16);
- }
- //读取自定义字符串3
- Error_OK = ReadDataFromEEPROM(EEPROM_USER_INFO3_ADDR_OFFSET, Data_Buf, 16);
- if(Error_OK == 0)
- {
- memcpy(&UserString3, Data_Buf, 16);
- }
- }
- void EEPROM_Check(void)
- {
- uint8_t DataBuf[4];
- uint32_t Flag, FlagCrc, FlagResult;
-
- //读标志位
- Flag = *(__IO uint32_t*)(EEPROM_FLAG_ADDR_OFFSET);
- //读校验位
- FlagCrc = *(__IO uint32_t*)(EEPROM_FLAG_ADDR_OFFSET + 4);
-
- DataBuf[0] = Flag >> 24;
- DataBuf[1] = Flag >> 16;
- DataBuf[2] = Flag >> 8;
- DataBuf[3] = Flag & 0xFF;
-
- FlagResult = CRC32_Calculate(DataBuf, 4);
-
- //判断数据是否有效
- if((FlagResult - FlagCrc) == 0)//数据有效
- {
- CopyDataFromEEPROM();
- IsFirstPowerOn = FALSE;
- }
- else//数据无效
- {
- IsFirstPowerOn = TRUE;
- CopyDataToEEPROM(IsFirstPowerOn);
- }
- }
- void EEPROM_DataUpdate(void)
- {
- CopyDataToEEPROM(IsFirstPowerOn);
- }
|