drv_qspi.c 13 KB

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