drv_flash.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-11-30 flybreak first version
  9. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include "board.h"
  14. #include "hal_data.h"
  15. #include "drv_common.h"
  16. #if defined(RT_USING_FAL)
  17. #include "fal.h"
  18. #endif
  19. //#define DRV_DEBUG
  20. #define LOG_TAG "drv.flash"
  21. #ifdef DRV_DEBUG
  22. #define DBG_LVL DBG_LOG
  23. #else
  24. #define DBG_LVL DBG_INFO
  25. #endif /* DRV_DEBUG */
  26. #include <rtdbg.h>
  27. #if BSP_FEATURE_FLASH_HP_VERSION
  28. /* FLASH API */
  29. #define R_FLASH_Open R_FLASH_HP_Open
  30. #define R_FLASH_Reset R_FLASH_HP_Reset
  31. #define R_FLASH_Write R_FLASH_HP_Write
  32. #define R_FLASH_Erase R_FLASH_HP_Erase
  33. #define R_FLASH_StartUpAreaSelect R_FLASH_HP_StartUpAreaSelect
  34. /* BSP_FEATURE_FLASH */
  35. #define FLASH_CF_WRITE_SIZE BSP_FEATURE_FLASH_HP_CF_WRITE_SIZE
  36. #else /* FLASH LP */
  37. /* FLASH API */
  38. #define R_FLASH_Open R_FLASH_LP_Open
  39. #define R_FLASH_Reset R_FLASH_LP_Reset
  40. #define R_FLASH_Write R_FLASH_LP_Write
  41. #define R_FLASH_Erase R_FLASH_LP_Erase
  42. #define R_FLASH_StartUpAreaSelect R_FLASH_LP_StartUpAreaSelect
  43. /* BSP_FEATURE_FLASH */
  44. #define FLASH_CF_WRITE_SIZE BSP_FEATURE_FLASH_LP_CF_WRITE_SIZE
  45. #endif
  46. int _flash_init(void)
  47. {
  48. fsp_err_t err = FSP_SUCCESS;
  49. /* Open Flash_HP */
  50. err = R_FLASH_Open(&g_flash_ctrl, &g_flash_cfg);
  51. /* Handle Error */
  52. if (FSP_SUCCESS != err)
  53. {
  54. LOG_E("\r\n Flah_HP_Open API failed");
  55. }
  56. /* Setup Default Block 0 as Startup Setup Block */
  57. err = R_FLASH_StartUpAreaSelect(&g_flash_ctrl, FLASH_STARTUP_AREA_BLOCK0, true);
  58. if (err != FSP_SUCCESS)
  59. {
  60. LOG_E("\r\n Flah_HP_StartUpAreaSelect API failed");
  61. }
  62. return 0;
  63. }
  64. /**
  65. * Read data from flash.
  66. * @note This operation's units is word.
  67. *
  68. * @param addr flash address
  69. * @param buf buffer to store read data
  70. * @param size read bytes size
  71. *
  72. * @return result
  73. */
  74. int _flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
  75. {
  76. size_t i;
  77. for (i = 0; i < size; i++, buf++, addr++)
  78. {
  79. *buf = *(rt_uint8_t *) addr;
  80. }
  81. return size;
  82. }
  83. /**
  84. * Write data to flash.
  85. * @note This operation's units is word.
  86. * @note This operation must after erase. @see flash_erase.
  87. *
  88. * @param addr flash address
  89. * @param buf the write data buffer
  90. * @param size write bytes size
  91. *
  92. * @return result
  93. */
  94. int _flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size)
  95. {
  96. rt_err_t result = RT_EOK;
  97. rt_base_t level;
  98. fsp_err_t err = FSP_SUCCESS;
  99. size_t written_size = 0;
  100. if (size % FLASH_CF_WRITE_SIZE)
  101. {
  102. LOG_E("Flash Write size must be an integer multiple of %d", FLASH_CF_WRITE_SIZE);
  103. return -RT_EINVAL;
  104. }
  105. while (written_size < size)
  106. {
  107. level = rt_hw_interrupt_disable();
  108. R_FLASH_Reset(&g_flash_ctrl);
  109. /* Write code flash data*/
  110. err = R_FLASH_Write(&g_flash_ctrl, (uint32_t)(buf + written_size), addr + written_size, FLASH_CF_WRITE_SIZE);
  111. rt_hw_interrupt_enable(level);
  112. /* Error Handle */
  113. if (FSP_SUCCESS != err)
  114. {
  115. LOG_E("Write API failed");
  116. return -RT_EIO;
  117. }
  118. written_size += FLASH_CF_WRITE_SIZE;
  119. }
  120. if (result != RT_EOK)
  121. {
  122. return result;
  123. }
  124. return size;
  125. }
  126. /**
  127. * Erase data on flash.
  128. * @note This operation is irreversible.
  129. * @note This operation's units is different which on many chips.
  130. *
  131. * @param addr flash address
  132. * @param size erase bytes size
  133. *
  134. * @return result
  135. */
  136. #if BSP_FEATURE_FLASH_HP_VERSION
  137. int _flash_hp0_erase(rt_uint32_t addr, size_t size)
  138. #else
  139. int _flash_lp_erase(rt_uint32_t addr, size_t size)
  140. #endif
  141. {
  142. fsp_err_t err = FSP_SUCCESS;
  143. rt_base_t level;
  144. #if BSP_FEATURE_FLASH_HP_VERSION
  145. if ((addr + size) > BSP_FEATURE_FLASH_HP_CF_REGION0_SIZE)
  146. #else
  147. if ((addr + size) > BSP_ROM_SIZE_BYTES)
  148. #endif
  149. {
  150. LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void *)(addr + size));
  151. return -RT_EINVAL;
  152. }
  153. if (size < 1)
  154. {
  155. return -RT_EINVAL;
  156. }
  157. level = rt_hw_interrupt_disable();
  158. R_FLASH_Reset(&g_flash_ctrl);
  159. /* Erase Block */
  160. #if BSP_FEATURE_FLASH_HP_VERSION
  161. err = R_FLASH_Erase(&g_flash_ctrl,
  162. RT_ALIGN_DOWN(addr, BSP_FEATURE_FLASH_HP_CF_REGION0_BLOCK_SIZE),
  163. ((size - 1) / BSP_FEATURE_FLASH_HP_CF_REGION0_BLOCK_SIZE + 1));
  164. #else
  165. err = R_FLASH_Erase(&g_flash_ctrl,
  166. RT_ALIGN_DOWN(addr, BSP_FEATURE_FLASH_LP_CF_BLOCK_SIZE),
  167. ((size - 1) / BSP_FEATURE_FLASH_LP_CF_BLOCK_SIZE + 1));
  168. #endif
  169. rt_hw_interrupt_enable(level);
  170. if (err != FSP_SUCCESS)
  171. {
  172. LOG_E("Erase failed:addr (0x%p), size %d", (void *)addr, size);
  173. return -RT_EIO;
  174. }
  175. LOG_D("erase done: addr (0x%p), size %d", (void *)addr, size);
  176. return size;
  177. }
  178. #if BSP_FEATURE_FLASH_HP_VERSION
  179. int _flash_hp1_erase(rt_uint32_t addr, size_t size)
  180. {
  181. fsp_err_t err = FSP_SUCCESS;
  182. rt_base_t level;
  183. if (size < 1)
  184. {
  185. return -RT_EINVAL;
  186. }
  187. level = rt_hw_interrupt_disable();
  188. R_FLASH_Reset(&g_flash_ctrl);
  189. /* Erase Block */
  190. err = R_FLASH_Erase(&g_flash_ctrl, RT_ALIGN_DOWN(addr, BSP_FEATURE_FLASH_HP_CF_REGION1_BLOCK_SIZE), (size - 1) / BSP_FEATURE_FLASH_HP_CF_REGION1_BLOCK_SIZE + 1);
  191. rt_hw_interrupt_enable(level);
  192. if (err != FSP_SUCCESS)
  193. {
  194. LOG_E("Erase API failed");
  195. return -RT_EIO;
  196. }
  197. LOG_D("erase done: addr (0x%p), size %d", (void *)addr, size);
  198. return size;
  199. }
  200. #endif
  201. #if defined(RT_USING_FAL)
  202. #define FLASH_START_ADDRESS 0x00000000
  203. #if BSP_FEATURE_FLASH_HP_VERSION
  204. static int fal_flash_hp0_read(long offset, rt_uint8_t *buf, size_t size);
  205. static int fal_flash_hp0_write(long offset, const rt_uint8_t *buf, size_t size);
  206. static int fal_flash_hp0_erase(long offset, size_t size);
  207. static int fal_flash_hp1_read(long offset, rt_uint8_t *buf, size_t size);
  208. static int fal_flash_hp1_write(long offset, const rt_uint8_t *buf, size_t size);
  209. static int fal_flash_hp1_erase(long offset, size_t size);
  210. const struct fal_flash_dev _onchip_flash_hp0 =
  211. {
  212. "onchip_flash_hp0",
  213. FLASH_START_ADDRESS,
  214. BSP_FEATURE_FLASH_HP_CF_REGION0_SIZE,
  215. BSP_FEATURE_FLASH_HP_CF_REGION0_BLOCK_SIZE,
  216. {
  217. _flash_init,
  218. fal_flash_hp0_read,
  219. fal_flash_hp0_write,
  220. fal_flash_hp0_erase
  221. },
  222. (BSP_FEATURE_FLASH_HP_CF_WRITE_SIZE * 8)
  223. };
  224. const struct fal_flash_dev _onchip_flash_hp1 =
  225. {
  226. "onchip_flash_hp1",
  227. BSP_FEATURE_FLASH_HP_CF_REGION0_SIZE,
  228. (BSP_ROM_SIZE_BYTES - BSP_FEATURE_FLASH_HP_CF_REGION0_SIZE),
  229. BSP_FEATURE_FLASH_HP_CF_REGION1_BLOCK_SIZE,
  230. {
  231. _flash_init,
  232. fal_flash_hp1_read,
  233. fal_flash_hp1_write,
  234. fal_flash_hp1_erase
  235. },
  236. (BSP_FEATURE_FLASH_HP_CF_WRITE_SIZE * 8)
  237. };
  238. /* code flash region0 */
  239. static int fal_flash_hp0_read(long offset, rt_uint8_t *buf, size_t size)
  240. {
  241. return _flash_read(_onchip_flash_hp0.addr + offset, buf, size);
  242. }
  243. static int fal_flash_hp0_write(long offset, const rt_uint8_t *buf, size_t size)
  244. {
  245. return _flash_write(_onchip_flash_hp0.addr + offset, buf, size);
  246. }
  247. static int fal_flash_hp0_erase(long offset, size_t size)
  248. {
  249. return _flash_hp0_erase(_onchip_flash_hp0.addr + offset, size);
  250. }
  251. /* code flash region1 */
  252. static int fal_flash_hp1_read(long offset, rt_uint8_t *buf, size_t size)
  253. {
  254. return _flash_read(_onchip_flash_hp1.addr + offset, buf, size);
  255. }
  256. static int fal_flash_hp1_write(long offset, const rt_uint8_t *buf, size_t size)
  257. {
  258. return _flash_write(_onchip_flash_hp1.addr + offset, buf, size);
  259. }
  260. static int fal_flash_hp1_erase(long offset, size_t size)
  261. {
  262. return _flash_hp1_erase(_onchip_flash_hp1.addr + offset, size);
  263. }
  264. #else /* flash lp code flash */
  265. static int fal_flash_lp_read(long offset, rt_uint8_t *buf, size_t size);
  266. static int fal_flash_lp_write(long offset, const rt_uint8_t *buf, size_t size);
  267. static int fal_flash_lp_erase(long offset, size_t size);
  268. const struct fal_flash_dev _onchip_flash_lp =
  269. {
  270. "onchip_flash_lp",
  271. FLASH_START_ADDRESS,
  272. BSP_ROM_SIZE_BYTES,
  273. BSP_FEATURE_FLASH_LP_CF_BLOCK_SIZE,
  274. {
  275. _flash_init,
  276. fal_flash_lp_read,
  277. fal_flash_lp_write,
  278. fal_flash_lp_erase
  279. },
  280. (BSP_FEATURE_FLASH_LP_CF_WRITE_SIZE * 8)
  281. };
  282. static int fal_flash_lp_read(long offset, rt_uint8_t *buf, size_t size)
  283. {
  284. return _flash_read(_onchip_flash_lp.addr + offset, buf, size);
  285. }
  286. static int fal_flash_lp_write(long offset, const rt_uint8_t *buf, size_t size)
  287. {
  288. return _flash_write(_onchip_flash_lp.addr + offset, buf, size);
  289. }
  290. static int fal_flash_lp_erase(long offset, size_t size)
  291. {
  292. return _flash_lp_erase(_onchip_flash_lp.addr + offset, size);
  293. }
  294. #endif
  295. int flash_test(void)
  296. {
  297. #if BSP_FEATURE_FLASH_HP_VERSION
  298. #define TEST_OFF (_onchip_flash_hp1.len - BSP_FEATURE_FLASH_HP_CF_REGION1_BLOCK_SIZE)
  299. #else
  300. #define TEST_OFF (_onchip_flash_lp.len - BSP_FEATURE_FLASH_LP_CF_BLOCK_SIZE)
  301. #endif
  302. const struct fal_partition *param;
  303. uint8_t write_buffer[FLASH_CF_WRITE_SIZE] = {0};
  304. uint8_t read_buffer[FLASH_CF_WRITE_SIZE] = {0};
  305. /* Set write buffer, clear read buffer */
  306. for (uint8_t index = 0; index < FLASH_CF_WRITE_SIZE; index++)
  307. {
  308. write_buffer[index] = index;
  309. read_buffer[index] = 0;
  310. }
  311. fal_init();
  312. #if BSP_FEATURE_FLASH_HP_VERSION
  313. param = fal_partition_find("param");
  314. #else
  315. param = fal_partition_find("app");
  316. #endif
  317. if (param == RT_NULL)
  318. {
  319. LOG_E("not find partition param!");
  320. return -1;
  321. }
  322. LOG_I("Erase Start...");
  323. #if BSP_FEATURE_FLASH_HP_VERSION
  324. fal_partition_erase(param, TEST_OFF, BSP_FEATURE_FLASH_HP_CF_REGION1_BLOCK_SIZE);
  325. #else
  326. fal_partition_erase(param, TEST_OFF, BSP_FEATURE_FLASH_LP_CF_BLOCK_SIZE);
  327. #endif
  328. LOG_I("Erase succeeded!");
  329. LOG_I("Write Start...");
  330. fal_partition_write(param, TEST_OFF, write_buffer, sizeof(write_buffer));
  331. LOG_I("Write succeeded!");
  332. LOG_I("Read Start...");
  333. fal_partition_read(param, TEST_OFF, read_buffer, FLASH_CF_WRITE_SIZE);
  334. LOG_I("Read succeeded!");
  335. for (int i = 0; i < FLASH_CF_WRITE_SIZE; i++)
  336. {
  337. if (read_buffer[i] != write_buffer[i])
  338. {
  339. LOG_E("Data verification failed!");
  340. return -1;
  341. }
  342. }
  343. LOG_I("Data verification succeeded!");
  344. return 0;
  345. }
  346. MSH_CMD_EXPORT(flash_test, "drv flash test.");
  347. #endif