drv_spi.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. /* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
  2. *
  3. * Redistribution and use in source and binary forms, with or without
  4. * modification, are permitted provided that the following conditions are met:
  5. * 1. Redistributions of source code must retain the above copyright
  6. * notice, this list of conditions and the following disclaimer.
  7. * 2. Redistributions in binary form must reproduce the above copyright
  8. * notice, this list of conditions and the following disclaimer in the
  9. * documentation and/or other materials provided with the distribution.
  10. *
  11. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  12. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  13. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  14. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  15. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  16. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  17. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  18. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  19. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  21. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  22. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. /*
  26. * Copyright (c) 2006-2025 RT-Thread Development Team
  27. *
  28. * SPDX-License-Identifier: Apache-2.0
  29. */
  30. #include <rtthread.h>
  31. #include <rtdevice.h>
  32. #include "drv_spi.h"
  33. #include <drivers/dev_spi.h>
  34. #include <string.h>
  35. #include "drv_gpio.h"
  36. #include "riscv_io.h"
  37. #include "board.h"
  38. #include "ioremap.h"
  39. #include "sysctl_rst.h"
  40. #include "sysctl_clk.h"
  41. #include "cache.h"
  42. #define DBG_TAG "spi"
  43. #include <rtdbg.h>
  44. struct k230_spi_dev
  45. {
  46. struct rt_spi_bus dev;
  47. void *base;
  48. const char *name;
  49. const char *event_name;
  50. rt_ubase_t pa_base;
  51. rt_uint32_t size;
  52. rt_uint8_t idx;
  53. rt_uint8_t rdse;
  54. rt_uint8_t rdsd;
  55. rt_uint8_t max_line;
  56. rt_uint32_t max_hz;
  57. struct rt_event event;
  58. void *send_buf;
  59. void *recv_buf;
  60. rt_size_t send_length;
  61. rt_size_t recv_length;
  62. rt_uint8_t cell_size;
  63. int vector;
  64. };
  65. static rt_err_t k230_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration)
  66. {
  67. RT_ASSERT(device != RT_NULL);
  68. RT_ASSERT(configuration != RT_NULL);
  69. struct k230_spi_dev *qspi_bus = (struct k230_spi_dev *)device->bus;
  70. k230_spi_reg_t *qspi_reg = (k230_spi_reg_t *)qspi_bus->base;
  71. struct rt_qspi_device *dev = (struct rt_qspi_device *)device;
  72. struct rt_qspi_configuration *qspi_cfg = &dev->config;
  73. struct rt_spi_configuration *qspi_cfg_parent = &dev->config.parent;
  74. rt_uint8_t dfs, mode, spi_ff;
  75. rt_uint32_t max_hz, qspi_clk;
  76. if (qspi_cfg->qspi_dl_width > qspi_bus->max_line || qspi_cfg->qspi_dl_width == 0)
  77. {
  78. return -RT_EINVAL;
  79. }
  80. if (qspi_cfg_parent->data_width < 4 || qspi_cfg_parent->data_width > 32)
  81. {
  82. return -RT_EINVAL;
  83. }
  84. /* Check if the clock frequency exceeds the hardware limits */
  85. max_hz = qspi_cfg_parent->max_hz;
  86. if (max_hz > qspi_bus->max_hz)
  87. {
  88. max_hz = qspi_bus->max_hz;
  89. }
  90. /* Get QSPI Controller Clock Frequency */
  91. if (qspi_bus->idx == 0)
  92. {
  93. qspi_clk = sysctl_clk_get_leaf_freq(SYSCTL_CLK_SSI0);
  94. }
  95. else if (qspi_bus->idx == 1)
  96. {
  97. qspi_clk = sysctl_clk_get_leaf_freq(SYSCTL_CLK_SSI1);
  98. }
  99. else if (qspi_bus->idx == 2)
  100. {
  101. qspi_clk = sysctl_clk_get_leaf_freq(SYSCTL_CLK_SSI2);
  102. }
  103. else
  104. {
  105. return -RT_EINVAL;
  106. }
  107. /* Set SPI_FRF to config SPI mode*/
  108. if (qspi_cfg->qspi_dl_width == 1)
  109. {
  110. spi_ff = SPI_FRF_STD_SPI;
  111. }
  112. else if (qspi_cfg->qspi_dl_width == 2)
  113. {
  114. spi_ff = SPI_FRF_DUAL_SPI;
  115. }
  116. else if (qspi_cfg->qspi_dl_width == 4)
  117. {
  118. spi_ff = SPI_FRF_QUAD_SPI;
  119. }
  120. else if (qspi_cfg->qspi_dl_width == 8)
  121. {
  122. spi_ff = SPI_FRF_OCT_SPI;
  123. }
  124. else
  125. {
  126. return -RT_EINVAL;
  127. }
  128. /*
  129. * dfs: Data Frame Size, Write dfs into bits 8-9 of the register ctrlr0
  130. * mode: SPI mode(CPOL and CPHA),Write mode into bits 0-4 of the register ctrlr0
  131. */
  132. mode = qspi_cfg_parent->mode & RT_SPI_MODE_3;
  133. dfs = qspi_cfg_parent->data_width - 1;
  134. qspi_reg->ssienr = 0;
  135. qspi_reg->ser = 0;
  136. qspi_reg->baudr = qspi_clk / max_hz;
  137. qspi_reg->rx_sample_delay = qspi_bus->rdse << 16 | qspi_bus->rdsd;
  138. qspi_reg->axiawlen = SSIC_AXI_BLW << 8;
  139. qspi_reg->axiarlen = SSIC_AXI_BLW << 8;
  140. qspi_reg->ctrlr0 = (dfs) | (mode << 8) | (spi_ff << 22);
  141. return RT_EOK;
  142. }
  143. static rt_ssize_t k230_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
  144. {
  145. struct k230_spi_dev *qspi_bus = (struct k230_spi_dev *)device->bus;
  146. k230_spi_reg_t *qspi_reg = (k230_spi_reg_t *)qspi_bus->base;
  147. struct rt_qspi_device *dev = (struct rt_qspi_device *)device;
  148. struct rt_qspi_configuration *qspi_cfg = &dev->config;
  149. struct rt_spi_configuration *qspi_cfg_parent = &dev->config.parent;
  150. struct rt_qspi_message *msg = (struct rt_qspi_message *)message;
  151. struct rt_spi_message *msg_parent = message;
  152. /* Multi-line SPI transfers (2, 4, or 8 lines) DSPI QSPI OSPI */
  153. if (msg->qspi_data_lines > 1)
  154. {
  155. rt_uint8_t trans_type = 0;
  156. if (msg->qspi_data_lines > qspi_cfg->qspi_dl_width)
  157. {
  158. LOG_E("data line is invalid");
  159. return 0;
  160. }
  161. /* Check other parameters */
  162. if (qspi_cfg_parent->data_width & (msg->qspi_data_lines - 1))
  163. {
  164. LOG_E("data line and data width do not match");
  165. return 0;
  166. }
  167. if (msg->instruction.qspi_lines != 1 && msg->instruction.qspi_lines != msg->qspi_data_lines)
  168. {
  169. LOG_E("instruction line is invalid");
  170. return 0;
  171. }
  172. if (msg->address.size & 3 || msg->address.size > 32)
  173. {
  174. LOG_E("address size is invalid");
  175. return 0;
  176. }
  177. if (msg->address.size && msg->address.qspi_lines != 1 && msg->address.qspi_lines != msg->qspi_data_lines)
  178. {
  179. LOG_E("address line is invalid");
  180. return 0;
  181. }
  182. if (msg_parent->length > 0x10000)
  183. {
  184. LOG_E("data length is invalid, more than 0x10000");
  185. return 0;
  186. }
  187. if (msg->instruction.qspi_lines != 1)
  188. {
  189. trans_type = 2;
  190. }
  191. if (msg->address.size)
  192. {
  193. if (msg->address.qspi_lines != 1)
  194. {
  195. trans_type = trans_type ? trans_type : 1;
  196. }
  197. else if (trans_type != 0)
  198. {
  199. LOG_E("instruction or address line is invalid");
  200. return 0;
  201. }
  202. }
  203. if (msg->dummy_cycles > 31)
  204. {
  205. LOG_E("dummy cycle is invalid");
  206. return 0;
  207. }
  208. rt_uint8_t tmod = msg_parent->recv_buf ? SPI_TMOD_RO : SPI_TMOD_TO;
  209. rt_size_t length = msg_parent->length;
  210. rt_size_t txfthr = length > (SSIC_TX_ABW / 2) ? (SSIC_TX_ABW / 2) : length - 1;
  211. rt_uint8_t cell_size = (qspi_cfg_parent->data_width + 7) >> 3;
  212. rt_uint8_t *buf = RT_NULL;
  213. /* Allocate buffer for DMA transfer */
  214. if (length)
  215. {
  216. buf = rt_malloc_align(CACHE_ALIGN_TOP(length * cell_size), L1_CACHE_BYTES);
  217. if (buf == RT_NULL)
  218. {
  219. LOG_E("alloc mem error");
  220. return 0;
  221. }
  222. }
  223. /* msg->address.size & ~0x03: Round address.size down to the nearest multiple of 4 and write it to ADDR_L[5:2] */
  224. qspi_reg->spi_ctrlr0 = trans_type | (msg->address.size & ~0x03) | (0x2 << 8) | (msg->dummy_cycles << 11);
  225. qspi_reg->ctrlr0 &= ~((3 << 22) | (3 << 10));
  226. /* Config SPI frame format and transmission mode */
  227. if (length)
  228. {
  229. qspi_reg->ctrlr0 |= (tmod << 10);
  230. qspi_reg->txftlr = (txfthr << 16) | (SSIC_TX_ABW / 2);
  231. qspi_reg->rxftlr = (SSIC_RX_ABW - 1);
  232. qspi_reg->imr = (1 << 11) | (1 << 8);
  233. qspi_reg->dmacr = (1 << 6) | (3 << 3) | (1 << 2);
  234. qspi_reg->ctrlr1 = length - 1;
  235. qspi_reg->spidr = msg->instruction.content;
  236. qspi_reg->spiar = msg->address.content;
  237. if (tmod == SPI_TMOD_TO)
  238. {
  239. rt_memcpy(buf, msg_parent->send_buf, length * cell_size);
  240. rt_hw_cpu_dcache_clean(buf, CACHE_ALIGN_TOP(length * cell_size));
  241. }
  242. qspi_reg->axiar0 = (rt_uint32_t)((uint64_t)buf);
  243. qspi_reg->axiar1 = (rt_uint32_t)((uint64_t)buf >> 32);
  244. }
  245. else
  246. {
  247. tmod = SPI_TMOD_TO;
  248. qspi_reg->ctrlr0 |= (tmod << 10);
  249. qspi_reg->txftlr = ((SSIC_TX_ABW - 1) << 16) | (SSIC_TX_ABW - 1);
  250. qspi_reg->rxftlr = (SSIC_RX_ABW - 1);
  251. qspi_reg->imr = 0;
  252. qspi_reg->dmacr = 0;
  253. }
  254. rt_event_control(&qspi_bus->event, RT_IPC_CMD_RESET, 0);
  255. qspi_reg->ser = 1;
  256. qspi_reg->ssienr = 1;
  257. rt_uint32_t event;
  258. rt_err_t err;
  259. /*
  260. * Config QSPI address and instruction,
  261. * if data is empty, unable dma and send address and instruction by write data register.
  262. */
  263. if (length)
  264. {
  265. err = rt_event_recv(&qspi_bus->event, BIT(SSI_DONE) | BIT(SSI_AXIE),
  266. RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 1000, &event);
  267. }
  268. else
  269. {
  270. err = RT_EOK;
  271. event = 0;
  272. qspi_reg->dr[0] = msg->instruction.content;
  273. length++;
  274. if (msg->address.size)
  275. {
  276. qspi_reg->dr[0] = msg->address.content;
  277. length++;
  278. }
  279. qspi_reg->txftlr = 0;
  280. /* Wait for SPI transfer to complete (busy-wait) */
  281. while ((qspi_reg->sr & 0x5) != 0x4)
  282. {
  283. /* Busy wait */
  284. }
  285. }
  286. qspi_reg->ser = 0;
  287. qspi_reg->ssienr = 0;
  288. if (err == -RT_ETIMEOUT)
  289. {
  290. LOG_E("qspi%d transfer data timeout", qspi_bus->idx);
  291. if (buf)
  292. {
  293. rt_free_align(buf);
  294. }
  295. return 0;
  296. }
  297. if (event & BIT(SSI_AXIE))
  298. {
  299. LOG_E("qspi%d dma error", qspi_bus->idx);
  300. if (buf)
  301. {
  302. rt_free_align(buf);
  303. }
  304. return 0;
  305. }
  306. /* Read data from FIFO */
  307. if (tmod == SPI_TMOD_RO)
  308. {
  309. rt_hw_cpu_dcache_invalidate(buf, CACHE_ALIGN_TOP(length * cell_size));
  310. rt_memcpy(msg_parent->recv_buf, buf, length * cell_size);
  311. }
  312. if (buf)
  313. {
  314. rt_free_align(buf);
  315. }
  316. return length;
  317. }
  318. /* Standard SPI transfers */
  319. else
  320. {
  321. if (msg_parent->length == 0)
  322. {
  323. return 0;
  324. }
  325. rt_uint8_t cell_size = (qspi_cfg_parent->data_width + 7) >> 3;
  326. rt_size_t length = msg_parent->length;
  327. rt_size_t count = length > 0x10000 ? 0x10000 : length;
  328. rt_size_t send_single = 0, send_length = 0, recv_single = 0, recv_length = 0;
  329. void *send_buf = (void *)msg_parent->send_buf;
  330. void *recv_buf = msg_parent->recv_buf;
  331. rt_uint8_t tmod = send_buf ? SPI_TMOD_TO : SPI_TMOD_EPROMREAD;
  332. tmod = recv_buf ? tmod & SPI_TMOD_RO : tmod;
  333. /* Check Qspi Parameters */
  334. if (tmod == SPI_TMOD_EPROMREAD)
  335. {
  336. LOG_E("send_buf and recv_buf cannot both be empty");
  337. return 0;
  338. }
  339. if (tmod == SPI_TMOD_RO && qspi_cfg_parent->data_width == 8)
  340. {
  341. if ((msg->address.size & 7) || (msg->dummy_cycles & 7))
  342. {
  343. LOG_E("instruction, address, dummy_cycles invalid");
  344. LOG_E("For read-only mode the instruction, address, dummy_cycles must be set to zero");
  345. LOG_E("For eeprom-read mode the instruction, address, dummy_cycles must be set to multiples of 8");
  346. return 0;
  347. }
  348. else if (msg->address.size)
  349. {
  350. if (length > 0x10000)
  351. {
  352. LOG_E("For eeprom-read mode, data length cannot exceed 0x10000");
  353. return 0;
  354. }
  355. tmod = SPI_TMOD_EPROMREAD;
  356. }
  357. }
  358. /* Prepare the send buffer*/
  359. if (send_buf)
  360. {
  361. send_single = count;
  362. send_buf = rt_malloc(count * cell_size);
  363. if (send_buf == RT_NULL)
  364. {
  365. LOG_E("alloc mem error");
  366. return 0;
  367. }
  368. rt_memcpy(send_buf, msg_parent->send_buf, count * cell_size);
  369. }
  370. else if (tmod == SPI_TMOD_EPROMREAD)
  371. {
  372. send_single = 1 + msg->address.size / 8 + msg->dummy_cycles / 8;
  373. send_buf = rt_malloc(send_single);
  374. if (send_buf == RT_NULL)
  375. {
  376. LOG_E("alloc mem error");
  377. return 0;
  378. }
  379. rt_uint8_t *temp = send_buf;
  380. *temp++ = msg->instruction.content;
  381. for (int i = msg->address.size / 8; i; i--)
  382. {
  383. *temp++ = msg->address.content >> ((i - 1) * 8);
  384. }
  385. for (int i = msg->dummy_cycles / 8; i; i--)
  386. {
  387. *temp++ = 0xFF;
  388. }
  389. }
  390. /* Prepare the receive buffer*/
  391. if (recv_buf)
  392. {
  393. recv_single = count;
  394. recv_buf = rt_malloc(count * cell_size);
  395. if (recv_buf == RT_NULL)
  396. {
  397. LOG_E("alloc mem error");
  398. if (send_buf)
  399. {
  400. rt_free(send_buf);
  401. }
  402. return 0;
  403. }
  404. }
  405. send_length = 0;
  406. recv_length = 0;
  407. qspi_bus->cell_size = cell_size;
  408. qspi_bus->send_buf = send_buf;
  409. qspi_bus->recv_buf = recv_buf;
  410. qspi_bus->send_length = send_single;
  411. qspi_bus->recv_length = recv_single;
  412. qspi_reg->ctrlr0 &= ~((3 << 22) | (3 << 10));
  413. qspi_reg->ctrlr0 |= (tmod << 10);
  414. qspi_reg->ctrlr1 = count - 1;
  415. qspi_reg->txftlr = ((SSIC_TX_ABW / 2) << 16) | (SSIC_TX_ABW / 2);
  416. qspi_reg->rxftlr = count >= (SSIC_RX_ABW / 2) ? (SSIC_RX_ABW / 2 - 1) : count - 1;
  417. qspi_reg->dmacr = 0;
  418. /* Interrupt transmit or receive */
  419. qspi_reg->imr = (1 << 4) | (1 << 0);
  420. rt_event_control(&qspi_bus->event, RT_IPC_CMD_RESET, 0);
  421. qspi_reg->ser = 1;
  422. qspi_reg->ssienr = 1;
  423. if (tmod == SPI_TMOD_RO)
  424. qspi_reg->dr[0] = 0;
  425. rt_uint32_t event;
  426. rt_err_t err;
  427. while (RT_TRUE)
  428. {
  429. /* Waiting for transfer events */
  430. err = rt_event_recv(&qspi_bus->event, BIT(SSI_TXE) | BIT(SSI_RXF),
  431. RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 10000, &event);
  432. if (err == -RT_ETIMEOUT)
  433. {
  434. LOG_E("qspi%d transfer data timeout", qspi_bus->idx);
  435. length = 0;
  436. if (send_buf)
  437. {
  438. rt_free(send_buf);
  439. }
  440. if (recv_buf)
  441. {
  442. rt_free(recv_buf);
  443. }
  444. return 0;
  445. }
  446. /* Handle Transmit buffer empty */
  447. if (event & BIT(SSI_TXE))
  448. {
  449. send_length += send_single;
  450. if (send_length < length && tmod <= SPI_TMOD_TO)
  451. {
  452. count = length - send_length;
  453. count = count > 0x10000 ? 0x10000 : count;
  454. rt_memcpy(send_buf, msg_parent->send_buf + send_length * cell_size, count * cell_size);
  455. qspi_bus->send_buf = send_buf;
  456. qspi_bus->send_length = count;
  457. send_single = count;
  458. qspi_reg->txftlr = ((SSIC_TX_ABW / 2) << 16) | (SSIC_TX_ABW / 2);
  459. if (tmod == SPI_TMOD_TO)
  460. qspi_reg->imr |= (1 << 0);
  461. }
  462. else if (tmod == SPI_TMOD_TO)
  463. {
  464. /* Wait for SPI transfer to complete (busy-wait) */
  465. while ((qspi_reg->sr & 0x5) != 0x4)
  466. {
  467. /* Busy wait */
  468. }
  469. break;
  470. }
  471. }
  472. /* Handle receive buffer full */
  473. if (event & BIT(SSI_RXF))
  474. {
  475. rt_memcpy(msg_parent->recv_buf + recv_length * cell_size, recv_buf, recv_single * cell_size);
  476. recv_length += recv_single;
  477. if (recv_length >= length)
  478. {
  479. break;
  480. }
  481. count = length - recv_length;
  482. count = count > 0x10000 ? 0x10000 : count;
  483. qspi_bus->recv_buf = recv_buf;
  484. qspi_bus->recv_length = count;
  485. recv_single = count;
  486. qspi_reg->rxftlr = count >= (SSIC_RX_ABW / 2) ? (SSIC_RX_ABW / 2 - 1) : count - 1;
  487. if (tmod == SPI_TMOD_TR)
  488. {
  489. qspi_reg->imr |= (1 << 0) | (1 << 4);
  490. }
  491. else if (tmod == SPI_TMOD_RO)
  492. {
  493. qspi_reg->imr |= (1 << 4);
  494. qspi_reg->ssienr = 0;
  495. qspi_reg->ctrlr1 = count - 1;
  496. qspi_reg->ssienr = 1;
  497. /* Trigger two dummy transfers to restart SPI read in read-only mode.
  498. * This is required by the hardware to ensure correct data reception.
  499. */
  500. qspi_reg->dr[0] = 0;
  501. qspi_reg->dr[0] = 0;
  502. }
  503. }
  504. }
  505. qspi_reg->ser = 0;
  506. qspi_reg->ssienr = 0;
  507. if (send_buf)
  508. {
  509. rt_free(send_buf);
  510. }
  511. if (recv_buf)
  512. {
  513. rt_free(recv_buf);
  514. }
  515. return length;
  516. }
  517. return 0;
  518. }
  519. static const struct rt_spi_ops k230_qspi_ops =
  520. {
  521. .configure = k230_spi_configure,
  522. .xfer = k230_spi_xfer,
  523. };
  524. static void k230_spi_irq(int vector, void *param)
  525. {
  526. struct k230_spi_dev *qspi_bus = param;
  527. k230_spi_reg_t *qspi_reg = (k230_spi_reg_t *)qspi_bus->base;
  528. vector -= IRQN_SPI0;
  529. vector %= (IRQN_SPI1 - IRQN_SPI0);
  530. /* Handle transmit buffer empty interrupt */
  531. if (vector == SSI_TXE)
  532. {
  533. if (qspi_bus->send_buf == RT_NULL)
  534. {
  535. qspi_reg->imr &= ~1;
  536. }
  537. else if (qspi_bus->cell_size == 1)
  538. {
  539. while ((qspi_bus->send_length) && (qspi_reg->sr & 2))
  540. {
  541. qspi_reg->dr[0] = *((rt_uint8_t *)qspi_bus->send_buf);
  542. qspi_bus->send_buf++;
  543. qspi_bus->send_length--;
  544. }
  545. }
  546. else if (qspi_bus->cell_size == 2)
  547. {
  548. while ((qspi_bus->send_length) && (qspi_reg->sr & 2))
  549. {
  550. qspi_reg->dr[0] = *((rt_uint16_t *)qspi_bus->send_buf);
  551. qspi_bus->send_buf += 2;
  552. qspi_bus->send_length--;
  553. }
  554. }
  555. else if (qspi_bus->cell_size == 4)
  556. {
  557. while ((qspi_bus->send_length) && (qspi_reg->sr & 2))
  558. {
  559. qspi_reg->dr[0] = *((rt_uint32_t *)qspi_bus->send_buf);
  560. qspi_bus->send_buf += 4;
  561. qspi_bus->send_length--;
  562. }
  563. }
  564. else
  565. {
  566. LOG_E("qspi%d datawidth error", qspi_bus->idx);
  567. }
  568. if (qspi_bus->send_length == 0)
  569. {
  570. if (((qspi_reg->ctrlr0 >> 10) & SPI_TMOD_EPROMREAD) == SPI_TMOD_TO)
  571. {
  572. if (qspi_reg->txftlr)
  573. return;
  574. }
  575. qspi_reg->txftlr = 0;
  576. qspi_reg->imr &= ~1;
  577. rt_event_send(&qspi_bus->event, BIT(SSI_TXE));
  578. }
  579. }
  580. /* Handle receive buffer full interrupt */
  581. else if (vector == SSI_RXF)
  582. {
  583. if (qspi_bus->recv_buf == RT_NULL)
  584. {
  585. qspi_reg->imr &= ~0x10;
  586. }
  587. else if (qspi_bus->cell_size == 1)
  588. {
  589. while ((qspi_bus->recv_length) && (qspi_reg->sr & 8))
  590. {
  591. *((rt_uint8_t *)qspi_bus->recv_buf) = qspi_reg->dr[0];
  592. qspi_bus->recv_buf++;
  593. qspi_bus->recv_length--;
  594. }
  595. }
  596. else if (qspi_bus->cell_size == 2)
  597. {
  598. while ((qspi_bus->recv_length) && (qspi_reg->sr & 8))
  599. {
  600. *((rt_uint16_t *)qspi_bus->recv_buf) = qspi_reg->dr[0];
  601. qspi_bus->recv_buf += 2;
  602. qspi_bus->recv_length--;
  603. }
  604. }
  605. else if (qspi_bus->cell_size == 4)
  606. {
  607. while ((qspi_bus->recv_length) && (qspi_reg->sr & 8))
  608. {
  609. *((rt_uint32_t *)qspi_bus->recv_buf) = qspi_reg->dr[0];
  610. qspi_bus->recv_buf += 4;
  611. qspi_bus->recv_length--;
  612. }
  613. }
  614. else
  615. {
  616. LOG_E("qspi%d datawidth error", qspi_bus->idx);
  617. }
  618. if (qspi_bus->recv_length == 0)
  619. {
  620. qspi_reg->imr &= ~0x10;
  621. rt_event_send(&qspi_bus->event, BIT(SSI_RXF));
  622. }
  623. else if (qspi_bus->recv_length <= qspi_reg->rxftlr)
  624. {
  625. qspi_reg->rxftlr = qspi_bus->recv_length - 1;
  626. }
  627. }
  628. /* Handle transfer complete interrupt */
  629. else if (vector == SSI_DONE)
  630. {
  631. /* Clear transfer done interrupt by reading donecr register */
  632. (void)qspi_reg->donecr;
  633. rt_event_send(&qspi_bus->event, BIT(SSI_DONE));
  634. }
  635. /* Handle DMA error interrupt */
  636. else if (vector == SSI_AXIE)
  637. {
  638. /* Clear AXI error interrupt by reading axiecr register */
  639. (void)qspi_reg->axiecr;
  640. rt_event_send(&qspi_bus->event, BIT(SSI_AXIE));
  641. }
  642. }
  643. static struct k230_spi_dev k230_spi_devs[] =
  644. {
  645. #ifdef BSP_USING_SPI0
  646. {
  647. .name = "spi0",
  648. .event_name = "spi0_event",
  649. .pa_base = SPI_OPI_BASE_ADDR,
  650. .size = SPI_OPI_IO_SIZE,
  651. .vector = IRQN_SPI0,
  652. .idx = 0,
  653. .rdse = 0,
  654. .rdsd = 0,
  655. .max_line = 8,
  656. .max_hz = 200000000,
  657. },
  658. #endif
  659. #ifdef BSP_USING_SPI1
  660. {
  661. .name = "spi1",
  662. .event_name = "spi1_event",
  663. .pa_base = SPI_QOPI_BASE_ADDR,
  664. .size = SPI_QOPI_IO_SIZE / 2,
  665. .vector = IRQN_SPI1,
  666. .idx = 1,
  667. .rdse = 0,
  668. .rdsd = 0,
  669. .max_line = 4,
  670. .max_hz = 100000000,
  671. },
  672. #endif
  673. #ifdef BSP_USING_SPI2
  674. {
  675. .name = "spi2",
  676. .event_name = "spi2_event",
  677. .pa_base = SPI_QOPI_BASE_ADDR + SPI_QOPI_IO_SIZE / 2,
  678. .size = SPI_QOPI_IO_SIZE / 2,
  679. .vector = IRQN_SPI2,
  680. .idx = 2,
  681. .rdse = 0,
  682. .rdsd = 0,
  683. .max_line = 4,
  684. .max_hz = 100000000,
  685. },
  686. #endif
  687. };
  688. int rt_hw_qspi_bus_init(void)
  689. {
  690. rt_err_t ret;
  691. int i;
  692. for (i = 0; i < sizeof(k230_spi_devs) / sizeof(k230_spi_devs[0]); i++)
  693. {
  694. k230_spi_devs[i].base = rt_ioremap((void *)k230_spi_devs[i].pa_base, k230_spi_devs[i].size);
  695. ret = rt_qspi_bus_register(&k230_spi_devs[i].dev, k230_spi_devs[i].name, &k230_qspi_ops);
  696. if (ret)
  697. {
  698. LOG_E("%s register fail", k230_spi_devs[i].name);
  699. return ret;
  700. }
  701. rt_event_init(&k230_spi_devs[i].event, k230_spi_devs[i].event_name, RT_IPC_FLAG_PRIO);
  702. rt_hw_interrupt_install(k230_spi_devs[i].vector + SSI_TXE, k230_spi_irq, &k230_spi_devs[i], k230_spi_devs[i].name);
  703. rt_hw_interrupt_umask(k230_spi_devs[i].vector + SSI_TXE);
  704. rt_hw_interrupt_install(k230_spi_devs[i].vector + SSI_RXF, k230_spi_irq, &k230_spi_devs[i], k230_spi_devs[i].name);
  705. rt_hw_interrupt_umask(k230_spi_devs[i].vector + SSI_RXF);
  706. rt_hw_interrupt_install(k230_spi_devs[i].vector + SSI_DONE, k230_spi_irq, &k230_spi_devs[i], k230_spi_devs[i].name);
  707. rt_hw_interrupt_umask(k230_spi_devs[i].vector + SSI_DONE);
  708. rt_hw_interrupt_install(k230_spi_devs[i].vector + SSI_AXIE, k230_spi_irq, &k230_spi_devs[i], k230_spi_devs[i].name);
  709. rt_hw_interrupt_umask(k230_spi_devs[i].vector + SSI_AXIE);
  710. }
  711. return RT_EOK;
  712. }
  713. INIT_DEVICE_EXPORT(rt_hw_qspi_bus_init);