1 /*
2  * Copyright (C) 2022-2024, Xiaohua Semiconductor Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2022-04-28     CDT          first version
9  * 2023-09-30     CDT          Delete dma transmit interrupt
10  * 2024-02-20     CDT          support HC32F448
11  * 2024-04-16     CDT          support HC32F472
12  * 2025-04-09     CDT          support HC32F4A8
13  */
14 
15 /*******************************************************************************
16  * Include files
17  ******************************************************************************/
18 #include <rtthread.h>
19 #include <rtdevice.h>
20 
21 #if defined(RT_USING_SPI)
22 
23 #if defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) || \
24     defined(BSP_USING_SPI4) || defined(BSP_USING_SPI5) || defined(BSP_USING_SPI6)
25 
26 #include "drv_spi.h"
27 #include "board_config.h"
28 
29 /*******************************************************************************
30  * Local type definitions ('typedef')
31  ******************************************************************************/
32 
33 /*******************************************************************************
34  * Local pre-processor symbols/macros ('#define')
35  ******************************************************************************/
36 // #define DRV_DEBUG
37 #define LOG_TAG                         "drv.spi"
38 #include <drv_log.h>
39 
40 /* SPI max division */
41 #if defined(HC32F4A0) || defined(HC32F460)
42     #define SPI_MAX_DIV_VAL                 (0x7U)  /* Div256 */
43 #elif defined(HC32F448) || defined(HC32F472) || defined(HC32F4A8)
44     #define SPI_MAX_DIV_VAL                 (0x39U)
45 #endif
46 
47 #ifdef BSP_SPI_USING_DMA
48     #define DMA_CH_REG(reg_base, ch)    (*(__IO uint32_t *)((uint32_t)(&(reg_base)) + ((ch) * 0x40UL)))
49 #endif
50 
51 /*******************************************************************************
52  * Global variable definitions (declared in header file with 'extern')
53  ******************************************************************************/
54 extern rt_err_t rt_hw_spi_board_init(CM_SPI_TypeDef *CM_SPIx);
55 
56 /*******************************************************************************
57  * Local function prototypes ('static')
58  ******************************************************************************/
59 
60 /*******************************************************************************
61  * Local variable definitions ('static')
62  ******************************************************************************/
63 enum
64 {
65 #ifdef BSP_USING_SPI1
66     SPI1_INDEX,
67 #endif
68 #ifdef BSP_USING_SPI2
69     SPI2_INDEX,
70 #endif
71 #ifdef BSP_USING_SPI3
72     SPI3_INDEX,
73 #endif
74 #ifdef BSP_USING_SPI4
75     SPI4_INDEX,
76 #endif
77 #ifdef BSP_USING_SPI5
78     SPI5_INDEX,
79 #endif
80 #ifdef BSP_USING_SPI6
81     SPI6_INDEX,
82 #endif
83 };
84 
85 static struct hc32_spi_config spi_config[] =
86 {
87 #ifdef BSP_USING_SPI1
88     SPI1_BUS_CONFIG,
89 #endif
90 #ifdef BSP_USING_SPI2
91     SPI2_BUS_CONFIG,
92 #endif
93 #ifdef BSP_USING_SPI3
94     SPI3_BUS_CONFIG,
95 #endif
96 #ifdef BSP_USING_SPI4
97     SPI4_BUS_CONFIG,
98 #endif
99 #ifdef BSP_USING_SPI5
100     SPI5_BUS_CONFIG,
101 #endif
102 #ifdef BSP_USING_SPI6
103     SPI6_BUS_CONFIG,
104 #endif
105 };
106 
107 static struct hc32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0};
108 
109 /*******************************************************************************
110  * Function implementation - global ('extern') and local ('static')
111  ******************************************************************************/
hc32_spi_init(struct hc32_spi * spi_drv,struct rt_spi_configuration * cfg)112 static rt_err_t hc32_spi_init(struct hc32_spi *spi_drv, struct rt_spi_configuration *cfg)
113 {
114     RT_ASSERT(spi_drv != RT_NULL);
115     RT_ASSERT(cfg != RT_NULL);
116 
117     uint32_t u32Cnt = 0;
118     uint32_t u32BusFreq;
119     stc_spi_init_t stcSpiInit;
120     CM_SPI_TypeDef *spi_instance = spi_drv->config->Instance;
121 
122     /* Enable spi clock */
123     FCG_Fcg1PeriphClockCmd(spi_drv->config->clock, ENABLE);
124     /* Init spi struct as default value */
125     SPI_StructInit(&stcSpiInit);
126 
127     if ((cfg->mode & RT_SPI_SLAVE) &&
128             ((RT_SPI_MODE_0 == (cfg->mode & RT_SPI_MODE_3)) || (RT_SPI_MODE_2 == (cfg->mode & RT_SPI_MODE_3))))
129     {
130         return -RT_EINVAL;
131     }
132     /* Slave or master mode */
133     if (cfg->mode & RT_SPI_SLAVE)
134     {
135         stcSpiInit.u32MasterSlave = SPI_SLAVE;
136         stcSpiInit.u32ModeFaultDetect = SPI_MD_FAULT_DETECT_ENABLE;
137     }
138     else
139     {
140         stcSpiInit.u32MasterSlave = SPI_MASTER;
141     }
142     /* SI/SO pin shared */
143     if (cfg->mode & RT_SPI_3WIRE)
144     {
145         return -RT_EINVAL;
146     }
147     else
148     {
149         stcSpiInit.u32TransMode = SPI_FULL_DUPLEX;
150     }
151     /* clock phase & polarity */
152     if (RT_SPI_MODE_3 == (cfg->mode & RT_SPI_MODE_3))
153     {
154         stcSpiInit.u32SpiMode = SPI_MD_3;
155     }
156     else if (RT_SPI_MODE_2 == (cfg->mode & RT_SPI_MODE_3))
157     {
158         stcSpiInit.u32SpiMode = SPI_MD_2;
159     }
160     else if (RT_SPI_MODE_1 == (cfg->mode & RT_SPI_MODE_3))
161     {
162         stcSpiInit.u32SpiMode = SPI_MD_1;
163     }
164     else
165     {
166         stcSpiInit.u32SpiMode = SPI_MD_0;
167     }
168     /* No chipselect */
169     if (cfg->mode & RT_SPI_NO_CS)
170     {
171         stcSpiInit.u32WireMode = SPI_4_WIRE;
172     }
173     else
174     {
175         stcSpiInit.u32WireMode = SPI_3_WIRE;
176     }
177     /* LSB or MSB */
178     if (cfg->mode & RT_SPI_MSB)
179     {
180         stcSpiInit.u32FirstBit = SPI_FIRST_MSB;
181     }
182     else
183     {
184         stcSpiInit.u32FirstBit = SPI_FIRST_LSB;
185     }
186     /* config data width 8,16,32 */
187     if (8 == cfg->data_width)
188     {
189         stcSpiInit.u32DataBits = SPI_DATA_SIZE_8BIT;
190     }
191     else if (16 == cfg->data_width)
192     {
193         stcSpiInit.u32DataBits = SPI_DATA_SIZE_16BIT;
194     }
195     else if (32 == cfg->data_width)
196     {
197         stcSpiInit.u32DataBits = SPI_DATA_SIZE_32BIT;
198     }
199     else
200     {
201         return -RT_EIO;
202     }
203     /* Get BUS clock */
204     u32BusFreq = CLK_GetBusClockFreq(CLK_BUS_PCLK1);
205     while (cfg->max_hz < u32BusFreq / (1UL << (u32Cnt + 1U)))
206     {
207         u32Cnt++;
208         if (u32Cnt >= SPI_MAX_DIV_VAL)  /* Div256 */
209         {
210             break;
211         }
212     }
213 #if defined(HC32F4A0) || defined(HC32F460)
214     stcSpiInit.u32BaudRatePrescaler = (u32Cnt << SPI_CFG2_MBR_POS);
215 #elif defined(HC32F448) || defined(HC32F472) || defined(HC32F4A8)
216     if (u32Cnt <= 15U)
217     {
218         stcSpiInit.u32BaudRatePrescaler = (u32Cnt << SPI_CFG1_CLKDIV_POS);
219     }
220     else
221     {
222         stcSpiInit.u32BaudRatePrescaler = (((7U + ((u32Cnt - 15U) & 0x07U)) << SPI_CFG1_CLKDIV_POS) | ((1U + ((u32Cnt - 15U) >> 3U)) << SPI_CFG2_MBR_POS));
223     }
224 #endif
225     /* slave limit */
226     if ((cfg->mode & RT_SPI_SLAVE) && (stcSpiInit.u32BaudRatePrescaler < SPI_BR_CLK_DIV8))
227     {
228         stcSpiInit.u32BaudRatePrescaler = SPI_BR_CLK_DIV8;
229     }
230     LOG_D("Bus freq: %d, SPI freq: %d, BaudRatePrescaler: %d, u32Cnt: %d", u32BusFreq, cfg->max_hz, stcSpiInit.u32BaudRatePrescaler, u32Cnt);
231 
232     /* spi port init */
233     rt_hw_spi_board_init(spi_instance);
234     if (LL_OK != SPI_Init(spi_instance, &stcSpiInit))
235     {
236         return -RT_EIO;
237     }
238 
239 #ifdef BSP_SPI_USING_DMA
240     /* DMA configuration */
241     if (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_RX)
242     {
243         struct dma_config *spi_dma;
244         stc_dma_init_t  stcDmaInit;
245 
246         /* Get spi dma_rx */
247         spi_dma = spi_drv->config->dma_rx;
248         /* Enable Dma clock */
249         FCG_Fcg0PeriphClockCmd(spi_dma->clock, ENABLE);
250         AOS_SetTriggerEventSrc(spi_dma->trigger_select, spi_dma->trigger_event);
251         /* Config Dma */
252         DMA_StructInit(&stcDmaInit);
253         stcDmaInit.u32BlockSize     = 1UL;
254         stcDmaInit.u32SrcAddr       = (uint32_t)(&spi_instance->DR);
255         stcDmaInit.u32SrcAddrInc    = DMA_SRC_ADDR_FIX;
256         if (8 == cfg->data_width)
257         {
258             stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;
259         }
260         else if (16 == cfg->data_width)
261         {
262             stcDmaInit.u32DataWidth = DMA_DATAWIDTH_16BIT;
263         }
264         else
265         {
266             stcDmaInit.u32DataWidth = DMA_DATAWIDTH_32BIT;
267         }
268         /* Init Dma */
269         if (LL_OK != DMA_Init(spi_dma->Instance, spi_dma->channel, &stcDmaInit))
270         {
271             return -RT_EIO;
272         }
273         /* Enable Dma */
274         DMA_Cmd(spi_dma->Instance, ENABLE);
275     }
276     if (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_TX)
277     {
278         struct dma_config *spi_dma;
279         stc_dma_init_t  stcDmaInit;
280 
281         /* Get spi dma_tx */
282         spi_dma = spi_drv->config->dma_tx;
283         FCG_Fcg0PeriphClockCmd(spi_dma->clock, ENABLE);
284         AOS_SetTriggerEventSrc(spi_dma->trigger_select, spi_dma->trigger_event);
285         /* Config Dma */
286         DMA_StructInit(&stcDmaInit);
287         stcDmaInit.u32BlockSize     = 1UL;
288         stcDmaInit.u32DestAddr      = (uint32_t)(&spi_instance->DR);;
289         stcDmaInit.u32DestAddrInc   = DMA_DEST_ADDR_FIX;
290         if (8 == cfg->data_width)
291         {
292             stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;
293         }
294         else if (16 == cfg->data_width)
295         {
296             stcDmaInit.u32DataWidth = DMA_DATAWIDTH_16BIT;
297         }
298         else
299         {
300             stcDmaInit.u32DataWidth = DMA_DATAWIDTH_32BIT;
301         }
302         /* Init Dma */
303         if (LL_OK != DMA_Init(spi_dma->Instance, spi_dma->channel, &stcDmaInit))
304         {
305             return -RT_EIO;
306         }
307         /* Enable Dma */
308         DMA_Cmd(spi_dma->Instance, ENABLE);
309     }
310 #endif
311 
312     /* Enable error interrupt */
313 #if defined (HC32F448) || defined (HC32F472)
314     INTC_IntSrcCmd(spi_drv->config->err_irq.irq_config.int_src, ENABLE);
315 #endif
316     NVIC_EnableIRQ(spi_drv->config->err_irq.irq_config.irq_num);
317     SPI_IntCmd(spi_instance, SPI_INT_ERR, ENABLE);
318 
319     LOG_D("%s init done", spi_drv->config->bus_name);
320     return RT_EOK;
321 }
322 
hc32_spi_enable(CM_SPI_TypeDef * SPIx)323 static void hc32_spi_enable(CM_SPI_TypeDef *SPIx)
324 {
325     /* Check if the SPI is already enabled */
326 #if defined (HC32F460) || defined (HC32F4A0)
327     if ((SPIx->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
328     {
329         SPI_Cmd(SPIx, ENABLE);
330     }
331 #elif defined (HC32F448) || defined (HC32F472) || defined (HC32F4A8)
332     if ((SPIx->CR & SPI_CR_SPE) != SPI_CR_SPE)
333     {
334         SPI_Cmd(SPIx, ENABLE);
335     }
336 #else
337 #error "Please select first the target HC32xxxx device used in your application."
338 #endif
339 }
340 
hc32_spi_set_trans_mode(CM_SPI_TypeDef * SPIx,uint32_t u32Mode)341 static void hc32_spi_set_trans_mode(CM_SPI_TypeDef *SPIx, uint32_t u32Mode)
342 {
343 #if defined (HC32F460) || defined (HC32F4A0)
344     if (SPI_SEND_ONLY == u32Mode)
345     {
346         SET_REG32_BIT(SPIx->CR1, SPI_CR1_TXMDS);
347     }
348     else
349     {
350         CLR_REG32_BIT(SPIx->CR1, SPI_CR1_TXMDS);
351     }
352 #elif defined (HC32F448) || defined (HC32F472) || defined (HC32F4A8)
353     if (SPI_SEND_ONLY == u32Mode)
354     {
355         SET_REG32_BIT(SPIx->CR, SPI_CR_TXMDS);
356     }
357     else
358     {
359         CLR_REG32_BIT(SPIx->CR, SPI_CR_TXMDS);
360     }
361 #else
362 #error "Please select first the target HC32xxxx device used in your application."
363 #endif
364 }
365 
366 #ifdef BSP_SPI_USING_DMA
hc32_spi_get_trans_mode(CM_SPI_TypeDef * SPIx)367 static uint32_t hc32_spi_get_trans_mode(CM_SPI_TypeDef *SPIx)
368 {
369 #if defined (HC32F460) || defined (HC32F4A0)
370     return READ_REG32_BIT(SPIx->CR1, SPI_CR1_TXMDS);
371 #elif defined (HC32F448) || defined (HC32F472) || defined (HC32F4A8)
372     return READ_REG32_BIT(SPIx->CR, SPI_CR_TXMDS);
373 #else
374 #error "Please select first the target HC32xxxx device used in your application."
375 #endif
376 }
377 
378 /**
379  * @brief  Config DMA source address increment mode.
380  * @param  [in] DMAx DMA unit instance.
381  * @param  [in] u8Ch DMA channel.
382  * @param  [in] u32IncMode DMA source address increment mode @ref DMA_SrcAddr_Incremented_Mode
383  * @retval None
384  */
DMA_SetSrcAddrIncMode(CM_DMA_TypeDef * DMAx,uint8_t u8Ch,uint32_t u32IncMode)385 void DMA_SetSrcAddrIncMode(CM_DMA_TypeDef *DMAx, uint8_t u8Ch, uint32_t u32IncMode)
386 {
387     __IO uint32_t *CHCTLx;
388 
389     CHCTLx = &DMA_CH_REG(DMAx->CHCTL0, u8Ch);
390     MODIFY_REG32(*CHCTLx, DMA_CHCTL_SINC, u32IncMode);
391 }
392 
393 /**
394  * @brief  Config DMA destination address increment mode.
395  * @param  [in] DMAx DMA unit instance.
396  * @param  [in] u8Ch DMA channel.
397  * @param  [in] u16Count DMA destination address increment mode @ref DMA_DesAddr_Incremented_Mode
398  * @retval None
399  */
DMA_SetDestAddrIncMode(CM_DMA_TypeDef * DMAx,uint8_t u8Ch,uint32_t u32IncMode)400 void DMA_SetDestAddrIncMode(CM_DMA_TypeDef *DMAx, uint8_t u8Ch, uint32_t u32IncMode)
401 {
402     __IO uint32_t *CHCTLx;
403 
404     CHCTLx = &DMA_CH_REG(DMAx->CHCTL0, u8Ch);
405     MODIFY_REG32(*CHCTLx, DMA_CHCTL_DINC, u32IncMode);
406 }
407 #endif
408 
hc32_spi_configure(struct rt_spi_device * device,struct rt_spi_configuration * configuration)409 static rt_err_t hc32_spi_configure(struct rt_spi_device *device,
410                                    struct rt_spi_configuration *configuration)
411 {
412     RT_ASSERT(device != RT_NULL);
413     RT_ASSERT(configuration != RT_NULL);
414 
415     struct hc32_spi *spi_drv =  rt_container_of(device->bus, struct hc32_spi, spi_bus);
416     spi_drv->cfg = configuration;
417 
418     return hc32_spi_init(spi_drv, configuration);
419 }
420 
hc32_spi_dma_trans(struct hc32_spi_config * spi_config,const uint8_t * pvTxBuf,void * pvRxBuf,uint32_t u32Length)421 static int32_t hc32_spi_dma_trans(struct hc32_spi_config *spi_config, const uint8_t *pvTxBuf, void *pvRxBuf, uint32_t u32Length)
422 {
423     int32_t i32Ret = LL_OK;
424 #ifdef BSP_SPI_USING_DMA
425     rt_uint32_t u32TimeoutCnt;
426     CM_DMA_TypeDef *DmaInstance;
427     rt_uint32_t DmaFlag;
428     uint32_t u32TxTmp, u32RxTmp;
429 
430     if ((spi_config == RT_NULL) || ((pvTxBuf == RT_NULL) && (pvRxBuf == RT_NULL)))
431     {
432         return LL_ERR;
433     }
434 
435     SPI_Cmd(spi_config->Instance, DISABLE);
436     if (RT_NULL != pvTxBuf)
437     {
438         DMA_ClearTransCompleteStatus(spi_config->dma_tx->Instance, spi_config->dma_tx->flag);
439         DMA_SetSrcAddr(spi_config->dma_tx->Instance, spi_config->dma_tx->channel, (uint32_t)pvTxBuf);
440         DMA_SetSrcAddrIncMode(spi_config->dma_tx->Instance, spi_config->dma_tx->channel, DMA_SRC_ADDR_INC);
441         DMA_SetTransCount(spi_config->dma_tx->Instance, spi_config->dma_tx->channel, u32Length);
442         DMA_ChCmd(spi_config->dma_tx->Instance, spi_config->dma_tx->channel, ENABLE);
443     }
444     else
445     {
446         if (SPI_FULL_DUPLEX == hc32_spi_get_trans_mode(spi_config->Instance))
447         {
448             u32TxTmp = 0xFFFFFFFFUL;
449             DMA_ClearTransCompleteStatus(spi_config->dma_tx->Instance, spi_config->dma_tx->flag);
450             DMA_SetSrcAddr(spi_config->dma_tx->Instance, spi_config->dma_tx->channel, (uint32_t)&u32TxTmp);
451             DMA_SetSrcAddrIncMode(spi_config->dma_tx->Instance, spi_config->dma_tx->channel, DMA_SRC_ADDR_FIX);
452             DMA_SetTransCount(spi_config->dma_tx->Instance, spi_config->dma_tx->channel, u32Length);
453             DMA_ChCmd(spi_config->dma_tx->Instance, spi_config->dma_tx->channel, ENABLE);
454         }
455     }
456     if (RT_NULL != pvRxBuf)
457     {
458         DMA_ClearTransCompleteStatus(spi_config->dma_rx->Instance, spi_config->dma_rx->flag);
459         DMA_SetDestAddr(spi_config->dma_rx->Instance, spi_config->dma_rx->channel, (uint32_t)pvRxBuf);
460         DMA_SetDestAddrIncMode(spi_config->dma_rx->Instance, spi_config->dma_rx->channel, DMA_DEST_ADDR_INC);
461         DMA_SetTransCount(spi_config->dma_rx->Instance, spi_config->dma_rx->channel, u32Length);
462         DMA_ChCmd(spi_config->dma_rx->Instance, spi_config->dma_rx->channel, ENABLE);
463     }
464     else
465     {
466         if (SPI_FULL_DUPLEX == hc32_spi_get_trans_mode(spi_config->Instance))
467         {
468             DMA_ClearTransCompleteStatus(spi_config->dma_rx->Instance, spi_config->dma_rx->flag);
469             DMA_SetDestAddr(spi_config->dma_rx->Instance, spi_config->dma_rx->channel, (uint32_t)&u32RxTmp);
470             DMA_SetDestAddrIncMode(spi_config->dma_rx->Instance, spi_config->dma_rx->channel, DMA_DEST_ADDR_FIX);
471             DMA_SetTransCount(spi_config->dma_rx->Instance, spi_config->dma_rx->channel, u32Length);
472             DMA_ChCmd(spi_config->dma_rx->Instance, spi_config->dma_rx->channel, ENABLE);
473         }
474     }
475     SPI_Cmd(spi_config->Instance, ENABLE);
476 
477     u32TimeoutCnt = 0U;
478     /* Wait DMA transfer completed */
479     if (RT_NULL != pvRxBuf)
480     {
481         DmaInstance = spi_config->dma_rx->Instance;
482         DmaFlag = spi_config->dma_rx->flag;
483     }
484     else
485     {
486         DmaInstance = spi_config->dma_tx->Instance;
487         DmaFlag = spi_config->dma_tx->flag;
488     }
489     while ((RESET == DMA_GetTransCompleteStatus(DmaInstance, DmaFlag)) &&
490             (u32TimeoutCnt < spi_config->timeout))
491     {
492         rt_thread_mdelay(1);
493         u32TimeoutCnt++;
494     }
495     if (u32TimeoutCnt >= spi_config->timeout)
496     {
497         i32Ret = LL_ERR_TIMEOUT;
498     }
499 #endif
500 
501     return i32Ret;
502 }
503 
hc32_spi_xfer(struct rt_spi_device * device,struct rt_spi_message * message)504 static rt_ssize_t hc32_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
505 {
506     int32_t state;
507     rt_size_t message_length, already_send_length;
508     rt_uint16_t send_length;
509     rt_uint8_t *recv_buf;
510     const rt_uint8_t *send_buf;
511     rt_uint32_t u32TimeoutCnt;
512 
513     RT_ASSERT(device != RT_NULL);
514     RT_ASSERT(device->bus != RT_NULL);
515     RT_ASSERT(message != RT_NULL);
516 
517     struct hc32_spi *spi_drv =  rt_container_of(device->bus, struct hc32_spi, spi_bus);
518     CM_SPI_TypeDef *spi_instance = spi_drv->config->Instance;
519 
520     if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE))
521     {
522         if (device->config.mode & RT_SPI_CS_HIGH)
523             rt_pin_write(device->cs_pin, PIN_HIGH);
524         else
525             rt_pin_write(device->cs_pin, PIN_LOW);
526     }
527 
528     LOG_D("%s transfer prepare and start", spi_drv->config->bus_name);
529     LOG_D("%s sendbuf: %X, recvbuf: %X, length: %d", spi_drv->config->bus_name,
530           (uint32_t)message->send_buf, (uint32_t)message->recv_buf, message->length);
531 
532     message_length  = message->length;
533     recv_buf        = message->recv_buf;
534     send_buf        = message->send_buf;
535     while (message_length)
536     {
537         if (message_length > 65535)
538         {
539             send_length     = 65535;
540             message_length  = message_length - 65535;
541         }
542         else
543         {
544             send_length     = message_length;
545             message_length  = 0;
546         }
547 
548         /* calculate the start address */
549         already_send_length = message->length - send_length - message_length;
550         /* avoid null pointer problems */
551         if (message->send_buf)
552         {
553             send_buf = (rt_uint8_t *)message->send_buf + already_send_length;
554         }
555         if (message->recv_buf)
556         {
557             recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length;
558         }
559 
560         if (message->send_buf && message->recv_buf)
561         {
562             hc32_spi_set_trans_mode(spi_instance, SPI_FULL_DUPLEX);
563             if ((spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_TX) && (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_RX))
564             {
565                 state = hc32_spi_dma_trans(spi_drv->config, send_buf, recv_buf, send_length);
566             }
567             else
568             {
569                 hc32_spi_enable(spi_instance);
570                 state = SPI_TransReceive(spi_instance, send_buf, recv_buf, send_length, spi_drv->config->timeout);
571             }
572         }
573         else if (message->send_buf)
574         {
575             hc32_spi_set_trans_mode(spi_instance, SPI_SEND_ONLY);
576             if (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_TX)
577             {
578                 state = hc32_spi_dma_trans(spi_drv->config, send_buf, RT_NULL, send_length);
579             }
580             else
581             {
582                 hc32_spi_enable(spi_instance);
583                 state = SPI_Trans(spi_instance, send_buf, send_length, spi_drv->config->timeout);
584             }
585         }
586         else
587         {
588             hc32_spi_set_trans_mode(spi_instance, SPI_FULL_DUPLEX);
589             if ((spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_TX) && (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_RX))
590             {
591                 state = hc32_spi_dma_trans(spi_drv->config, RT_NULL, recv_buf, send_length);
592             }
593             else
594             {
595                 hc32_spi_enable(spi_instance);
596                 state = SPI_Receive(spi_instance, recv_buf, send_length, spi_drv->config->timeout);
597             }
598         }
599         if (state != LL_OK)
600         {
601             LOG_I("spi transfer error : %d", state);
602             message->length = 0;
603             break;
604         }
605         else
606         {
607             /* Wait for the spi transfer complete */
608             if (spi_drv->spi_dma_flag & (RT_DEVICE_FLAG_DMA_TX | RT_DEVICE_FLAG_DMA_RX))
609             {
610                 if (spi_drv->cfg->mode & RT_SPI_SLAVE)
611                 {
612                     rt_thread_mdelay(1);
613                 }
614                 else
615                 {
616                     u32TimeoutCnt = 0U;
617                     while ((RESET == SPI_GetStatus(spi_instance, SPI_FLAG_IDLE)) &&
618                             (u32TimeoutCnt < spi_drv->config->timeout))
619                     {
620                         rt_thread_mdelay(1);
621                         u32TimeoutCnt++;
622                     }
623                     if (u32TimeoutCnt >= spi_drv->config->timeout)
624                     {
625                         LOG_I("spi transfer timeout!");
626                         message->length = 0;
627                         break;
628                     }
629                 }
630             }
631         }
632     }
633     /* clear error flag */
634     SPI_ClearStatus(spi_instance, SPI_FLAG_CLR_ALL);
635 
636     if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE))
637     {
638         if (device->config.mode & RT_SPI_CS_HIGH)
639             rt_pin_write(device->cs_pin, PIN_LOW);
640         else
641             rt_pin_write(device->cs_pin, PIN_HIGH);
642     }
643 
644     return message->length;
645 }
646 
647 static const struct rt_spi_ops hc32_spi_ops =
648 {
649     .configure  = hc32_spi_configure,
650     .xfer       = hc32_spi_xfer,
651 };
652 
653 /**
654   * Attach the spi device to SPI bus, this function must be used after initialization.
655   */
rt_hw_spi_device_attach(const char * bus_name,const char * device_name,rt_base_t cs_pin)656 rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin)
657 {
658     RT_ASSERT(bus_name != RT_NULL);
659     RT_ASSERT(device_name != RT_NULL);
660 
661     rt_err_t result;
662     struct rt_spi_device *spi_device;
663 
664     /* attach the device to spi bus*/
665     spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
666     RT_ASSERT(spi_device != RT_NULL);
667 
668     result = rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, cs_pin, RT_NULL);
669 
670     if (result != RT_EOK)
671     {
672         LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
673     }
674 
675     return result;
676 }
677 
hc32_spi_err_irq_handle(struct hc32_spi * spi)678 static void hc32_spi_err_irq_handle(struct hc32_spi *spi)
679 {
680     __UNUSED uint32_t UnusedData;
681     CM_SPI_TypeDef *spi_instance = spi->config->Instance;
682 
683     if (RESET != SPI_GetStatus(spi_instance, SPI_FLAG_OVERRUN))
684     {
685         UnusedData = SPI_ReadData(spi_instance);
686         SPI_ClearStatus(spi_instance, SPI_FLAG_OVERRUN);
687     }
688     if (RESET != SPI_GetStatus(spi_instance, SPI_FLAG_UNDERRUN))
689     {
690         SPI_ClearStatus(spi_instance, SPI_FLAG_UNDERRUN);
691     }
692     if (RESET != SPI_GetStatus(spi_instance, SPI_FLAG_MD_FAULT))
693     {
694         SPI_ClearStatus(spi_instance, SPI_FLAG_MD_FAULT);
695     }
696     if (RESET != SPI_GetStatus(spi_instance, SPI_FLAG_PARITY_ERR))
697     {
698         SPI_ClearStatus(spi_instance, SPI_FLAG_PARITY_ERR);
699     }
700 }
701 
702 #if defined(BSP_USING_SPI1)
hc32_spi1_err_irq_handler(void)703 static void hc32_spi1_err_irq_handler(void)
704 {
705     /* enter interrupt */
706     rt_interrupt_enter();
707     hc32_spi_err_irq_handle(&spi_bus_obj[SPI1_INDEX]);
708     /* leave interrupt */
709     rt_interrupt_leave();
710 }
711 
712 #if defined (HC32F448) ||defined (HC32F472)
SPI1_Handler(void)713 void SPI1_Handler(void)
714 {
715     hc32_spi1_err_irq_handler();
716 }
717 #endif /* HC32F448, HC32F472 */
718 
719 #endif /* BSP_USING_SPI1 */
720 
721 #if defined(BSP_USING_SPI2)
hc32_spi2_err_irq_handler(void)722 static void hc32_spi2_err_irq_handler(void)
723 {
724     /* enter interrupt */
725     rt_interrupt_enter();
726     hc32_spi_err_irq_handle(&spi_bus_obj[SPI2_INDEX]);
727     /* leave interrupt */
728     rt_interrupt_leave();
729 }
730 #if defined (HC32F448) ||defined (HC32F472)
SPI2_Handler(void)731 void SPI2_Handler(void)
732 {
733     hc32_spi2_err_irq_handler();
734 }
735 #endif /* HC32F448, HC32F472 */
736 
737 #endif /* BSP_USING_SPI2 */
738 
739 #if defined(BSP_USING_SPI3)
hc32_spi3_err_irq_handler(void)740 static void hc32_spi3_err_irq_handler(void)
741 {
742     /* enter interrupt */
743     rt_interrupt_enter();
744     hc32_spi_err_irq_handle(&spi_bus_obj[SPI3_INDEX]);
745     /* leave interrupt */
746     rt_interrupt_leave();
747 }
748 #if defined (HC32F448) ||defined (HC32F472)
SPI3_Handler(void)749 void SPI3_Handler(void)
750 {
751     hc32_spi3_err_irq_handler();
752 }
753 #endif /* HC32F448, HC32F472 */
754 
755 #endif /* BSP_USING_SPI3 */
756 
757 #if defined(BSP_USING_SPI4)
hc32_spi4_err_irq_handler(void)758 static void hc32_spi4_err_irq_handler(void)
759 {
760     /* enter interrupt */
761     rt_interrupt_enter();
762     hc32_spi_err_irq_handle(&spi_bus_obj[SPI4_INDEX]);
763     /* leave interrupt */
764     rt_interrupt_leave();
765 }
766 #endif /* BSP_USING_SPI4 */
767 #if defined (HC32F472)
SPI4_Handler(void)768 void SPI4_Handler(void)
769 {
770     hc32_spi4_err_irq_handler();
771 }
772 #endif /* HC32F472 */
773 
774 #if defined(BSP_USING_SPI5)
hc32_spi5_err_irq_handler(void)775 static void hc32_spi5_err_irq_handler(void)
776 {
777     /* enter interrupt */
778     rt_interrupt_enter();
779     hc32_spi_err_irq_handle(&spi_bus_obj[SPI5_INDEX]);
780     /* leave interrupt */
781     rt_interrupt_leave();
782 }
783 #endif /* BSP_USING_SPI5 */
784 
785 #if defined(BSP_USING_SPI6)
hc32_spi6_err_irq_handler(void)786 static void hc32_spi6_err_irq_handler(void)
787 {
788     /* enter interrupt */
789     rt_interrupt_enter();
790     hc32_spi_err_irq_handle(&spi_bus_obj[SPI6_INDEX]);
791     /* leave interrupt */
792     rt_interrupt_leave();
793 }
794 #endif /* BSP_USING_SPI6 */
795 
796 
797 /**
798  * @brief  This function gets spi irq handle.
799  * @param  None
800  * @retval None
801  */
hc32_get_spi_callback(void)802 static void hc32_get_spi_callback(void)
803 {
804 #ifdef BSP_USING_SPI1
805     spi_config[SPI1_INDEX].err_irq.irq_callback = hc32_spi1_err_irq_handler;
806 #endif
807 #ifdef BSP_USING_SPI2
808     spi_config[SPI2_INDEX].err_irq.irq_callback = hc32_spi2_err_irq_handler;
809 #endif
810 #ifdef BSP_USING_SPI3
811     spi_config[SPI3_INDEX].err_irq.irq_callback = hc32_spi3_err_irq_handler;
812 #endif
813 #ifdef BSP_USING_SPI4
814     spi_config[SPI4_INDEX].err_irq.irq_callback = hc32_spi4_err_irq_handler;
815 #endif
816 #ifdef BSP_USING_SPI5
817     spi_config[SPI5_INDEX].err_irq.irq_callback = hc32_spi5_err_irq_handler;
818 #endif
819 #ifdef BSP_USING_SPI6
820     spi_config[SPI6_INDEX].err_irq.irq_callback = hc32_spi6_err_irq_handler;
821 #endif
822 }
823 
824 /**
825   * @brief  This function gets dma witch spi used infomation include unit,
826   *         channel, interrupt etc.
827   * @param  None
828   * @retval None
829   */
hc32_get_dma_info(void)830 static void hc32_get_dma_info(void)
831 {
832 #ifdef BSP_SPI1_RX_USING_DMA
833     spi_bus_obj[SPI1_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
834     static struct dma_config spi1_dma_rx = SPI1_RX_DMA_CONFIG;
835     spi_config[SPI1_INDEX].dma_rx   = &spi1_dma_rx;
836 #endif
837 #ifdef BSP_SPI1_TX_USING_DMA
838     spi_bus_obj[SPI1_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
839     static struct dma_config spi1_dma_tx = SPI1_TX_DMA_CONFIG;
840     spi_config[SPI1_INDEX].dma_tx   = &spi1_dma_tx;
841 #endif
842 
843 #ifdef BSP_SPI2_RX_USING_DMA
844     spi_bus_obj[SPI2_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
845     static struct dma_config spi2_dma_rx = SPI2_RX_DMA_CONFIG;
846     spi_config[SPI2_INDEX].dma_rx   = &spi2_dma_rx;
847 #endif
848 #ifdef BSP_SPI2_TX_USING_DMA
849     spi_bus_obj[SPI2_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
850     static struct dma_config spi2_dma_tx = SPI2_TX_DMA_CONFIG;
851     spi_config[SPI2_INDEX].dma_tx   = &spi2_dma_tx;
852 #endif
853 
854 #ifdef BSP_SPI3_RX_USING_DMA
855     spi_bus_obj[SPI3_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
856     static struct dma_config spi3_dma_rx = SPI3_RX_DMA_CONFIG;
857     spi_config[SPI3_INDEX].dma_rx   = &spi3_dma_rx;
858 #endif
859 #ifdef BSP_SPI3_TX_USING_DMA
860     spi_bus_obj[SPI3_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
861     static struct dma_config spi3_dma_tx = SPI3_TX_DMA_CONFIG;
862     spi_config[SPI3_INDEX].dma_tx   = &spi3_dma_tx;
863 #endif
864 
865 #ifdef BSP_SPI4_RX_USING_DMA
866     spi_bus_obj[SPI4_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
867     static struct dma_config spi4_dma_rx = SPI4_RX_DMA_CONFIG;
868     spi_config[SPI4_INDEX].dma_rx   = &spi4_dma_rx;
869 #endif
870 #ifdef BSP_SPI4_TX_USING_DMA
871     spi_bus_obj[SPI4_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
872     static struct dma_config spi4_dma_tx = SPI4_TX_DMA_CONFIG;
873     spi_config[SPI4_INDEX].dma_tx   = &spi4_dma_tx;
874 #endif
875 
876 #ifdef BSP_SPI5_RX_USING_DMA
877     spi_bus_obj[SPI5_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
878     static struct dma_config spi5_dma_rx = SPI5_RX_DMA_CONFIG;
879     spi_config[SPI5_INDEX].dma_rx   = &spi5_dma_rx;
880 #endif
881 #ifdef BSP_SPI5_TX_USING_DMA
882     spi_bus_obj[SPI5_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
883     static struct dma_config spi5_dma_tx = SPI5_TX_DMA_CONFIG;
884     spi_config[SPI5_INDEX].dma_tx   = &spi5_dma_tx;
885 #endif
886 
887 #ifdef BSP_SPI6_RX_USING_DMA
888     spi_bus_obj[SPI6_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
889     static struct dma_config spi6_dma_rx = SPI6_RX_DMA_CONFIG;
890     spi_config[SPI6_INDEX].dma_rx   = &spi6_dma_rx;
891 #endif
892 #ifdef BSP_SPI6_TX_USING_DMA
893     spi_bus_obj[SPI6_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
894     static struct dma_config spi6_dma_tx = SPI6_TX_DMA_CONFIG;
895     spi_config[SPI6_INDEX].dma_tx   = &spi6_dma_tx;
896 #endif
897 }
898 
hc32_hw_spi_bus_init(void)899 static int hc32_hw_spi_bus_init(void)
900 {
901     rt_err_t result;
902 
903     hc32_get_spi_callback();
904     for (int i = 0; i < sizeof(spi_config) / sizeof(spi_config[0]); i++)
905     {
906         spi_bus_obj[i].config = &spi_config[i];
907         spi_bus_obj[i].spi_bus.parent.user_data = &spi_config[i];
908         /* register the handle */
909 #if defined (HC32F460) || defined (HC32F4A0) || defined (HC32F4A8)
910         hc32_install_irq_handler(&spi_config[i].err_irq.irq_config, spi_config[i].err_irq.irq_callback, RT_FALSE);
911 #elif defined (HC32F448) || defined (HC32F472)
912         INTC_IntSrcCmd(spi_config[i].err_irq.irq_config.int_src, DISABLE);
913         NVIC_DisableIRQ(spi_config[i].err_irq.irq_config.irq_num);
914 #endif
915         result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, spi_config[i].bus_name, &hc32_spi_ops);
916         LOG_D("%s bus init done", spi_config[i].bus_name);
917     }
918 
919     return result;
920 }
921 
hc32_hw_spi_init(void)922 int hc32_hw_spi_init(void)
923 {
924     hc32_get_dma_info();
925     return hc32_hw_spi_bus_init();
926 }
927 
928 INIT_BOARD_EXPORT(hc32_hw_spi_init);
929 
930 #endif
931 
932 #endif /* BSP_USING_SPI */
933