drv_qspi.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  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. * 2022-05-16 shelton first version
  9. */
  10. #include <rtdevice.h>
  11. #include "drv_common.h"
  12. #include "drv_qspi.h"
  13. #ifdef BSP_USING_QSPI
  14. #if !defined(BSP_USING_QSPI1) && !defined(BSP_USING_QSPI2)
  15. #error "Please define at least one BSP_USING_QSPIx"
  16. #endif
  17. #define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
  18. #define QSPI_FIFO_DEPTH (32 * 4)
  19. #define DRV_DEBUG
  20. #define LOG_TAG "drv.qspi"
  21. #include <drv_log.h>
  22. struct at32_qspi_bus
  23. {
  24. struct rt_spi_bus bus;
  25. qspi_type *qspi_x;
  26. char *bus_name;
  27. };
  28. enum
  29. {
  30. #ifdef BSP_USING_QSPI1
  31. QSPI1_INDEX,
  32. #endif
  33. #ifdef BSP_USING_QSPI2
  34. QSPI2_INDEX,
  35. #endif
  36. };
  37. static struct at32_qspi_bus at32_qspi_obj[] =
  38. {
  39. #ifdef BSP_USING_QSPI1
  40. QSPI1_BUS_CONFIG,
  41. #endif
  42. #ifdef BSP_USING_QSPI2
  43. QSPI2_BUS_CONFIG,
  44. #endif
  45. };
  46. static int at32_qspi_init(struct rt_qspi_device *device, struct rt_qspi_configuration *qspi_cfg)
  47. {
  48. int result = RT_EOK;
  49. unsigned int i = 0;
  50. crm_clocks_freq_type clocks;
  51. rt_uint8_t qspi_div_tab[] = {2, 4, 6, 8, 3, 5, 10, 12};
  52. RT_ASSERT(device != RT_NULL);
  53. RT_ASSERT(qspi_cfg != RT_NULL);
  54. struct rt_spi_configuration *cfg = &qspi_cfg->parent;
  55. struct at32_qspi_bus *qspi_bus = device->parent.bus->parent.user_data;
  56. at32_msp_qspi_init(qspi_bus->qspi_x);
  57. /* switch to cmd port */
  58. qspi_xip_enable(qspi_bus->qspi_x, FALSE);
  59. /* get clocks and config qspi clock div */
  60. crm_clocks_freq_get(&clocks);
  61. while (cfg->max_hz < clocks.ahb_freq / qspi_div_tab[i])
  62. {
  63. i++;
  64. if (i == 8)
  65. {
  66. LOG_E("qspi init failed, qspi frequency(%d) is too low.", cfg->max_hz);
  67. return -RT_ERROR;
  68. }
  69. }
  70. /* set qspi sclk */
  71. qspi_clk_division_set(qspi_bus->qspi_x, (qspi_clk_div_type)i);
  72. if (!(cfg->mode & RT_SPI_CPOL))
  73. {
  74. /* qspi mode0 */
  75. qspi_sck_mode_set(qspi_bus->qspi_x, QSPI_SCK_MODE_0);
  76. }
  77. else
  78. {
  79. /* qspi mode3 */
  80. qspi_sck_mode_set(qspi_bus->qspi_x, QSPI_SCK_MODE_3);
  81. }
  82. /* flash size */
  83. qspi_bus->qspi_x->fsize = POSITION_VAL(qspi_cfg->medium_size) - 1;
  84. return result;
  85. }
  86. static void qspi_send_cmd(struct at32_qspi_bus *qspi_bus, struct rt_qspi_message *message, rt_bool_t dir)
  87. {
  88. qspi_cmd_type cmd;
  89. RT_ASSERT(qspi_bus != RT_NULL);
  90. RT_ASSERT(message != RT_NULL);
  91. /* set qspi cmd struct */
  92. cmd.instruction_code = message->instruction.content;
  93. cmd.address_code = message->address.content;
  94. cmd.second_dummy_cycle_num = message->dummy_cycles;
  95. /* address length */
  96. if (message->address.size == 0)
  97. {
  98. cmd.address_length = QSPI_CMD_ADRLEN_0_BYTE;
  99. }
  100. else if (message->address.size == 8)
  101. {
  102. cmd.address_length = QSPI_CMD_ADRLEN_1_BYTE;
  103. }
  104. else if (message->address.size == 16)
  105. {
  106. cmd.address_length = QSPI_CMD_ADRLEN_2_BYTE;
  107. }
  108. else if (message->address.size == 24)
  109. {
  110. cmd.address_length = QSPI_CMD_ADRLEN_3_BYTE;
  111. }
  112. else if (message->address.size == 32)
  113. {
  114. cmd.address_length = QSPI_CMD_ADRLEN_4_BYTE;
  115. }
  116. /* instruction length */
  117. if (message->instruction.qspi_lines == 0)
  118. {
  119. cmd.instruction_length = QSPI_CMD_INSLEN_0_BYTE;
  120. }
  121. else
  122. {
  123. cmd.instruction_length = QSPI_CMD_INSLEN_1_BYTE;
  124. }
  125. /* operate mode */
  126. switch(message->instruction.qspi_lines)
  127. {
  128. case 0:
  129. case 1:
  130. {
  131. switch(message->address.qspi_lines)
  132. {
  133. case 0:
  134. case 1:
  135. {
  136. switch(message->qspi_data_lines)
  137. {
  138. case 1:
  139. {
  140. cmd.operation_mode = QSPI_OPERATE_MODE_111;
  141. break;
  142. }
  143. case 2:
  144. {
  145. cmd.operation_mode = QSPI_OPERATE_MODE_112;
  146. break;
  147. }
  148. case 4:
  149. {
  150. cmd.operation_mode = QSPI_OPERATE_MODE_114;
  151. break;
  152. }
  153. default:
  154. {
  155. cmd.operation_mode = QSPI_OPERATE_MODE_111;
  156. break;
  157. }
  158. }
  159. break;
  160. }
  161. case 2:
  162. {
  163. cmd.operation_mode = QSPI_OPERATE_MODE_122;
  164. break;
  165. }
  166. case 4:
  167. {
  168. cmd.operation_mode = QSPI_OPERATE_MODE_144;
  169. break;
  170. }
  171. }
  172. break;
  173. }
  174. case 2:
  175. {
  176. cmd.operation_mode = QSPI_OPERATE_MODE_222;
  177. break;
  178. }
  179. case 4:
  180. {
  181. cmd.operation_mode = QSPI_OPERATE_MODE_444;
  182. break;
  183. }
  184. default:
  185. {
  186. cmd.operation_mode = QSPI_OPERATE_MODE_111;
  187. break;
  188. }
  189. }
  190. cmd.pe_mode_enable = FALSE;
  191. cmd.pe_mode_operate_code = 0;
  192. cmd.read_status_enable = FALSE;
  193. cmd.read_status_config = QSPI_RSTSC_SW_ONCE;
  194. if(dir == 1)
  195. {
  196. cmd.write_data_enable = TRUE;
  197. }
  198. else
  199. {
  200. cmd.write_data_enable = FALSE;
  201. }
  202. cmd.data_counter = message->parent.length;
  203. qspi_cmd_operation_kick(qspi_bus->qspi_x, &cmd);
  204. /* no date need to be processed, wait command completed. */
  205. if(cmd.data_counter == 0)
  206. {
  207. while(qspi_flag_get(qspi_bus->qspi_x, QSPI_CMDSTS_FLAG) == RESET);
  208. qspi_flag_clear(qspi_bus->qspi_x, QSPI_CMDSTS_FLAG);
  209. }
  210. }
  211. static error_status qspi_data_transmit(struct at32_qspi_bus *qspi_bus, rt_uint8_t* buf, rt_uint32_t length, rt_uint32_t timeout)
  212. {
  213. rt_uint32_t index = 0, ticks = 0, len = length;
  214. for(index = 0; index < len; index++)
  215. {
  216. /* wait fifo ready */
  217. ticks = 0;
  218. while((qspi_flag_get(qspi_bus->qspi_x, QSPI_TXFIFORDY_FLAG) == RESET) && (ticks <= timeout))
  219. {
  220. ticks ++;
  221. }
  222. if(ticks >= timeout)
  223. {
  224. return ERROR;
  225. }
  226. /* write data */
  227. qspi_byte_write(qspi_bus->qspi_x, *buf++);
  228. }
  229. /* wait command completed. */
  230. ticks = 0;
  231. while((qspi_flag_get(qspi_bus->qspi_x, QSPI_CMDSTS_FLAG) == RESET) && (ticks <= timeout))
  232. {
  233. ticks++;
  234. }
  235. if(ticks >= timeout)
  236. {
  237. return ERROR;
  238. }
  239. /* clear cmdsts flag */
  240. qspi_flag_clear(qspi_bus->qspi_x, QSPI_CMDSTS_FLAG);
  241. return SUCCESS;
  242. }
  243. static error_status qspi_data_receive(struct at32_qspi_bus *qspi_bus, rt_uint8_t* buf, rt_uint32_t length, rt_uint32_t timeout)
  244. {
  245. rt_uint32_t index = 0, ticks = 0, len = 0;
  246. do
  247. {
  248. if(length >= QSPI_FIFO_DEPTH)
  249. {
  250. len = QSPI_FIFO_DEPTH;
  251. }
  252. else
  253. {
  254. len = length;
  255. }
  256. /* wait fifo ready */
  257. ticks = 0;
  258. while((qspi_flag_get(qspi_bus->qspi_x, QSPI_RXFIFORDY_FLAG) == RESET) && (ticks <= timeout))
  259. {
  260. ticks ++;
  261. }
  262. if(ticks >= timeout)
  263. {
  264. return ERROR;
  265. }
  266. /* read data */
  267. for(index = 0; index < len; index++)
  268. {
  269. *buf++ = qspi_byte_read(qspi_bus->qspi_x);
  270. }
  271. length -= len;
  272. } while(length);
  273. /* wait command completed. */
  274. ticks = 0;
  275. while((qspi_flag_get(qspi_bus->qspi_x, QSPI_CMDSTS_FLAG) == RESET) && (ticks <= timeout))
  276. {
  277. ticks++;
  278. }
  279. if(ticks >= timeout)
  280. {
  281. return ERROR;
  282. }
  283. /* clear cmdsts flag */
  284. qspi_flag_clear(qspi_bus->qspi_x, QSPI_CMDSTS_FLAG);
  285. return SUCCESS;
  286. }
  287. static rt_ssize_t qspi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
  288. {
  289. rt_size_t len = 0;
  290. RT_ASSERT(device != RT_NULL);
  291. RT_ASSERT(device->bus != RT_NULL);
  292. struct rt_qspi_message *qspi_message = (struct rt_qspi_message *)message;
  293. struct at32_qspi_bus *qspi_bus = device->bus->parent.user_data;
  294. const rt_uint8_t *sndb = message->send_buf;
  295. rt_uint8_t *rcvb = message->recv_buf;
  296. rt_int32_t length = message->length;
  297. #ifdef BSP_QSPI_USING_SOFTCS
  298. if (message->cs_take && (device->cs_pin != PIN_NONE))
  299. {
  300. rt_pin_write(device->cs_pin, PIN_LOW);
  301. }
  302. #endif
  303. /* send data */
  304. if (sndb)
  305. {
  306. /* dir == 1, send */
  307. qspi_send_cmd(qspi_bus, qspi_message, 1);
  308. if (qspi_message->parent.length != 0)
  309. {
  310. if(qspi_data_transmit(qspi_bus, (rt_uint8_t *)sndb, length, 0xFFFF) == SUCCESS)
  311. {
  312. len = length;
  313. }
  314. else
  315. {
  316. LOG_E("qspi send data failed!");
  317. goto __exit;
  318. }
  319. }
  320. else
  321. {
  322. len = 1;
  323. }
  324. }
  325. /* recv data */
  326. else if (rcvb)
  327. {
  328. /* dir == 0, recv */
  329. qspi_send_cmd(qspi_bus, qspi_message, 0);
  330. if(qspi_data_receive(qspi_bus, (rt_uint8_t *)rcvb, length, 0xFFFF) == SUCCESS)
  331. {
  332. len = length;
  333. }
  334. else
  335. {
  336. LOG_E("qspi recv data failed!");
  337. goto __exit;
  338. }
  339. }
  340. __exit:
  341. #ifdef BSP_QSPI_USING_SOFTCS
  342. if (message->cs_release)
  343. {
  344. rt_pin_write(cs->pin, 1);
  345. }
  346. #endif
  347. return len;
  348. }
  349. static rt_err_t qspi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration)
  350. {
  351. RT_ASSERT(device != RT_NULL);
  352. RT_ASSERT(configuration != RT_NULL);
  353. struct rt_qspi_device *qspi_device = (struct rt_qspi_device *)device;
  354. return at32_qspi_init(qspi_device, &qspi_device->config);
  355. }
  356. static const struct rt_spi_ops at32_qspi_ops =
  357. {
  358. .configure = qspi_configure,
  359. .xfer = qspi_xfer,
  360. };
  361. /**
  362. * @brief This function attach device to QSPI bus.
  363. * @param device_name QSPI device name
  364. * @param cs_pin QSPI cs pin number
  365. * @param data_line_width QSPI data lines width, such as 1, 2, 4
  366. * @param enter_qspi_mode Callback function that lets FLASH enter QSPI mode
  367. * @param exit_qspi_mode Callback function that lets FLASH exit QSPI mode
  368. * @retval 0 : success
  369. * -1 : failed
  370. */
  371. rt_err_t rt_hw_qspi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin, rt_uint8_t data_line_width, void (*enter_qspi_mode)(), void (*exit_qspi_mode)())
  372. {
  373. struct rt_qspi_device *qspi_device = RT_NULL;
  374. rt_err_t result = RT_EOK;
  375. RT_ASSERT(bus_name != RT_NULL);
  376. RT_ASSERT(device_name != RT_NULL);
  377. RT_ASSERT(data_line_width == 1 || data_line_width == 2 || data_line_width == 4);
  378. qspi_device = (struct rt_qspi_device *)rt_malloc(sizeof(struct rt_qspi_device));
  379. if (qspi_device == RT_NULL)
  380. {
  381. LOG_E("no memory, qspi bus attach device failed!");
  382. result = -RT_ENOMEM;
  383. goto __exit;
  384. }
  385. qspi_device->enter_qspi_mode = enter_qspi_mode;
  386. qspi_device->exit_qspi_mode = exit_qspi_mode;
  387. qspi_device->config.qspi_dl_width = data_line_width;
  388. #ifdef BSP_QSPI_USING_SOFTCS
  389. result = rt_spi_bus_attach_device_cspin(&qspi_device->parent, device_name, bus_name, cs_pin, RT_NULL);
  390. #else
  391. result = rt_spi_bus_attach_device_cspin(&qspi_device->parent, device_name, bus_name, PIN_NONE, RT_NULL);
  392. #endif /* BSP_QSPI_USING_SOFTCS */
  393. __exit:
  394. if (result != RT_EOK)
  395. {
  396. if (qspi_device)
  397. {
  398. rt_free(qspi_device);
  399. }
  400. }
  401. return result;
  402. }
  403. static int rt_hw_qspi_bus_init(void)
  404. {
  405. int i = 0;
  406. int result = RT_EOK;
  407. for(i = 0; i < sizeof(at32_qspi_obj) / sizeof(at32_qspi_obj[0]); i++)
  408. {
  409. at32_qspi_obj[i].bus.parent.user_data = &at32_qspi_obj[i];
  410. if(rt_qspi_bus_register(&at32_qspi_obj[i].bus, at32_qspi_obj[i].bus_name, &at32_qspi_ops) == RT_EOK)
  411. {
  412. LOG_D("%s register success", at32_qspi_obj[i].bus_name);
  413. }
  414. else
  415. {
  416. LOG_D("%s register failed", at32_qspi_obj[i].bus_name);
  417. result = -RT_ERROR;
  418. }
  419. }
  420. return result;
  421. }
  422. INIT_BOARD_EXPORT(rt_hw_qspi_bus_init);
  423. #endif /* BSP_USING_QSPI */