FLASH.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. #include "FLASH.h"
  2. #include "usart.h"
  3. #include "stdio.h"
  4. #include <string.h> // 包含 strlen 的头文件
  5. /*************下面所有的数都必须是4字节对齐的******************/
  6. extern uint32_t W25_Tempaddress;
  7. extern uint32_t wifior4G_flag;
  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值
  36. ***************************************************************/
  37. uint32_t Flash_GetPage(uint32_t faddr)
  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. /***************************************************************
  45. * 函数名称: Flash_ReadOneWord
  46. * 说 明: 从指定地址中读取一个32位的数据
  47. * 参 数: faddr,Flash地址
  48. * 返 回 值: Flash地址内的一个32位的数据
  49. ***************************************************************/
  50. uint32_t Flash_ReadOneWord(uint32_t faddr)
  51. {
  52. return *(__IO uint32_t *)faddr;
  53. }
  54. /***************************************************************
  55. * 函数名称: Flash_ErasePages
  56. * 说 明: 擦除页
  57. * 参 数: faddr,起始地址
  58. * fdataNum,要擦除的字数,实际上也是整页擦除
  59. * 返 回 值: 无
  60. ***************************************************************/
  61. void Flash_ErasePages(uint32_t faddr,uint32_t fdataNum)
  62. {
  63. if(fdataNum == 0||faddr>FLASH_ADDR_MAX)
  64. {
  65. return;
  66. }
  67. uint32_t PageError = 0;
  68. HAL_FLASH_Unlock();
  69. FLASH_EraseInitTypeDef FLASH_EraseInitSturcture;
  70. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
  71. FLASH_EraseInitSturcture.TypeErase = FLASH_TYPEERASE_PAGES;
  72. FLASH_EraseInitSturcture.Banks = Flash_GetBank(faddr);
  73. FLASH_EraseInitSturcture.Page = Flash_GetPage(faddr);
  74. FLASH_EraseInitSturcture.NbPages = Flash_GetPage(faddr + 4 * fdataNum - 1) - FLASH_EraseInitSturcture.Page + 1;
  75. if(HAL_FLASHEx_Erase(&FLASH_EraseInitSturcture,&PageError) != HAL_OK)
  76. {
  77. HAL_FLASH_Lock();
  78. return;
  79. }
  80. }
  81. /***************************************************************
  82. * 函数名称: Flash_WriteOneWord
  83. * 说 明: 向指定地址中写入一个32位的数据
  84. * 参 数: faddr,Flash地址
  85. * fdata32,Flash地址内的一个32位的数据
  86. * 返 回 值: 写FLASH返回的状态
  87. ***************************************************************/
  88. uint8_t Flash_WriteOneWord(uint32_t faddr,uint32_t fdata32)
  89. {
  90. if(faddr<FLASH_BASE) //非法地址
  91. return HAL_ERROR;
  92. uint8_t FLASH_STATUS;
  93. uint64_t fdata64;
  94. HAL_FLASH_Unlock();
  95. if(faddr<FLASH_ADDR_MAX) //写入数据地址小于STM32L431RC的flash地址最大值
  96. {
  97. fdata64 = fdata32|0xffffffff00000000uL;
  98. FLASH_STATUS = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,faddr,fdata64);//写入数据
  99. }
  100. HAL_FLASH_Lock();
  101. return FLASH_STATUS;
  102. }
  103. /***************************************************************
  104. * 函数名称: Flash_WriteDoubleWord
  105. * 说 明: 向指定地址中写入一个双字(64位)数据
  106. * 参 数: faddr,Flash地址
  107. * fdata64,Flash地址内的一个双字(64位)数据
  108. * 返 回 值: 写FLASH返回的状态
  109. ***************************************************************/
  110. uint8_t Flash_WriteDoubleWord(uint32_t faddr,uint64_t fdata64)
  111. {
  112. if(faddr<FLASH_BASE) //非法地址
  113. return HAL_ERROR;
  114. uint8_t FLASH_STATUS;
  115. HAL_FLASH_Unlock(); //解锁FLASH
  116. if(faddr<FLASH_ADDR_MAX) //写入数据地址小于STM32L431RC的flash地址最大值
  117. {
  118. FLASH_STATUS = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,faddr,fdata64);//写入数据
  119. }
  120. HAL_FLASH_Lock(); //上锁
  121. return FLASH_STATUS;
  122. }
  123. /***************************************************************
  124. * 函数名称: Flash_Write32
  125. * 说 明: 向指定地址中写入fdataNum个32位的数据
  126. * 参 数: faddr,Flash起始地址
  127. * fdata,Flash地址内的32位的数据指针
  128. * fdata32Num,要写入的字(32位)数的数量
  129. * 返 回 值: 无
  130. ***************************************************************/
  131. void Flash_Write32(uint32_t faddr,uint32_t *fdata32, uint32_t fdata32Num)
  132. {
  133. uint64_t fdata64;
  134. HAL_FLASH_Unlock(); //解锁FLASH
  135. if(faddr<FLASH_ADDR_MAX) //写入数据地址小于STM32L431RC的flash地址最大值
  136. {
  137. for (uint32_t i = 0; i < fdata32Num / 2; i++)
  138. {
  139. fdata64 = *(uint64_t*)fdata32;
  140. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, faddr, fdata64) != HAL_OK)
  141. { //如果出现错误
  142. HAL_FLASH_Lock(); //锁定FLASH
  143. return;
  144. }
  145. faddr += 8;
  146. fdata32 += 2;
  147. }
  148. if ((fdata32Num & 0x01) == 1)
  149. {
  150. uint64_t fdata64 = *(uint64_t*)faddr;
  151. fdata64 = (fdata64 & 0xffffffff00000000uL) | (*fdata32);
  152. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, faddr, fdata64) != HAL_OK)
  153. { //如果出现错误
  154. HAL_FLASH_Lock(); //锁定FLASH
  155. return;
  156. }
  157. }
  158. }
  159. HAL_FLASH_Lock();
  160. }
  161. /***************************************************************
  162. * 函数名称: Flash_Write64
  163. * 说 明: 向指定地址中写入fdataNum个64位的数据
  164. * 参 数: faddr,Flash起始地址
  165. * fdata,Flash地址内的64位的数据指针
  166. * fdata64Num,要写入的字(64位)数的数量
  167. * 返 回 值: 无
  168. ***************************************************************/
  169. void Flash_Write64(uint32_t faddr,uint64_t *fdata64, uint32_t fdata64Num)
  170. {
  171. HAL_FLASH_Unlock(); //解锁FLASH
  172. if(faddr<FLASH_ADDR_MAX) //写入数据地址小于STM32L431RC的flash地址最大值
  173. {
  174. for (uint32_t i = 0; i < fdata64Num; i++)
  175. {
  176. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, faddr, *fdata64) != HAL_OK)
  177. { //如果写入异常
  178. HAL_FLASH_Lock(); //上锁FLASH
  179. return;
  180. }
  181. faddr += 8;
  182. fdata64 += 1;
  183. }
  184. }
  185. HAL_FLASH_Lock(); //上锁FLASH
  186. }
  187. /***************************************************************
  188. * 函数名称: Flash_Read32
  189. * 说 明: 从指定地址开始读出指定长度的数据
  190. * 参 数: ReadAddr,起始地址
  191. * *pBuffer,数据指针
  192. * fdata32Num,字(32位)数
  193. * 返 回 值: 无
  194. ***************************************************************/
  195. void Flash_Read32(uint32_t faddr,uint32_t *fdata32,uint32_t fdata32Num)
  196. {
  197. uint32_t i;
  198. if(faddr>FLASH_ADDR_MAX) //地址小于STM32L431RC的flash地址最大值
  199. return;
  200. for(i=0;i<fdata32Num;i++)
  201. {
  202. fdata32[i] = Flash_ReadOneWord(faddr); //读取4个字节
  203. // printf("Read Flash Addr: 0x%08X, Data: 0x%08X\r\n", (unsigned int)faddr, (unsigned int)fdata32[i]);
  204. faddr+=4;
  205. }
  206. }
  207. /***************************************************************
  208. * 函数名称: FlashRead
  209. * 说 明: 从指定地址开始读出指定长度的数据
  210. * 参 数: ReadAddr,起始地址
  211. * *pBuffer,数据指针
  212. * fdata8Num,字(8位)数
  213. * 返 回 值: 无
  214. ***************************************************************/
  215. void Flash_ReadBytes(uint32_t faddr,uint8_t *fdata8,uint32_t fdata8Num)
  216. {
  217. uint32_t i;
  218. if(faddr>FLASH_ADDR_MAX) //地址小于STM32L431RC的flash地址最大值
  219. return;
  220. for(i=0;i<fdata8Num;i++)
  221. {
  222. fdata8[i] = *(__IO uint8_t *)faddr; //读取1个字节
  223. faddr+=1;
  224. }
  225. }
  226. /***************************************************************
  227. * 函数名称: Flash_WriteRead
  228. * 说 明: Flash数据写入、读取测试
  229. * 参 数: fAdress,flash地址
  230. * *wData,向flash地址里写入的数据
  231. * wDataLen,写入数据的长度
  232. * *rData,从flash地址里读出的数据
  233. * 返 回 值: ERROR,失败
  234. * SUCCESS,成功
  235. ***************************************************************/
  236. uint8_t Flash_WriteRead(uint32_t fAdress, uint8_t *wData, uint32_t wDataLen, uint8_t *rData)
  237. {
  238. char str_adc_vol[200];
  239. char str_read_vol[200];
  240. if (wData == NULL)
  241. {
  242. return ERROR;
  243. }
  244. uint16_t strWriteLen = (wDataLen % 4) == 0 ? (wDataLen / 4) : (wDataLen / 4 + 1);
  245. // 将 wData 转换为十六进制字符串
  246. str_adc_vol[0] = '\0';
  247. for (uint32_t i = 0; i < wDataLen; i++)
  248. {
  249. sprintf(str_adc_vol + strlen(str_adc_vol), "%02X ", wData[i]);
  250. }
  251. // printf("Flash_Write32: %s\r\n", str_adc_vol);
  252. Flash_ErasePages(fAdress, 1); // 擦除flash
  253. Flash_Write32(fAdress, (uint32_t *)wData, strWriteLen); // 写入数据
  254. Flash_ReadBytes(fAdress,rData, wDataLen); // 读出数据
  255. // 将 rData 转换为十六进制字符串
  256. str_read_vol[0] = '\0';
  257. for (uint32_t i = 0; i < wDataLen; i++)
  258. {
  259. sprintf(str_read_vol + strlen(str_read_vol), "%02X ", rData[i]);
  260. }
  261. // printf("Flash_ReadBytes: %s\r\n", str_read_vol);
  262. return SUCCESS;
  263. }
  264. void Load_W25_Tempaddress_From_Flash(void)
  265. {
  266. uint32_t temp;
  267. Flash_Read32(FLASH_THIRD_LAST_PAGE_ADDR, &temp, 1);
  268. W25_Tempaddress = temp;
  269. }
  270. void Load_version_From_Flash(void)
  271. {
  272. uint32_t version;
  273. Flash_Read32(FLASH_FOURTH_LAST_PAGE_ADDR, &version, 1);
  274. printf("Version 0x%04x\r\n",version);
  275. }
  276. void Read_wifior4G_flag_From_Flash(void)
  277. {
  278. uint32_t wifior4G_f;
  279. Flash_Read32(FLASH_SIXTH_LAST_PAGE_ADDR, &wifior4G_f, 1);
  280. wifior4G_flag = wifior4G_f;
  281. printf("wifior4G_flag 0x%04x\r\n",wifior4G_flag);
  282. }
  283. /**********************END OF FILE**********************/