summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c
index 9205ba491b..11b47ba09e 100644
--- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c
+++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c
@@ -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);
}