@@ -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