drv_flash_ch32f20x.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-01-21 charlown the first version
  9. */
  10. #include <rtthread.h>
  11. #include <board.h>
  12. #ifdef BSP_USING_ON_CHIP_FLASH
  13. #include "drv_flash.h"
  14. #if defined(RT_USING_FAL)
  15. #include "fal.h"
  16. #endif
  17. #define LOG_TAG "drv.flash"
  18. #include <drv_log.h>
  19. /**
  20. * @brief Gets the page of a given address
  21. * @param addr: address of the flash memory
  22. * @retval The page of a given address
  23. */
  24. static rt_uint32_t get_page(uint32_t addr)
  25. {
  26. rt_uint32_t page = 0;
  27. page = RT_ALIGN_DOWN(addr, FLASH_PAGE_SIZE);
  28. return page;
  29. }
  30. /**
  31. * Read data from flash.
  32. * @note This operation's units is word.
  33. *
  34. * @param addr flash address
  35. * @param buf buffer to store read data
  36. * @param size read bytes size
  37. *
  38. * @return result
  39. */
  40. int ch32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, rt_size_t size)
  41. {
  42. rt_size_t i;
  43. if ((addr + size) > CH32_FLASH_END_ADDRESS)
  44. {
  45. LOG_E("read outrange flash size! addr is (0x%p)", (void *)(addr + size));
  46. return -RT_EINVAL;
  47. }
  48. for (i = 0; i < size; i++, buf++, addr++)
  49. {
  50. *buf = *(rt_uint8_t *) addr;
  51. }
  52. return size;
  53. }
  54. /**
  55. * Write data to flash.
  56. * @note This operation's units is word.
  57. * @note This operation must after erase. @see flash_erase.
  58. *
  59. * @param addr flash address
  60. * @param buf the write data buffer
  61. * @param size write bytes size
  62. *
  63. * @return result
  64. */
  65. int ch32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, rt_size_t size)
  66. {
  67. rt_err_t result = RT_EOK;
  68. rt_uint32_t end_addr = addr + size;
  69. if (addr % 4 != 0)
  70. {
  71. LOG_E("write addr must be 4-byte alignment");
  72. return -RT_EINVAL;
  73. }
  74. if ((end_addr) > CH32_FLASH_END_ADDRESS)
  75. {
  76. LOG_E("write outrange flash size! addr is (0x%p)", (void *)(addr + size));
  77. return -RT_EINVAL;
  78. }
  79. FLASH_Unlock();
  80. while (addr < end_addr)
  81. {
  82. if (FLASH_ProgramWord(addr, *((rt_uint32_t *)buf)) == FLASH_COMPLETE)
  83. {
  84. if (*(rt_uint32_t *)addr != *(rt_uint32_t *)buf)
  85. {
  86. result = -RT_ERROR;
  87. break;
  88. }
  89. addr += 4;
  90. buf += 4;
  91. }
  92. else
  93. {
  94. result = -RT_ERROR;
  95. break;
  96. }
  97. }
  98. FLASH_Lock();
  99. if (result != RT_EOK)
  100. {
  101. return result;
  102. }
  103. return size;
  104. }
  105. /**
  106. * Erase data on flash .
  107. * @note This operation is irreversible.
  108. * @note This operation's units is different which on many chips.
  109. *
  110. * @param addr flash address
  111. * @param size erase bytes size
  112. *
  113. * @return result
  114. */
  115. int ch32_flash_erase(rt_uint32_t addr, rt_size_t size)
  116. {
  117. rt_err_t result = RT_EOK;
  118. rt_uint32_t end_addr = addr + size;
  119. rt_uint32_t page_addr = 0;
  120. FLASH_Unlock();
  121. if ((end_addr) > CH32_FLASH_END_ADDRESS)
  122. {
  123. LOG_E("erase outrange flash size! addr is (0x%p)", (void *)(addr + size));
  124. return -RT_EINVAL;
  125. }
  126. while(addr < end_addr)
  127. {
  128. page_addr = get_page(addr);
  129. if(FLASH_ErasePage(page_addr) != FLASH_COMPLETE)
  130. {
  131. result = -RT_ERROR;
  132. goto __exit;
  133. }
  134. addr += FLASH_PAGE_SIZE;
  135. }
  136. FLASH_Lock();
  137. __exit:
  138. if(result != RT_EOK)
  139. {
  140. return result;
  141. }
  142. return size;
  143. }
  144. #if defined(RT_USING_FAL)
  145. static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size);
  146. static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size);
  147. static int fal_flash_erase(long offset, size_t size);
  148. /*fal_cfg.h use it*/
  149. const struct fal_flash_dev ch32_onchip_flash =
  150. {
  151. "onchip_flash",
  152. CH32_FLASH_START_ADRESS,
  153. CH32_FLASH_SIZE,
  154. FLASH_PAGE_SIZE,
  155. {
  156. NULL,
  157. fal_flash_read,
  158. fal_flash_write,
  159. fal_flash_erase
  160. }
  161. };
  162. static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size)
  163. {
  164. return ch32_flash_read(ch32_onchip_flash.addr + offset, buf, size);
  165. }
  166. static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size)
  167. {
  168. return ch32_flash_write(ch32_onchip_flash.addr + offset, buf, size);
  169. }
  170. static int fal_flash_erase(long offset, size_t size)
  171. {
  172. return ch32_flash_erase(ch32_onchip_flash.addr + offset, size);
  173. }
  174. #endif /* RT_USING_FAL */
  175. #endif /* BSP_USING_ON_CHIP_FLASH */