serial.c: Finish implementation of TCDRAIN. Based partly on logic from Sebastien Lorquet.
This commit is contained in:
parent
2c504003f3
commit
4f0238339e
@ -1001,12 +1001,94 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
}
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case TCDRN:
|
||||
{
|
||||
/* Get exclusive access to the to dev->tmit. We cannot permit
|
||||
* new data to be written while we are trying to flush the old
|
||||
* data.
|
||||
*
|
||||
* A signal received while waiting for access to the xmit.head
|
||||
* will abort the operation with EINTR.
|
||||
*/
|
||||
|
||||
ret = (ssize_t)uart_takesem(&dev->xmit.sem, true);
|
||||
if (ret >= 0)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
/* Trigger emission to flush the contents of the tx buffer */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* Check if the removable device is no longer connected
|
||||
* while we have interrupts off. We do not want the
|
||||
* transition to occur as a race condition before we begin
|
||||
* the wait.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
ret = -ENOTCONN;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Continue waiting while the TX buffer is not empty */
|
||||
|
||||
ret = OK;
|
||||
while (ret >= 0 && dev->xmit.head != dev->xmit.tail)
|
||||
{
|
||||
/* Inform the interrupt level logic that we are
|
||||
* waiting.
|
||||
*/
|
||||
|
||||
dev->xmitwaiting = true;
|
||||
|
||||
/* Wait for some characters to be sent from the
|
||||
* buffer with the TX interrupt enabled. When the
|
||||
* TX interrupt is enabled, uart_xmitchars()
|
||||
* should execute and remove some of the data from
|
||||
* the TX buffer. We mayhave to wait several
|
||||
* times for the TX buffer to be entirely emptied.
|
||||
*
|
||||
* NOTE that interrupts will be re-enabled while we
|
||||
* wait for the semaphore.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SERIAL_DMA
|
||||
uart_dmatxavail(dev);
|
||||
#endif
|
||||
uart_enabletxint(dev);
|
||||
ret = uart_takesem(&dev->xmitsem, true);
|
||||
uart_disabletxint(dev);
|
||||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* The TX buffer is empty (or an error occurred). But
|
||||
* there still may be data in the UART TX FIFO. We get no
|
||||
* asynchronous indication of this event, so we have to do
|
||||
* a busy wait poll.
|
||||
*/
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
while (!uart_txempty(dev))
|
||||
{
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
usleep(HALF_SECOND_USEC);
|
||||
#else
|
||||
up_mdelay(HALF_SECOND_MSEC);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
uart_givesem(&dev->xmit.sem);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user