Skip to content

Commit 7c3f5c3

Browse files
wdfk-progmysterywolf
authored andcommitted
[bsp][stm32][spi] 优化DMA数据非字节对齐的处理流程
1 parent 1d239db commit 7c3f5c3

File tree

1 file changed

+41
-22
lines changed

1 file changed

+41
-22
lines changed

bsp/stm32/libraries/HAL_Drivers/drv_spi.c

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -341,35 +341,50 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
341341
recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length;
342342
}
343343

344-
#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
345-
rt_uint32_t* dma_buf = RT_NULL;
346-
if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) && (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN))
344+
rt_uint32_t* dma_aligned_buffer = RT_NULL;
345+
rt_uint32_t* p_txrx_buffer = RT_NULL;
346+
347+
if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN))
347348
{
348-
dma_buf = (rt_uint32_t *)rt_malloc_align(send_length,32);
349-
if(send_buf)
349+
#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
350+
if (RT_IS_ALIGN((rt_uint32_t)send_buf, 32)) /* aligned with 32 bytes? */
350351
{
351-
rt_memcpy(dma_buf, send_buf, send_length);
352+
p_txrx_buffer = (rt_uint32_t *)send_buf; /* send_buf aligns with 32 bytes, no more operations */
352353
}
353354
else
354355
{
355-
rt_memset(dma_buf, 0xFF, send_length);
356+
/* send_buf doesn't align with 32 bytes, so creat a cache buffer with 32 bytes aligned */
357+
dma_aligned_buffer = (rt_uint32_t *)rt_malloc_align(send_length, 32);
358+
rt_memcpy(dma_aligned_buffer, send_buf, send_length);
359+
p_txrx_buffer = dma_aligned_buffer;
360+
}
361+
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, dma_aligned_buffer, send_length);
362+
#else
363+
if (RT_IS_ALIGN((rt_uint32_t)send_buf, 4)) /* aligned with 4 bytes? */
364+
{
365+
p_txrx_buffer = (rt_uint32_t *)send_buf; /* send_buf aligns with 4 bytes, no more operations */
366+
}
367+
else
368+
{
369+
/* send_buf doesn't align with 4 bytes, so creat a cache buffer with 4 bytes aligned */
370+
dma_aligned_buffer = (rt_uint32_t *)rt_malloc(send_length); /* aligned with RT_ALIGN_SIZE (8 bytes by default) */
371+
rt_memcpy(dma_aligned_buffer, send_buf, send_length);
372+
p_txrx_buffer = dma_aligned_buffer;
356373
}
357-
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, dma_buf, send_length);
358-
state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)dma_buf, (uint8_t *)dma_buf, send_length);
359-
}
360-
else
361374
#endif /* SOC_SERIES_STM32H7 || SOC_SERIES_STM32F7 */
375+
}
376+
362377
/* start once data exchange in DMA mode */
363378
if (message->send_buf && message->recv_buf)
364379
{
365380
if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) && (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN))
366381
{
367-
state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)send_buf, (uint8_t *)recv_buf, send_length);
382+
state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)p_txrx_buffer, (uint8_t *)p_txrx_buffer, send_length);
368383
}
369384
else if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN))
370385
{
371386
/* same as Tx ONLY. It will not receive SPI data any more. */
372-
state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)send_buf, send_length);
387+
state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)p_txrx_buffer, send_length);
373388
}
374389
else if ((spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN))
375390
{
@@ -386,7 +401,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
386401
{
387402
if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN))
388403
{
389-
state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)send_buf, send_length);
404+
state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)p_txrx_buffer, send_length);
390405
}
391406
else
392407
{
@@ -404,7 +419,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
404419
rt_memset((uint8_t *)recv_buf, 0xff, send_length);
405420
if ((spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN))
406421
{
407-
state = HAL_SPI_Receive_DMA(spi_handle, (uint8_t *)recv_buf, send_length);
422+
state = HAL_SPI_Receive_DMA(spi_handle, (uint8_t *)p_txrx_buffer, send_length);
408423
}
409424
else
410425
{
@@ -449,17 +464,21 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
449464
while (HAL_SPI_GetState(spi_handle) != HAL_SPI_STATE_READY);
450465
}
451466

452-
#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
453-
if(dma_buf)
467+
if(dma_aligned_buffer != RT_NULL) /* re-aligned, so need to copy the data to recv_buf */
454468
{
455-
if(recv_buf)
469+
if(recv_buf != RT_NULL)
456470
{
457-
rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, dma_buf, send_length);
458-
rt_memcpy(recv_buf, dma_buf,send_length);
471+
#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
472+
rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, p_txrx_buffer, send_length);
473+
#endif /* SOC_SERIES_STM32H7 || SOC_SERIES_STM32F7 */
474+
rt_memcpy(recv_buf, p_txrx_buffer, send_length);
459475
}
460-
rt_free_align(dma_buf);
461-
}
476+
#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
477+
rt_free_align(dma_aligned_buffer);
478+
#else
479+
rt_free(dma_aligned_buffer);
462480
#endif /* SOC_SERIES_STM32H7 || SOC_SERIES_STM32F7 */
481+
}
463482
}
464483

465484
if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE))

0 commit comments

Comments
 (0)