1
0
Эх сурвалжийг харах

[stm32][spi-dma] 只有传输数据超过一定长度才会使用DMA方式
在传输数据为短小报文时,使用DMA模式反倒会慢

Meco Man 2 жил өмнө
parent
commit
22fb7152d9

+ 9 - 7
bsp/stm32/libraries/HAL_Drivers/drv_spi.c

@@ -283,6 +283,8 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur
 
 
 static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
 static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
 {
 {
+    #define DMA_TRANS_MIN_LEN  10 /* only buffer length >= DMA_TRANS_MIN_LEN will use DMA mode */
+
     HAL_StatusTypeDef state = HAL_OK;
     HAL_StatusTypeDef state = HAL_OK;
     rt_size_t message_length, already_send_length;
     rt_size_t message_length, already_send_length;
     rt_uint16_t send_length;
     rt_uint16_t send_length;
@@ -341,7 +343,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
 
 
 #if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
 #if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
         rt_uint32_t* dma_buf = RT_NULL;
         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))
+        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))
         {
         {
             dma_buf = (rt_uint32_t *)rt_malloc_align(send_length,32);
             dma_buf = (rt_uint32_t *)rt_malloc_align(send_length,32);
             if(send_buf)
             if(send_buf)
@@ -360,16 +362,16 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
         /* 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))
+            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 *)send_buf, (uint8_t *)recv_buf, send_length);
             }
             }
-            else if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG))
+            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 *)send_buf, send_length);
             }
             }
-            else if ((spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG))
+            else if ((spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG) && (send_length >= DMA_TRANS_MIN_LEN))
             {
             {
                 state = HAL_ERROR;
                 state = HAL_ERROR;
                 LOG_E("It shoule be enabled both BSP_SPIx_TX_USING_DMA and BSP_SPIx_TX_USING_DMA flag, if wants to use SPI DMA Rx singly.");
                 LOG_E("It shoule be enabled both BSP_SPIx_TX_USING_DMA and BSP_SPIx_TX_USING_DMA flag, if wants to use SPI DMA Rx singly.");
@@ -382,7 +384,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
         }
         }
         else if (message->send_buf)
         else if (message->send_buf)
         {
         {
-            if (spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG)
+            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 *)send_buf, send_length);
             }
             }
@@ -400,7 +402,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
         else if(message->recv_buf)
         else if(message->recv_buf)
         {
         {
             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)
+            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 *)recv_buf, send_length);
             }
             }
@@ -432,7 +434,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
         /* For simplicity reasons, this example is just waiting till the end of the
         /* For simplicity reasons, this example is just waiting till the end of the
            transfer, but application may perform other tasks while transfer operation
            transfer, but application may perform other tasks while transfer operation
            is ongoing. */
            is ongoing. */
-        if (spi_drv->spi_dma_flag & (SPI_USING_TX_DMA_FLAG | SPI_USING_RX_DMA_FLAG))
+        if ((spi_drv->spi_dma_flag & (SPI_USING_TX_DMA_FLAG | SPI_USING_RX_DMA_FLAG)) && (send_length >= DMA_TRANS_MIN_LEN))
         {
         {
             /* blocking the thread,and the other tasks can run */
             /* blocking the thread,and the other tasks can run */
             if (rt_completion_wait(&spi_drv->cpt, 1000) != RT_EOK)
             if (rt_completion_wait(&spi_drv->cpt, 1000) != RT_EOK)