Fix SPI DMA timeout units and free temporary buffers

This commit is contained in:
wdfk-prog
2026-03-06 16:10:28 +08:00
committed by Rbb666
parent d9ff39eec2
commit b0e55a46a1

View File

@@ -287,7 +287,7 @@ 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 */
#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;
@@ -301,6 +301,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_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)
@@ -383,7 +384,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
{
state = HAL_ERROR;
LOG_E("malloc aligned_send_buf failed!");
break;
goto transfer_cleanup;
}
rt_memcpy(aligned_send_buf, send_buf, send_length);
dma_send_buf = aligned_send_buf;
@@ -396,7 +397,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
{
state = HAL_ERROR;
LOG_E("malloc aligned_recv_buf failed!");
break;
goto transfer_cleanup;
}
dma_recv_buf = aligned_recv_buf;
}
@@ -462,7 +463,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
LOG_E("SPI transfer error: %d", state);
message->length = 0;
spi_handle->State = HAL_SPI_STATE_READY;
break;
goto transfer_cleanup;
}
else
{
@@ -476,7 +477,8 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
{
state = HAL_ERROR;
LOG_E("wait for DMA interrupt overtime!");
break;
HAL_SPI_DMAStop(spi_handle);
goto transfer_cleanup;
}
}
else
@@ -497,16 +499,27 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
}
}
if (state == HAL_OK && aligned_recv_buf != RT_NULL)
transfer_cleanup:
/* Post-transfer processing */
if (state == HAL_OK)
{
if (aligned_recv_buf != RT_NULL)
{
#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, aligned_recv_buf, send_length);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, aligned_recv_buf, send_length);
#endif
rt_memcpy(recv_buf, aligned_recv_buf, send_length);
rt_memcpy(recv_buf, aligned_recv_buf, send_length);
}
}
// 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);
if (state != HAL_OK)
{
break;
}
}
if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE))
@@ -532,6 +545,7 @@ static rt_err_t spi_configure(struct rt_spi_device *device,
struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus);
spi_drv->cfg = configuration;
return stm32_spi_init(spi_drv, configuration);
}