提交 7c3f5c38 编写于 作者: 哈哈哈可是开电脑's avatar 哈哈哈可是开电脑 提交者: mysterywolf

[bsp][stm32][spi] 优化DMA数据非字节对齐的处理流程

上级 1d239db5
...@@ -341,35 +341,50 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m ...@@ -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; recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length;
} }
#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) rt_uint32_t* dma_aligned_buffer = RT_NULL;
rt_uint32_t* dma_buf = RT_NULL; rt_uint32_t* p_txrx_buffer = 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))
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 defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
if(send_buf) 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 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 */ #endif /* SOC_SERIES_STM32H7 || SOC_SERIES_STM32F7 */
}
/* start once data exchange in DMA mode */ /* start once data exchange in DMA mode */
if (message->send_buf && message->recv_buf) 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)) 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)) 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. */ /* 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)) 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 ...@@ -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)) 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 else
{ {
...@@ -404,7 +419,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m ...@@ -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); 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)) 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 else
{ {
...@@ -449,17 +464,21 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m ...@@ -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); while (HAL_SPI_GetState(spi_handle) != HAL_SPI_STATE_READY);
} }
#if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) if(dma_aligned_buffer != RT_NULL) /* re-aligned, so need to copy the data to recv_buf */
if(dma_buf)
{ {
if(recv_buf) if(recv_buf != RT_NULL)
{ {
rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, dma_buf, send_length); #if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
rt_memcpy(recv_buf, dma_buf,send_length); 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 */ #endif /* SOC_SERIES_STM32H7 || SOC_SERIES_STM32F7 */
}
} }
if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册