drv_spi.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-05-01 flyingcys first version
  9. */
  10. #include <rtthread.h>
  11. #include <rthw.h>
  12. #include <rtdevice.h>
  13. #include "board.h"
  14. #include "drv_spi.h"
  15. #ifdef BSP_USING_SPI
  16. #define DBG_LEVEL DBG_LOG
  17. #include <rtdbg.h>
  18. #define LOG_TAG "drv.spi"
  19. #define DMA_MAX_BUFSIZE 4095
  20. #if defined(BSP_USING_BL808)
  21. #define NOCACHE_BUFSTART 0x22026000
  22. #define NOCACHE_BUFSIZE (40 * 1024)
  23. #elif defined (BSP_USING_BL61X)
  24. #define NOCACHE_BUFSTART 0x22FC6000
  25. #define NOCACHE_BUFSIZE (104 * 1024)
  26. #endif
  27. struct bl_device_spi
  28. {
  29. struct rt_spi_bus spi_bus;
  30. struct bflb_device_s *spi;
  31. #if defined(BSP_SPI_TX_USING_DMA)
  32. struct bflb_device_s *dma_tx;
  33. rt_uint32_t dma_dst_req;
  34. rt_sem_t sem_tx;
  35. #endif
  36. #if defined(BSP_SPI_RX_USING_DMA)
  37. struct bflb_device_s *dma_rx;
  38. rt_uint32_t dma_src_req;
  39. rt_sem_t sem_rx;
  40. #endif
  41. };
  42. #if defined(BSP_SPI_TX_USING_DMA) && defined(BSP_SPI_TX_DMA_NOCACHE_BUFSIZE)
  43. static ATTR_NOCACHE_NOINIT_RAM_SECTION rt_uint8_t dma_tx_buf[BSP_SPI_TX_DMA_NOCACHE_BUFSIZE];
  44. #endif
  45. #if defined(BSP_SPI_RX_USING_DMA) && defined(BSP_SPI_RX_DMA_NOCACHE_BUFSIZE)
  46. static ATTR_NOCACHE_NOINIT_RAM_SECTION rt_uint8_t dma_rx_buf[BSP_SPI_RX_DMA_NOCACHE_BUFSIZE];
  47. #endif
  48. #if defined(BSP_SPI_TX_USING_DMA)
  49. static void spi_bl_spi_dma_tx_isr(void *arg)
  50. {
  51. struct bl_device_spi *bl_spi = (struct bl_device_spi *)arg;
  52. LOG_D("spi dma tx done ");
  53. rt_sem_release(bl_spi->sem_tx);
  54. }
  55. #endif
  56. #if defined(BSP_SPI_RX_USING_DMA)
  57. void spi_dma_rx_isr(void *arg)
  58. {
  59. struct bl_device_spi *bl_spi = (struct bl_device_spi *)arg;
  60. LOG_D("spi dma rx done");
  61. rt_sem_release(bl_spi->sem_rx);
  62. }
  63. #endif
  64. static rt_err_t spi_configure(struct rt_spi_device *device,
  65. struct rt_spi_configuration *cfg)
  66. {
  67. RT_ASSERT(device != RT_NULL);
  68. RT_ASSERT(device->bus != RT_NULL);
  69. RT_ASSERT(device->bus->parent.user_data != RT_NULL);
  70. RT_ASSERT(cfg != RT_NULL);
  71. struct bflb_spi_config_s spi_cfg = {
  72. .freq = 1 * 1000 * 1000,
  73. .role = SPI_ROLE_MASTER,
  74. .mode = SPI_MODE3,
  75. .data_width = SPI_DATA_WIDTH_8BIT,
  76. .bit_order = SPI_BIT_MSB,
  77. .byte_order = SPI_BYTE_LSB,
  78. .tx_fifo_threshold = 0,
  79. .rx_fifo_threshold = 0,
  80. };
  81. switch (cfg->mode & RT_SPI_MODE_3)
  82. {
  83. case RT_SPI_MODE_0: /* RT_SPI_CPOL:0 , RT_SPI_CPHA:0 */
  84. spi_cfg.mode = SPI_MODE0;
  85. break;
  86. case RT_SPI_MODE_1: /* RT_SPI_CPOL:0 , RT_SPI_CPHA:1 */
  87. spi_cfg.mode = SPI_MODE1;
  88. break;
  89. case RT_SPI_MODE_2: /* RT_SPI_CPOL:1 , RT_SPI_CPHA:0 */
  90. spi_cfg.mode = SPI_MODE2;
  91. break;
  92. case RT_SPI_MODE_3: /* RT_SPI_CPOL:1 , RT_SPI_CPHA:1 */
  93. spi_cfg.mode = SPI_MODE3;
  94. break;
  95. default:
  96. LOG_E("spi_configure mode error %x\n", cfg->mode);
  97. return -RT_EINVAL;
  98. }
  99. switch (cfg->data_width)
  100. {
  101. case 8:
  102. spi_cfg.data_width = SPI_DATA_WIDTH_8BIT;
  103. break;
  104. case 16:
  105. spi_cfg.data_width = SPI_DATA_WIDTH_16BIT;
  106. break;
  107. case 24:
  108. spi_cfg.data_width = SPI_DATA_WIDTH_24BIT;
  109. break;
  110. case 32:
  111. spi_cfg.data_width = SPI_DATA_WIDTH_32BIT;
  112. break;
  113. default:
  114. LOG_E("spi_configure data_width error %x\n", cfg->data_width);
  115. return RT_ERROR;
  116. }
  117. spi_cfg.freq = cfg->max_hz;
  118. if (cfg->mode & RT_SPI_MSB)
  119. spi_cfg.bit_order = SPI_BIT_MSB;
  120. else
  121. spi_cfg.bit_order = SPI_BIT_LSB;
  122. if (cfg->mode & RT_SPI_SLAVE)
  123. spi_cfg.role = SPI_ROLE_SLAVE;
  124. else
  125. spi_cfg.role = SPI_ROLE_MASTER;
  126. struct bl_device_spi *bl_spi;
  127. bl_spi = (struct bl_device_spi *)device->bus->parent.user_data;
  128. bflb_spi_init(bl_spi->spi, &spi_cfg);
  129. #if defined(BSP_SPI_TX_USING_DMA)
  130. bl_spi->sem_tx = rt_sem_create("dam_tx", 0, RT_IPC_FLAG_PRIO);
  131. if (bl_spi->sem_tx == RT_NULL)
  132. {
  133. LOG_E("rt_sem_create dma_tx error");
  134. return -RT_ENOMEM;
  135. }
  136. rt_uint8_t tx_data_width = DMA_DATA_WIDTH_8BIT;
  137. if (spi_cfg.data_width == SPI_DATA_WIDTH_8BIT)
  138. tx_data_width = DMA_DATA_WIDTH_8BIT;
  139. else if (spi_cfg.data_width == SPI_DATA_WIDTH_16BIT)
  140. tx_data_width = DMA_DATA_WIDTH_16BIT;
  141. else if (spi_cfg.data_width == SPI_DATA_WIDTH_32BIT)
  142. tx_data_width = DMA_DATA_WIDTH_32BIT;
  143. else
  144. {
  145. LOG_E("spi dma not support 24bit...");
  146. return -RT_EINVAL;
  147. }
  148. struct bflb_dma_channel_config_s tx_config = {
  149. .direction = DMA_MEMORY_TO_PERIPH,
  150. .src_req = DMA_REQUEST_NONE,
  151. .dst_req = bl_spi->dma_dst_req,
  152. .src_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
  153. .dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
  154. .src_burst_count = DMA_BURST_INCR1,
  155. .dst_burst_count = DMA_BURST_INCR1,
  156. .src_width = tx_data_width,
  157. .dst_width = tx_data_width,
  158. };
  159. bflb_spi_link_txdma(bl_spi->spi, true);
  160. bflb_dma_channel_init(bl_spi->dma_tx, &tx_config);
  161. bflb_dma_channel_irq_attach(bl_spi->dma_tx, spi_bl_spi_dma_tx_isr, (void *)bl_spi);
  162. #endif
  163. #if defined(BSP_SPI_RX_USING_DMA)
  164. bl_spi->sem_rx = rt_sem_create("dam_rx", 0, RT_IPC_FLAG_PRIO);
  165. if (bl_spi->sem_rx == RT_NULL)
  166. {
  167. LOG_E("rt_sem_create dma_rx error");
  168. return -RT_ENOMEM;
  169. }
  170. rt_uint8_t rx_data_width = DMA_DATA_WIDTH_8BIT;
  171. if (spi_cfg.data_width == SPI_DATA_WIDTH_8BIT)
  172. rx_data_width = DMA_DATA_WIDTH_8BIT;
  173. else if (spi_cfg.data_width == SPI_DATA_WIDTH_16BIT)
  174. rx_data_width = DMA_DATA_WIDTH_16BIT;
  175. else if (spi_cfg.data_width == SPI_DATA_WIDTH_32BIT)
  176. rx_data_width = DMA_DATA_WIDTH_32BIT;
  177. else
  178. {
  179. LOG_E("spi dma not support 24bit...");
  180. return -RT_EINVAL;
  181. }
  182. struct bflb_dma_channel_config_s rx_config = {
  183. .direction = DMA_PERIPH_TO_MEMORY,
  184. .src_req = bl_spi->dma_src_req,
  185. .dst_req = DMA_REQUEST_NONE,
  186. .src_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
  187. .dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
  188. .src_burst_count = DMA_BURST_INCR1,
  189. .dst_burst_count = DMA_BURST_INCR1,
  190. .src_width = rx_data_width,
  191. .dst_width = rx_data_width,
  192. };
  193. bflb_spi_link_rxdma(bl_spi->spi, true);
  194. bflb_dma_channel_init(bl_spi->dma_rx, &rx_config);
  195. bflb_dma_channel_irq_attach(bl_spi->dma_rx, spi_dma_rx_isr, (void *)bl_spi);
  196. #endif
  197. return RT_EOK;
  198. }
  199. #if defined(BSP_SPI_TX_USING_DMA)
  200. static rt_err_t _bl_spi_dma_tx(struct bl_device_spi *bl_spi, rt_uint8_t *src, rt_size_t length)
  201. {
  202. rt_err_t result;
  203. struct bflb_dma_channel_lli_pool_s tx_llipool[1];
  204. struct bflb_dma_channel_lli_transfer_s tx_transfers[1];
  205. tx_transfers[0].src_addr = (rt_uint32_t)src;
  206. tx_transfers[0].dst_addr = (rt_uint32_t)DMA_ADDR_SPI0_TDR;
  207. tx_transfers[0].nbytes = length;
  208. LOG_D("dma tx start...");
  209. rt_kprintf("tx length:%d\n", length);
  210. bflb_dma_channel_lli_reload(bl_spi->dma_tx, tx_llipool, 1, tx_transfers, 1);
  211. bflb_dma_channel_start(bl_spi->dma_tx);
  212. result = rt_sem_take(bl_spi->sem_tx, BSP_SPI_TX_DMA_TIMEOUT);
  213. if (result != RT_EOK)
  214. LOG_E("sem take dma tx error:%d", result);
  215. return result;
  216. }
  217. static rt_err_t _spi_dma_xfer_tx(struct rt_spi_device *device, struct rt_spi_message *message)
  218. {
  219. rt_err_t result = RT_EOK;
  220. rt_uint8_t *src = (rt_uint8_t *)message->send_buf;
  221. rt_size_t length = message->length;
  222. struct bl_device_spi *bl_spi = (struct bl_device_spi *)device->bus->parent.user_data;
  223. #if defined(NOCACHE_BUFSTART) && defined(NOCACHE_BUFSIZE)
  224. if ((message->send_buf < NOCACHE_BUFSTART) || (message->send_buf > (NOCACHE_BUFSTART + NOCACHE_BUFSIZE)))
  225. {
  226. if (length <= BSP_SPI_TX_DMA_NOCACHE_BUFSIZE)
  227. {
  228. memcpy(dma_tx_buf, src, length);
  229. result = _bl_spi_dma_tx(bl_spi, dma_tx_buf, length);
  230. }
  231. else
  232. {
  233. while(length > 0)
  234. {
  235. if (length >= BSP_SPI_TX_DMA_NOCACHE_BUFSIZE)
  236. {
  237. memcpy(dma_tx_buf, src, BSP_SPI_TX_DMA_NOCACHE_BUFSIZE);
  238. result = _bl_spi_dma_tx(bl_spi, dma_tx_buf, BSP_SPI_TX_DMA_NOCACHE_BUFSIZE);
  239. if (result != RT_EOK)
  240. break;
  241. length -= BSP_SPI_TX_DMA_NOCACHE_BUFSIZE;
  242. src += BSP_SPI_TX_DMA_NOCACHE_BUFSIZE;
  243. }
  244. else
  245. {
  246. memcpy(dma_tx_buf, src, length);
  247. result = _bl_spi_dma_tx(bl_spi, dma_tx_buf, length);
  248. length = 0;
  249. }
  250. }
  251. }
  252. }
  253. else
  254. #endif
  255. {
  256. if (length <= DMA_MAX_BUFSIZE)
  257. {
  258. result = _bl_spi_dma_tx(bl_spi, src, length);
  259. }
  260. else
  261. {
  262. while(length > 0)
  263. {
  264. if (length >= DMA_MAX_BUFSIZE)
  265. {
  266. result = _bl_spi_dma_tx(bl_spi, src, DMA_MAX_BUFSIZE);
  267. if (result != RT_EOK)
  268. break;
  269. length -= DMA_MAX_BUFSIZE;
  270. src += DMA_MAX_BUFSIZE;
  271. }
  272. else
  273. {
  274. result = _bl_spi_dma_tx(bl_spi, src, length);
  275. length = 0;
  276. }
  277. }
  278. }
  279. }
  280. LOG_D("dma tx finish...");
  281. return result;
  282. }
  283. #endif
  284. #if defined(BSP_SPI_RX_USING_DMA)
  285. static rt_err_t _bl_spi_dma_rx(struct bl_device_spi *bl_spi, rt_uint8_t *dst, rt_size_t length)
  286. {
  287. rt_err_t result;
  288. struct bflb_dma_channel_lli_pool_s rx_llipool[1];
  289. struct bflb_dma_channel_lli_transfer_s rx_transfers[1];
  290. rx_transfers[0].src_addr = (rt_uint32_t)DMA_ADDR_SPI0_RDR;
  291. rx_transfers[0].dst_addr = (rt_uint32_t)dst;
  292. rx_transfers[0].nbytes = length;
  293. bflb_dma_channel_lli_reload(bl_spi->dma_rx, rx_llipool, 1, rx_transfers, 1);
  294. bflb_dma_channel_start(bl_spi->dma_rx);
  295. result = rt_sem_take(bl_spi->sem_rx, BSP_SPI_RX_DMA_TIMEOUT);
  296. if (result != RT_EOK)
  297. LOG_E("sem take dma rx error:%d", result);
  298. return result;
  299. }
  300. static rt_err_t _spi_dma_xfer_rx(struct rt_spi_device *device, struct rt_spi_message *message)
  301. {
  302. rt_err_t result = RT_EOK;
  303. rt_uint8_t *dst = (rt_uint8_t *)message->recv_buf;
  304. rt_size_t length = message->length;
  305. struct bl_device_spi *bl_spi = (struct bl_device_spi *)device->bus->parent.user_data;
  306. #if defined(NOCACHE_BUFSTART) && defined(NOCACHE_BUFSIZE)
  307. if ((message->recv_buf < NOCACHE_BUFSTART) || (message->recv_buf > (NOCACHE_BUFSTART + NOCACHE_BUFSIZE)))
  308. {
  309. if (length <= BSP_SPI_RX_DMA_NOCACHE_BUFSIZE)
  310. {
  311. result = _bl_spi_dma_rx(bl_spi, dst, length);
  312. if (result == RT_EOK)
  313. memcpy(dst, dma_rx_buf, length);
  314. }
  315. else
  316. {
  317. while(length > 0)
  318. {
  319. if (length >= BSP_SPI_RX_DMA_NOCACHE_BUFSIZE)
  320. {
  321. result = _bl_spi_dma_rx(bl_spi, dma_tx_buf, BSP_SPI_RX_DMA_NOCACHE_BUFSIZE);
  322. if (result != RT_EOK)
  323. break;
  324. memcpy(dst, dma_rx_buf, BSP_SPI_RX_DMA_NOCACHE_BUFSIZE);
  325. length -= BSP_SPI_RX_DMA_NOCACHE_BUFSIZE;
  326. dst += BSP_SPI_RX_DMA_NOCACHE_BUFSIZE;
  327. }
  328. else
  329. {
  330. result = _bl_spi_dma_rx(bl_spi, dma_rx_buf, length);
  331. if (result != RT_EOK)
  332. break;
  333. memcpy(dst, dma_rx_buf, length);
  334. length = 0;
  335. }
  336. }
  337. }
  338. }
  339. else
  340. #endif
  341. {
  342. if (length <= DMA_MAX_BUFSIZE)
  343. {
  344. result = _bl_spi_dma_rx(bl_spi, dst, length);
  345. if (result == RT_EOK)
  346. memcpy(dst, dma_rx_buf, length);
  347. }
  348. else
  349. {
  350. while(length > 0)
  351. {
  352. if (length >= DMA_MAX_BUFSIZE)
  353. {
  354. result = _bl_spi_dma_rx(bl_spi, dst, DMA_MAX_BUFSIZE);
  355. if (result != RT_EOK)
  356. break;
  357. memcpy(dst, dma_rx_buf, DMA_MAX_BUFSIZE);
  358. length -= DMA_MAX_BUFSIZE;
  359. dst += DMA_MAX_BUFSIZE;
  360. }
  361. else
  362. {
  363. result = _bl_spi_dma_rx(bl_spi, dst, length);
  364. if (result != RT_EOK)
  365. break;
  366. memcpy(dst, dma_rx_buf, length);
  367. length = 0;
  368. }
  369. }
  370. }
  371. }
  372. LOG_D("dma rx finish...");
  373. return result;
  374. }
  375. #endif
  376. static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
  377. {
  378. RT_ASSERT(device != RT_NULL);
  379. RT_ASSERT(device->bus != RT_NULL);
  380. RT_ASSERT(device->bus->parent.user_data != RT_NULL);
  381. rt_err_t result;
  382. rt_uint32_t cs_pin = (rt_uint32_t)device->parent.user_data;
  383. struct bflb_device_s* gpio = bflb_device_get_by_name("gpio");
  384. struct bl_device_spi *bl_spi;
  385. bl_spi = (struct bl_device_spi *)device->bus->parent.user_data;
  386. if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS))
  387. {
  388. if (device->config.mode & RT_SPI_CS_HIGH)
  389. bflb_gpio_set(gpio, cs_pin);
  390. else
  391. bflb_gpio_reset(gpio, cs_pin);
  392. }
  393. if (message->send_buf && message->recv_buf)
  394. {
  395. rt_memset(message->recv_buf, 0x0, message->length);
  396. bflb_spi_poll_exchange(bl_spi->spi, (void *)message->send_buf, (void *)message->recv_buf, message->length);
  397. message->length += strlen(message->recv_buf);
  398. }
  399. else if (message->send_buf)
  400. {
  401. #if defined(BSP_SPI_TX_USING_DMA)
  402. result = _spi_dma_xfer_tx(device, message);
  403. if(result != RT_EOK)
  404. message->length = -1;
  405. #else
  406. bflb_spi_poll_exchange(bl_spi->spi, (void *)message->send_buf, NULL, message->length);
  407. #endif
  408. }
  409. else if (message->recv_buf)
  410. {
  411. rt_memset(message->recv_buf, 0x0, message->length);
  412. #if defined(BSP_SPI_RX_USING_DMA)
  413. result = _spi_dma_xfer_rx(device, message);
  414. if(result != RT_EOK)
  415. message->length = -1;
  416. #else
  417. bflb_spi_poll_exchange(bl_spi->spi, NULL, (void *)message->recv_buf, message->length);
  418. #endif
  419. }
  420. else
  421. {
  422. LOG_E("both send_buf and recv_buf is null!");
  423. message->length = -1;
  424. }
  425. if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS))
  426. {
  427. if (device->config.mode & RT_SPI_CS_HIGH)
  428. bflb_gpio_reset(gpio, cs_pin);
  429. else
  430. bflb_gpio_set(gpio, cs_pin);
  431. }
  432. return message->length;
  433. }
  434. /* spi bus callback function */
  435. static const struct rt_spi_ops bl_spi_ops =
  436. {
  437. .configure = spi_configure,
  438. .xfer = spixfer,
  439. };
  440. /**
  441. * Attach the spi device to SPI bus, this function must be used after initialization.
  442. */
  443. rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t cs_pin)
  444. {
  445. RT_ASSERT(bus_name != RT_NULL);
  446. RT_ASSERT(device_name != RT_NULL);
  447. rt_err_t ret;
  448. struct rt_spi_device *spi_device;
  449. /* attach the device to spi bus*/
  450. spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
  451. RT_ASSERT(spi_device != RT_NULL);
  452. /* initialize the cs pin */
  453. ret = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
  454. if (ret != RT_EOK)
  455. {
  456. LOG_E("%s attach to %s faild, %d", device_name, bus_name, ret);
  457. ret = RT_ERROR;
  458. }
  459. RT_ASSERT(ret == RT_EOK);
  460. return ret;
  461. }
  462. int rt_hw_spi_init(void)
  463. {
  464. rt_err_t ret = RT_ERROR;
  465. static struct bl_device_spi dev_spi;
  466. struct bflb_device_s *gpio;
  467. gpio = bflb_device_get_by_name("gpio");
  468. #ifndef BL808_CORE_D0
  469. bflb_gpio_init(gpio, SPI_SCK_PIN, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
  470. bflb_gpio_init(gpio, SPI_MISO_PIN, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
  471. bflb_gpio_init(gpio, SPI_MOSI_PIN, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
  472. dev_spi.spi = bflb_device_get_by_name("spi0");
  473. #ifdef BSP_SPI_TX_USING_DMA
  474. dev_spi.dma_dst_req = DMA_REQUEST_SPI0_TX;
  475. dev_spi.dma_tx = bflb_device_get_by_name(BSP_SPI_TX_DMA_CHANNEL);
  476. #endif
  477. #ifdef BSP_SPI_RX_USING_DMA
  478. dev_spi.dma_src_req = DMA_REQUEST_SPI0_RX;
  479. dev_spi.dma_rx = bflb_device_get_by_name(BSP_SPI_RX_DMA_CHANNEL);
  480. #endif
  481. #else
  482. bflb_gpio_init(gpio, SPI_SCK_PIN, GPIO_FUNC_SPI1 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
  483. bflb_gpio_init(gpio, SPI_MISO_PIN, GPIO_FUNC_SPI1 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
  484. bflb_gpio_init(gpio, SPI_MOSI_PIN, GPIO_FUNC_SPI1 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
  485. dev_spi.spi = bflb_device_get_by_name("spi1");
  486. #endif /* BL808_CORE_D0 */
  487. dev_spi.spi_bus.parent.user_data = (void *)&dev_spi;
  488. ret = rt_spi_bus_register(&dev_spi.spi_bus, "spi0", &bl_spi_ops);
  489. RT_ASSERT(ret == RT_EOK);
  490. return ret;
  491. }
  492. INIT_BOARD_EXPORT(rt_hw_spi_init);
  493. #endif /* BSP_USING_SPI */