You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ag...@apache.org on 2020/09/25 21:09:17 UTC

[incubator-nuttx] branch master updated: stm32f7:serial Bug Fix: Ensure next buffer is processed

This is an automated email from the ASF dual-hosted git repository.

aguettouche pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 4a6f7ca  stm32f7:serial Bug Fix: Ensure next buffer is processed
4a6f7ca is described below

commit 4a6f7cacd5a4354a93ebf92bb9cd426b016ad409
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Fri Sep 25 04:38:09 2020 -0700

    stm32f7:serial Bug Fix: Ensure next buffer is processed
    
       When the Head to Tail relationship was H < T, then
       only the tail to end of buffer was sent.
    
       The fix is: In the txdma completion to do a second
       the DMA operation using nbuffer if the nlength is
       non zero.
    
    stm32f7:serial UART5 use actual size
    
       UART5 was using the CONFIG_UART5_TXBUFSIZE
       not the UART5_TXBUFSIZE_ADJUSTED.
       Since the buffer size was adjusted up, this
       has no dcache implications.
       If the UART5_TXBUFSIZE_ADJUSTED is larger
       then CONFIG_UART5_TXBUFSIZE it will present
       a larger usable buffer to the system's
       serial driver.
---
 arch/arm/src/stm32f7/stm32_serial.c | 47 ++++++++++++++++++++++++++++++-------
 1 file changed, 39 insertions(+), 8 deletions(-)

diff --git a/arch/arm/src/stm32f7/stm32_serial.c b/arch/arm/src/stm32f7/stm32_serial.c
index faf0e6e..ad1f3d1 100644
--- a/arch/arm/src/stm32f7/stm32_serial.c
+++ b/arch/arm/src/stm32f7/stm32_serial.c
@@ -1067,12 +1067,12 @@ static struct up_dev_s g_uart5priv =
 #endif
       .recv     =
       {
-        .size   = CONFIG_UART5_RXBUFSIZE,
+        .size   = sizeof(g_uart5rxbuffer),
         .buffer = g_uart5rxbuffer,
       },
       .xmit     =
       {
-        .size   = CONFIG_UART5_TXBUFSIZE,
+        .size   = sizeof(g_uart5txbuffer),
         .buffer = g_uart5txbuffer,
       },
 #if defined(CONFIG_UART5_RXDMA) && defined(CONFIG_UART5_TXDMA)
@@ -3124,20 +3124,37 @@ static void up_dma_txcallback(DMA_HANDLE handle, uint8_t status, void *arg)
 
   if (status & DMA_SCR_HTIE)
     {
-      priv->dev.dmatx.nbytes = priv->dev.dmatx.length / 2;
+      priv->dev.dmatx.nbytes += priv->dev.dmatx.length / 2;
     }
   else if (status & DMA_SCR_TCIE)
     {
-      priv->dev.dmatx.nbytes = priv->dev.dmatx.length;
+      priv->dev.dmatx.nbytes += priv->dev.dmatx.length;
+      if (priv->dev.dmatx.nlength)
+        {
+          /* Set up DMA on next buffer */
+
+          stm32_dmasetup(priv->txdma,
+                         priv->usartbase + STM32_USART_TDR_OFFSET,
+                         (uint32_t) priv->dev.dmatx.nbuffer,
+                         (size_t) priv->dev.dmatx.nlength,
+                         SERIAL_TXDMA_CONTROL_WORD);
+
+          /* Set length for next next completion */
+
+          priv->dev.dmatx.length  = priv->dev.dmatx.nlength;
+          priv->dev.dmatx.nlength = 0;
+
+          /* Start transmission with the callback on DMA completion */
+
+          stm32_dmastart(priv->txdma, up_dma_txcallback, (void *)priv, false);
+
+          return;
+        }
     }
 
   /* Adjust the pointers */
 
   uart_xmitchars_done(&priv->dev);
-
-  /* Kick off the next DMA to keep the channel as busy as possible */
-
-  uart_xmitchars_dma(&priv->dev);
 }
 #endif
 
@@ -3181,11 +3198,25 @@ static void up_dma_send(struct uart_dev_s *dev)
 
   stm32_dmastop(priv->txdma);
 
+  /* Reset the number sent */
+
+  dev->dmatx.nbytes = 0;
+
   /* Flush the contents of the TX buffer into physical memory */
 
   up_clean_dcache((uintptr_t)dev->dmatx.buffer,
                   (uintptr_t)dev->dmatx.buffer + dev->dmatx.length);
 
+  /* Is this a split transfer */
+
+  if (dev->dmatx.nbuffer)
+    {
+      /* Flush the contents of the next TX buffer into physical memory */
+
+      up_clean_dcache((uintptr_t)dev->dmatx.nbuffer,
+                      (uintptr_t)dev->dmatx.nbuffer + dev->dmatx.nlength);
+    }
+
   /* Make use of setup function to update buffer and its length for next transfer */
 
   stm32_dmasetup(priv->txdma,