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.
This commit is contained in:
parent
c47ad0c909
commit
4a6f7cacd5
@ -1067,12 +1067,12 @@ static struct up_dev_s g_uart5priv =
|
|||||||
#endif
|
#endif
|
||||||
.recv =
|
.recv =
|
||||||
{
|
{
|
||||||
.size = CONFIG_UART5_RXBUFSIZE,
|
.size = sizeof(g_uart5rxbuffer),
|
||||||
.buffer = g_uart5rxbuffer,
|
.buffer = g_uart5rxbuffer,
|
||||||
},
|
},
|
||||||
.xmit =
|
.xmit =
|
||||||
{
|
{
|
||||||
.size = CONFIG_UART5_TXBUFSIZE,
|
.size = sizeof(g_uart5txbuffer),
|
||||||
.buffer = g_uart5txbuffer,
|
.buffer = g_uart5txbuffer,
|
||||||
},
|
},
|
||||||
#if defined(CONFIG_UART5_RXDMA) && defined(CONFIG_UART5_TXDMA)
|
#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)
|
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)
|
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 */
|
/* Adjust the pointers */
|
||||||
|
|
||||||
uart_xmitchars_done(&priv->dev);
|
uart_xmitchars_done(&priv->dev);
|
||||||
|
|
||||||
/* Kick off the next DMA to keep the channel as busy as possible */
|
|
||||||
|
|
||||||
uart_xmitchars_dma(&priv->dev);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -3181,11 +3198,25 @@ static void up_dma_send(struct uart_dev_s *dev)
|
|||||||
|
|
||||||
stm32_dmastop(priv->txdma);
|
stm32_dmastop(priv->txdma);
|
||||||
|
|
||||||
|
/* Reset the number sent */
|
||||||
|
|
||||||
|
dev->dmatx.nbytes = 0;
|
||||||
|
|
||||||
/* Flush the contents of the TX buffer into physical memory */
|
/* Flush the contents of the TX buffer into physical memory */
|
||||||
|
|
||||||
up_clean_dcache((uintptr_t)dev->dmatx.buffer,
|
up_clean_dcache((uintptr_t)dev->dmatx.buffer,
|
||||||
(uintptr_t)dev->dmatx.buffer + dev->dmatx.length);
|
(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 */
|
/* Make use of setup function to update buffer and its length for next transfer */
|
||||||
|
|
||||||
stm32_dmasetup(priv->txdma,
|
stm32_dmasetup(priv->txdma,
|
||||||
|
Loading…
Reference in New Issue
Block a user