drv_flash_f4.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-03-16 luobeihai first version
  9. */
  10. #include "board.h"
  11. #ifdef BSP_USING_ON_CHIP_FLASH
  12. #include "drv_flash.h"
  13. #if defined(RT_USING_FAL)
  14. #include "fal.h"
  15. #endif
  16. #define DRV_DEBUG
  17. #define LOG_TAG "drv.flash"
  18. #include <drv_log.h>
  19. /* Base address of the Flash sectors */
  20. #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
  21. #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
  22. #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
  23. #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
  24. #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
  25. #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
  26. #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */
  27. #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */
  28. #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */
  29. #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */
  30. #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
  31. #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
  32. /**
  33. * @brief Gets the sector of a given address
  34. * @param None
  35. * @retval The sector of a given address
  36. */
  37. static rt_uint32_t GetSector(rt_uint32_t Address)
  38. {
  39. rt_uint32_t sector = 0;
  40. if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
  41. {
  42. sector = FMC_SECTOR_0;
  43. }
  44. else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
  45. {
  46. sector = FMC_SECTOR_1;
  47. }
  48. else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
  49. {
  50. sector = FMC_SECTOR_2;
  51. }
  52. else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
  53. {
  54. sector = FMC_SECTOR_3;
  55. }
  56. else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
  57. {
  58. sector = FMC_SECTOR_4;
  59. }
  60. else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
  61. {
  62. sector = FMC_SECTOR_5;
  63. }
  64. else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
  65. {
  66. sector = FMC_SECTOR_6;
  67. }
  68. else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
  69. {
  70. sector = FMC_SECTOR_7;
  71. }
  72. else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
  73. {
  74. sector = FMC_SECTOR_8;
  75. }
  76. else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
  77. {
  78. sector = FMC_SECTOR_9;
  79. }
  80. else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
  81. {
  82. sector = FMC_SECTOR_10;
  83. }
  84. else if((Address < APM32_FLASH_END_ADDRESS) && (Address >= ADDR_FLASH_SECTOR_11))
  85. {
  86. sector = FMC_SECTOR_11;
  87. }
  88. return sector;
  89. }
  90. /**
  91. * Read data from flash.
  92. * @note This operation's units is word.
  93. *
  94. * @param addr flash address
  95. * @param buf buffer to store read data
  96. * @param size read bytes size
  97. *
  98. * @return result
  99. */
  100. int apm32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
  101. {
  102. size_t i;
  103. if ((addr + size) > APM32_FLASH_END_ADDRESS)
  104. {
  105. LOG_E("read outrange flash size! addr is (0x%p)", (void*)(addr + size));
  106. return -1;
  107. }
  108. for (i = 0; i < size; i++, buf++, addr++)
  109. {
  110. *buf = *(rt_uint8_t *) addr;
  111. }
  112. return size;
  113. }
  114. /**
  115. * Write data to flash.
  116. * @note This operation's units is word.
  117. * @note This operation must after erase. @see flash_erase.
  118. *
  119. * @param addr flash address
  120. * @param buf the write data buffer
  121. * @param size write bytes size
  122. *
  123. * @return result
  124. */
  125. int apm32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size)
  126. {
  127. rt_err_t result = RT_EOK;
  128. rt_uint32_t end_addr = addr + size;
  129. rt_uint32_t written_size = 0;
  130. rt_uint32_t write_size = 0;
  131. if ((end_addr) > APM32_FLASH_END_ADDRESS)
  132. {
  133. LOG_E("write outrange flash size! addr is (0x%p)", (void*)(addr + size));
  134. return -RT_EINVAL;
  135. }
  136. if (size < 1)
  137. {
  138. return -RT_EINVAL;
  139. }
  140. FMC_Unlock();
  141. FMC_ClearStatusFlag(FMC_FLAG_ENDOP | FMC_FLAG_ERROP | FMC_FLAG_ERRWRP | FMC_FLAG_ERRPGA | FMC_FLAG_ERRPGP | FMC_FLAG_ERRPGS);
  142. while (written_size < size)
  143. {
  144. if (((addr + written_size) % 4 == 0) && (size - written_size >= 4))
  145. {
  146. if (FMC_ProgramWord(addr + written_size, *((rt_uint32_t *)(buf + written_size))) == FMC_COMPLETE)
  147. {
  148. if (*(rt_uint32_t *)(addr + written_size) != *(rt_uint32_t *)(buf + written_size))
  149. {
  150. result = -RT_ERROR;
  151. break;
  152. }
  153. }
  154. else
  155. {
  156. result = -RT_ERROR;
  157. break;
  158. }
  159. write_size = 4;
  160. }
  161. else if (((addr + written_size) % 2 == 0) && (size - written_size >= 2))
  162. {
  163. if (FMC_ProgramHalfWord(addr + written_size, *((rt_uint16_t *)(buf + written_size))) == FMC_COMPLETE)
  164. {
  165. if (*(rt_uint16_t *)(addr + written_size) != *(rt_uint16_t *)(buf + written_size))
  166. {
  167. result = -RT_ERROR;
  168. break;
  169. }
  170. }
  171. else
  172. {
  173. result = -RT_ERROR;
  174. break;
  175. }
  176. write_size = 2;
  177. }
  178. else
  179. {
  180. if (FMC_ProgramByte(addr + written_size, *((rt_uint8_t *)(buf + written_size))) == FMC_COMPLETE)
  181. {
  182. if (*(rt_uint8_t *)(addr + written_size) != *(rt_uint8_t *)(buf + written_size))
  183. {
  184. result = -RT_ERROR;
  185. break;
  186. }
  187. }
  188. else
  189. {
  190. result = -RT_ERROR;
  191. break;
  192. }
  193. write_size = 1;
  194. }
  195. written_size += write_size;
  196. }
  197. FMC_Lock();
  198. if (result != RT_EOK)
  199. {
  200. return result;
  201. }
  202. return size;
  203. }
  204. /**
  205. * Erase data on flash.
  206. * @note This operation is irreversible.
  207. * @note This operation's units is different which on many chips.
  208. *
  209. * @param addr flash address
  210. * @param size erase bytes size
  211. *
  212. * @return result
  213. */
  214. int apm32_flash_erase(rt_uint32_t addr, size_t size)
  215. {
  216. rt_err_t result = RT_EOK;
  217. rt_uint32_t FirstSector = 0, NbOfSectors = 0;
  218. rt_uint32_t index = 0;
  219. if ((addr + size) > APM32_FLASH_END_ADDRESS)
  220. {
  221. LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void*)(addr + size));
  222. return -RT_EINVAL;
  223. }
  224. if (size < 1)
  225. {
  226. return -RT_EINVAL;
  227. }
  228. /* Unlock the Flash to enable the flash control register access */
  229. FMC_Unlock();
  230. FMC_ClearStatusFlag(FMC_FLAG_ENDOP | FMC_FLAG_ERROP | FMC_FLAG_ERRWRP | FMC_FLAG_ERRPGA | FMC_FLAG_ERRPGP | FMC_FLAG_ERRPGS);
  231. /* Get the 1st sector to erase */
  232. FirstSector = GetSector(addr) >> 3;
  233. /* Get the number of sector to erase from 1st sector */
  234. NbOfSectors = (GetSector(addr + size - 1) >> 3) - FirstSector + 1;
  235. /* Erase by sector by sector to be done */
  236. for (index = FirstSector; index < (FirstSector + NbOfSectors); index++)
  237. {
  238. if (FMC_EraseSector((FMC_SECTOR_T)(index << 3), FMC_VOLTAGE_3) != FMC_COMPLETE)
  239. {
  240. result = -RT_ERROR;
  241. goto __exit;
  242. }
  243. }
  244. __exit:
  245. FMC_Lock();
  246. if (result != RT_EOK)
  247. {
  248. return result;
  249. }
  250. LOG_D("erase done: addr (0x%p), size %d", (void*)addr, size);
  251. return size;
  252. }
  253. #if defined(RT_USING_FAL)
  254. static int fal_flash_read_16k(long offset, rt_uint8_t *buf, size_t size);
  255. static int fal_flash_read_64k(long offset, rt_uint8_t *buf, size_t size);
  256. static int fal_flash_read_128k(long offset, rt_uint8_t *buf, size_t size);
  257. static int fal_flash_write_16k(long offset, const rt_uint8_t *buf, size_t size);
  258. static int fal_flash_write_64k(long offset, const rt_uint8_t *buf, size_t size);
  259. static int fal_flash_write_128k(long offset, const rt_uint8_t *buf, size_t size);
  260. static int fal_flash_erase_16k(long offset, size_t size);
  261. static int fal_flash_erase_64k(long offset, size_t size);
  262. static int fal_flash_erase_128k(long offset, size_t size);
  263. const struct fal_flash_dev apm32_onchip_flash_16k =
  264. {
  265. "onchip_flash_16k",
  266. APM32_FLASH_START_ADRESS_16K,
  267. FLASH_SIZE_GRANULARITY_16K,
  268. (16 * 1024),
  269. {
  270. NULL,
  271. fal_flash_read_16k,
  272. fal_flash_write_16k,
  273. fal_flash_erase_16k,
  274. },
  275. 8,
  276. };
  277. const struct fal_flash_dev apm32_onchip_flash_64k =
  278. {
  279. "onchip_flash_64k",
  280. APM32_FLASH_START_ADRESS_64K,
  281. FLASH_SIZE_GRANULARITY_64K,
  282. (64 * 1024),
  283. {
  284. NULL,
  285. fal_flash_read_64k,
  286. fal_flash_write_64k,
  287. fal_flash_erase_64k,
  288. },
  289. 8,
  290. };
  291. const struct fal_flash_dev apm32_onchip_flash_128k =
  292. {
  293. "onchip_flash_128k",
  294. APM32_FLASH_START_ADRESS_128K,
  295. FLASH_SIZE_GRANULARITY_128K,
  296. (128 * 1024),
  297. {
  298. NULL,
  299. fal_flash_read_128k,
  300. fal_flash_write_128k,
  301. fal_flash_erase_128k,
  302. },
  303. 8,
  304. };
  305. static int fal_flash_read_16k(long offset, rt_uint8_t *buf, size_t size)
  306. {
  307. return apm32_flash_read(apm32_onchip_flash_16k.addr + offset, buf, size);
  308. }
  309. static int fal_flash_read_64k(long offset, rt_uint8_t *buf, size_t size)
  310. {
  311. return apm32_flash_read(apm32_onchip_flash_64k.addr + offset, buf, size);
  312. }
  313. static int fal_flash_read_128k(long offset, rt_uint8_t *buf, size_t size)
  314. {
  315. return apm32_flash_read(apm32_onchip_flash_128k.addr + offset, buf, size);
  316. }
  317. static int fal_flash_write_16k(long offset, const rt_uint8_t *buf, size_t size)
  318. {
  319. return apm32_flash_write(apm32_onchip_flash_16k.addr + offset, buf, size);
  320. }
  321. static int fal_flash_write_64k(long offset, const rt_uint8_t *buf, size_t size)
  322. {
  323. return apm32_flash_write(apm32_onchip_flash_64k.addr + offset, buf, size);
  324. }
  325. static int fal_flash_write_128k(long offset, const rt_uint8_t *buf, size_t size)
  326. {
  327. return apm32_flash_write(apm32_onchip_flash_128k.addr + offset, buf, size);
  328. }
  329. static int fal_flash_erase_16k(long offset, size_t size)
  330. {
  331. return apm32_flash_erase(apm32_onchip_flash_16k.addr + offset, size);
  332. }
  333. static int fal_flash_erase_64k(long offset, size_t size)
  334. {
  335. return apm32_flash_erase(apm32_onchip_flash_64k.addr + offset, size);
  336. }
  337. static int fal_flash_erase_128k(long offset, size_t size)
  338. {
  339. return apm32_flash_erase(apm32_onchip_flash_128k.addr + offset, size);
  340. }
  341. #endif
  342. #endif /* BSP_USING_ON_CHIP_FLASH */