mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-05-12 21:25:53 +00:00
Fix SPI DMA timeout units and free temporary buffers
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user