From 6c186b6084e0952f29aaca0ea8296451b8646a72 Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Thu, 18 Jan 2024 07:18:01 -0800 Subject: [PATCH] stm32h7:serial make TX DMA busy when there are an outstanding transaction If a TX DMA completion interrups a forground write. The TX DMA completion can start a dma_send and it will then followed by the forground write's dma_send stoping the,then in progress DMA. By atomicaly marking the tx dma busy, the forground write will not perform the dma_send, and will only enqueue the data. At the next TX dma completion any data pending in the tx queue will be sent --- arch/arm/src/stm32h7/stm32_serial.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/src/stm32h7/stm32_serial.c b/arch/arm/src/stm32h7/stm32_serial.c index 22efa0d147..dffca7cc96 100644 --- a/arch/arm/src/stm32h7/stm32_serial.c +++ b/arch/arm/src/stm32h7/stm32_serial.c @@ -3356,13 +3356,17 @@ static void up_dma_txcallback(DMA_HANDLE handle, uint8_t status, void *arg) static void up_dma_txavailable(struct uart_dev_s *dev) { struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags = enter_critical_section(); /* Only send when the DMA is idle */ - if (stm32_dmaresidual(priv->txdma) == 0) + if ((priv->dev.dmatx.length && priv->dev.dmatx.nlength) == 0 && + stm32_dmaresidual(priv->txdma) == 0) { uart_xmitchars_dma(dev); } + + leave_critical_section(flags); } #endif