FLASH.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. #include "FLASH.h"
  2. #include "calib_piecewise_linear.h"
  3. #include "usart.h"
  4. #include "cmsis_os.h"
  5. #include "stdio.h"
  6. #include <string.h> // 包含 strlen 的头文件
  7. /*************下面所有的数都必须是4字节对齐的******************/
  8. /***************************************************************
  9. * 函数名称: Flash_GetBank
  10. * 说 明: 获得传入地址所在Bank
  11. * 参 数: faddr,Flash地址
  12. * 返 回 值: Bank值
  13. ***************************************************************/
  14. uint32_t Flash_GetBank(uint32_t faddr)
  15. {
  16. if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_MEM_MODE_Pos) == 0)
  17. {
  18. if (faddr < (FLASH_BASE + FLASH_BANK_SIZE))
  19. return FLASH_BANK_1;
  20. else
  21. return FLASH_BANK_1;
  22. }
  23. else
  24. {
  25. if (faddr < (FLASH_BASE + FLASH_BANK_SIZE)) // bank swap
  26. return FLASH_BANK_1;
  27. else
  28. return FLASH_BANK_1;
  29. }
  30. }
  31. /***************************************************************
  32. * 函数名称: Flash_GetPage
  33. * 说 明: 获得传入地址所在Page
  34. * 参 数: faddr,Flash地址
  35. * 返 回 值: Bank值 双Bank STM32L431CCT6只有一个Bank
  36. ***************************************************************/
  37. //uint32_t Flash_GetPage(uint32_t faddr) // 双Bank
  38. //{
  39. // if (faddr < (FLASH_BASE + FLASH_BANK_SIZE))
  40. // return (faddr - FLASH_BASE) / FLASH_PAGE_SIZE;
  41. // else
  42. // return (faddr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE;
  43. //}
  44. uint32_t Flash_GetPage(uint32_t faddr) // 单Bank
  45. {
  46. return (faddr - FLASH_BASE) / FLASH_PAGE_SIZE;
  47. }
  48. /***************************************************************
  49. * 函数名称: Flash_ReadOneWord
  50. * 说 明: 从指定地址中读取一个32位的数据
  51. * 参 数: faddr,Flash地址
  52. * 返 回 值: Flash地址内的一个32位的数据
  53. ***************************************************************/
  54. uint32_t Flash_ReadOneWord(uint32_t faddr)
  55. {
  56. return *(__IO uint32_t *)faddr;
  57. }
  58. /***************************************************************
  59. * 函数名称: Flash_ErasePages
  60. * 说 明: 擦除页
  61. * 参 数: faddr,起始地址
  62. * fdataNum,要擦除的字节数,实际上也是整页擦除
  63. * 返 回 值: 无
  64. ***************************************************************/
  65. void Flash_ErasePages(uint32_t faddr,uint32_t fdataNum)
  66. {
  67. // 连续擦除多个页(按字数计算)
  68. if(fdataNum == 0||faddr>FLASH_ADDR_MAX)
  69. {
  70. return;
  71. }
  72. uint32_t PageError = 0;
  73. HAL_FLASH_Unlock();
  74. FLASH_EraseInitTypeDef FLASH_EraseInitSturcture;
  75. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
  76. FLASH_EraseInitSturcture.TypeErase = FLASH_TYPEERASE_PAGES;
  77. FLASH_EraseInitSturcture.Banks = Flash_GetBank(faddr);
  78. FLASH_EraseInitSturcture.Page = Flash_GetPage(faddr);
  79. FLASH_EraseInitSturcture.NbPages = Flash_GetPage(faddr + 4 * fdataNum - 1) - FLASH_EraseInitSturcture.Page + 1;
  80. if(HAL_FLASHEx_Erase(&FLASH_EraseInitSturcture,&PageError) != HAL_OK)
  81. {
  82. HAL_FLASH_Lock();
  83. return;
  84. }
  85. }
  86. /***************************************************************
  87. * 函数名称: Flash_WriteOneWord
  88. * 说 明: 向指定地址中写入一个32位的数据
  89. * 参 数: faddr,Flash地址
  90. * fdata32,Flash地址内的一个32位的数据
  91. * 返 回 值: 写FLASH返回的状态
  92. ***************************************************************/
  93. uint8_t Flash_WriteOneWord(uint32_t faddr,uint32_t fdata32)
  94. {
  95. if(faddr<FLASH_BASE) //非法地址
  96. return HAL_ERROR;
  97. uint8_t FLASH_STATUS;
  98. uint64_t fdata64;
  99. HAL_FLASH_Unlock();
  100. if(faddr<FLASH_ADDR_MAX) //写入数据地址小于STM32L431RC的flash地址最大值
  101. {
  102. fdata64 = fdata32|0xffffffff00000000uL;
  103. FLASH_STATUS = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,faddr,fdata64);//写入数据
  104. }
  105. HAL_FLASH_Lock();
  106. return FLASH_STATUS;
  107. }
  108. /***************************************************************
  109. * 函数名称: Flash_WriteDoubleWord
  110. * 说 明: 向指定地址中写入一个双字(64位)数据
  111. * 参 数: faddr,Flash地址
  112. * fdata64,Flash地址内的一个双字(64位)数据
  113. * 返 回 值: 写FLASH返回的状态
  114. ***************************************************************/
  115. uint8_t Flash_WriteDoubleWord(uint32_t faddr,uint64_t fdata64)
  116. {
  117. if(faddr<FLASH_BASE) //非法地址
  118. return HAL_ERROR;
  119. uint8_t FLASH_STATUS;
  120. HAL_FLASH_Unlock(); //解锁FLASH
  121. if(faddr<FLASH_ADDR_MAX) //写入数据地址小于STM32L431RC的flash地址最大值
  122. {
  123. FLASH_STATUS = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,faddr,fdata64);//写入数据
  124. }
  125. HAL_FLASH_Lock(); //上锁
  126. return FLASH_STATUS;
  127. }
  128. /***************************************************************
  129. * 函数名称: Flash_Write32
  130. * 说 明: 向指定地址中写入fdataNum个32位的数据
  131. * 参 数: faddr,Flash起始地址
  132. * fdata,Flash地址内的32位的数据指针
  133. * fdata32Num,要写入的字(32位)数的数量
  134. * 返 回 值: 无
  135. ***************************************************************/
  136. void Flash_Write32(uint32_t faddr,uint32_t *fdata32, uint32_t fdata32Num) // 写入函数里没有擦除,调用的时候记得先擦除再写入
  137. {
  138. uint64_t fdata64;
  139. HAL_FLASH_Unlock(); //解锁FLASH
  140. if(faddr<FLASH_ADDR_MAX) //写入数据地址小于STM32L431RC的flash地址最大值
  141. {
  142. for (uint32_t i = 0; i < fdata32Num / 2; i++)
  143. {
  144. fdata64 = *(uint64_t*)fdata32;
  145. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, faddr, fdata64) != HAL_OK)
  146. { //如果出现错误
  147. HAL_FLASH_Lock(); //锁定FLASH
  148. return;
  149. }
  150. faddr += 8;
  151. fdata32 += 2;
  152. }
  153. if ((fdata32Num & 0x01) == 1)
  154. {
  155. uint64_t fdata64 = *(uint64_t*)faddr;
  156. fdata64 = (fdata64 & 0xffffffff00000000uL) | (*fdata32);
  157. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, faddr, fdata64) != HAL_OK)
  158. { //如果出现错误
  159. HAL_FLASH_Lock(); //锁定FLASH
  160. return;
  161. }
  162. }
  163. }
  164. HAL_FLASH_Lock();
  165. }
  166. /***************************************************************
  167. * 函数名称: Flash_Write64
  168. * 说 明: 向指定地址中写入fdataNum个64位的数据
  169. * 参 数: faddr,Flash起始地址
  170. * fdata,Flash地址内的64位的数据指针
  171. * fdata64Num,要写入的字(64位)数的数量
  172. * 返 回 值: 无
  173. ***************************************************************/
  174. void Flash_Write64(uint32_t faddr,uint64_t *fdata64, uint32_t fdata64Num)
  175. {
  176. // 写入订场结构体或数组 直接写 uint64_t[]
  177. HAL_FLASH_Unlock(); //解锁FLASH
  178. if(faddr<FLASH_ADDR_MAX) //写入数据地址小于STM32L431RC的flash地址最大值
  179. {
  180. for (uint32_t i = 0; i < fdata64Num; i++)
  181. {
  182. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, faddr, *fdata64) != HAL_OK)
  183. { //如果写入异常
  184. HAL_FLASH_Lock(); //上锁FLASH
  185. return;
  186. }
  187. faddr += 8;
  188. fdata64 += 1;
  189. }
  190. }
  191. HAL_FLASH_Lock(); //上锁FLASH
  192. }
  193. /***************************************************************
  194. * 函数名称: Flash_Read32
  195. * 说 明: 从指定地址开始读出指定长度的数据
  196. * 参 数: ReadAddr,起始地址
  197. * *pBuffer,数据指针
  198. * fdata32Num,字(32位)数
  199. * 返 回 值: 无
  200. ***************************************************************/
  201. void Flash_Read32(uint32_t faddr,uint32_t *fdata32,uint32_t fdata32Num)
  202. {
  203. uint32_t i;
  204. if(faddr>FLASH_ADDR_MAX) //地址小于STM32L431RC的flash地址最大值
  205. return;
  206. for(i=0;i<fdata32Num;i++)
  207. {
  208. fdata32[i] = Flash_ReadOneWord(faddr); //读取4个字节
  209. // DEBUG_PRINTF("Read Flash Addr: 0x%08X, Data: 0x%08X\r\n", (unsigned int)faddr, (unsigned int)fdata32[i]);
  210. faddr+=4;
  211. }
  212. }
  213. /***************************************************************
  214. * 函数名称: FlashRead
  215. * 说 明: 从指定地址开始读出指定长度的数据
  216. * 参 数: ReadAddr,起始地址
  217. * *pBuffer,数据指针
  218. * fdata8Num,字(8位)数
  219. * 返 回 值: 无
  220. ***************************************************************/
  221. void Flash_ReadBytes(uint32_t faddr,uint8_t *fdata8,uint32_t fdata8Num)
  222. {
  223. uint32_t i;
  224. if(faddr>FLASH_ADDR_MAX) //地址小于STM32L431的flash地址最大值
  225. return;
  226. for(i=0;i<fdata8Num;i++)
  227. {
  228. fdata8[i] = *(__IO uint8_t *)faddr; //读取1个字节
  229. faddr+=1;
  230. }
  231. }
  232. void Flash_ReadBytesto32(uint32_t faddr, uint8_t *fdata8, uint32_t fdata8Num) {
  233. if (faddr > FLASH_ADDR_MAX || (faddr % 4 != 0)) { // 检查地址对齐
  234. return;
  235. }
  236. uint32_t *pSrc = (uint32_t *)faddr;
  237. uint32_t *pDest = (uint32_t *)fdata8;
  238. uint32_t wordNum = (fdata8Num + 3) / 4; // 转换为32位字数
  239. for (uint32_t i = 0; i < wordNum; i++) {
  240. pDest[i] = pSrc[i]; // 按32位读取,避免字节访问异常
  241. }
  242. }
  243. /***************************************************************
  244. * 函数名称: Flash_WriteRead
  245. * 说 明: Flash数据写入、读取测试
  246. * 参 数: fAdress,flash地址
  247. * *wData,向flash地址里写入的数据
  248. * wDataLen,写入数据的长度
  249. * *rData,从flash地址里读出的数据
  250. * 返 回 值: ERROR,失败
  251. * SUCCESS,成功
  252. ***************************************************************/
  253. uint8_t Flash_WriteRead(uint32_t fAdress, uint8_t *wData, uint32_t wDataLen, uint8_t *rData)
  254. {
  255. char str_adc_vol[200];
  256. char str_read_vol[200];
  257. if (wData == NULL)
  258. {
  259. return ERROR;
  260. }
  261. uint16_t strWriteLen = (wDataLen % 4) == 0 ? (wDataLen / 4) : (wDataLen / 4 + 1);
  262. // 将 wData 转换为十六进制字符串
  263. str_adc_vol[0] = '\0';
  264. for (uint32_t i = 0; i < wDataLen; i++)
  265. {
  266. sprintf(str_adc_vol + strlen(str_adc_vol), "%02X ", wData[i]);
  267. }
  268. // DEBUG_PRINTF("Flash_Write32: %s\r\n", str_adc_vol);
  269. Flash_ErasePages(fAdress, 1); // 擦除flash
  270. Flash_Write32(fAdress, (uint32_t *)wData, strWriteLen); // 写入数据
  271. Flash_ReadBytes(fAdress,rData, wDataLen); // 读出数据
  272. // 将 rData 转换为十六进制字符串
  273. str_read_vol[0] = '\0';
  274. for (uint32_t i = 0; i < wDataLen; i++)
  275. {
  276. sprintf(str_read_vol + strlen(str_read_vol), "%02X ", rData[i]);
  277. }
  278. // DEBUG_PRINTF("Flash_ReadBytes: %s\r\n", str_read_vol);
  279. return SUCCESS;
  280. }
  281. /****************************************************************************************/
  282. /* 分段线性插值 */
  283. //void Save_CalibPoints_ToFlash(void)
  284. //{
  285. // Flash_ErasePages(CALIB_PARAM_ADDR, sizeof(CalibPoints_t));
  286. // Flash_Write32(CALIB_PARAM_ADDR, (uint32_t *)&g_calibPoints, sizeof(CalibPoints_t) / sizeof(uint32_t));
  287. //}
  288. //void Load_CalibPoints_FromFlash(void)
  289. //{
  290. // CalibPoints_t CalibPoints_flashparams;
  291. // Flash_ReadBytesto32(CALIB_PARAM_ADDR, (uint8_t *)&CalibPoints_flashparams, sizeof(CalibPoints_t));
  292. // if (CalibPoints_flashparams.magic == CALIB_MAGIC) {
  293. // memcpy(g_calibPoints.cap_values, CalibPoints_flashparams.cap_values, sizeof(CalibPoints_flashparams.cap_values));
  294. // } else {
  295. // Load_Default_CalibPoints();
  296. // Save_CalibPoints_ToFlash();
  297. // }
  298. // print_calibPoints_params();
  299. //}
  300. void Save_Calib_residualheight_ToFlash(void)
  301. {
  302. // 余油标定值
  303. }
  304. void Save_Calib_rodvol_ToFlash(void)
  305. {
  306. // 阀杆标定值
  307. }
  308. /**********************END OF FILE**********************/