|
|
@@ -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 */
|
|
|
|