drv_flash.c 4.3 KB

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