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); }