Skip to content

Commit b0e55a4

Browse files
wdfk-progRbb666
authored andcommitted
Fix SPI DMA timeout units and free temporary buffers
1 parent d9ff39e commit b0e55a4

File tree

1 file changed

+22
-8
lines changed
  • bsp/stm32/libraries/HAL_Drivers/drivers

1 file changed

+22
-8
lines changed

bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur
287287

288288
static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
289289
{
290-
#define DMA_TRANS_MIN_LEN 10 /* only buffer length >= DMA_TRANS_MIN_LEN will use DMA mode */
290+
#define DMA_TRANS_MIN_LEN 10 /* only buffer length >= DMA_TRANS_MIN_LEN will use DMA mode */
291291

292292
HAL_StatusTypeDef state = HAL_OK;
293293
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
301301

302302
struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus);
303303
SPI_HandleTypeDef *spi_handle = &spi_drv->handle;
304+
304305
rt_uint64_t total_byte_ms = (rt_uint64_t)message->length * 1000;
305306
rt_uint32_t speed_bytes_per_sec = spi_drv->cfg->usage_freq / 8;
306307
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
383384
{
384385
state = HAL_ERROR;
385386
LOG_E("malloc aligned_send_buf failed!");
386-
break;
387+
goto transfer_cleanup;
387388
}
388389
rt_memcpy(aligned_send_buf, send_buf, send_length);
389390
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
396397
{
397398
state = HAL_ERROR;
398399
LOG_E("malloc aligned_recv_buf failed!");
399-
break;
400+
goto transfer_cleanup;
400401
}
401402
dma_recv_buf = aligned_recv_buf;
402403
}
@@ -462,7 +463,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
462463
LOG_E("SPI transfer error: %d", state);
463464
message->length = 0;
464465
spi_handle->State = HAL_SPI_STATE_READY;
465-
break;
466+
goto transfer_cleanup;
466467
}
467468
else
468469
{
@@ -476,7 +477,8 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
476477
{
477478
state = HAL_ERROR;
478479
LOG_E("wait for DMA interrupt overtime!");
479-
break;
480+
HAL_SPI_DMAStop(spi_handle);
481+
goto transfer_cleanup;
480482
}
481483
}
482484
else
@@ -497,16 +499,27 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
497499
}
498500
}
499501

500-
if (state == HAL_OK && aligned_recv_buf != RT_NULL)
502+
transfer_cleanup:
503+
/* Post-transfer processing */
504+
if (state == HAL_OK)
501505
{
506+
if (aligned_recv_buf != RT_NULL)
507+
{
502508
#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
503-
rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, aligned_recv_buf, send_length);
509+
rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, aligned_recv_buf, send_length);
504510
#endif
505-
rt_memcpy(recv_buf, aligned_recv_buf, send_length);
511+
rt_memcpy(recv_buf, aligned_recv_buf, send_length);
512+
}
506513
}
507514

515+
// Free any temporary buffers that were allocated
508516
if (aligned_send_buf) rt_free_align(aligned_send_buf);
509517
if (aligned_recv_buf) rt_free_align(aligned_recv_buf);
518+
519+
if (state != HAL_OK)
520+
{
521+
break;
522+
}
510523
}
511524

512525
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,
532545

533546
struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus);
534547
spi_drv->cfg = configuration;
548+
535549
return stm32_spi_init(spi_drv, configuration);
536550
}
537551

0 commit comments

Comments
 (0)