drv_flexspi_hyper.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-07-05 ZYH the first version
  9. */
  10. #include <rtthread.h>
  11. #define PRINTF rt_kprintf
  12. #include "board.h"
  13. #include <rthw.h>
  14. #include "drv_flexspi.h"
  15. #define DBG_ENABLE
  16. #define DBG_SECTION_NAME "[Hyper]"
  17. #define DBG_LEVEL DBG_LOG
  18. #define DBG_COLOR
  19. #include <rtdbg.h>
  20. #define FLEXSPI_CLOCK kCLOCK_FlexSpi
  21. #define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0
  22. #define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1
  23. #define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2
  24. #define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4
  25. #define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6
  26. #define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10
  27. #define CUSTOM_LUT_LENGTH 48
  28. static flexspi_device_config_t deviceconfig = {
  29. .flexspiRootClk = 42000000, /* 42MHZ SPI serial clock */
  30. .isSck2Enabled = false,
  31. .flashSize = FLASH_SIZE,
  32. .CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,
  33. .CSInterval = 2,
  34. .CSHoldTime = 0,
  35. .CSSetupTime = 3,
  36. .dataValidTime = 1,
  37. .columnspace = 3,
  38. .enableWordAddress = true,
  39. .AWRSeqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA,
  40. .AWRSeqNumber = 1,
  41. .ARDSeqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA,
  42. .ARDSeqNumber = 1,
  43. .AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
  44. .AHBWriteWaitInterval = 20,
  45. };
  46. static uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
  47. /* Read Data */
  48. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] =
  49. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
  50. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ(
  51. kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04),
  52. /* Write Data */
  53. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] =
  54. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
  55. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ(
  56. kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02),
  57. /* Read Status */
  58. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] =
  59. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
  60. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ(
  61. kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555
  62. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 2] =
  63. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
  64. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 3] = FLEXSPI_LUT_SEQ(
  65. kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x70), // DATA 0x70
  66. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 4] =
  67. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
  68. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 5] = FLEXSPI_LUT_SEQ(
  69. kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x0B),
  70. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 6] =
  71. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0),
  72. /* Write Enable */
  73. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] =
  74. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
  75. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ(
  76. kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555
  77. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 2] =
  78. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
  79. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 3] = FLEXSPI_LUT_SEQ(
  80. kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // DATA 0xAA
  81. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 4] =
  82. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
  83. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 5] =
  84. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
  85. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 6] =
  86. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02),
  87. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 7] =
  88. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
  89. /* Erase Sector */
  90. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] =
  91. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
  92. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ(
  93. kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555
  94. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 2] =
  95. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
  96. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 3] = FLEXSPI_LUT_SEQ(
  97. kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), // DATA 0x80
  98. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 4] =
  99. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
  100. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 5] =
  101. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
  102. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 6] =
  103. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
  104. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 7] = FLEXSPI_LUT_SEQ(
  105. kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555
  106. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 8] =
  107. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
  108. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 9] =
  109. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
  110. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 10] =
  111. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02),
  112. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 11] =
  113. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
  114. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 12] =
  115. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
  116. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 13] =
  117. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
  118. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 14] =
  119. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x30, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00),
  120. /* program page */
  121. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] =
  122. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
  123. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ(
  124. kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555
  125. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2] =
  126. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
  127. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3] = FLEXSPI_LUT_SEQ(
  128. kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0), // DATA 0xA0
  129. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4] =
  130. FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
  131. [4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5] = FLEXSPI_LUT_SEQ(
  132. kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x80),
  133. };
  134. SECTION("itcm") status_t flexspi_nor_hyperbus_read(FLEXSPI_Type *base, uint32_t addr, uint32_t *buffer, uint32_t bytes)
  135. {
  136. flexspi_transfer_t flashXfer;
  137. status_t status;
  138. flashXfer.deviceAddress = addr * 2;
  139. flashXfer.port = kFLEXSPI_PortA1;
  140. flashXfer.cmdType = kFLEXSPI_Read;
  141. flashXfer.SeqNumber = 1;
  142. flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA;
  143. flashXfer.data = buffer;
  144. flashXfer.dataSize = bytes;
  145. status = FLEXSPI_TransferBlocking(base, &flashXfer);
  146. if (status != kStatus_Success)
  147. {
  148. return status;
  149. }
  150. return status;
  151. }
  152. SECTION("itcm") status_t flexspi_nor_hyperbus_write(FLEXSPI_Type *base, uint32_t addr, uint32_t *buffer, uint32_t bytes)
  153. {
  154. flexspi_transfer_t flashXfer;
  155. status_t status;
  156. flashXfer.deviceAddress = addr * 2;
  157. flashXfer.port = kFLEXSPI_PortA1;
  158. flashXfer.cmdType = kFLEXSPI_Write;
  159. flashXfer.SeqNumber = 1;
  160. flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA;
  161. flashXfer.data = buffer;
  162. flashXfer.dataSize = bytes;
  163. status = FLEXSPI_TransferBlocking(base, &flashXfer);
  164. if (status != kStatus_Success)
  165. {
  166. return status;
  167. }
  168. return status;
  169. }
  170. SECTION("itcm") status_t flexspi_nor_write_enable(FLEXSPI_Type *base, uint32_t baseAddr)
  171. {
  172. flexspi_transfer_t flashXfer;
  173. status_t status;
  174. /* Write neable */
  175. flashXfer.deviceAddress = baseAddr;
  176. flashXfer.port = kFLEXSPI_PortA1;
  177. flashXfer.cmdType = kFLEXSPI_Command;
  178. flashXfer.SeqNumber = 2;
  179. flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE;
  180. status = FLEXSPI_TransferBlocking(base, &flashXfer);
  181. return status;
  182. }
  183. SECTION("itcm") status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base)
  184. {
  185. /* Wait status ready. */
  186. bool isBusy;
  187. uint32_t readValue;
  188. status_t status;
  189. flexspi_transfer_t flashXfer;
  190. flashXfer.deviceAddress = 0;
  191. flashXfer.port = kFLEXSPI_PortA1;
  192. flashXfer.cmdType = kFLEXSPI_Read;
  193. flashXfer.SeqNumber = 2;
  194. flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS;
  195. flashXfer.data = &readValue;
  196. flashXfer.dataSize = 2;
  197. do
  198. {
  199. status = FLEXSPI_TransferBlocking(base, &flashXfer);
  200. if (status != kStatus_Success)
  201. {
  202. return status;
  203. }
  204. if (readValue & 0x8000)
  205. {
  206. isBusy = false;
  207. }
  208. else
  209. {
  210. isBusy = true;
  211. }
  212. if (readValue & 0x3200)
  213. {
  214. status = kStatus_Fail;
  215. break;
  216. }
  217. } while (isBusy);
  218. return status;
  219. }
  220. SECTION("itcm") status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address)
  221. {
  222. status_t status;
  223. flexspi_transfer_t flashXfer;
  224. rt_uint32_t level;
  225. level = rt_hw_interrupt_disable();
  226. FLEXSPI_Enable(FLEXSPI, false);
  227. CLOCK_DisableClock(FLEXSPI_CLOCK);
  228. CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* flexspi clock 332M, DDR mode, internal clock 166M. */
  229. CLOCK_EnableClock(FLEXSPI_CLOCK);
  230. FLEXSPI_Enable(FLEXSPI, true);
  231. /* Write enable */
  232. status = flexspi_nor_write_enable(base, address);
  233. if (status != kStatus_Success)
  234. {
  235. FLEXSPI_Enable(FLEXSPI, false);
  236. CLOCK_DisableClock(FLEXSPI_CLOCK);
  237. CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */
  238. CLOCK_EnableClock(FLEXSPI_CLOCK);
  239. FLEXSPI_Enable(FLEXSPI, true);
  240. FLEXSPI_SoftwareReset(FLEXSPI);
  241. rt_hw_interrupt_enable(level);
  242. return status;
  243. }
  244. flashXfer.deviceAddress = address;
  245. flashXfer.port = kFLEXSPI_PortA1;
  246. flashXfer.cmdType = kFLEXSPI_Command;
  247. flashXfer.SeqNumber = 4;
  248. flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR;
  249. status = FLEXSPI_TransferBlocking(base, &flashXfer);
  250. if (status != kStatus_Success)
  251. {
  252. FLEXSPI_Enable(FLEXSPI, false);
  253. CLOCK_DisableClock(FLEXSPI_CLOCK);
  254. CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */
  255. CLOCK_EnableClock(FLEXSPI_CLOCK);
  256. FLEXSPI_Enable(FLEXSPI, true);
  257. FLEXSPI_SoftwareReset(FLEXSPI);
  258. rt_hw_interrupt_enable(level);
  259. return status;
  260. }
  261. status = flexspi_nor_wait_bus_busy(base);
  262. rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE,(void *)(FLEXSPI_AMBA_BASE+address),FLEXSPI_NOR_SECTOR_SIZE);
  263. rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE,(void *)(FLEXSPI_AMBA_BASE+address),FLEXSPI_NOR_SECTOR_SIZE);
  264. FLEXSPI_Enable(FLEXSPI, false);
  265. CLOCK_DisableClock(FLEXSPI_CLOCK);
  266. CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */
  267. CLOCK_EnableClock(FLEXSPI_CLOCK);
  268. FLEXSPI_Enable(FLEXSPI, true);
  269. FLEXSPI_SoftwareReset(FLEXSPI);
  270. rt_hw_interrupt_enable(level);
  271. return status;
  272. }
  273. SECTION("itcm") status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src)
  274. {
  275. status_t status;
  276. flexspi_transfer_t flashXfer;
  277. rt_uint32_t level;
  278. level = rt_hw_interrupt_disable();
  279. FLEXSPI_Enable(FLEXSPI, false);
  280. CLOCK_DisableClock(FLEXSPI_CLOCK);
  281. CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* flexspi clock 332M, DDR mode, internal clock 166M. */
  282. CLOCK_EnableClock(FLEXSPI_CLOCK);
  283. FLEXSPI_Enable(FLEXSPI, true);
  284. /* Write neable */
  285. status = flexspi_nor_write_enable(base, address);
  286. if (status != kStatus_Success)
  287. {
  288. rt_hw_interrupt_enable(level);
  289. return status;
  290. }
  291. /* Prepare page program command */
  292. flashXfer.deviceAddress = address;
  293. flashXfer.port = kFLEXSPI_PortA1;
  294. flashXfer.cmdType = kFLEXSPI_Write;
  295. flashXfer.SeqNumber = 2;
  296. flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM;
  297. flashXfer.data = (uint32_t *)src;
  298. flashXfer.dataSize = FLASH_PAGE_SIZE;
  299. status = FLEXSPI_TransferBlocking(base, &flashXfer);
  300. if (status != kStatus_Success)
  301. {
  302. rt_hw_interrupt_enable(level);
  303. return status;
  304. }
  305. status = flexspi_nor_wait_bus_busy(base);
  306. rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE,(void *)(FLEXSPI_AMBA_BASE+address),FLASH_PAGE_SIZE);
  307. rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE,(void *)(FLEXSPI_AMBA_BASE+address),FLASH_PAGE_SIZE);
  308. FLEXSPI_Enable(FLEXSPI, false);
  309. CLOCK_DisableClock(FLEXSPI_CLOCK);
  310. CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */
  311. CLOCK_EnableClock(FLEXSPI_CLOCK);
  312. FLEXSPI_Enable(FLEXSPI, true);
  313. FLEXSPI_SoftwareReset(FLEXSPI);
  314. rt_hw_interrupt_enable(level);
  315. return status;
  316. }
  317. SECTION("itcm") status_t flexspi_nor_hyperflash_cfi(FLEXSPI_Type *base)
  318. {
  319. /*
  320. * Read ID-CFI Parameters
  321. */
  322. // CFI Entry
  323. status_t status;
  324. uint32_t buffer[2];
  325. uint32_t data = 0x9800;
  326. status = flexspi_nor_hyperbus_write(base, 0x555, &data, 2);
  327. if (status != kStatus_Success)
  328. {
  329. return status;
  330. }
  331. // ID-CFI Read
  332. // Read Query Unique ASCII String
  333. status = flexspi_nor_hyperbus_read(base, 0x10, &buffer[0], sizeof(buffer));
  334. if (status != kStatus_Success)
  335. {
  336. return status;
  337. }
  338. buffer[1] &= 0xFFFF;
  339. // Check that the data read out is unicode "QRY" in big-endian order
  340. if ((buffer[0] != 0x52005100) || (buffer[1] != 0x5900))
  341. {
  342. status = kStatus_Fail;
  343. return status;
  344. }
  345. // ASO Exit
  346. data = 0xF000;
  347. status = flexspi_nor_hyperbus_write(base, 0x0, &data, 2);
  348. if (status != kStatus_Success)
  349. {
  350. return status;
  351. }
  352. return status;
  353. }
  354. SECTION("itcm") int rt_hw_flexspi_init(void)
  355. {
  356. flexspi_config_t config;
  357. status_t status;
  358. rt_uint32_t level;
  359. level = rt_hw_interrupt_disable();
  360. // Set flexspi root clock to 166MHZ.
  361. const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
  362. CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
  363. CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 26); /* Set PLL3 PFD0 clock 332MHZ. */
  364. CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */
  365. CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* flexspi clock 83M, DDR mode, internal clock 42M. */
  366. /*Get FLEXSPI default settings and configure the flexspi. */
  367. FLEXSPI_GetDefaultConfig(&config);
  368. /*Set AHB buffer size for reading data through AHB bus. */
  369. config.ahbConfig.enableAHBPrefetch = true;
  370. /*Allow AHB read start address do not follow the alignment requirement. */
  371. config.ahbConfig.enableReadAddressOpt = true;
  372. /* enable diff clock and DQS */
  373. config.enableSckBDiffOpt = true;
  374. config.rxSampleClock = kFLEXSPI_ReadSampleClkExternalInputFromDqsPad;
  375. config.enableCombination = true;
  376. FLEXSPI_Init(FLEXSPI, &config);
  377. /* Configure flash settings according to serial flash feature. */
  378. FLEXSPI_SetFlashConfig(FLEXSPI, &deviceconfig, kFLEXSPI_PortA1);
  379. /* Update LUT table. */
  380. FLEXSPI_UpdateLUT(FLEXSPI, 0, customLUT, CUSTOM_LUT_LENGTH);
  381. /* Do software reset. */
  382. FLEXSPI_SoftwareReset(FLEXSPI);
  383. status = flexspi_nor_hyperflash_cfi(FLEXSPI);
  384. /* Get vendor ID. */
  385. if (status != kStatus_Success)
  386. {
  387. FLEXSPI_Enable(FLEXSPI, false);
  388. CLOCK_DisableClock(FLEXSPI_CLOCK);
  389. CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */
  390. CLOCK_EnableClock(FLEXSPI_CLOCK);
  391. FLEXSPI_Enable(FLEXSPI, true);
  392. FLEXSPI_SoftwareReset(FLEXSPI);
  393. rt_hw_interrupt_enable(level);
  394. return status;
  395. }
  396. FLEXSPI_Enable(FLEXSPI, false);
  397. CLOCK_DisableClock(FLEXSPI_CLOCK);
  398. CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */
  399. CLOCK_EnableClock(FLEXSPI_CLOCK);
  400. FLEXSPI_Enable(FLEXSPI, true);
  401. FLEXSPI_SoftwareReset(FLEXSPI);
  402. rt_hw_interrupt_enable(level);
  403. return 0;
  404. }