Sfoglia il codice sorgente

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
wdfk-prog 1 settimana fa
parent
commit
415f924c5f

+ 213 - 63
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 <rtthread.h>
@@ -25,9 +26,30 @@
 #include "drv_config.h"
 #include <string.h>
 
+#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 */
 

+ 103 - 4
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