drv_spi.c 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. /*
  2. * Copyright (C) 2020, Huada Semiconductor Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-10-30 CDT first version
  9. */
  10. /*******************************************************************************
  11. * Include files
  12. ******************************************************************************/
  13. #include <rtthread.h>
  14. #include "drv_spi.h"
  15. #if defined(RT_USING_SPI) && defined(RT_USING_PIN)
  16. #include <rtdevice.h>
  17. #if !defined(BSP_USING_SPI1) && !defined(BSP_USING_SPI2) && \
  18. !defined(BSP_USING_SPI3) && !defined(BSP_USING_SPI4) && \
  19. !defined(BSP_USING_SPI5) && !defined(BSP_USING_SPI6)
  20. #error "Please define at least one SPIx"
  21. #endif
  22. /*******************************************************************************
  23. * Local type definitions ('typedef')
  24. ******************************************************************************/
  25. /*******************************************************************************
  26. * Local pre-processor symbols/macros ('#define')
  27. ******************************************************************************/
  28. /* #define DEBUG */
  29. #ifndef HC32_SPI_DEBUG
  30. #define SPI_PRINT_DBG(fmt, args...)
  31. #define SPI_PRINT_ERR(fmt, args...) rt_kprintf(fmt, ##args);
  32. #else
  33. #define SPI_PRINT_DBG(fmt, args...) rt_kprintf(fmt, ##args);
  34. #define SPI_PRINT_ERR(fmt, args...) rt_kprintf(fmt, ##args);
  35. #endif
  36. /*******************************************************************************
  37. * Global variable definitions (declared in header file with 'extern')
  38. ******************************************************************************/
  39. /*******************************************************************************
  40. * Local function prototypes ('static')
  41. ******************************************************************************/
  42. /* private rt-thread spi ops function */
  43. static rt_err_t hc32_spi_configure(struct rt_spi_device* device,
  44. struct rt_spi_configuration* configuration);
  45. static rt_uint32_t hc32_spi_xfer(struct rt_spi_device* device,
  46. struct rt_spi_message* message);
  47. #if defined(BSP_USING_SPI1)
  48. static void spi1_rx_dma_irq_handle(void);
  49. static void spi1_tx_dma_irq_handle(void);
  50. #endif /* BSP_USING_SPI1 */
  51. #if defined(BSP_USING_SPI2)
  52. static void spi2_rx_dma_irq_handle(void);
  53. static void spi2_tx_dma_irq_handle(void);
  54. #endif /* BSP_USING_SPI2 */
  55. #if defined(BSP_USING_SPI3)
  56. static void spi3_rx_dma_irq_handle(void);
  57. static void spi3_tx_dma_irq_handle(void);
  58. #endif /* BSP_USING_SPI3 */
  59. #if defined(BSP_USING_SPI4)
  60. static void spi4_rx_dma_irq_handle(void);
  61. static void spi4_tx_dma_irq_handle(void);
  62. #endif /* BSP_USING_SPI4 */
  63. #if defined(BSP_USING_SPI5)
  64. static void spi5_rx_dma_irq_handle(void);
  65. static void spi5_tx_dma_irq_handle(void);
  66. #endif /* BSP_USING_SPI5 */
  67. #if defined(BSP_USING_SPI6)
  68. static void spi6_rx_dma_irq_handle(void);
  69. static void spi6_tx_dma_irq_handle(void);
  70. #endif /* BSP_USING_SPI6 */
  71. /*******************************************************************************
  72. * Local variable definitions ('static')
  73. ******************************************************************************/
  74. enum
  75. {
  76. #ifdef BSP_USING_SPI1
  77. SPI1_INDEX,
  78. #endif
  79. #ifdef BSP_USING_SPI2
  80. SPI2_INDEX,
  81. #endif
  82. #ifdef BSP_USING_SPI3
  83. SPI3_INDEX,
  84. #endif
  85. #ifdef BSP_USING_SPI4
  86. SPI4_INDEX,
  87. #endif
  88. #ifdef BSP_USING_SPI5
  89. SPI5_INDEX,
  90. #endif
  91. #ifdef BSP_USING_SPI6
  92. SPI6_INDEX,
  93. #endif
  94. SPI_INDEX_MAX,
  95. };
  96. static const struct spi_index spi_map[] =
  97. {
  98. #ifdef BSP_USING_SPI1
  99. {SPI1_INDEX, M4_SPI1},
  100. #endif
  101. #ifdef BSP_USING_SPI2
  102. {SPI2_INDEX, M4_SPI2},
  103. #endif
  104. #ifdef BSP_USING_SPI3
  105. {SPI3_INDEX, M4_SPI3},
  106. #endif
  107. #ifdef BSP_USING_SPI4
  108. {SPI4_INDEX, M4_SPI4},
  109. #endif
  110. #ifdef BSP_USING_SPI5
  111. {SPI5_INDEX, M4_SPI5},
  112. #endif
  113. #ifdef BSP_USING_SPI6
  114. {SPI6_INDEX, M4_SPI6},
  115. #endif
  116. };
  117. static struct hc32_spi_config spi_config[] =
  118. {
  119. #ifdef BSP_USING_SPI1
  120. SPI1_BUS_CONFIG,
  121. #endif
  122. #ifdef BSP_USING_SPI2
  123. SPI2_BUS_CONFIG,
  124. #endif
  125. #ifdef BSP_USING_SPI3
  126. SPI3_BUS_CONFIG,
  127. #endif
  128. #ifdef BSP_USING_SPI4
  129. SPI4_BUS_CONFIG,
  130. #endif
  131. #ifdef BSP_USING_SPI5
  132. SPI5_BUS_CONFIG,
  133. #endif
  134. #ifdef BSP_USING_SPI6
  135. SPI6_BUS_CONFIG,
  136. #endif
  137. };
  138. static const struct spi_irq_handler spi_irq_handlers[] =
  139. {
  140. #ifdef BSP_USING_SPI1
  141. {spi1_rx_dma_irq_handle, spi1_tx_dma_irq_handle},
  142. #endif
  143. #ifdef BSP_USING_SPI2
  144. {spi2_rx_dma_irq_handle, spi2_tx_dma_irq_handle},
  145. #endif
  146. #ifdef BSP_USING_SPI3
  147. {spi3_rx_dma_irq_handle, spi3_tx_dma_irq_handle},
  148. #endif
  149. #ifdef BSP_USING_SPI4
  150. {spi4_rx_dma_irq_handle, spi4_tx_dma_irq_handle},
  151. #endif
  152. #ifdef BSP_USING_SPI5
  153. {spi5_rx_dma_irq_handle, spi5_tx_dma_irq_handle},
  154. #endif
  155. #ifdef BSP_USING_SPI6
  156. {spi6_rx_dma_irq_handle, spi6_tx_dma_irq_handle},
  157. #endif
  158. };
  159. static struct hc32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0};
  160. /*******************************************************************************
  161. * Function implementation - global ('extern') and local ('static')
  162. ******************************************************************************/
  163. extern void hc32_board_spi_init(M4_SPI_TypeDef *M4_SPIx, rt_uint8_t mode);
  164. /**
  165. * @brief This function gets index for specific SPI_Instance.
  166. * @param Instance
  167. * @retval index
  168. */
  169. static uint32_t get_spi_index(M4_SPI_TypeDef *Instance)
  170. {
  171. uint32_t index = SPI_INDEX_MAX;
  172. for (uint8_t i = 0U; i < ARRAY_SZ(spi_map); i++)
  173. {
  174. if (spi_map[i].Instance == Instance)
  175. {
  176. index = spi_map[i].index;
  177. RT_ASSERT(index < SPI_INDEX_MAX)
  178. break;
  179. }
  180. }
  181. return index;
  182. }
  183. static uint32_t get_spi_fcg(M4_SPI_TypeDef *Instance)
  184. {
  185. return (PWC_FCG1_SPI1 << get_spi_index(Instance));
  186. }
  187. rt_err_t hc32_spi_init(struct hc32_spi *spi_drv, struct rt_spi_configuration *cfg)
  188. {
  189. RT_ASSERT(spi_drv != RT_NULL);
  190. RT_ASSERT(cfg != RT_NULL);
  191. stc_spi_init_t stcSpiInit;
  192. stc_clk_freq_t stcClkFreq;
  193. M4_SPI_TypeDef *spi_handle = spi_drv->handle.Instance;
  194. /* Enable spi clock gate */
  195. PWC_Fcg1PeriphClockCmd(get_spi_fcg(spi_handle), Enable);
  196. /* Init spi struct as default value */
  197. SPI_StructInit(&stcSpiInit);
  198. /* Slave or master mode */
  199. if (cfg->mode & RT_SPI_SLAVE)
  200. {
  201. stcSpiInit.u32MasterSlave = SPI_SLAVE;
  202. }
  203. else
  204. {
  205. stcSpiInit.u32MasterSlave = SPI_MASTER;
  206. }
  207. /* 3 wire or 4 wire mode */
  208. if (cfg->mode & RT_SPI_3WIRE)
  209. {
  210. stcSpiInit.u32WireMode = SPI_WIRE_3;
  211. }
  212. else
  213. {
  214. stcSpiInit.u32WireMode = SPI_WIRE_4;
  215. }
  216. /* spi mode */
  217. if (0x00 == (cfg->mode & (RT_SPI_CPHA | RT_SPI_CPOL)))
  218. {
  219. stcSpiInit.u32SpiMode = SPI_MODE_0;
  220. }
  221. else if (0x01 == (cfg->mode & (RT_SPI_CPHA | RT_SPI_CPOL)))
  222. {
  223. stcSpiInit.u32SpiMode = SPI_MODE_1;
  224. }
  225. else if (0x02 == (cfg->mode & (RT_SPI_CPHA | RT_SPI_CPOL)))
  226. {
  227. stcSpiInit.u32SpiMode = SPI_MODE_2;
  228. }
  229. else if (0x03 == (cfg->mode & (RT_SPI_CPHA | RT_SPI_CPOL)))
  230. {
  231. stcSpiInit.u32SpiMode = SPI_MODE_3;
  232. }
  233. /* LSB or MSB */
  234. if (cfg->mode & RT_SPI_MSB)
  235. {
  236. stcSpiInit.u32FirstBit = SPI_FIRST_MSB;
  237. }
  238. else
  239. {
  240. stcSpiInit.u32FirstBit = SPI_FIRST_LSB;
  241. }
  242. /* config data width 4~16, 20, 24, 32 */
  243. if (4u > cfg->data_width)
  244. {
  245. return RT_EIO;
  246. }
  247. else if (16u >= cfg->data_width)
  248. {
  249. stcSpiInit.u32DataBits = ((cfg->data_width - 4u) << 8u);
  250. }
  251. else if (20u == cfg->data_width)
  252. {
  253. stcSpiInit.u32DataBits = SPI_DATA_SIZE_20BIT;
  254. }
  255. else if (24u == cfg->data_width)
  256. {
  257. stcSpiInit.u32DataBits = SPI_DATA_SIZE_24BIT;
  258. }
  259. else if (32u == cfg->data_width)
  260. {
  261. stcSpiInit.u32DataBits = SPI_DATA_SIZE_32BIT;
  262. }
  263. else
  264. {
  265. return RT_EIO;
  266. }
  267. /* Get APB clock */
  268. CLK_GetClockFreq(&stcClkFreq);
  269. if (cfg->max_hz >= stcClkFreq.pclk1Freq / 2u)
  270. {
  271. stcSpiInit.u32BaudRatePrescaler = SPI_BR_PCLK1_DIV2;
  272. }
  273. else if (cfg->max_hz >= stcClkFreq.pclk1Freq / 4u)
  274. {
  275. stcSpiInit.u32BaudRatePrescaler = SPI_BR_PCLK1_DIV4;
  276. }
  277. else if (cfg->max_hz >= stcClkFreq.pclk1Freq / 8u)
  278. {
  279. stcSpiInit.u32BaudRatePrescaler = SPI_BR_PCLK1_DIV8;
  280. }
  281. else if (cfg->max_hz >= stcClkFreq.pclk1Freq / 16u)
  282. {
  283. stcSpiInit.u32BaudRatePrescaler = SPI_BR_PCLK1_DIV16;
  284. }
  285. else if (cfg->max_hz >= stcClkFreq.pclk1Freq / 32u)
  286. {
  287. stcSpiInit.u32BaudRatePrescaler = SPI_BR_PCLK1_DIV32;
  288. }
  289. else if (cfg->max_hz >= stcClkFreq.pclk1Freq / 64u)
  290. {
  291. stcSpiInit.u32BaudRatePrescaler = SPI_BR_PCLK1_DIV64;
  292. }
  293. else if (cfg->max_hz >= stcClkFreq.pclk1Freq / 128u)
  294. {
  295. stcSpiInit.u32BaudRatePrescaler = SPI_BR_PCLK1_DIV128;
  296. }
  297. else if (cfg->max_hz >= stcClkFreq.pclk1Freq / 256u)
  298. {
  299. stcSpiInit.u32BaudRatePrescaler = SPI_BR_PCLK1_DIV256;
  300. }
  301. /* spi port init */
  302. hc32_board_spi_init(spi_handle, cfg->mode);
  303. if (Ok != SPI_Init(spi_handle, &stcSpiInit))
  304. {
  305. return RT_EIO;
  306. }
  307. /* DMA configuration */
  308. if (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_RX)
  309. {
  310. struct dma_config *spi_dma;
  311. stc_dma_init_t stcDmaInit;
  312. /* Get spi dma_rx */
  313. spi_dma = spi_drv->config->dma_rx;
  314. /* Config Dma */
  315. DMA_StructInit(&stcDmaInit);
  316. stcDmaInit.u32IntEn = DMA_INT_ENABLE;
  317. stcDmaInit.u32BlockSize = 1UL;
  318. stcDmaInit.u32TransCnt = 0;
  319. stcDmaInit.u32DestAddr = 0;
  320. stcDmaInit.u32SrcAddr = (uint32_t)(&spi_handle->DR);
  321. stcDmaInit.u32SrcInc = DMA_SRC_ADDR_FIX;
  322. stcDmaInit.u32DestInc = DMA_DEST_ADDR_INC;
  323. if (8u >= cfg->data_width)
  324. {
  325. stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;
  326. }
  327. else if (16u >= cfg->data_width)
  328. {
  329. stcDmaInit.u32DataWidth = DMA_DATAWIDTH_16BIT;
  330. }
  331. else
  332. {
  333. stcDmaInit.u32DataWidth = DMA_DATAWIDTH_32BIT;
  334. }
  335. /* Enable Dma clock gate */
  336. if (M4_DMA1 == spi_dma->Instance)
  337. {
  338. PWC_Fcg0PeriphClockCmd(PWC_FCG0_DMA1, Enable);
  339. }
  340. else
  341. {
  342. PWC_Fcg0PeriphClockCmd(PWC_FCG0_DMA2, Enable);
  343. }
  344. /* Init Dma */
  345. if (Ok != DMA_Init(spi_dma->Instance, spi_dma->channel, &stcDmaInit))
  346. {
  347. return RT_EIO;
  348. }
  349. /* register interrupt */
  350. hc32_install_irq_handler(&spi_dma->irq_config,
  351. spi_irq_handlers[get_spi_index(spi_handle)].rx_dma_irq_handler,
  352. RT_TRUE);
  353. /* Enable Dma */
  354. DMA_Cmd(spi_dma->Instance, Enable);
  355. }
  356. if (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_TX)
  357. {
  358. struct dma_config *spi_dma;
  359. stc_dma_init_t stcDmaInit;
  360. /* Get spi dma_tx */
  361. spi_dma = spi_drv->config->dma_tx;
  362. /* Config Dma */
  363. DMA_StructInit(&stcDmaInit);
  364. stcDmaInit.u32IntEn = DMA_INT_ENABLE;
  365. stcDmaInit.u32BlockSize = 1UL;
  366. stcDmaInit.u32TransCnt = 0;
  367. stcDmaInit.u32DestAddr = (uint32_t)(&spi_handle->DR);;
  368. stcDmaInit.u32SrcAddr = 0;
  369. stcDmaInit.u32SrcInc = DMA_SRC_ADDR_INC;
  370. stcDmaInit.u32DestInc = DMA_DEST_ADDR_FIX;
  371. if (8u >= cfg->data_width)
  372. {
  373. stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;
  374. }
  375. else if (16u >= cfg->data_width)
  376. {
  377. stcDmaInit.u32DataWidth = DMA_DATAWIDTH_16BIT;
  378. }
  379. else
  380. {
  381. stcDmaInit.u32DataWidth = DMA_DATAWIDTH_32BIT;
  382. }
  383. /* Enable Dma clock gate */
  384. if (M4_DMA1 == spi_dma->Instance)
  385. {
  386. PWC_Fcg0PeriphClockCmd(PWC_FCG0_DMA1 | PWC_FCG0_AOS, Enable);
  387. }
  388. else
  389. {
  390. PWC_Fcg0PeriphClockCmd(PWC_FCG0_DMA2 | PWC_FCG0_AOS, Enable);
  391. }
  392. /* Init Dma */
  393. if (Ok != DMA_Init(spi_dma->Instance, spi_dma->channel, &stcDmaInit))
  394. {
  395. return RT_EIO;
  396. }
  397. /* register interrupt */
  398. hc32_install_irq_handler(&spi_dma->irq_config,
  399. spi_irq_handlers[get_spi_index(spi_handle)].tx_dma_irq_handler,
  400. RT_TRUE);
  401. /* Enable Dma */
  402. DMA_Cmd(spi_dma->Instance, Enable);
  403. }
  404. return RT_EOK;
  405. }
  406. static void hc32_spi_deinit(struct hc32_spi *spi_drv)
  407. {
  408. M4_SPI_TypeDef *spi_handle = spi_drv->handle.Instance;
  409. SPI_DeInit(spi_handle);
  410. /* Disable spi clock gate */
  411. PWC_Fcg1PeriphClockCmd(get_spi_fcg(spi_handle), Disable);
  412. }
  413. static rt_err_t hc32_spi_dma(struct hc32_spi_config *spi_dma, const uint8_t *pvTxBuf, void *pvRxBuf, uint32_t u32Length)
  414. {
  415. if (RT_NULL == pvTxBuf)
  416. {
  417. DMA_SetDestAddr(spi_dma->dma_rx->Instance, spi_dma->dma_rx->channel, (uint32_t)pvRxBuf);
  418. DMA_SetTransCnt(spi_dma->dma_rx->Instance, spi_dma->dma_rx->channel, u32Length);
  419. DMA_SetTriggerSrc(spi_dma->dma_rx->Instance, spi_dma->dma_rx->channel,spi_dma->dma_rx->trigger_evt_src);
  420. DMA_ChannelCmd(spi_dma->dma_rx->Instance, spi_dma->dma_rx->channel, Enable);
  421. }
  422. else if (RT_NULL == pvRxBuf)
  423. {
  424. DMA_SetSrcAddr(spi_dma->dma_tx->Instance, spi_dma->dma_tx->channel, (uint32_t)pvTxBuf);
  425. DMA_SetTransCnt(spi_dma->dma_tx->Instance, spi_dma->dma_tx->channel, u32Length);
  426. DMA_SetTriggerSrc(spi_dma->dma_tx->Instance, spi_dma->dma_tx->channel,spi_dma->dma_tx->trigger_evt_src);
  427. DMA_ChannelCmd(spi_dma->dma_tx->Instance, spi_dma->dma_tx->channel, Enable);
  428. }
  429. else
  430. {
  431. DMA_SetDestAddr(spi_dma->dma_rx->Instance, spi_dma->dma_rx->channel, (uint32_t)pvRxBuf);
  432. DMA_SetTransCnt(spi_dma->dma_rx->Instance, spi_dma->dma_rx->channel, u32Length);
  433. DMA_SetTriggerSrc(spi_dma->dma_rx->Instance, spi_dma->dma_rx->channel,spi_dma->dma_rx->trigger_evt_src);
  434. DMA_SetSrcAddr(spi_dma->dma_tx->Instance, spi_dma->dma_tx->channel, (uint32_t)pvTxBuf);
  435. DMA_SetTransCnt(spi_dma->dma_tx->Instance, spi_dma->dma_tx->channel, u32Length);
  436. DMA_SetTriggerSrc(spi_dma->dma_tx->Instance, spi_dma->dma_tx->channel,spi_dma->dma_tx->trigger_evt_src);
  437. DMA_ChannelCmd(spi_dma->dma_tx->Instance, spi_dma->dma_tx->channel, Enable);
  438. DMA_ChannelCmd(spi_dma->dma_rx->Instance, spi_dma->dma_rx->channel, Enable);
  439. }
  440. SPI_FunctionCmd(spi_dma->Instance, Enable);
  441. return RT_EOK;
  442. }
  443. static struct rt_spi_ops hc32_spi_ops =
  444. {
  445. .configure = hc32_spi_configure,
  446. .xfer = hc32_spi_xfer,
  447. };
  448. static rt_err_t hc32_spi_configure(struct rt_spi_device *device,
  449. struct rt_spi_configuration *configuration)
  450. {
  451. RT_ASSERT(device != RT_NULL);
  452. RT_ASSERT(configuration != RT_NULL);
  453. struct hc32_spi *spi_drv = rt_container_of(device->bus, struct hc32_spi, spi_bus);
  454. spi_drv->cfg = configuration;
  455. return hc32_spi_init(spi_drv, configuration);
  456. }
  457. static rt_uint32_t hc32_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
  458. {
  459. rt_uint8_t state;
  460. rt_size_t message_length, already_send_length;
  461. rt_uint16_t send_length;
  462. rt_uint8_t *recv_buf;
  463. const rt_uint8_t *send_buf;
  464. RT_ASSERT(device != RT_NULL);
  465. RT_ASSERT(device->bus != RT_NULL);
  466. RT_ASSERT(device->bus->parent.user_data != RT_NULL);
  467. RT_ASSERT(message != RT_NULL);
  468. struct hc32_spi *spi_drv = rt_container_of(device->bus, struct hc32_spi, spi_bus);
  469. SPI_HandleType *spi_handle = &spi_drv->handle;
  470. struct hc32_hw_spi_cs *cs = device->parent.user_data;
  471. if (message->cs_take)
  472. {
  473. GPIO_ResetPins(cs->port, cs->pin);
  474. }
  475. message_length = message->length;
  476. recv_buf = message->recv_buf;
  477. send_buf = message->send_buf;
  478. while (message_length)
  479. {
  480. if (message_length > 65535)
  481. {
  482. send_length = 65535;
  483. message_length = message_length - 65535;
  484. }
  485. else
  486. {
  487. send_length = message_length;
  488. message_length = 0;
  489. }
  490. /* calculate the start address */
  491. already_send_length = message->length - send_length - message_length;
  492. send_buf = (rt_uint8_t *)message->send_buf + already_send_length;
  493. recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length;
  494. if(message->send_buf && message->recv_buf)
  495. {
  496. if ((spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_TX) && (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_RX))
  497. {
  498. state = hc32_spi_dma(spi_drv->config, send_buf, recv_buf, send_length);
  499. }
  500. else
  501. {
  502. SPI_FunctionCmd(spi_handle->Instance, Enable);
  503. state = SPI_TransmitReceive(spi_handle->Instance, send_buf, recv_buf, send_length);
  504. }
  505. }
  506. else if(message->send_buf)
  507. {
  508. if (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_TX)
  509. {
  510. state = hc32_spi_dma(spi_drv->config, send_buf, RT_NULL, send_length);
  511. }
  512. else
  513. {
  514. SPI_FunctionCmd(spi_handle->Instance, Enable);
  515. state = SPI_Transmit(spi_handle->Instance, send_buf, send_length);
  516. }
  517. if (message->cs_release && (device->config.mode & RT_SPI_3WIRE))
  518. {
  519. SPI_FunctionCmd(spi_handle->Instance, Disable);
  520. }
  521. }
  522. else
  523. {
  524. rt_memset((uint8_t *)recv_buf, 0xff, send_length);
  525. if (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_RX)
  526. {
  527. state = hc32_spi_dma(spi_drv->config, RT_NULL, recv_buf, send_length);
  528. }
  529. else
  530. {
  531. SPI_FunctionCmd(spi_handle->Instance, Enable);
  532. state = SPI_Receive(spi_handle->Instance, recv_buf, send_length);
  533. }
  534. }
  535. if(state != RT_EOK)
  536. {
  537. message->length = 0;
  538. }
  539. /* wait spi transfer complete */
  540. while(Reset != SPI_GetStatus(spi_handle->Instance, SPI_FLAG_IDLE));
  541. }
  542. if (message->cs_release)
  543. {
  544. GPIO_SetPins(cs->port, cs->pin);
  545. }
  546. return message->length;
  547. }
  548. /**
  549. * Attach the spi device to SPI bus, this function must be used after initialization.
  550. */
  551. rt_err_t hc32_hw_spi_device_attach(const char *bus_name,
  552. const char *device_name,
  553. uint8_t cs_gpio_port,
  554. uint16_t cs_gpio_pin)
  555. {
  556. RT_ASSERT(bus_name != RT_NULL);
  557. RT_ASSERT(device_name != RT_NULL);
  558. rt_err_t result;
  559. struct rt_spi_device *spi_device;
  560. struct hc32_hw_spi_cs *cs_pin;
  561. stc_gpio_init_t stcGpioInit;
  562. GPIO_StructInit(&stcGpioInit);
  563. stcGpioInit.u16PinState = PIN_STATE_SET;
  564. stcGpioInit.u16PinDir = PIN_DIR_OUT;
  565. stcGpioInit.u16PullUp = PIN_PU_ON;
  566. stcGpioInit.u16PinDrv = PIN_DRV_HIGH;
  567. GPIO_Init(SPI1_NSS_PORT, SPI1_NSS_PIN, &stcGpioInit);
  568. /* attach the device to spi bus*/
  569. spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
  570. RT_ASSERT(spi_device != RT_NULL);
  571. cs_pin = (struct hc32_hw_spi_cs *)rt_malloc(sizeof(struct hc32_hw_spi_cs));
  572. RT_ASSERT(cs_pin != RT_NULL);
  573. cs_pin->port = cs_gpio_port;
  574. cs_pin->pin = cs_gpio_pin;
  575. result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
  576. return result;
  577. }
  578. static int hc32_hw_spi_bus_init(void)
  579. {
  580. rt_err_t result;
  581. for (int i = 0; i < sizeof(spi_config) / sizeof(spi_config[0]); i++)
  582. {
  583. spi_bus_obj[i].config = &spi_config[i];
  584. spi_bus_obj[i].spi_bus.parent.user_data = &spi_config[i];
  585. spi_bus_obj[i].handle.Instance = spi_config[i].Instance;
  586. result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, spi_config[i].bus_name, &hc32_spi_ops);
  587. }
  588. return result;
  589. }
  590. /**
  591. * @brief Clear DMA transfer complete flag.
  592. * @param dma specific dam witch spi used.
  593. * @retval None
  594. */
  595. static void hc32_dma_irq_handle(struct dma_config *dma)
  596. {
  597. dma->Instance->INTCLR1 |= (1u << dma->channel);
  598. }
  599. #if defined(BSP_USING_SPI1)
  600. /**
  601. * @brief This function handles DMA Rx complete interrupt request.
  602. * @param None
  603. * @retval None
  604. */
  605. static void spi1_rx_dma_irq_handle(void)
  606. {
  607. #if defined(BSP_SPI1_RX_USING_DMA)
  608. /* enter interrupt */
  609. rt_interrupt_enter();
  610. hc32_dma_irq_handle(spi_config[SPI1_INDEX].dma_rx);
  611. SPI_FunctionCmd(spi_config[SPI1_INDEX].Instance, Disable);
  612. /* leave interrupt */
  613. rt_interrupt_leave();
  614. #endif /* BSP_SPI1_RX_USING_DMA */
  615. }
  616. /**
  617. * @brief This function handles DMA Tx complete interrupt request.
  618. * @param None
  619. * @retval None
  620. */
  621. static void spi1_tx_dma_irq_handle(void)
  622. {
  623. #if defined(BSP_SPI1_TX_USING_DMA)
  624. /* enter interrupt */
  625. rt_interrupt_enter();
  626. hc32_dma_irq_handle(spi_config[SPI1_INDEX].dma_tx);
  627. /* leave interrupt */
  628. rt_interrupt_leave();
  629. #endif /* BSP_SPI1_TX_USING_DMA */
  630. }
  631. #endif /* BSP_USING_SPI1 */
  632. #if defined(BSP_USING_SPI2)
  633. /**
  634. * @brief This function handles DMA Rx complete interrupt request.
  635. * @param None
  636. * @retval None
  637. */
  638. static void spi2_rx_dma_irq_handle(void)
  639. {
  640. #if defined(BSP_SPI2_RX_USING_DMA)
  641. /* enter interrupt */
  642. rt_interrupt_enter();
  643. hc32_dma_irq_handle(spi_config[SPI2_INDEX].dma_rx);
  644. SPI_FunctionCmd(spi_config[SPI2_INDEX].Instance, Disable);
  645. /* leave interrupt */
  646. rt_interrupt_leave();
  647. #endif /* BSP_SPI2_RX_USING_DMA */
  648. }
  649. /**
  650. * @brief This function handles DMA Tx complete interrupt request.
  651. * @param None
  652. * @retval None
  653. */
  654. static void spi2_tx_dma_irq_handle(void)
  655. {
  656. #if defined(BSP_SPI2_TX_USING_DMA)
  657. /* enter interrupt */
  658. rt_interrupt_enter();
  659. hc32_dma_irq_handle(spi_config[SPI2_INDEX].dma_tx);
  660. /* leave interrupt */
  661. rt_interrupt_leave();
  662. #endif /* BSP_SPI2_TX_USING_DMA */
  663. }
  664. #endif /* BSP_USING_SPI2 */
  665. #if defined(BSP_USING_SPI3)
  666. /**
  667. * @brief This function handles DMA Rx complete interrupt request.
  668. * @param None
  669. * @retval None
  670. */
  671. static void spi3_rx_dma_irq_handle(void)
  672. {
  673. #if defined(BSP_SPI3_RX_USING_DMA)
  674. /* enter interrupt */
  675. rt_interrupt_enter();
  676. hc32_dma_irq_handle(spi_config[SPI3_INDEX].dma_rx);
  677. SPI_FunctionCmd(spi_config[SPI3_INDEX].Instance, Disable);
  678. /* leave interrupt */
  679. rt_interrupt_leave();
  680. #endif /* BSP_SPI3_RX_USING_DMA */
  681. }
  682. /**
  683. * @brief This function handles DMA Tx complete interrupt request.
  684. * @param None
  685. * @retval None
  686. */
  687. static void spi3_tx_dma_irq_handle(void)
  688. {
  689. #if defined(BSP_SPI3_TX_USING_DMA)
  690. /* enter interrupt */
  691. rt_interrupt_enter();
  692. hc32_dma_irq_handle(spi_config[SPI3_INDEX].dma_tx);
  693. /* leave interrupt */
  694. rt_interrupt_leave();
  695. #endif /* BSP_SPI3_TX_USING_DMA */
  696. }
  697. #endif /* BSP_USING_SPI3 */
  698. #if defined(BSP_USING_SPI4)
  699. /**
  700. * @brief This function handles DMA Rx complete interrupt request.
  701. * @param None
  702. * @retval None
  703. */
  704. static void spi4_rx_dma_irq_handle(void)
  705. {
  706. #if defined(BSP_SPI4_RX_USING_DMA)
  707. /* enter interrupt */
  708. rt_interrupt_enter();
  709. hc32_dma_irq_handle(spi_config[SPI4_INDEX].dma_rx);
  710. SPI_FunctionCmd(spi_config[SPI4_INDEX].Instance, Disable);
  711. /* leave interrupt */
  712. rt_interrupt_leave();
  713. #endif /* BSP_SPI4_RX_USING_DMA */
  714. }
  715. /**
  716. * @brief This function handles DMA Tx complete interrupt request.
  717. * @param None
  718. * @retval None
  719. */
  720. static void spi4_tx_dma_irq_handle(void)
  721. {
  722. #if defined(BSP_SPI4_TX_USING_DMA)
  723. /* enter interrupt */
  724. rt_interrupt_enter();
  725. hc32_dma_irq_handle(spi_config[SPI4_INDEX].dma_tx);
  726. /* leave interrupt */
  727. rt_interrupt_leave();
  728. #endif /* BSP_SPI4_TX_USING_DMA */
  729. }
  730. #endif /* BSP_USING_SPI4 */
  731. #if defined(BSP_USING_SPI5)
  732. /**
  733. * @brief This function handles DMA Rx complete interrupt request.
  734. * @param None
  735. * @retval None
  736. */
  737. static void spi5_rx_dma_irq_handle(void)
  738. {
  739. #if defined(BSP_SPI5_RX_USING_DMA)
  740. /* enter interrupt */
  741. rt_interrupt_enter();
  742. hc32_dma_irq_handle(spi_config[SPI5_INDEX].dma_rx);
  743. SPI_FunctionCmd(spi_config[SPI5_INDEX].Instance, Disable);
  744. /* leave interrupt */
  745. rt_interrupt_leave();
  746. #endif /* BSP_SPI5_RX_USING_DMA */
  747. }
  748. /**
  749. * @brief This function handles DMA Tx complete interrupt request.
  750. * @param None
  751. * @retval None
  752. */
  753. static void spi5_tx_dma_irq_handle(void)
  754. {
  755. #if defined(BSP_SPI5_TX_USING_DMA)
  756. /* enter interrupt */
  757. rt_interrupt_enter();
  758. hc32_dma_irq_handle(spi_config[SPI5_INDEX].dma_tx);
  759. /* leave interrupt */
  760. rt_interrupt_leave();
  761. #endif /* BSP_SPI5_TX_USING_DMA */
  762. }
  763. #endif /* BSP_USING_SPI5 */
  764. #if defined(BSP_USING_SPI6)
  765. /**
  766. * @brief This function handles DMA Rx complete interrupt request.
  767. * @param None
  768. * @retval None
  769. */
  770. static void spi6_rx_dma_irq_handle(void)
  771. {
  772. #if defined(BSP_SPI6_RX_USING_DMA)
  773. /* enter interrupt */
  774. rt_interrupt_enter();
  775. hc32_dma_irq_handle(spi_config[SPI6_INDEX].dma_rx);
  776. SPI_FunctionCmd(spi_config[SPI6_INDEX].Instance, Disable);
  777. /* leave interrupt */
  778. rt_interrupt_leave();
  779. #endif /* BSP_SPI6_RX_USING_DMA */
  780. }
  781. /**
  782. * @brief This function handles DMA Tx complete interrupt request.
  783. * @param None
  784. * @retval None
  785. */
  786. static void spi6_tx_dma_irq_handle(void)
  787. {
  788. #if defined(BSP_SPI6_TX_USING_DMA)
  789. /* enter interrupt */
  790. rt_interrupt_enter();
  791. hc32_dma_irq_handle(spi_config[SPI6_INDEX].dma_tx);
  792. /* leave interrupt */
  793. rt_interrupt_leave();
  794. #endif /* BSP_SPI6_TX_USING_DMA */
  795. }
  796. #endif /* BSP_USING_SPI6 */
  797. /**
  798. * @brief This function gets dma witch spi used infomation include unit,
  799. * channel, interrupt etc.
  800. * @param None
  801. * @retval None
  802. */
  803. static void hc32_get_dma_info(void)
  804. {
  805. #ifdef BSP_SPI1_RX_USING_DMA
  806. spi_bus_obj[SPI1_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
  807. static struct dma_config spi1_dma_rx = SPI1_RX_DMA_CONFIG;
  808. spi_config[SPI1_INDEX].dma_rx = &spi1_dma_rx;
  809. #endif
  810. #ifdef BSP_SPI1_TX_USING_DMA
  811. spi_bus_obj[SPI1_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
  812. static struct dma_config spi1_dma_tx = SPI1_TX_DMA_CONFIG;
  813. spi_config[SPI1_INDEX].dma_tx = &spi1_dma_tx;
  814. #endif
  815. #ifdef BSP_SPI2_RX_USING_DMA
  816. spi_bus_obj[SPI2_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
  817. static struct dma_config spi2_dma_rx = SPI2_RX_DMA_CONFIG;
  818. spi_config[SPI2_INDEX].dma_rx = &spi2_dma_rx;
  819. #endif
  820. #ifdef BSP_SPI2_TX_USING_DMA
  821. spi_bus_obj[SPI2_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
  822. static struct dma_config spi2_dma_tx = SPI2_TX_DMA_CONFIG;
  823. spi_config[SPI2_INDEX].dma_tx = &spi2_dma_tx;
  824. #endif
  825. #ifdef BSP_SPI3_RX_USING_DMA
  826. spi_bus_obj[SPI3_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
  827. static struct dma_config spi3_dma_rx = SPI3_RX_DMA_CONFIG;
  828. spi_config[SPI3_INDEX].dma_rx = &spi3_dma_rx;
  829. #endif
  830. #ifdef BSP_SPI3_TX_USING_DMA
  831. spi_bus_obj[SPI3_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
  832. static struct dma_config spi3_dma_tx = SPI3_TX_DMA_CONFIG;
  833. spi_config[SPI3_INDEX].dma_tx = &spi3_dma_tx;
  834. #endif
  835. #ifdef BSP_SPI4_RX_USING_DMA
  836. spi_bus_obj[SPI4_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
  837. static struct dma_config spi4_dma_rx = SPI4_RX_DMA_CONFIG;
  838. spi_config[SPI4_INDEX].dma_rx = &spi4_dma_rx;
  839. #endif
  840. #ifdef BSP_SPI4_TX_USING_DMA
  841. spi_bus_obj[SPI4_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
  842. static struct dma_config spi4_dma_tx = SPI4_TX_DMA_CONFIG;
  843. spi_config[SPI4_INDEX].dma_tx = &spi4_dma_tx;
  844. #endif
  845. #ifdef BSP_SPI5_RX_USING_DMA
  846. spi_bus_obj[SPI5_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
  847. static struct dma_config spi5_dma_rx = SPI5_RX_DMA_CONFIG;
  848. spi_config[SPI5_INDEX].dma_rx = &spi5_dma_rx;
  849. #endif
  850. #ifdef BSP_SPI5_TX_USING_DMA
  851. spi_bus_obj[SPI5_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
  852. static struct dma_config spi5_dma_tx = SPI5_TX_DMA_CONFIG;
  853. spi_config[SPI5_INDEX].dma_tx = &spi5_dma_tx;
  854. #endif
  855. #ifdef BSP_SPI6_RX_USING_DMA
  856. spi_bus_obj[SPI6_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
  857. static struct dma_config spi6_dma_rx = SPI6_RX_DMA_CONFIG;
  858. spi_config[SPI6_INDEX].dma_rx = &spi6_dma_rx;
  859. #endif
  860. #ifdef BSP_SPI6_TX_USING_DMA
  861. spi_bus_obj[SPI6_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
  862. static struct dma_config spi6_dma_tx = SPI6_TX_DMA_CONFIG;
  863. spi_config[SPI6_INDEX].dma_tx = &spi6_dma_tx;
  864. #endif
  865. }
  866. int hc32_hw_spi_init(void)
  867. {
  868. hc32_get_dma_info();
  869. return hc32_hw_spi_bus_init();
  870. }
  871. INIT_BOARD_EXPORT(hc32_hw_spi_init);
  872. #endif /* BSP_USING_SPI */