drivers/serial/serial.c: Support UART direct write for non console device

This commit is contained in:
xuanlin
2018-08-26 09:47:25 -06:00
committed by Gregory Nutt
parent 4c4d2b54a3
commit c8df5f3df3
+21 -24
View File
@@ -63,14 +63,6 @@
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ************************************************************************************/
/* The architecture must provide up_putc for this driver */
#ifndef CONFIG_ARCH_LOWPUTC
# error "Architecture must provide up_putc() for this driver"
#endif
#define uart_putc(ch) up_putc(ch)
/* Check watermark levels */ /* Check watermark levels */
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && \ #if defined(CONFIG_SERIAL_IFLOWCONTROL) && \
@@ -358,6 +350,19 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock)
return OK; return OK;
} }
/************************************************************************************
* Name: uart_putc
************************************************************************************/
static inline void uart_putc(FAR uart_dev_t *dev, int ch)
{
while (!uart_txready(dev))
{
}
uart_send(dev, ch);
}
/************************************************************************************ /************************************************************************************
* Name: uart_irqwrite * Name: uart_irqwrite
************************************************************************************/ ************************************************************************************/
@@ -375,14 +380,14 @@ static inline ssize_t uart_irqwrite(FAR uart_dev_t *dev, FAR const char *buffer,
/* If this is the console, then we should replace LF with CR-LF */ /* If this is the console, then we should replace LF with CR-LF */
if (ch == '\n') if (dev->isconsole && ch == '\n')
{ {
uart_putc('\r'); uart_putc(dev, '\r');
} }
/* Output the character, using the low-level direct UART interfaces */ /* Output the character, using the low-level direct UART interfaces */
uart_putc(ch); uart_putc(dev, ch);
} }
return ret; return ret;
@@ -1062,13 +1067,15 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer,
int ret; int ret;
char ch; char ch;
/* We may receive console writes through this path from interrupt handlers and /* We may receive serial writes through this path from interrupt handlers and
* from debug output in the IDLE task! In these cases, we will need to do things * from debug output in the IDLE task! In these cases, we will need to do things
* a little differently. * a little differently.
*/ */
if (up_interrupt_context() || sched_idletask()) if (up_interrupt_context() || sched_idletask())
{ {
irqstate_t flags;
#ifdef CONFIG_SERIAL_REMOVABLE #ifdef CONFIG_SERIAL_REMOVABLE
/* If the removable device is no longer connected, refuse to write to /* If the removable device is no longer connected, refuse to write to
* the device. * the device.
@@ -1080,22 +1087,12 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer,
} }
#endif #endif
/* up_putc() will be used to generate the output in a busy-wait loop. flags = enter_critical_section();
* up_putc() is only available for the console device.
*/
if (dev->isconsole)
{
irqstate_t flags = enter_critical_section();
ret = uart_irqwrite(dev, buffer, buflen); ret = uart_irqwrite(dev, buffer, buflen);
leave_critical_section(flags); leave_critical_section(flags);
return ret; return ret;
} }
else
{
return -EPERM;
}
}
/* Only one user can access dev->xmit.head at a time */ /* Only one user can access dev->xmit.head at a time */