drivers/serial: Move head/tail pointer reset to uart_recvchars_dma since dma may be still transferring in the background.

This commit is contained in:
Xiang Xiao 2018-08-26 10:03:30 -06:00 committed by Gregory Nutt
parent 4465cccdbd
commit 9e922873d4
2 changed files with 21 additions and 26 deletions

View File

@ -431,8 +431,7 @@ static int uart_tcdrain(FAR uart_dev_t *dev, clock_t timeout)
if (dev->disconnected) if (dev->disconnected)
{ {
dev->xmit.head = 0; /* Drop the buffered TX data */ dev->xmit.tail = dev->xmit.head; /* Drop the buffered TX data */
dev->xmit.tail = 0;
ret = -ENOTCONN; ret = -ENOTCONN;
} }
else else
@ -908,17 +907,11 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
flags = enter_critical_section(); flags = enter_critical_section();
#ifdef CONFIG_SERIAL_DMA #ifdef CONFIG_SERIAL_DMA
/* If RX buffer is empty move tail and head to zero position */
if (rxbuf->head == rxbuf->tail)
{
rxbuf->head = rxbuf->tail = 0;
}
/* Notify DMA that there is free space in the RX buffer */ /* Notify DMA that there is free space in the RX buffer */
uart_dmarxfree(dev); uart_dmarxfree(dev);
#endif #endif
/* Re-enable UART Rx interrupts */
uart_enablerxint(dev); uart_enablerxint(dev);
@ -992,25 +985,16 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
} }
#ifdef CONFIG_SERIAL_DMA #ifdef CONFIG_SERIAL_DMA
flags = enter_critical_section();
/* If RX buffer is empty move tail and head to zero position */
if (rxbuf->head == rxbuf->tail)
{
rxbuf->head = rxbuf->tail = 0;
}
leave_critical_section(flags);
/* Notify DMA that there is free space in the RX buffer */ /* Notify DMA that there is free space in the RX buffer */
flags = enter_critical_section();
uart_dmarxfree(dev); uart_dmarxfree(dev);
leave_critical_section(flags);
#endif
/* RX interrupt could be disabled by RX buffer overflow. Enable it now. */ /* RX interrupt could be disabled by RX buffer overflow. Enable it now. */
uart_enablerxint(dev); uart_enablerxint(dev);
#endif
#ifdef CONFIG_SERIAL_IFLOWCONTROL #ifdef CONFIG_SERIAL_IFLOWCONTROL
#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS #ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
@ -1340,8 +1324,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
if (arg == TCIFLUSH || arg == TCIOFLUSH) if (arg == TCIFLUSH || arg == TCIOFLUSH)
{ {
dev->recv.head = 0; dev->recv.tail = dev->recv.head;
dev->recv.tail = 0;
#ifdef CONFIG_SERIAL_IFLOWCONTROL #ifdef CONFIG_SERIAL_IFLOWCONTROL
/* De-activate RX flow control. */ /* De-activate RX flow control. */
@ -1352,8 +1335,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
if (arg == TCOFLUSH || arg == TCIOFLUSH) if (arg == TCOFLUSH || arg == TCIOFLUSH)
{ {
dev->xmit.head = 0; dev->xmit.tail = dev->xmit.head;
dev->xmit.tail = 0;
/* Inform any waiters there there is space available. */ /* Inform any waiters there there is space available. */

View File

@ -199,8 +199,21 @@ void uart_recvchars_dma(FAR uart_dev_t *dev)
unsigned int watermark; unsigned int watermark;
#endif #endif
bool is_full; bool is_full;
int nexthead = rxbuf->head + 1; int nexthead;
/* If RX buffer is empty move tail and head to zero position */
if (rxbuf->head == rxbuf->tail)
{
rxbuf->head = 0;
rxbuf->head = 0;
}
/* Get the next head index and check if there is room to adding another
* byte to the buffer.
*/
nexthead = rxbuf->head + 1;
if (nexthead >= rxbuf->size) if (nexthead >= rxbuf->size)
{ {
nexthead = 0; nexthead = 0;