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