diff --git a/arch/arm/src/stm32h7/stm32_serial.c b/arch/arm/src/stm32h7/stm32_serial.c index 75971f1a11..107df66414 100644 --- a/arch/arm/src/stm32h7/stm32_serial.c +++ b/arch/arm/src/stm32h7/stm32_serial.c @@ -628,7 +628,6 @@ struct up_dev_s #ifdef SERIAL_HAVE_TXDMA const unsigned int txdma_channel; /* DMA channel assigned */ DMA_HANDLE txdma; /* currently-open trasnmit DMA stream */ - sem_t txdmasem; /* Indicate TX DMA completion */ #endif /* RX DMA state */ @@ -3299,8 +3298,9 @@ static bool up_dma_rxavailable(struct uart_dev_s *dev) * Name: up_dma_txcallback * * Description: - * This function clears dma buffer at complete of DMA transfer and wakes up - * threads waiting for space in buffer. + * This function clears dma buffer at completion of DMA transfer. It wakes + * up threads waiting for space in buffer and restarts the DMA if there is + * more data to send. * ****************************************************************************/ @@ -3314,11 +3314,7 @@ static void up_dma_txcallback(DMA_HANDLE handle, uint8_t status, void *arg) * This is important to free TX buffer space by 'uart_xmitchars_done'. */ - if (status & DMA_SCR_HTIE) - { - priv->dev.dmatx.nbytes += priv->dev.dmatx.length / 2; - } - else if (status & DMA_SCR_TCIE) + if (status & DMA_SCR_TCIE) { priv->dev.dmatx.nbytes += priv->dev.dmatx.length; if (priv->dev.dmatx.nlength) @@ -3346,11 +3342,13 @@ static void up_dma_txcallback(DMA_HANDLE handle, uint8_t status, void *arg) } } - nxsem_post(&priv->txdmasem); - /* Adjust the pointers */ uart_xmitchars_done(&priv->dev); + + /* Send more if availaible */ + + up_dma_txavailable(&priv->dev); } #endif @@ -3369,8 +3367,7 @@ static void up_dma_txavailable(struct uart_dev_s *dev) /* Only send when the DMA is idle */ - int rv = nxsem_trywait(&priv->txdmasem); - if (rv == OK) + if (stm32_dmaresidual(priv->txdma) == 0) { uart_xmitchars_dma(dev); }