From 17cdf347a6b17230f0a5d8ec03da43e447fe3066 Mon Sep 17 00:00:00 2001 From: wdfk-prog <1425075683@qq.com> Date: Wed, 15 Apr 2026 10:53:21 +0800 Subject: [PATCH 1/2] feat[STM32][SPI]: refine dma config hierarchy for hard spi refine the stm32 hard spi dma configuration hierarchy with shared feature macros align dma flag usage with rt-device dma flags and gate dma-only fields and paths make the dma transfer threshold configurable through BSP_SPI_DMA_TRANS_MIN_LEN --- .../libraries/HAL_Drivers/drivers/drv_spi.c | 180 +++++++++++------- .../libraries/HAL_Drivers/drivers/drv_spi.h | 74 ++++++- 2 files changed, 176 insertions(+), 78 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c index 8e65b759c5a..14ea783d0da 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c @@ -10,8 +10,9 @@ * 2019-01-03 zylx modify DMA initialization and spixfer function * 2020-01-15 whj4674672 Porting for stm32h7xx * 2020-06-18 thread-liu Porting for stm32mp1xx - * 2020-10-14 Dozingfiretruck Porting for stm32wbxx + * 2020-10-14 PeakRacing Porting for stm32wbxx * 2025-09-22 wdfk_prog Refactor spixfer to fix DMA reception bug, correct timeout calculation. + * 2026-04-14 wdfk_prog Refine SPI DMA config hierarchy */ #include @@ -20,12 +21,14 @@ #ifdef BSP_USING_SPI -#if defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) || defined(BSP_USING_SPI4) || defined(BSP_USING_SPI5) || defined(BSP_USING_SPI6) - #include "drv_spi.h" #include "drv_config.h" #include +#ifndef BSP_SPI_DMA_TRANS_MIN_LEN +#define BSP_SPI_DMA_TRANS_MIN_LEN 10U +#endif /* BSP_SPI_DMA_TRANS_MIN_LEN */ + /*#define DRV_DEBUG*/ #define LOG_TAG "drv.spi" #include @@ -81,22 +84,28 @@ static struct stm32_spi_config spi_config[] = static struct stm32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0}; +#ifdef BSP_SPI_USING_DMA static void stm32_spi_dma_rollback(struct stm32_spi *spi_drv, rt_uint16_t dma_flags) { - if ((dma_flags & SPI_USING_RX_DMA_FLAG) && (spi_drv->config->dma_rx != RT_NULL)) +#if defined(BSP_SPI_RX_USING_DMA) + if ((dma_flags & RT_DEVICE_FLAG_DMA_RX) && (spi_drv->config->dma_rx != RT_NULL)) { (void)stm32_dma_deinit(&spi_drv->dma.handle_rx, spi_drv->config->dma_rx, RT_FALSE); spi_drv->dma.handle_rx.Parent = RT_NULL; spi_drv->handle.hdmarx = RT_NULL; } +#endif /* BSP_SPI_RX_USING_DMA */ - if ((dma_flags & SPI_USING_TX_DMA_FLAG) && (spi_drv->config->dma_tx != RT_NULL)) +#if defined(BSP_SPI_TX_USING_DMA) + if ((dma_flags & RT_DEVICE_FLAG_DMA_TX) && (spi_drv->config->dma_tx != RT_NULL)) { (void)stm32_dma_deinit(&spi_drv->dma.handle_tx, spi_drv->config->dma_tx, RT_FALSE); spi_drv->dma.handle_tx.Parent = RT_NULL; spi_drv->handle.hdmatx = RT_NULL; } +#endif /* BSP_SPI_TX_USING_DMA */ } +#endif /* BSP_SPI_USING_DMA */ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configuration *cfg) { @@ -269,36 +278,42 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur SET_BIT(spi_handle->Instance->CR2, SPI_RXFIFO_THRESHOLD_HF); #endif +#ifdef BSP_SPI_USING_DMA /* DMA configuration */ - if (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG) +#if defined(BSP_SPI_RX_USING_DMA) + if (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_RX) { if (stm32_dma_setup(&spi_drv->dma.handle_rx, &spi_drv->handle, &spi_drv->handle.hdmarx, spi_drv->config->dma_rx) != RT_EOK) { - stm32_spi_dma_rollback(spi_drv, SPI_USING_RX_DMA_FLAG); + stm32_spi_dma_rollback(spi_drv, RT_DEVICE_FLAG_DMA_RX); return -RT_EIO; } } +#endif /* BSP_SPI_RX_USING_DMA */ - if (spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) +#if defined(BSP_SPI_TX_USING_DMA) + if (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_TX) { if (stm32_dma_setup(&spi_drv->dma.handle_tx, &spi_drv->handle, &spi_drv->handle.hdmatx, spi_drv->config->dma_tx) != RT_EOK) { - stm32_spi_dma_rollback(spi_drv, SPI_USING_TX_DMA_FLAG | (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG)); + stm32_spi_dma_rollback(spi_drv, RT_DEVICE_FLAG_DMA_TX | (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_RX)); return -RT_EIO; } } +#endif /* BSP_SPI_TX_USING_DMA */ - if(spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG || spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG) + if ((spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_TX) || (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_RX)) { HAL_NVIC_SetPriority(spi_drv->config->irq_type, 2, 0); HAL_NVIC_EnableIRQ(spi_drv->config->irq_type); } +#endif /* BSP_SPI_USING_DMA */ LOG_D("%s init done", spi_drv->config->bus_name); return RT_EOK; @@ -306,8 +321,6 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message) { -#define DMA_TRANS_MIN_LEN 10 /* only buffer length >= DMA_TRANS_MIN_LEN will use DMA mode */ - HAL_StatusTypeDef state = HAL_OK; rt_size_t message_length, already_send_length; rt_uint16_t send_length; @@ -329,7 +342,9 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m } rt_uint32_t timeout_ms = total_byte_ms / speed_bytes_per_sec + 100; +#ifdef BSP_SPI_USING_DMA rt_tick_t timeout_tick = rt_tick_from_millisecond(timeout_ms); +#endif /* BSP_SPI_USING_DMA */ if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) { @@ -378,6 +393,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length; } +#ifdef BSP_SPI_USING_DMA const rt_uint8_t *dma_send_buf = send_buf; rt_uint8_t *dma_recv_buf = recv_buf; @@ -427,26 +443,31 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m if (dma_recv_buf) rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, dma_recv_buf, send_length); #endif } +#endif /* BSP_SPI_USING_DMA */ /* Start data exchange in full-duplex DMA mode. */ if (message->send_buf && message->recv_buf) { +#ifdef BSP_SPI_USING_DMA if (use_tx_dma && use_rx_dma) { state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)dma_send_buf, dma_recv_buf, send_length); } else +#endif /* BSP_SPI_USING_DMA */ { state = HAL_SPI_TransmitReceive(spi_handle, (uint8_t *)send_buf, recv_buf, send_length, timeout_ms); } } else if (message->send_buf) { +#ifdef BSP_SPI_USING_DMA if (use_tx_dma) { state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)dma_send_buf, send_length); } else +#endif /* BSP_SPI_USING_DMA */ { state = HAL_SPI_Transmit(spi_handle, (uint8_t *)send_buf, send_length, timeout_ms); } @@ -459,12 +480,14 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m } else if(message->recv_buf) { +#ifdef BSP_SPI_USING_DMA rt_memset(dma_recv_buf, 0xFF, send_length); if (use_rx_dma) { state = HAL_SPI_Receive_DMA(spi_handle, dma_recv_buf, send_length); } else +#endif /* BSP_SPI_USING_DMA */ { /* clear the old error flag */ __HAL_SPI_CLEAR_OVRFLAG(spi_handle); @@ -489,6 +512,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m LOG_D("%s transfer done", spi_drv->config->bus_name); } +#ifdef BSP_SPI_USING_DMA if (use_tx_dma || use_rx_dma) { /* blocking the thread,and the other tasks can run */ @@ -519,6 +543,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m } transfer_cleanup: +#ifdef BSP_SPI_USING_DMA /* Post-transfer processing */ if (state == HAL_OK) { @@ -534,7 +559,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m // Free any temporary buffers that were allocated if (aligned_send_buf) rt_free_align(aligned_send_buf); if (aligned_recv_buf) rt_free_align(aligned_recv_buf); - +#endif /* BSP_SPI_USING_DMA */ if (state != HAL_OK) { break; @@ -584,8 +609,10 @@ static int rt_hw_spi_bus_init(void) spi_bus_obj[i].spi_bus.parent.user_data = &spi_config[i]; spi_bus_obj[i].handle.Instance = spi_config[i].Instance; +#ifdef BSP_SPI_USING_DMA /* initialize completion object */ rt_completion_init(&spi_bus_obj[i].cpt); +#endif /* BSP_SPI_USING_DMA */ result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, spi_config[i].bus_name, &stm_spi_ops); RT_ASSERT(result == RT_EOK); @@ -665,7 +692,7 @@ rt_err_t rt_hw_spi_device_detach(const char *device_name) return RT_EOK; } -#if defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI1_RX_USING_DMA) +#if defined(BSP_USING_SPI1) && defined(BSP_SPI1_USING_DMA) void SPI1_IRQHandler(void) { /* enter interrupt */ @@ -676,9 +703,8 @@ void SPI1_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif -#if defined(BSP_USING_SPI1) && defined(BSP_SPI1_RX_USING_DMA) +#ifdef BSP_SPI1_RX_USING_DMA /** * @brief This function handles DMA Rx interrupt request. * @param None @@ -694,9 +720,9 @@ void SPI1_DMA_RX_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif +#endif /* BSP_SPI1_RX_USING_DMA */ -#if defined(BSP_USING_SPI1) && defined(BSP_SPI1_TX_USING_DMA) +#ifdef BSP_SPI1_TX_USING_DMA /** * @brief This function handles DMA Tx interrupt request. * @param None @@ -712,9 +738,10 @@ void SPI1_DMA_TX_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif /* defined(BSP_USING_SPI1) && defined(BSP_SPI_USING_DMA) */ +#endif /* BSP_SPI1_TX_USING_DMA */ +#endif /* defined(BSP_USING_SPI1) && defined(BSP_SPI1_USING_DMA) */ -#if defined(BSP_SPI2_TX_USING_DMA) || defined(BSP_SPI2_RX_USING_DMA) +#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_USING_DMA) void SPI2_IRQHandler(void) { /* enter interrupt */ @@ -725,9 +752,8 @@ void SPI2_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif -#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_RX_USING_DMA) +#ifdef BSP_SPI2_RX_USING_DMA /** * @brief This function handles DMA Rx interrupt request. * @param None @@ -743,9 +769,9 @@ void SPI2_DMA_RX_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif +#endif /* BSP_SPI2_RX_USING_DMA */ -#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_TX_USING_DMA) +#ifdef BSP_SPI2_TX_USING_DMA /** * @brief This function handles DMA Tx interrupt request. * @param None @@ -761,9 +787,10 @@ void SPI2_DMA_TX_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif /* defined(BSP_USING_SPI2) && defined(BSP_SPI_USING_DMA) */ +#endif /* BSP_SPI2_TX_USING_DMA */ +#endif /* defined(BSP_USING_SPI2) && defined(BSP_SPI2_USING_DMA) */ -#if defined(BSP_SPI3_TX_USING_DMA) || defined(BSP_SPI3_RX_USING_DMA) +#if defined(BSP_USING_SPI3) && defined(BSP_SPI3_USING_DMA) void SPI3_IRQHandler(void) { /* enter interrupt */ @@ -774,9 +801,8 @@ void SPI3_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif -#if defined(BSP_USING_SPI3) && defined(BSP_SPI3_RX_USING_DMA) +#ifdef BSP_SPI3_RX_USING_DMA /** * @brief This function handles DMA Rx interrupt request. * @param None @@ -792,9 +818,9 @@ void SPI3_DMA_RX_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif +#endif /* BSP_SPI3_RX_USING_DMA */ -#if defined(BSP_USING_SPI3) && defined(BSP_SPI3_TX_USING_DMA) +#ifdef BSP_SPI3_TX_USING_DMA /** * @brief This function handles DMA Tx interrupt request. * @param None @@ -810,9 +836,10 @@ void SPI3_DMA_TX_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif /* defined(BSP_USING_SPI3) && defined(BSP_SPI_USING_DMA) */ +#endif /* BSP_SPI3_TX_USING_DMA */ +#endif /* defined(BSP_USING_SPI3) && defined(BSP_SPI3_USING_DMA) */ -#if defined(BSP_SPI4_TX_USING_DMA) || defined(BSP_SPI4_RX_USING_DMA) +#if defined(BSP_USING_SPI4) && defined(BSP_SPI4_USING_DMA) void SPI4_IRQHandler(void) { /* enter interrupt */ @@ -823,9 +850,8 @@ void SPI4_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif -#if defined(BSP_USING_SPI4) && defined(BSP_SPI4_RX_USING_DMA) +#ifdef BSP_SPI4_RX_USING_DMA /** * @brief This function handles DMA Rx interrupt request. * @param None @@ -841,9 +867,9 @@ void SPI4_DMA_RX_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif +#endif /* BSP_SPI4_RX_USING_DMA */ -#if defined(BSP_USING_SPI4) && defined(BSP_SPI4_TX_USING_DMA) +#ifdef BSP_SPI4_TX_USING_DMA /** * @brief This function handles DMA Tx interrupt request. * @param None @@ -859,9 +885,10 @@ void SPI4_DMA_TX_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif /* defined(BSP_USING_SPI4) && defined(BSP_SPI_USING_DMA) */ +#endif /* BSP_SPI4_TX_USING_DMA */ +#endif /* defined(BSP_USING_SPI4) && defined(BSP_SPI4_USING_DMA) */ -#if defined(BSP_SPI5_TX_USING_DMA) || defined(BSP_SPI5_RX_USING_DMA) +#if defined(BSP_USING_SPI5) && defined(BSP_SPI5_USING_DMA) void SPI5_IRQHandler(void) { /* enter interrupt */ @@ -872,9 +899,8 @@ void SPI5_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif -#if defined(BSP_USING_SPI5) && defined(BSP_SPI5_RX_USING_DMA) +#ifdef BSP_SPI5_RX_USING_DMA /** * @brief This function handles DMA Rx interrupt request. * @param None @@ -890,9 +916,9 @@ void SPI5_DMA_RX_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif +#endif /* BSP_SPI5_RX_USING_DMA */ -#if defined(BSP_USING_SPI5) && defined(BSP_SPI5_TX_USING_DMA) +#ifdef BSP_SPI5_TX_USING_DMA /** * @brief This function handles DMA Tx interrupt request. * @param None @@ -908,9 +934,22 @@ void SPI5_DMA_TX_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif /* defined(BSP_USING_SPI5) && defined(BSP_SPI_USING_DMA) */ +#endif /* BSP_SPI5_TX_USING_DMA */ +#endif /* defined(BSP_USING_SPI5) && defined(BSP_SPI5_USING_DMA) */ + +#if defined(BSP_USING_SPI6) && defined(BSP_SPI6_USING_DMA) +void SPI6_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + HAL_SPI_IRQHandler(&spi_bus_obj[SPI6_INDEX].handle); + + /* leave interrupt */ + rt_interrupt_leave(); +} -#if defined(BSP_USING_SPI6) && defined(BSP_SPI6_RX_USING_DMA) +#ifdef BSP_SPI6_RX_USING_DMA /** * @brief This function handles DMA Rx interrupt request. * @param None @@ -926,9 +965,9 @@ void SPI6_DMA_RX_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif +#endif /* BSP_SPI6_RX_USING_DMA */ -#if defined(BSP_USING_SPI6) && defined(BSP_SPI6_TX_USING_DMA) +#ifdef BSP_SPI6_TX_USING_DMA /** * @brief This function handles DMA Tx interrupt request. * @param None @@ -944,72 +983,74 @@ void SPI6_DMA_TX_IRQHandler(void) /* leave interrupt */ rt_interrupt_leave(); } -#endif /* defined(BSP_USING_SPI6) && defined(BSP_SPI_USING_DMA) */ +#endif /* BSP_SPI6_TX_USING_DMA */ +#endif /* defined(BSP_USING_SPI6) && defined(BSP_SPI6_USING_DMA) */ +#ifdef BSP_SPI_USING_DMA static void stm32_get_dma_info(void) { #ifdef BSP_SPI1_RX_USING_DMA - spi_bus_obj[SPI1_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG; + spi_bus_obj[SPI1_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static const struct stm32_dma_config spi1_dma_rx = SPI1_RX_DMA_CONFIG; spi_config[SPI1_INDEX].dma_rx = &spi1_dma_rx; #endif #ifdef BSP_SPI1_TX_USING_DMA - spi_bus_obj[SPI1_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG; + spi_bus_obj[SPI1_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX; static const struct stm32_dma_config spi1_dma_tx = SPI1_TX_DMA_CONFIG; spi_config[SPI1_INDEX].dma_tx = &spi1_dma_tx; #endif #ifdef BSP_SPI2_RX_USING_DMA - spi_bus_obj[SPI2_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG; + spi_bus_obj[SPI2_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static const struct stm32_dma_config spi2_dma_rx = SPI2_RX_DMA_CONFIG; spi_config[SPI2_INDEX].dma_rx = &spi2_dma_rx; #endif #ifdef BSP_SPI2_TX_USING_DMA - spi_bus_obj[SPI2_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG; + spi_bus_obj[SPI2_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX; static const struct stm32_dma_config spi2_dma_tx = SPI2_TX_DMA_CONFIG; spi_config[SPI2_INDEX].dma_tx = &spi2_dma_tx; #endif #ifdef BSP_SPI3_RX_USING_DMA - spi_bus_obj[SPI3_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG; + spi_bus_obj[SPI3_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static const struct stm32_dma_config spi3_dma_rx = SPI3_RX_DMA_CONFIG; spi_config[SPI3_INDEX].dma_rx = &spi3_dma_rx; #endif #ifdef BSP_SPI3_TX_USING_DMA - spi_bus_obj[SPI3_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG; + spi_bus_obj[SPI3_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX; static const struct stm32_dma_config spi3_dma_tx = SPI3_TX_DMA_CONFIG; spi_config[SPI3_INDEX].dma_tx = &spi3_dma_tx; #endif #ifdef BSP_SPI4_RX_USING_DMA - spi_bus_obj[SPI4_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG; + spi_bus_obj[SPI4_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static const struct stm32_dma_config spi4_dma_rx = SPI4_RX_DMA_CONFIG; spi_config[SPI4_INDEX].dma_rx = &spi4_dma_rx; #endif #ifdef BSP_SPI4_TX_USING_DMA - spi_bus_obj[SPI4_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG; + spi_bus_obj[SPI4_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX; static const struct stm32_dma_config spi4_dma_tx = SPI4_TX_DMA_CONFIG; spi_config[SPI4_INDEX].dma_tx = &spi4_dma_tx; #endif #ifdef BSP_SPI5_RX_USING_DMA - spi_bus_obj[SPI5_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG; + spi_bus_obj[SPI5_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static const struct stm32_dma_config spi5_dma_rx = SPI5_RX_DMA_CONFIG; spi_config[SPI5_INDEX].dma_rx = &spi5_dma_rx; #endif #ifdef BSP_SPI5_TX_USING_DMA - spi_bus_obj[SPI5_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG; + spi_bus_obj[SPI5_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX; static const struct stm32_dma_config spi5_dma_tx = SPI5_TX_DMA_CONFIG; spi_config[SPI5_INDEX].dma_tx = &spi5_dma_tx; #endif #ifdef BSP_SPI6_RX_USING_DMA - spi_bus_obj[SPI6_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG; + spi_bus_obj[SPI6_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static const struct stm32_dma_config spi6_dma_rx = SPI6_RX_DMA_CONFIG; spi_config[SPI6_INDEX].dma_rx = &spi6_dma_rx; #endif #ifdef BSP_SPI6_TX_USING_DMA - spi_bus_obj[SPI6_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG; + spi_bus_obj[SPI6_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_TX; static const struct stm32_dma_config spi6_dma_tx = SPI6_TX_DMA_CONFIG; spi_config[SPI6_INDEX].dma_tx = &spi6_dma_tx; #endif @@ -1032,6 +1073,7 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) struct stm32_spi *spi_drv = rt_container_of(hspi, struct stm32_spi, handle); rt_completion_done(&spi_drv->cpt); } +#endif /* BSP_SPI_USING_DMA */ #if defined(SOC_SERIES_STM32F0) void SPI1_DMA_RX_TX_IRQHandler(void) @@ -1056,26 +1098,26 @@ void SPI2_DMA_RX_TX_IRQHandler(void) #endif } #elif defined(SOC_SERIES_STM32G0) -#if defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI1_RX_USING_DMA) +#if defined(BSP_USING_SPI1) && defined(BSP_SPI1_USING_DMA) void SPI1_DMA_RX_TX_IRQHandler(void) { -#if defined(BSP_SPI1_TX_USING_DMA) +#if defined(BSP_USING_SPI1) && defined(BSP_SPI1_TX_USING_DMA) SPI1_DMA_TX_IRQHandler(); #endif -#if defined(BSP_SPI1_RX_USING_DMA) +#if defined(BSP_USING_SPI1) && defined(BSP_SPI1_RX_USING_DMA) SPI1_DMA_RX_IRQHandler(); #endif } #endif /* defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI1_RX_USING_DMA) */ -#if defined(BSP_SPI2_TX_USING_DMA) || defined(BSP_SPI2_RX_USING_DMA) +#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_USING_DMA) void SPI2_DMA_RX_TX_IRQHandler(void) { -#if defined(BSP_SPI2_TX_USING_DMA) +#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_TX_USING_DMA) SPI2_DMA_TX_IRQHandler(); #endif -#if defined(BSP_SPI2_RX_USING_DMA) +#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_RX_USING_DMA) SPI2_DMA_RX_IRQHandler(); #endif } @@ -1084,10 +1126,10 @@ void SPI2_DMA_RX_TX_IRQHandler(void) #if defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) void SPI2_3_IRQHandler(void) { -#if defined(BSP_SPI2_TX_USING_DMA) || defined(BSP_SPI2_RX_USING_DMA) +#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_USING_DMA) SPI2_IRQHandler(); #endif -#if defined(BSP_SPI3_TX_USING_DMA) || defined(BSP_SPI3_RX_USING_DMA) +#if defined(BSP_USING_SPI3) && defined(BSP_SPI3_USING_DMA) SPI3_IRQHandler(); #endif } @@ -1097,10 +1139,12 @@ void SPI2_3_IRQHandler(void) int rt_hw_spi_init(void) { +#ifdef BSP_SPI_USING_DMA stm32_get_dma_info(); +#endif /* BSP_SPI_USING_DMA */ return rt_hw_spi_bus_init(); } INIT_BOARD_EXPORT(rt_hw_spi_init); -#endif /* BSP_USING_SPI1 || BSP_USING_SPI2 || BSP_USING_SPI3 || BSP_USING_SPI4 || BSP_USING_SPI5 */ #endif /* BSP_USING_SPI */ + diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h index 62506ba7dcc..880b8f3aacc 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h @@ -18,6 +18,53 @@ #include "drv_dma.h" #include +/* hardware bus */ +#if defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) || defined(BSP_USING_SPI4) || defined(BSP_USING_SPI5) || defined(BSP_USING_SPI6) +#define BSP_HARDWARE_SPI +#endif + +/* DMA */ +#if defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI2_TX_USING_DMA) || defined(BSP_SPI3_TX_USING_DMA) || defined(BSP_SPI4_TX_USING_DMA) || defined(BSP_SPI5_TX_USING_DMA) || defined(BSP_SPI6_TX_USING_DMA) +#define BSP_SPI_TX_USING_DMA +#endif + +#if defined(BSP_SPI1_RX_USING_DMA) || defined(BSP_SPI2_RX_USING_DMA) || defined(BSP_SPI3_RX_USING_DMA) || defined(BSP_SPI4_RX_USING_DMA) || defined(BSP_SPI5_RX_USING_DMA) || defined(BSP_SPI6_RX_USING_DMA) +#define BSP_SPI_RX_USING_DMA +#endif + +#if defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI1_RX_USING_DMA) +#define BSP_SPI1_USING_DMA +#endif + +#if defined(BSP_SPI2_TX_USING_DMA) || defined(BSP_SPI2_RX_USING_DMA) +#define BSP_SPI2_USING_DMA +#endif + +#if defined(BSP_SPI3_TX_USING_DMA) || defined(BSP_SPI3_RX_USING_DMA) +#define BSP_SPI3_USING_DMA +#endif + +#if defined(BSP_SPI4_TX_USING_DMA) || defined(BSP_SPI4_RX_USING_DMA) +#define BSP_SPI4_USING_DMA +#endif + +#if defined(BSP_SPI5_TX_USING_DMA) || defined(BSP_SPI5_RX_USING_DMA) +#define BSP_SPI5_USING_DMA +#endif + +#if defined(BSP_SPI6_TX_USING_DMA) || defined(BSP_SPI6_RX_USING_DMA) +#define BSP_SPI6_USING_DMA +#endif + +#if defined(BSP_SPI_TX_USING_DMA) || defined(BSP_SPI_RX_USING_DMA) +#define BSP_SPI_USING_DMA +#endif + +#if defined(BSP_SPI_USING_DMA) +#define BSP_SPI_USING_IRQ +#endif + + #ifdef __cplusplus extern "C" { #endif @@ -34,7 +81,14 @@ struct stm32_spi_config SPI_TypeDef *Instance; char *bus_name; IRQn_Type irq_type; - const struct stm32_dma_config *dma_rx, *dma_tx; +#ifdef BSP_SPI_USING_DMA +#ifdef BSP_SPI_RX_USING_DMA + const struct stm32_dma_config *dma_rx; +#endif /* BSP_SPI_RX_USING_DMA */ +#ifdef BSP_SPI_TX_USING_DMA + const struct stm32_dma_config *dma_tx; +#endif /* BSP_SPI_TX_USING_DMA */ +#endif /* BSP_SPI_USING_DMA */ }; struct stm32_spi_device @@ -44,26 +98,26 @@ struct stm32_spi_device char *device_name; }; -#define SPI_USING_RX_DMA_FLAG (1<<0) -#define SPI_USING_TX_DMA_FLAG (1<<1) - /* stm32 spi dirver class */ struct stm32_spi { SPI_HandleTypeDef handle; struct stm32_spi_config *config; struct rt_spi_configuration *cfg; - + struct rt_spi_bus spi_bus; +#ifdef BSP_SPI_USING_DMA + rt_uint16_t spi_dma_flag; + struct rt_completion cpt; struct { +#ifdef BSP_SPI_RX_USING_DMA DMA_HandleTypeDef handle_rx; +#endif /* BSP_SPI_RX_USING_DMA */ +#ifdef BSP_SPI_TX_USING_DMA DMA_HandleTypeDef handle_tx; +#endif /* BSP_SPI_TX_USING_DMA */ } dma; - - rt_uint8_t spi_dma_flag; - struct rt_spi_bus spi_bus; - - struct rt_completion cpt; +#endif /* BSP_SPI_USING_DMA */ }; #endif /*__DRV_SPI_H__ */ From 70bbd2879a39f407344bd5ea6ec9a52ad7565ba2 Mon Sep 17 00:00:00 2001 From: wdfk-prog <1425075683@qq.com> Date: Wed, 6 May 2026 21:02:37 +0800 Subject: [PATCH 2/2] feat[STM32][SPI]: add interrupt transfer scaffolding for spi driver introduce interrupt transfer route selection and SPI IRQ visibility macros unify DMA and INT completion handling with timeout-triggered abort recovery keep short transfers on polling and use DMA or INT only when eligible refine STM32 SPI init and IRQ registration paths for mixed transfer backends --- .../libraries/HAL_Drivers/drivers/drv_spi.c | 276 ++++++++++++++---- .../libraries/HAL_Drivers/drivers/drv_spi.h | 107 ++++++- 2 files changed, 316 insertions(+), 67 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c index 14ea783d0da..18fad23e579 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c @@ -13,6 +13,7 @@ * 2020-10-14 PeakRacing Porting for stm32wbxx * 2025-09-22 wdfk_prog Refactor spixfer to fix DMA reception bug, correct timeout calculation. * 2026-04-14 wdfk_prog Refine SPI DMA config hierarchy + * 2026-04-16 wdfk_prog Add SPI interrupt transfer mode scaffolding */ #include @@ -25,9 +26,30 @@ #include "drv_config.h" #include +#ifdef BSP_HARDWARE_SPI +/* + * SPI transfer route policy: + * + * For a universal and most conservative strategy across all STM32 series + * under full-duplex operation at the highest supported SPI clock rates, + * there is no generally safe transfer-length threshold for interrupt mode. + * The interrupt servicing latency depends on MCU performance, bus clock, + * HAL/LL implementation cost, system interrupt load, and runtime context, + * so a single INT threshold cannot be guaranteed to work reliably on all targets. + * + * Therefore, use the following unified rule: + * - transfer length < 32 bytes : use polling mode + * - transfer length >= 32 bytes : use DMA mode + * - interrupt mode : disabled by default + * + * This policy prioritizes robustness and portability over theoretical peak efficiency. + */ #ifndef BSP_SPI_DMA_TRANS_MIN_LEN -#define BSP_SPI_DMA_TRANS_MIN_LEN 10U +#define BSP_SPI_DMA_TRANS_MIN_LEN 32U #endif /* BSP_SPI_DMA_TRANS_MIN_LEN */ +#ifndef BSP_SPI_INT_TRANS_MIN_LEN +#define BSP_SPI_INT_TRANS_MIN_LEN 32U +#endif /* BSP_SPI_INT_TRANS_MIN_LEN */ /*#define DRV_DEBUG*/ #define LOG_TAG "drv.spi" @@ -253,7 +275,6 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32WB) spi_handle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE; #elif defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) - spi_handle->Init.Mode = SPI_MODE_MASTER; spi_handle->Init.NSS = SPI_NSS_SOFT; spi_handle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE; spi_handle->Init.NSSPolarity = SPI_NSS_POLARITY_LOW; @@ -307,13 +328,16 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur } } #endif /* BSP_SPI_TX_USING_DMA */ +#endif /* BSP_SPI_USING_DMA */ - if ((spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_TX) || (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_RX)) +#ifdef BSP_SPI_USING_IRQ + if ((spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_TX) || (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_RX) + || (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_INT_TX) || (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_INT_RX)) { HAL_NVIC_SetPriority(spi_drv->config->irq_type, 2, 0); HAL_NVIC_EnableIRQ(spi_drv->config->irq_type); } -#endif /* BSP_SPI_USING_DMA */ +#endif /* BSP_SPI_USING_IRQ */ LOG_D("%s init done", spi_drv->config->bus_name); return RT_EOK; @@ -334,6 +358,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus); SPI_HandleTypeDef *spi_handle = &spi_drv->handle; + rt_bool_t need_abort = RT_FALSE; rt_uint64_t total_byte_ms = (rt_uint64_t)message->length * 1000; rt_uint32_t speed_bytes_per_sec = spi_drv->cfg->usage_freq / 8; if (speed_bytes_per_sec == 0) @@ -342,9 +367,9 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m } rt_uint32_t timeout_ms = total_byte_ms / speed_bytes_per_sec + 100; -#ifdef BSP_SPI_USING_DMA +#ifdef BSP_SPI_USING_IRQ rt_tick_t timeout_tick = rt_tick_from_millisecond(timeout_ms); -#endif /* BSP_SPI_USING_DMA */ +#endif /* BSP_SPI_USING_IRQ */ if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) { @@ -392,7 +417,8 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m { recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length; } - + const rt_bool_t scheduler_available = rt_scheduler_is_available(); + const rt_bool_t irq_disabled = rt_hw_interrupt_is_disabled(); #ifdef BSP_SPI_USING_DMA const rt_uint8_t *dma_send_buf = send_buf; rt_uint8_t *dma_recv_buf = recv_buf; @@ -400,9 +426,22 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m rt_uint8_t *aligned_send_buf = RT_NULL; rt_uint8_t *aligned_recv_buf = RT_NULL; - const rt_bool_t dma_eligible = (send_length >= DMA_TRANS_MIN_LEN); - const rt_bool_t use_tx_dma = dma_eligible && (spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG); - const rt_bool_t use_rx_dma = dma_eligible && (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG); + rt_bool_t dma_eligible = (send_length >= BSP_SPI_DMA_TRANS_MIN_LEN); +#if defined(BSP_SPI_TX_USING_DMA) + rt_bool_t use_tx_dma = dma_eligible && (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_TX); +#else + rt_bool_t use_tx_dma = RT_FALSE; +#endif /* BSP_SPI_TX_USING_DMA */ +#if defined(BSP_SPI_RX_USING_DMA) + rt_bool_t use_rx_dma = dma_eligible && (spi_drv->spi_dma_flag & RT_DEVICE_FLAG_DMA_RX); +#else + rt_bool_t use_rx_dma = RT_FALSE; +#endif /* BSP_SPI_RX_USING_DMA */ + + if (!scheduler_available || irq_disabled) + { + use_rx_dma = use_tx_dma = dma_eligible = RT_FALSE; + } if (dma_eligible) { @@ -445,6 +484,29 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m } #endif /* BSP_SPI_USING_DMA */ +#ifdef BSP_SPI_USING_INT + rt_bool_t int_eligible = (send_length >= BSP_SPI_INT_TRANS_MIN_LEN); +#if defined(BSP_SPI_TX_USING_INT) + rt_bool_t use_tx_int = int_eligible && spi_drv->spi_dma_flag & RT_DEVICE_FLAG_INT_TX; +#else + rt_bool_t use_tx_int = RT_FALSE; +#endif /* BSP_SPI_TX_USING_INT */ +#if defined(BSP_SPI_RX_USING_INT) + rt_bool_t use_rx_int = int_eligible && spi_drv->spi_dma_flag & RT_DEVICE_FLAG_INT_RX; +#else + rt_bool_t use_rx_int = RT_FALSE; +#endif /* BSP_SPI_RX_USING_INT */ + if (!scheduler_available || irq_disabled) + { + use_rx_int = use_tx_int = int_eligible = RT_FALSE; + } +#endif /* BSP_SPI_USING_INT */ + + rt_bool_t async_started = RT_TRUE; +#ifdef BSP_SPI_USING_IRQ + /* Ensure that the current completion volume is solely associated with the current affairs.*/ + rt_completion_init(&spi_drv->cpt); +#endif /* BSP_SPI_USING_IRQ */ /* Start data exchange in full-duplex DMA mode. */ if (message->send_buf && message->recv_buf) { @@ -455,8 +517,16 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m } else #endif /* BSP_SPI_USING_DMA */ +#ifdef BSP_SPI_USING_INT + if (use_tx_int && use_rx_int) + { + state = HAL_SPI_TransmitReceive_IT(spi_handle, (uint8_t *)send_buf, recv_buf, send_length); + } + else +#endif /* BSP_SPI_USING_INT */ { state = HAL_SPI_TransmitReceive(spi_handle, (uint8_t *)send_buf, recv_buf, send_length, timeout_ms); + async_started = RT_FALSE; } } else if (message->send_buf) @@ -468,18 +538,22 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m } else #endif /* BSP_SPI_USING_DMA */ +#ifdef BSP_SPI_USING_INT + if (use_tx_int) { - state = HAL_SPI_Transmit(spi_handle, (uint8_t *)send_buf, send_length, timeout_ms); + state = HAL_SPI_Transmit_IT(spi_handle, (uint8_t *)send_buf, send_length); } - - if (message->cs_release && (device->config.mode & RT_SPI_3WIRE)) + else +#endif /* BSP_SPI_USING_INT */ { - /* release the CS by disable SPI when using 3 wires SPI */ - __HAL_SPI_DISABLE(spi_handle); + state = HAL_SPI_Transmit(spi_handle, (uint8_t *)send_buf, send_length, timeout_ms); + async_started = RT_FALSE; } } - else if(message->recv_buf) + else if (message->recv_buf) { + /* clear the old error flag */ + __HAL_SPI_CLEAR_OVRFLAG(spi_handle); #ifdef BSP_SPI_USING_DMA rt_memset(dma_recv_buf, 0xFF, send_length); if (use_rx_dma) @@ -488,10 +562,16 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m } else #endif /* BSP_SPI_USING_DMA */ +#ifdef BSP_SPI_USING_INT + if (use_rx_int) + { + state = HAL_SPI_Receive_IT(spi_handle, recv_buf, send_length); + } + else +#endif /* BSP_SPI_USING_INT */ { - /* clear the old error flag */ - __HAL_SPI_CLEAR_OVRFLAG(spi_handle); state = HAL_SPI_Receive(spi_handle, recv_buf, send_length, timeout_ms); + async_started = RT_FALSE; } } else @@ -507,42 +587,50 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m spi_handle->State = HAL_SPI_STATE_READY; goto transfer_cleanup; } - else - { - LOG_D("%s transfer done", spi_drv->config->bus_name); - } -#ifdef BSP_SPI_USING_DMA - if (use_tx_dma || use_rx_dma) +#ifdef BSP_SPI_USING_IRQ + if (async_started) { /* blocking the thread,and the other tasks can run */ if (rt_completion_wait(&spi_drv->cpt, timeout_tick) != RT_EOK) + { + state = HAL_TIMEOUT; + need_abort = RT_TRUE; + LOG_E("wait for SPI async transfer overtime!"); + goto transfer_cleanup; + } + + if (spi_handle->ErrorCode != HAL_SPI_ERROR_NONE) { state = HAL_ERROR; - LOG_E("wait for DMA interrupt overtime!"); - HAL_SPI_DMAStop(spi_handle); + need_abort = RT_TRUE; + LOG_E("SPI async transfer failed, error code: 0x%08x", spi_handle->ErrorCode); goto transfer_cleanup; } } - else +#endif /* BSP_SPI_USING_IRQ */ + if (state == HAL_OK) { - rt_uint32_t timeout = timeout_ms; - while (HAL_SPI_GetState(spi_handle) != HAL_SPI_STATE_READY) + /* send-only */ + if (message->send_buf != RT_NULL && message->recv_buf == RT_NULL + && message->cs_release && (device->config.mode & RT_SPI_3WIRE)) { - if (timeout-- > 0) - { - rt_thread_mdelay(1); - } - else - { - LOG_E("timeout! SPI state did not become READY."); - state = HAL_TIMEOUT; - break; - } + /* release the CS by disable SPI when using 3 wires SPI */ + __HAL_SPI_DISABLE(spi_handle); } + LOG_D("%s transfer done", spi_drv->config->bus_name); } transfer_cleanup: + if (need_abort) + { + if (HAL_SPI_Abort(spi_handle) != HAL_OK) + { + LOG_W("abort SPI async transfer failed, state: %d, error: 0x%08x", + HAL_SPI_GetState(spi_handle), + spi_handle->ErrorCode); + } + } #ifdef BSP_SPI_USING_DMA /* Post-transfer processing */ if (state == HAL_OK) @@ -609,10 +697,10 @@ static int rt_hw_spi_bus_init(void) spi_bus_obj[i].spi_bus.parent.user_data = &spi_config[i]; spi_bus_obj[i].handle.Instance = spi_config[i].Instance; -#ifdef BSP_SPI_USING_DMA +#ifdef BSP_SPI_USING_IRQ /* initialize completion object */ rt_completion_init(&spi_bus_obj[i].cpt); -#endif /* BSP_SPI_USING_DMA */ +#endif /* BSP_SPI_USING_IRQ */ result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, spi_config[i].bus_name, &stm_spi_ops); RT_ASSERT(result == RT_EOK); @@ -692,7 +780,7 @@ rt_err_t rt_hw_spi_device_detach(const char *device_name) return RT_EOK; } -#if defined(BSP_USING_SPI1) && defined(BSP_SPI1_USING_DMA) +#if defined(BSP_USING_SPI1) && defined(BSP_SPI1_USING_IRQ) void SPI1_IRQHandler(void) { /* enter interrupt */ @@ -739,9 +827,9 @@ void SPI1_DMA_TX_IRQHandler(void) rt_interrupt_leave(); } #endif /* BSP_SPI1_TX_USING_DMA */ -#endif /* defined(BSP_USING_SPI1) && defined(BSP_SPI1_USING_DMA) */ +#endif /* defined(BSP_USING_SPI1) && defined(BSP_SPI1_USING_IRQ) */ -#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_USING_DMA) +#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_USING_IRQ) void SPI2_IRQHandler(void) { /* enter interrupt */ @@ -788,9 +876,9 @@ void SPI2_DMA_TX_IRQHandler(void) rt_interrupt_leave(); } #endif /* BSP_SPI2_TX_USING_DMA */ -#endif /* defined(BSP_USING_SPI2) && defined(BSP_SPI2_USING_DMA) */ +#endif /* defined(BSP_USING_SPI2) && defined(BSP_SPI2_USING_IRQ) */ -#if defined(BSP_USING_SPI3) && defined(BSP_SPI3_USING_DMA) +#if defined(BSP_USING_SPI3) && defined(BSP_SPI3_USING_IRQ) void SPI3_IRQHandler(void) { /* enter interrupt */ @@ -837,9 +925,9 @@ void SPI3_DMA_TX_IRQHandler(void) rt_interrupt_leave(); } #endif /* BSP_SPI3_TX_USING_DMA */ -#endif /* defined(BSP_USING_SPI3) && defined(BSP_SPI3_USING_DMA) */ +#endif /* defined(BSP_USING_SPI3) && defined(BSP_SPI3_USING_IRQ) */ -#if defined(BSP_USING_SPI4) && defined(BSP_SPI4_USING_DMA) +#if defined(BSP_USING_SPI4) && defined(BSP_SPI4_USING_IRQ) void SPI4_IRQHandler(void) { /* enter interrupt */ @@ -886,9 +974,9 @@ void SPI4_DMA_TX_IRQHandler(void) rt_interrupt_leave(); } #endif /* BSP_SPI4_TX_USING_DMA */ -#endif /* defined(BSP_USING_SPI4) && defined(BSP_SPI4_USING_DMA) */ +#endif /* defined(BSP_USING_SPI4) && defined(BSP_SPI4_USING_IRQ) */ -#if defined(BSP_USING_SPI5) && defined(BSP_SPI5_USING_DMA) +#if defined(BSP_USING_SPI5) && defined(BSP_SPI5_USING_IRQ) void SPI5_IRQHandler(void) { /* enter interrupt */ @@ -935,9 +1023,9 @@ void SPI5_DMA_TX_IRQHandler(void) rt_interrupt_leave(); } #endif /* BSP_SPI5_TX_USING_DMA */ -#endif /* defined(BSP_USING_SPI5) && defined(BSP_SPI5_USING_DMA) */ +#endif /* defined(BSP_USING_SPI5) && defined(BSP_SPI5_USING_IRQ) */ -#if defined(BSP_USING_SPI6) && defined(BSP_SPI6_USING_DMA) +#if defined(BSP_USING_SPI6) && defined(BSP_SPI6_USING_IRQ) void SPI6_IRQHandler(void) { /* enter interrupt */ @@ -984,11 +1072,19 @@ void SPI6_DMA_TX_IRQHandler(void) rt_interrupt_leave(); } #endif /* BSP_SPI6_TX_USING_DMA */ -#endif /* defined(BSP_USING_SPI6) && defined(BSP_SPI6_USING_DMA) */ +#endif /* defined(BSP_USING_SPI6) && defined(BSP_SPI6_USING_IRQ) */ -#ifdef BSP_SPI_USING_DMA -static void stm32_get_dma_info(void) +#ifdef BSP_SPI_USING_IRQ +static void stm32_get_xfer_info(void) { +#ifdef BSP_USING_SPI1 + spi_bus_obj[SPI1_INDEX].spi_dma_flag = 0; +#ifdef BSP_SPI1_RX_USING_INT + spi_bus_obj[SPI1_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_INT_RX; +#endif +#ifdef BSP_SPI1_TX_USING_INT + spi_bus_obj[SPI1_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_INT_TX; +#endif #ifdef BSP_SPI1_RX_USING_DMA spi_bus_obj[SPI1_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static const struct stm32_dma_config spi1_dma_rx = SPI1_RX_DMA_CONFIG; @@ -999,7 +1095,16 @@ static void stm32_get_dma_info(void) static const struct stm32_dma_config spi1_dma_tx = SPI1_TX_DMA_CONFIG; spi_config[SPI1_INDEX].dma_tx = &spi1_dma_tx; #endif +#endif /* BSP_USING_SPI1 */ +#ifdef BSP_USING_SPI2 + spi_bus_obj[SPI2_INDEX].spi_dma_flag = 0; +#ifdef BSP_SPI2_RX_USING_INT + spi_bus_obj[SPI2_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_INT_RX; +#endif +#ifdef BSP_SPI2_TX_USING_INT + spi_bus_obj[SPI2_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_INT_TX; +#endif #ifdef BSP_SPI2_RX_USING_DMA spi_bus_obj[SPI2_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static const struct stm32_dma_config spi2_dma_rx = SPI2_RX_DMA_CONFIG; @@ -1010,7 +1115,16 @@ static void stm32_get_dma_info(void) static const struct stm32_dma_config spi2_dma_tx = SPI2_TX_DMA_CONFIG; spi_config[SPI2_INDEX].dma_tx = &spi2_dma_tx; #endif +#endif /* BSP_USING_SPI2 */ +#ifdef BSP_USING_SPI3 + spi_bus_obj[SPI3_INDEX].spi_dma_flag = 0; +#ifdef BSP_SPI3_RX_USING_INT + spi_bus_obj[SPI3_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_INT_RX; +#endif +#ifdef BSP_SPI3_TX_USING_INT + spi_bus_obj[SPI3_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_INT_TX; +#endif #ifdef BSP_SPI3_RX_USING_DMA spi_bus_obj[SPI3_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static const struct stm32_dma_config spi3_dma_rx = SPI3_RX_DMA_CONFIG; @@ -1021,7 +1135,16 @@ static void stm32_get_dma_info(void) static const struct stm32_dma_config spi3_dma_tx = SPI3_TX_DMA_CONFIG; spi_config[SPI3_INDEX].dma_tx = &spi3_dma_tx; #endif +#endif /* BSP_USING_SPI3 */ +#ifdef BSP_USING_SPI4 + spi_bus_obj[SPI4_INDEX].spi_dma_flag = 0; +#ifdef BSP_SPI4_RX_USING_INT + spi_bus_obj[SPI4_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_INT_RX; +#endif +#ifdef BSP_SPI4_TX_USING_INT + spi_bus_obj[SPI4_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_INT_TX; +#endif #ifdef BSP_SPI4_RX_USING_DMA spi_bus_obj[SPI4_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static const struct stm32_dma_config spi4_dma_rx = SPI4_RX_DMA_CONFIG; @@ -1032,7 +1155,16 @@ static void stm32_get_dma_info(void) static const struct stm32_dma_config spi4_dma_tx = SPI4_TX_DMA_CONFIG; spi_config[SPI4_INDEX].dma_tx = &spi4_dma_tx; #endif +#endif /* BSP_USING_SPI4 */ +#ifdef BSP_USING_SPI5 + spi_bus_obj[SPI5_INDEX].spi_dma_flag = 0; +#ifdef BSP_SPI5_RX_USING_INT + spi_bus_obj[SPI5_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_INT_RX; +#endif +#ifdef BSP_SPI5_TX_USING_INT + spi_bus_obj[SPI5_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_INT_TX; +#endif #ifdef BSP_SPI5_RX_USING_DMA spi_bus_obj[SPI5_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static const struct stm32_dma_config spi5_dma_rx = SPI5_RX_DMA_CONFIG; @@ -1043,7 +1175,16 @@ static void stm32_get_dma_info(void) static const struct stm32_dma_config spi5_dma_tx = SPI5_TX_DMA_CONFIG; spi_config[SPI5_INDEX].dma_tx = &spi5_dma_tx; #endif +#endif /* BSP_USING_SPI5 */ +#ifdef BSP_USING_SPI6 + spi_bus_obj[SPI6_INDEX].spi_dma_flag = 0; +#ifdef BSP_SPI6_RX_USING_INT + spi_bus_obj[SPI6_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_INT_RX; +#endif +#ifdef BSP_SPI6_TX_USING_INT + spi_bus_obj[SPI6_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_INT_TX; +#endif #ifdef BSP_SPI6_RX_USING_DMA spi_bus_obj[SPI6_INDEX].spi_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static const struct stm32_dma_config spi6_dma_rx = SPI6_RX_DMA_CONFIG; @@ -1054,6 +1195,7 @@ static void stm32_get_dma_info(void) static const struct stm32_dma_config spi6_dma_tx = SPI6_TX_DMA_CONFIG; spi_config[SPI6_INDEX].dma_tx = &spi6_dma_tx; #endif +#endif /* BSP_USING_SPI6 */ } void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) @@ -1073,7 +1215,14 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) struct stm32_spi *spi_drv = rt_container_of(hspi, struct stm32_spi, handle); rt_completion_done(&spi_drv->cpt); } -#endif /* BSP_SPI_USING_DMA */ + +void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) +{ + struct stm32_spi *spi_drv = rt_container_of(hspi, struct stm32_spi, handle); + LOG_W("%s error code 0x%08x", spi_drv->config->bus_name, hspi->ErrorCode); + rt_completion_done(&spi_drv->cpt); +} +#endif /* BSP_SPI_USING_IRQ */ #if defined(SOC_SERIES_STM32F0) void SPI1_DMA_RX_TX_IRQHandler(void) @@ -1109,7 +1258,7 @@ void SPI1_DMA_RX_TX_IRQHandler(void) SPI1_DMA_RX_IRQHandler(); #endif } -#endif /* defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI1_RX_USING_DMA) */ +#endif /* defined(BSP_USING_SPI1) && defined(BSP_SPI1_USING_DMA) */ #if defined(BSP_USING_SPI2) && defined(BSP_SPI2_USING_DMA) void SPI2_DMA_RX_TX_IRQHandler(void) { @@ -1121,15 +1270,15 @@ void SPI2_DMA_RX_TX_IRQHandler(void) SPI2_DMA_RX_IRQHandler(); #endif } -#endif /* defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI1_RX_USING_DMA) */ +#endif /* defined(BSP_SPI2_TX_USING_DMA) || defined(BSP_SPI2_RX_USING_DMA) */ #if defined(STM32G0B0xx) || defined(STM32G0B1xx) || defined(STM32G0C1xx) #if defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) void SPI2_3_IRQHandler(void) { -#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_USING_DMA) +#if defined(BSP_USING_SPI2) && defined(BSP_SPI2_USING_IRQ) SPI2_IRQHandler(); #endif -#if defined(BSP_USING_SPI3) && defined(BSP_SPI3_USING_DMA) +#if defined(BSP_USING_SPI3) && defined(BSP_SPI3_USING_IRQ) SPI3_IRQHandler(); #endif } @@ -1139,12 +1288,13 @@ void SPI2_3_IRQHandler(void) int rt_hw_spi_init(void) { -#ifdef BSP_SPI_USING_DMA - stm32_get_dma_info(); -#endif /* BSP_SPI_USING_DMA */ +#ifdef BSP_SPI_USING_IRQ + stm32_get_xfer_info(); +#endif /* BSP_SPI_USING_IRQ */ return rt_hw_spi_bus_init(); } INIT_BOARD_EXPORT(rt_hw_spi_init); +#endif /* BSP_HARDWARE_SPI */ #endif /* BSP_USING_SPI */ diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h index 880b8f3aacc..8211870f957 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2018-11-5 SummerGift first version + * 2026-04-16 wdfk-prog Add SPI interrupt transfer mode scaffolding */ #ifndef __DRV_SPI_H__ @@ -23,6 +24,43 @@ #define BSP_HARDWARE_SPI #endif +/* POLL configuration visibility */ +#if defined(BSP_SPI1_TX_USING_POLL) || defined(BSP_SPI2_TX_USING_POLL) || defined(BSP_SPI3_TX_USING_POLL) || defined(BSP_SPI4_TX_USING_POLL) || defined(BSP_SPI5_TX_USING_POLL) || defined(BSP_SPI6_TX_USING_POLL) +#define BSP_SPI_TX_USING_POLL +#endif + +#if defined(BSP_SPI1_RX_USING_POLL) || defined(BSP_SPI2_RX_USING_POLL) || defined(BSP_SPI3_RX_USING_POLL) || defined(BSP_SPI4_RX_USING_POLL) || defined(BSP_SPI5_RX_USING_POLL) || defined(BSP_SPI6_RX_USING_POLL) +#define BSP_SPI_RX_USING_POLL +#endif + +#if defined(BSP_SPI1_TX_USING_POLL) || defined(BSP_SPI1_RX_USING_POLL) +#define BSP_SPI1_USING_POLL +#endif + +#if defined(BSP_SPI2_TX_USING_POLL) || defined(BSP_SPI2_RX_USING_POLL) +#define BSP_SPI2_USING_POLL +#endif + +#if defined(BSP_SPI3_TX_USING_POLL) || defined(BSP_SPI3_RX_USING_POLL) +#define BSP_SPI3_USING_POLL +#endif + +#if defined(BSP_SPI4_TX_USING_POLL) || defined(BSP_SPI4_RX_USING_POLL) +#define BSP_SPI4_USING_POLL +#endif + +#if defined(BSP_SPI5_TX_USING_POLL) || defined(BSP_SPI5_RX_USING_POLL) +#define BSP_SPI5_USING_POLL +#endif + +#if defined(BSP_SPI6_TX_USING_POLL) || defined(BSP_SPI6_RX_USING_POLL) +#define BSP_SPI6_USING_POLL +#endif + +#if defined(BSP_SPI_TX_USING_POLL) || defined(BSP_SPI_RX_USING_POLL) +#define BSP_SPI_USING_POLL +#endif + /* DMA */ #if defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI2_TX_USING_DMA) || defined(BSP_SPI3_TX_USING_DMA) || defined(BSP_SPI4_TX_USING_DMA) || defined(BSP_SPI5_TX_USING_DMA) || defined(BSP_SPI6_TX_USING_DMA) #define BSP_SPI_TX_USING_DMA @@ -60,7 +98,68 @@ #define BSP_SPI_USING_DMA #endif -#if defined(BSP_SPI_USING_DMA) +/* INT */ +#if defined(BSP_SPI1_TX_USING_INT) || defined(BSP_SPI2_TX_USING_INT) || defined(BSP_SPI3_TX_USING_INT) || defined(BSP_SPI4_TX_USING_INT) || defined(BSP_SPI5_TX_USING_INT) || defined(BSP_SPI6_TX_USING_INT) +#define BSP_SPI_TX_USING_INT +#endif + +#if defined(BSP_SPI1_RX_USING_INT) || defined(BSP_SPI2_RX_USING_INT) || defined(BSP_SPI3_RX_USING_INT) || defined(BSP_SPI4_RX_USING_INT) || defined(BSP_SPI5_RX_USING_INT) || defined(BSP_SPI6_RX_USING_INT) +#define BSP_SPI_RX_USING_INT +#endif + +#if defined(BSP_SPI1_TX_USING_INT) || defined(BSP_SPI1_RX_USING_INT) +#define BSP_SPI1_USING_INT +#endif + +#if defined(BSP_SPI2_TX_USING_INT) || defined(BSP_SPI2_RX_USING_INT) +#define BSP_SPI2_USING_INT +#endif + +#if defined(BSP_SPI3_TX_USING_INT) || defined(BSP_SPI3_RX_USING_INT) +#define BSP_SPI3_USING_INT +#endif + +#if defined(BSP_SPI4_TX_USING_INT) || defined(BSP_SPI4_RX_USING_INT) +#define BSP_SPI4_USING_INT +#endif + +#if defined(BSP_SPI5_TX_USING_INT) || defined(BSP_SPI5_RX_USING_INT) +#define BSP_SPI5_USING_INT +#endif + +#if defined(BSP_SPI6_TX_USING_INT) || defined(BSP_SPI6_RX_USING_INT) +#define BSP_SPI6_USING_INT +#endif + +#if defined(BSP_SPI_TX_USING_INT) || defined(BSP_SPI_RX_USING_INT) +#define BSP_SPI_USING_INT +#endif + +#if defined(BSP_SPI1_USING_DMA) || defined(BSP_SPI1_USING_INT) +#define BSP_SPI1_USING_IRQ +#endif + +#if defined(BSP_SPI2_USING_DMA) || defined(BSP_SPI2_USING_INT) +#define BSP_SPI2_USING_IRQ +#endif + +#if defined(BSP_SPI3_USING_DMA) || defined(BSP_SPI3_USING_INT) +#define BSP_SPI3_USING_IRQ +#endif + +#if defined(BSP_SPI4_USING_DMA) || defined(BSP_SPI4_USING_INT) +#define BSP_SPI4_USING_IRQ +#endif + +#if defined(BSP_SPI5_USING_DMA) || defined(BSP_SPI5_USING_INT) +#define BSP_SPI5_USING_IRQ +#endif + +#if defined(BSP_SPI6_USING_DMA) || defined(BSP_SPI6_USING_INT) +#define BSP_SPI6_USING_IRQ +#endif + +#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) #define BSP_SPI_USING_IRQ #endif @@ -81,14 +180,12 @@ struct stm32_spi_config SPI_TypeDef *Instance; char *bus_name; IRQn_Type irq_type; -#ifdef BSP_SPI_USING_DMA #ifdef BSP_SPI_RX_USING_DMA const struct stm32_dma_config *dma_rx; #endif /* BSP_SPI_RX_USING_DMA */ #ifdef BSP_SPI_TX_USING_DMA const struct stm32_dma_config *dma_tx; #endif /* BSP_SPI_TX_USING_DMA */ -#endif /* BSP_SPI_USING_DMA */ }; struct stm32_spi_device @@ -105,9 +202,11 @@ struct stm32_spi struct stm32_spi_config *config; struct rt_spi_configuration *cfg; struct rt_spi_bus spi_bus; -#ifdef BSP_SPI_USING_DMA rt_uint16_t spi_dma_flag; +#ifdef BSP_SPI_USING_IRQ struct rt_completion cpt; +#endif /* BSP_SPI_USING_IRQ */ +#ifdef BSP_SPI_USING_DMA struct { #ifdef BSP_SPI_RX_USING_DMA