From 7c3f5c3879a05ceeb524f546a1d7a9a4cd48cf96 Mon Sep 17 00:00:00 2001 From: wdfk-prog <1425075683@qq.com> Date: Wed, 7 Jun 2023 22:28:12 +0800 Subject: [PATCH] =?UTF-8?q?[bsp][stm32][spi]=20=E4=BC=98=E5=8C=96DMA?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E9=9D=9E=E5=AD=97=E8=8A=82=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/stm32/libraries/HAL_Drivers/drv_spi.c | 63 +++++++++++++++-------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_spi.c b/bsp/stm32/libraries/HAL_Drivers/drv_spi.c index fe0028c06d..0762b9bf2a 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_spi.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_spi.c @@ -341,35 +341,50 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length; } -#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) - rt_uint32_t* dma_buf = RT_NULL; - 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)) + rt_uint32_t* dma_aligned_buffer = RT_NULL; + rt_uint32_t* p_txrx_buffer = RT_NULL; + + if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN)) { - dma_buf = (rt_uint32_t *)rt_malloc_align(send_length,32); - if(send_buf) +#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) + if (RT_IS_ALIGN((rt_uint32_t)send_buf, 32)) /* aligned with 32 bytes? */ { - rt_memcpy(dma_buf, send_buf, send_length); + p_txrx_buffer = (rt_uint32_t *)send_buf; /* send_buf aligns with 32 bytes, no more operations */ } else { - rt_memset(dma_buf, 0xFF, send_length); + /* send_buf doesn't align with 32 bytes, so creat a cache buffer with 32 bytes aligned */ + dma_aligned_buffer = (rt_uint32_t *)rt_malloc_align(send_length, 32); + rt_memcpy(dma_aligned_buffer, send_buf, send_length); + p_txrx_buffer = dma_aligned_buffer; + } + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, dma_aligned_buffer, send_length); +#else + if (RT_IS_ALIGN((rt_uint32_t)send_buf, 4)) /* aligned with 4 bytes? */ + { + p_txrx_buffer = (rt_uint32_t *)send_buf; /* send_buf aligns with 4 bytes, no more operations */ + } + else + { + /* send_buf doesn't align with 4 bytes, so creat a cache buffer with 4 bytes aligned */ + dma_aligned_buffer = (rt_uint32_t *)rt_malloc(send_length); /* aligned with RT_ALIGN_SIZE (8 bytes by default) */ + rt_memcpy(dma_aligned_buffer, send_buf, send_length); + p_txrx_buffer = dma_aligned_buffer; } - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, dma_buf, send_length); - state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)dma_buf, (uint8_t *)dma_buf, send_length); - } - else #endif /* SOC_SERIES_STM32H7 || SOC_SERIES_STM32F7 */ + } + /* start once data exchange in DMA mode */ if (message->send_buf && message->recv_buf) { 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)) { - state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)send_buf, (uint8_t *)recv_buf, send_length); + state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)p_txrx_buffer, (uint8_t *)p_txrx_buffer, send_length); } else if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN)) { /* same as Tx ONLY. It will not receive SPI data any more. */ - state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)send_buf, send_length); + state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)p_txrx_buffer, send_length); } else if ((spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN)) { @@ -386,7 +401,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m { if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN)) { - state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)send_buf, send_length); + state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)p_txrx_buffer, send_length); } else { @@ -404,7 +419,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m rt_memset((uint8_t *)recv_buf, 0xff, send_length); if ((spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN)) { - state = HAL_SPI_Receive_DMA(spi_handle, (uint8_t *)recv_buf, send_length); + state = HAL_SPI_Receive_DMA(spi_handle, (uint8_t *)p_txrx_buffer, send_length); } else { @@ -449,17 +464,21 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m while (HAL_SPI_GetState(spi_handle) != HAL_SPI_STATE_READY); } -#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) - if(dma_buf) + if(dma_aligned_buffer != RT_NULL) /* re-aligned, so need to copy the data to recv_buf */ { - if(recv_buf) + if(recv_buf != RT_NULL) { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, dma_buf, send_length); - rt_memcpy(recv_buf, dma_buf,send_length); +#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) + rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, p_txrx_buffer, send_length); +#endif /* SOC_SERIES_STM32H7 || SOC_SERIES_STM32F7 */ + rt_memcpy(recv_buf, p_txrx_buffer, send_length); } - rt_free_align(dma_buf); - } +#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) + rt_free_align(dma_aligned_buffer); +#else + rt_free(dma_aligned_buffer); #endif /* SOC_SERIES_STM32H7 || SOC_SERIES_STM32F7 */ + } } if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) -- GitLab