Squashed commit of the following:
drivers/serial/uart_16550.c: Support 16550 auto hardware flow control drivers/serial/uart_16550.c: Add configuration option CONFIG_16550_SUPRESS_INITIAL_CONFIG. This is identical to the standard configuration in arch/Kconfig CONFIG_SUPPRESS_UART_CONFIG, but with scope of only the 16550 driver.
This commit is contained in:
parent
fa08e69cca
commit
ead2c40cd4
@ -312,6 +312,11 @@ endchoice # 16550 Serial Console
|
||||
config 16550_SUPRESS_CONFIG
|
||||
bool "Suppress 16550 configuration"
|
||||
default n
|
||||
|
||||
config 16550_SUPRESS_INITIAL_CONFIG
|
||||
bool "Suppress initial 16550 configuration"
|
||||
depends on !16550_SUPRESS_CONFIG
|
||||
default n
|
||||
---help---
|
||||
This option is useful, for example, if you are using a bootloader
|
||||
that configures the 16550_UART. In that case, you may want to
|
||||
|
@ -80,6 +80,9 @@ struct u16550_s
|
||||
uint8_t parity; /* 0=none, 1=odd, 2=even */
|
||||
uint8_t bits; /* Number of bits (7 or 8) */
|
||||
bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL)
|
||||
bool flow; /* flow control (RTS/CTS) enabled */
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -96,6 +99,10 @@ static int u16550_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||
static int u16550_receive(FAR struct uart_dev_s *dev, uint32_t *status);
|
||||
static void u16550_rxint(FAR struct uart_dev_s *dev, bool enable);
|
||||
static bool u16550_rxavailable(FAR struct uart_dev_s *dev);
|
||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||
static bool u16550_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered,
|
||||
bool upper);
|
||||
#endif
|
||||
#ifdef CONFIG_SERIAL_DMA
|
||||
static void u16550_dmasend(FAR struct uart_dev_s *dev);
|
||||
static void u16550_dmareceive(FAR struct uart_dev_s *dev);
|
||||
@ -122,7 +129,7 @@ static const struct uart_ops_s g_uart_ops =
|
||||
.rxint = u16550_rxint,
|
||||
.rxavailable = u16550_rxavailable,
|
||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||
.rxflowcontrol = NULL,
|
||||
.rxflowcontrol = u16550_rxflowcontrol,
|
||||
#endif
|
||||
#ifdef CONFIG_SERIAL_DMA
|
||||
.dmasend = u16550_dmasend,
|
||||
@ -170,6 +177,9 @@ static struct u16550_s g_uart0priv =
|
||||
.parity = CONFIG_16550_UART0_PARITY,
|
||||
.bits = CONFIG_16550_UART0_BITS,
|
||||
.stopbits2 = CONFIG_16550_UART0_2STOP,
|
||||
#if defined(CONFIG_16550_UART0_IFLOWCONTROL) || defined(CONFIG_16550_UART0_OFLOWCONTROL)
|
||||
.flow = true,
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -205,6 +215,9 @@ static struct u16550_s g_uart1priv =
|
||||
.parity = CONFIG_16550_UART1_PARITY,
|
||||
.bits = CONFIG_16550_UART1_BITS,
|
||||
.stopbits2 = CONFIG_16550_UART1_2STOP,
|
||||
#if defined(CONFIG_16550_UART1_IFLOWCONTROL) || defined(CONFIG_16551_UART1_OFLOWCONTROL)
|
||||
.flow = true,
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -240,6 +253,9 @@ static struct u16550_s g_uart2priv =
|
||||
.parity = CONFIG_16550_UART2_PARITY,
|
||||
.bits = CONFIG_16550_UART2_BITS,
|
||||
.stopbits2 = CONFIG_16550_UART2_2STOP,
|
||||
#if defined(CONFIG_16550_UART2_IFLOWCONTROL) || defined(CONFIG_16550_UART2_OFLOWCONTROL)
|
||||
.flow = true,
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -275,6 +291,9 @@ static struct u16550_s g_uart3priv =
|
||||
.parity = CONFIG_16550_UART3_PARITY,
|
||||
.bits = CONFIG_16550_UART3_BITS,
|
||||
.stopbits2 = CONFIG_16550_UART3_2STOP,
|
||||
#if defined(CONFIG_16550_UART3_IFLOWCONTROL) || defined(CONFIG_16550_UART3_OFLOWCONTROL)
|
||||
.flow = true,
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -606,6 +625,9 @@ static int u16550_setup(FAR struct uart_dev_s *dev)
|
||||
FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv;
|
||||
uint16_t div;
|
||||
uint32_t lcr;
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL)
|
||||
uint32_t mcr;
|
||||
#endif
|
||||
|
||||
/* Clear fifos */
|
||||
|
||||
@ -677,6 +699,23 @@ static int u16550_setup(FAR struct uart_dev_s *dev)
|
||||
u16550_serialout(priv, UART_FCR_OFFSET,
|
||||
(UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST | UART_FCR_RXRST |
|
||||
UART_FCR_FIFOEN));
|
||||
|
||||
/* Set up the auto flow control */
|
||||
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL)
|
||||
mcr = u16550_serialin(priv, UART_MCR_OFFSET);
|
||||
if (priv->flow)
|
||||
{
|
||||
mcr |= UART_MCR_AFCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mcr &= ~UART_MCR_AFCE;
|
||||
}
|
||||
|
||||
u16550_serialout(priv, UART_MCR_OFFSET, mcr);
|
||||
#endif /* defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) */
|
||||
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
@ -934,6 +973,9 @@ static int u16550_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
termiosp->c_cflag = ((priv->parity != 0) ? PARENB : 0) |
|
||||
((priv->parity == 1) ? PARODD : 0);
|
||||
termiosp->c_cflag |= (priv->stopbits2) ? CSTOPB : 0;
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL)
|
||||
termiosp->c_cflag |= priv->flow ? CRTSCTS : 0;
|
||||
#endif
|
||||
|
||||
switch (priv->bits)
|
||||
{
|
||||
@ -1003,6 +1045,9 @@ static int u16550_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
|
||||
priv->baud = cfgetispeed(termiosp);
|
||||
priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0;
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL)
|
||||
priv->flow = (termiosp->c_cflag & CRTSCTS) != 0;
|
||||
#endif
|
||||
|
||||
u16550_setup(dev);
|
||||
leave_critical_section(flags);
|
||||
@ -1084,6 +1129,31 @@ static bool u16550_rxavailable(struct uart_dev_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||
static bool u16550_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered,
|
||||
bool upper)
|
||||
{
|
||||
#ifndef CONFIG_16550_SUPRESS_CONFIG
|
||||
FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv;
|
||||
|
||||
if (priv->flow)
|
||||
{
|
||||
/* Disable Rx interrupt to prevent more data being from
|
||||
* peripheral if the RX buffer is near full. When hardware
|
||||
* RTS is enabled, this will prevent more data from coming
|
||||
* in. Otherwise, enable Rx interrupt to make sure that more
|
||||
* input is received.
|
||||
*/
|
||||
|
||||
u16550_rxint(dev, !upper);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_DMA
|
||||
static void u16550_dmasend(FAR struct uart_dev_s *dev)
|
||||
{
|
||||
@ -1232,8 +1302,10 @@ void up_earlyserialinit(void)
|
||||
|
||||
#ifdef CONSOLE_DEV
|
||||
CONSOLE_DEV.isconsole = true;
|
||||
#ifndef CONFIG_16550_SUPRESS_INITIAL_CONFIG
|
||||
u16550_setup(&CONSOLE_DEV);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -290,7 +290,8 @@
|
||||
#define UART_MCR_OUT1 (1 << 2) /* Bit 2: Auxiliary user-defined output 1 */
|
||||
#define UART_MCR_OUT2 (1 << 3) /* Bit 3: Auxiliary user-defined output 2 */
|
||||
#define UART_MCR_LPBK (1 << 4) /* Bit 4: Loopback Mode Select */
|
||||
/* Bit 5-7: Reserved */
|
||||
#define UART_MCR_AFCE (1 << 5) /* Bit 5: Auto Flow Control Enable */
|
||||
/* Bit 6-7: Reserved */
|
||||
|
||||
/* LSR Line Status Register */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user