drv_qspi.c 13 KB

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