eeprom.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. #include "eeprom.h"
  2. FLASH_EraseInitTypeDef EEPROM_AreaEraseInitStruct;
  3. TrueOrFalse_Flag_Struct_t IsFirstPowerOn;
  4. static void EEPROM_Erase(void)
  5. {
  6. uint32_t PageError;
  7. EEPROM_AreaEraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
  8. EEPROM_AreaEraseInitStruct.PageAddress = EEPROM_BEGIN_ADDRESS;
  9. EEPROM_AreaEraseInitStruct.NbPages = 1;
  10. HAL_FLASH_Unlock();
  11. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
  12. HAL_FLASHEx_Erase(&EEPROM_AreaEraseInitStruct, &PageError);
  13. HAL_FLASH_Lock();
  14. HAL_Delay(100);
  15. }
  16. static void FLASH_Write(uint32_t FlashAddress, uint32_t* Data, uint16_t DataLength)
  17. {
  18. uint32_t i = 0;
  19. HAL_FLASH_Unlock();
  20. for (i = 0; (i < DataLength) && (FlashAddress <= (EEPROM_END_ADDRESS-4)); i++)
  21. {
  22. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FlashAddress, *(uint32_t*)(Data + i)) == HAL_OK)
  23. {
  24. FlashAddress += 4;
  25. }
  26. else
  27. {
  28. // Error occurred while writing data in Flash memory
  29. return;
  30. }
  31. }
  32. HAL_FLASH_Lock();
  33. return;
  34. }
  35. static void SaveDataToEEPROM(uint32_t FlashAddress, uint8_t* Data, uint8_t Length) // Length必须为4的倍数
  36. {
  37. #if 0
  38. uint32_t CRC_Result, DataBuf[64];
  39. uint8_t PakageNum, LastPakageNum, i;
  40. LastPakageNum = Length % 4;//组合成32bit数据,最后一包数据个数
  41. //数据组包成32bit
  42. if(LastPakageNum == 0)
  43. {
  44. PakageNum = Length / 4;
  45. for(i=0; i<PakageNum; i++)
  46. {
  47. DataBuf[i] = (Data[4 * i + 0] << 24) + (Data[4 * i + 1] << 16) + (Data[4 * i + 2] << 8) + Data[4 * i + 3];
  48. }
  49. CRC_Result = CRC32_Calculate(Data, Length);
  50. }
  51. else
  52. {
  53. PakageNum = Length / 4 + 1;
  54. PakageNum = Length / 4;
  55. for(i=0; i<(PakageNum - 1); i++)
  56. {
  57. DataBuf[i] = (Data[4 * i + 0] << 24) + (Data[4 * i + 1] << 16) + (Data[4 * i + 2] << 8) + Data[4 * i + 3];
  58. }
  59. switch(LastPakageNum)
  60. {
  61. case 1:
  62. {
  63. DataBuf[PakageNum - 1] = (DataBuf[Length - 1] << 24) & 0xFF000000;
  64. break;
  65. }
  66. case 2:
  67. {
  68. DataBuf[PakageNum - 1] = ((DataBuf[Length - 2] << 24) + (DataBuf[Length - 1] << 16)) & 0xFFFF0000;
  69. break;
  70. }
  71. case 3:
  72. {
  73. DataBuf[PakageNum - 1] = ((DataBuf[Length - 3] << 24) + (DataBuf[Length - 2] << 16) + (DataBuf[Length - 1] << 8)) & 0xFFFFFF00;
  74. break;
  75. }
  76. default:break;
  77. }
  78. }
  79. #elif 1
  80. uint32_t CRC_Result, DataBuf[65];
  81. uint8_t PakageNum, i;
  82. PakageNum = Length / 4;
  83. //数据组包成32bit,最后一包存储CRC校验结果
  84. for(i=0; i<PakageNum; i++)
  85. {
  86. DataBuf[i] = (Data[4 * i + 0] << 24) + (Data[4 * i + 1] << 16) + (Data[4 * i + 2] << 8) + Data[4 * i + 3];
  87. }
  88. CRC_Result = CRC32_Calculate(Data, Length);
  89. DataBuf[PakageNum] = CRC_Result;
  90. #endif
  91. //存储数据
  92. FLASH_Write(FlashAddress, DataBuf, PakageNum + 1);
  93. }
  94. static void CopyDataToEEPROM(TrueOrFalse_Flag_Struct_t Flag_FirstPowerOn)
  95. {
  96. uint8_t Flag[4] = {0x55,0xAA,0x55,0xAA};
  97. uint32_t Flag_32[2];
  98. //Flash页擦除
  99. EEPROM_Erase();
  100. //默认值初始化,未初始化部分存储随机值
  101. if(Flag_FirstPowerOn == TRUE)
  102. {
  103. PBU_ConfigParam.GearsNum = 4; //PBU配置参数
  104. PBU_ConfigParam.RatedVoltage = 1; //0-24 1-36 2-48
  105. PBU_ConfigParam.NoHMI_Flag = 0xAA;
  106. strcpy(PBU_VerInfo.Mode, (char*)"CN304. "); //型号
  107. strcpy(PBU_VerInfo.SN_Num, (char*)"0000000000. ");//序列号
  108. strcpy(PBU_MacInfo.Manufacturer, (char*)"TTIUM. "); //生产信息
  109. strcpy(PBU_MacInfo.MacAddr, (char*)"WUHAN. ");
  110. strcpy(PBU_MacInfo.MacDate, (char*)"20191016");
  111. PBU_RunLog.PowerOnCnt = 0; //历史信息
  112. PBU_RunLog.RunTime = 0;
  113. }
  114. //写入数据
  115. SaveDataToEEPROM(EEPROM_CHECK_CODE_ADDR_OFFSET, PBU_CheckInfo.CheckCode, 12);//存储校验码
  116. SaveDataToEEPROM(EEPROM_USER_PARAM_ADDR_OFFSET, &(PBU_ConfigParam.RatedVoltage),16);//存储出厂参数
  117. SaveDataToEEPROM(EEPROM_MODE_ADDR_OFFSET, (uint8_t*)PBU_VerInfo.Mode, 16);//存储型号信息
  118. SaveDataToEEPROM(EEPROM_SN_ADDR_OFFSET, (uint8_t*)PBU_VerInfo.SN_Num,16);//存储序列号
  119. SaveDataToEEPROM(EEPROM_MAC_INFO_ADDR_OFFSET, (uint8_t*)PBU_MacInfo.Manufacturer, 32);//存储生产信息
  120. SaveDataToEEPROM(EEPROM_LOG_INFO_ADDR_OFFSET, (uint8_t*)&PBU_RunLog.RunTime, 16);//存储历史信息
  121. SaveDataToEEPROM(EEPROM_USER_INFO1_ADDR_OFFSET,(uint8_t*)UserString1, 16);//用户自定义字符串1
  122. SaveDataToEEPROM(EEPROM_USER_INFO2_ADDR_OFFSET,(uint8_t*)UserString2, 16);//用户自定义字符串1
  123. SaveDataToEEPROM(EEPROM_USER_INFO3_ADDR_OFFSET,(uint8_t*)UserString3, 16);//用户自定义字符串1
  124. //写入标志
  125. Flag_32[0] = (Flag[0] << 24) + (Flag[1] << 16) + (Flag[2] << 8) + Flag[3];
  126. Flag_32[1] = CRC32_Calculate(Flag, 4);
  127. FLASH_Write(EEPROM_FLAG_ADDR_OFFSET, Flag_32, 2);
  128. }
  129. static int8_t ReadDataFromEEPROM(uint32_t FlashAddress, uint8_t* Data, uint8_t Length) // Length必须为4的倍数
  130. {
  131. uint32_t DataTemp32[8], CRC_Data, CRC_Result;
  132. uint8_t CRC_Buf[40], i;
  133. Length = Length >> 2;//按照32bit读取
  134. for(i=0; i<Length; i++)
  135. {
  136. DataTemp32[i] = *(__IO uint32_t*)(FlashAddress + i * 4);
  137. CRC_Buf[4 * i] = (uint8_t)((DataTemp32[i] >> 24) & 0xFF);
  138. CRC_Buf[4 * i + 1] = (uint8_t)((DataTemp32[i] >> 16) & 0xFF);
  139. CRC_Buf[4 * i + 2] = (uint8_t)((DataTemp32[i] >> 8) & 0xFF);
  140. CRC_Buf[4 * i + 3] = (uint8_t)(DataTemp32[i] & 0xFF);
  141. }
  142. CRC_Data = *(__IO uint32_t*)(FlashAddress + Length * 4);
  143. CRC_Result = CRC32_Calculate(CRC_Buf, i * 4);
  144. if((CRC_Data - CRC_Result) == 0)
  145. {
  146. memcpy(Data, CRC_Buf, Length * 4);
  147. return 0;
  148. }
  149. else
  150. {
  151. return -1;
  152. }
  153. }
  154. static void CopyDataFromEEPROM(void)
  155. {
  156. uint8_t Data_Buf[40];
  157. int8_t Error_OK;
  158. //读取校验码
  159. Error_OK = ReadDataFromEEPROM(EEPROM_CHECK_CODE_ADDR_OFFSET, Data_Buf, 12);
  160. if(Error_OK == 0)
  161. {
  162. memcpy(PBU_CheckInfo.CheckCode, Data_Buf, 12);
  163. }
  164. //读取出厂参数
  165. Error_OK = ReadDataFromEEPROM(EEPROM_USER_PARAM_ADDR_OFFSET, Data_Buf, 16);
  166. if(Error_OK == 0)
  167. {
  168. memcpy(&(PBU_ConfigParam.RatedVoltage), Data_Buf, 16);
  169. }
  170. else
  171. {
  172. PBU_ConfigParam.RatedVoltage = 1; //0-24 1-36 2-48
  173. PBU_ConfigParam.GearsNum = 4;
  174. }
  175. //读取型号
  176. Error_OK = ReadDataFromEEPROM(EEPROM_MODE_ADDR_OFFSET, Data_Buf, 16);
  177. if(Error_OK == 0)
  178. {
  179. memcpy(PBU_VerInfo.Mode, Data_Buf, 16);
  180. }
  181. //读取序列号
  182. Error_OK = ReadDataFromEEPROM(EEPROM_SN_ADDR_OFFSET, Data_Buf, 16);
  183. if(Error_OK == 0)
  184. {
  185. memcpy(PBU_VerInfo.SN_Num, Data_Buf, 16);
  186. }
  187. //读取生产信息
  188. Error_OK = ReadDataFromEEPROM(EEPROM_MAC_INFO_ADDR_OFFSET, Data_Buf, 32);
  189. if(Error_OK == 0)
  190. {
  191. memcpy(PBU_MacInfo.Manufacturer, Data_Buf, 32);
  192. }
  193. //读取历史信息
  194. Error_OK = ReadDataFromEEPROM(EEPROM_LOG_INFO_ADDR_OFFSET, Data_Buf, 16);
  195. if(Error_OK == 0)
  196. {
  197. PBU_RunLog.RunTime = Data_Buf[0] + (Data_Buf[1] << 8 ) + (Data_Buf[2] << 16 ) + (Data_Buf[3] << 24 );
  198. PBU_RunLog.PowerOnCnt = Data_Buf[4] + (Data_Buf[5] << 8 ) + (Data_Buf[6] << 16 ) + (Data_Buf[7] << 24 );
  199. PBU_RunLog.PowerOnCnt += 1;
  200. }
  201. //读取自定义字符串1
  202. Error_OK = ReadDataFromEEPROM(EEPROM_USER_INFO1_ADDR_OFFSET, Data_Buf, 16);
  203. if(Error_OK == 0)
  204. {
  205. memcpy(&UserString1, Data_Buf, 16);
  206. }
  207. //读取自定义字符串2
  208. Error_OK = ReadDataFromEEPROM(EEPROM_USER_INFO2_ADDR_OFFSET, Data_Buf, 16);
  209. if(Error_OK == 0)
  210. {
  211. memcpy(&UserString2, Data_Buf, 16);
  212. }
  213. //读取自定义字符串3
  214. Error_OK = ReadDataFromEEPROM(EEPROM_USER_INFO3_ADDR_OFFSET, Data_Buf, 16);
  215. if(Error_OK == 0)
  216. {
  217. memcpy(&UserString3, Data_Buf, 16);
  218. }
  219. }
  220. void EEPROM_Check(void)
  221. {
  222. uint8_t DataBuf[4];
  223. uint32_t Flag, FlagCrc, FlagResult;
  224. //读标志位
  225. Flag = *(__IO uint32_t*)(EEPROM_FLAG_ADDR_OFFSET);
  226. //读校验位
  227. FlagCrc = *(__IO uint32_t*)(EEPROM_FLAG_ADDR_OFFSET + 4);
  228. DataBuf[0] = Flag >> 24;
  229. DataBuf[1] = Flag >> 16;
  230. DataBuf[2] = Flag >> 8;
  231. DataBuf[3] = Flag & 0xFF;
  232. FlagResult = CRC32_Calculate(DataBuf, 4);
  233. //判断数据是否有效
  234. if((FlagResult - FlagCrc) == 0)//数据有效
  235. {
  236. CopyDataFromEEPROM();
  237. IsFirstPowerOn = FALSE;
  238. }
  239. else//数据无效
  240. {
  241. IsFirstPowerOn = TRUE;
  242. CopyDataToEEPROM(IsFirstPowerOn);
  243. }
  244. }
  245. void EEPROM_DataUpdate(void)
  246. {
  247. CopyDataToEEPROM(IsFirstPowerOn);
  248. }