From 78681b6d8ff3c4df8011d82299915c5335d79df6 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 6 Jun 2013 14:49:14 -0600 Subject: [PATCH] Add flow control support to the STM32 serial driver; Fix some issues with UART2 and 5. From Lorenz Meier and Mike Smith --- arch/arm/src/lpc17xx/Kconfig | 28 --- arch/arm/src/lpc17xx/lpc17_lowputc.c | 2 +- arch/arm/src/lpc17xx/lpc17_serial.c | 10 +- arch/arm/src/lpc17xx/lpc17_serial.h | 14 +- arch/arm/src/stm32/stm32_serial.c | 260 +++++++++++++++++++++------ 5 files changed, 221 insertions(+), 93 deletions(-) diff --git a/arch/arm/src/lpc17xx/Kconfig b/arch/arm/src/lpc17xx/Kconfig index 6f8967054c..ff383bae4a 100644 --- a/arch/arm/src/lpc17xx/Kconfig +++ b/arch/arm/src/lpc17xx/Kconfig @@ -335,20 +335,6 @@ config SERIAL_TERMIOS If this is not defined, then the terminal settings (baud, parity, etc). are not configurable at runtime; serial streams cannot be flushed, etc.. -config UART0_FLOWCONTROL - bool "UART0 flow control" - depends on LPC17_UART0 - default n - ---help--- - Enable UART0 flow control - -config UART1_FLOWCONTROL - bool "UART1 flow control" - depends on LPC17_UART1 - default n - ---help--- - Enable UART1 flow control - config UART1_RINGINDICATOR bool "UART1 ring indicator" depends on LPC17_UART1 @@ -356,20 +342,6 @@ config UART1_RINGINDICATOR ---help--- Enable UART1 ring indicator -config UART2_FLOWCONTROL - bool "UART0 flow control" - depends on LPC17_UART2 - default n - ---help--- - Enable UART2 flow control - -config UART3_FLOWCONTROL - bool "UART3 flow control" - depends on LPC17_UART3 - default n - ---help--- - Enable UART3 flow control - endmenu menu "ADC driver options" diff --git a/arch/arm/src/lpc17xx/lpc17_lowputc.c b/arch/arm/src/lpc17xx/lpc17_lowputc.c index 9ff0eab60c..3926c87126 100644 --- a/arch/arm/src/lpc17xx/lpc17_lowputc.c +++ b/arch/arm/src/lpc17xx/lpc17_lowputc.c @@ -359,7 +359,7 @@ void lpc17_lowsetup(void) #elif defined(CONFIG_UART1_SERIAL_CONSOLE) lpc17_configgpio(GPIO_UART1_TXD); lpc17_configgpio(GPIO_UART1_RXD); -#ifdef CONFIG_UART1_FLOWCONTROL +#if defined(CONFIG_UART1_IFLOWCONTROL) || defined(CONFIG_UART1_OFLOWCONTROL) lpc17_configgpio(GPIO_UART1_CTS); lpc17_configgpio(GPIO_UART1_DCD); lpc17_configgpio(GPIO_UART1_DSR); diff --git a/arch/arm/src/lpc17xx/lpc17_serial.c b/arch/arm/src/lpc17xx/lpc17_serial.c index 6bf519ac30..ed1a378147 100644 --- a/arch/arm/src/lpc17xx/lpc17_serial.c +++ b/arch/arm/src/lpc17xx/lpc17_serial.c @@ -736,7 +736,7 @@ static inline void lpc17_uart1config(void) lpc17_configgpio(GPIO_UART1_TXD); lpc17_configgpio(GPIO_UART1_RXD); -#ifdef CONFIG_UART1_FLOWCONTROL +#if defined(CONFIG_UART1_IFLOWCONTROL) || defined(CONFIG_UART1_OFLOWCONTROL) lpc17_configgpio(GPIO_UART1_CTS); lpc17_configgpio(GPIO_UART1_RTS); lpc17_configgpio(GPIO_UART1_DCD); @@ -943,10 +943,16 @@ static int up_setup(struct uart_dev_s *dev) /* Enable Auto-RTS and Auto-CS Flow Control in the Modem Control Register */ -#ifdef CONFIG_UART1_FLOWCONTROL +#if defined(CONFIG_UART1_IFLOWCONTROL) || defined(CONFIG_UART1_OFLOWCONTROL) if (priv->uartbase == LPC17_UART1_BASE) { +#if defined(CONFIG_UART1_IFLOWCONTROL) && defined(CONFIG_UART1_OFLOWCONTROL) up_serialout(priv, LPC17_UART_MCR_OFFSET, (UART_MCR_RTSEN|UART_MCR_CTSEN)); +#elif defined(CONFIG_UART1_IFLOWCONTROL) + up_serialout(priv, LPC17_UART_MCR_OFFSET, UART_MCR_RTSEN); +#else + up_serialout(priv, LPC17_UART_MCR_OFFSET, UART_MCR_CTSEN); +#endif } #endif diff --git a/arch/arm/src/lpc17xx/lpc17_serial.h b/arch/arm/src/lpc17xx/lpc17_serial.h index 95e8155de8..3db62f7f8a 100644 --- a/arch/arm/src/lpc17xx/lpc17_serial.h +++ b/arch/arm/src/lpc17xx/lpc17_serial.h @@ -1,7 +1,7 @@ /************************************************************************************ * arch/arm/src/lpc17xx/lpc17_serial.h * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -96,11 +96,15 @@ /* Check UART flow control (Only supported by UART1) */ -# undef CONFIG_UART0_FLOWCONTROL -# undef CONFIG_UART2_FLOWCONTROL -# undef CONFIG_UART3_FLOWCONTROL +# undef CONFIG_UART0_IFLOWCONTROL +# undef CONFIG_UART0_OFLOWCONTROL +# undef CONFIG_UART2_IFLOWCONTROL +# undef CONFIG_UART2_OFLOWCONTROL +# undef CONFIG_UART3_IFLOWCONTROL +# undef CONFIG_UART3_OFLOWCONTROL #ifndef CONFIG_LPC17_UART1 -# undef CONFIG_UART1_FLOWCONTROL +# undef CONFIG_UART1_IFLOWCONTROL +# undef CONFIG_UART1_OFLOWCONTROL #endif /* We cannot allow the DLM/DLL divisor to become to small or will will lose too diff --git a/arch/arm/src/stm32/stm32_serial.c b/arch/arm/src/stm32/stm32_serial.c index af95244f00..52a77e2558 100644 --- a/arch/arm/src/stm32/stm32_serial.c +++ b/arch/arm/src/stm32/stm32_serial.c @@ -257,11 +257,23 @@ struct up_dev_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 */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + bool iflow; /* input flow control (RTS) enabled */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + bool oflow; /* output flow control (CTS) enabled */ +#endif uint32_t baud; /* Configured baud */ #else const uint8_t parity; /* 0=none, 1=odd, 2=even */ const uint8_t bits; /* Number of bits (7 or 8) */ const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + const bool iflow; /* input flow control (RTS) enabled */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + const bool oflow; /* output flow control (CTS) enabled */ +#endif const uint32_t baud; /* Configured baud */ #endif @@ -270,8 +282,12 @@ struct up_dev_s const uint32_t usartbase; /* Base address of USART registers */ const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */ const uint32_t rx_gpio; /* U[S]ART RX GPIO pin configuration */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL const uint32_t rts_gpio; /* U[S]ART RTS GPIO pin configuration */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */ +#endif #ifdef SERIAL_HAVE_DMA const unsigned int rxdma_channel; /* DMA channel assigned */ @@ -298,7 +314,7 @@ struct up_dev_s * Private Function Prototypes ****************************************************************************/ -static void up_setspeed(struct uart_dev_s *dev); +static void up_set_format(struct uart_dev_s *dev); static int up_setup(struct uart_dev_s *dev); static void up_shutdown(struct uart_dev_s *dev); static int up_attach(struct uart_dev_s *dev); @@ -492,15 +508,21 @@ static struct up_dev_s g_usart1priv = .parity = CONFIG_USART1_PARITY, .bits = CONFIG_USART1_BITS, .stopbits2 = CONFIG_USART1_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif .baud = CONFIG_USART1_BAUD, .apbclock = STM32_PCLK2_FREQUENCY, .usartbase = STM32_USART1_BASE, .tx_gpio = GPIO_USART1_TX, .rx_gpio = GPIO_USART1_RX, -#ifdef GPIO_USART1_CTS +#if defined(CONFIG_SERIAL_OFLOWCONROL) && defined(CONFIG_USART1_OFLOWCONTROL) .cts_gpio = GPIO_USART1_CTS, #endif -#ifdef GPIO_USART1_RTS +#if defined(CONFIG_SERIAL_IFLOWCONROL) && defined(CONFIG_USART1_IFLOWCONTROL) .rts_gpio = GPIO_USART1_RTS, #endif #ifdef CONFIG_USART1_RXDMA @@ -552,15 +574,21 @@ static struct up_dev_s g_usart2priv = .parity = CONFIG_USART2_PARITY, .bits = CONFIG_USART2_BITS, .stopbits2 = CONFIG_USART2_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif .baud = CONFIG_USART2_BAUD, .apbclock = STM32_PCLK1_FREQUENCY, .usartbase = STM32_USART2_BASE, .tx_gpio = GPIO_USART2_TX, .rx_gpio = GPIO_USART2_RX, -#ifdef GPIO_USART2_CTS +#if defined(CONFIG_SERIAL_OFLOWCONROL) && defined(CONFIG_USART2_OFLOWCONTROL) .cts_gpio = GPIO_USART2_CTS, #endif -#ifdef GPIO_USART2_RTS +#if defined(CONFIG_SERIAL_IFLOWCONROL) && defined(CONFIG_USART2_IFLOWCONTROL) .rts_gpio = GPIO_USART2_RTS, #endif #ifdef CONFIG_USART2_RXDMA @@ -612,15 +640,21 @@ static struct up_dev_s g_usart3priv = .parity = CONFIG_USART3_PARITY, .bits = CONFIG_USART3_BITS, .stopbits2 = CONFIG_USART3_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif .baud = CONFIG_USART3_BAUD, .apbclock = STM32_PCLK1_FREQUENCY, .usartbase = STM32_USART3_BASE, .tx_gpio = GPIO_USART3_TX, .rx_gpio = GPIO_USART3_RX, -#ifdef GPIO_USART3_CTS +#if defined(CONFIG_SERIAL_OFLOWCONROL) && defined(CONFIG_USART3_OFLOWCONTROL) .cts_gpio = GPIO_USART3_CTS, #endif -#ifdef GPIO_USART3_RTS +#if defined(CONFIG_SERIAL_IFLOWCONROL) && defined(CONFIG_USART3_IFLOWCONTROL) .rts_gpio = GPIO_USART3_RTS, #endif #ifdef CONFIG_USART3_RXDMA @@ -672,16 +706,22 @@ static struct up_dev_s g_uart4priv = .parity = CONFIG_UART4_PARITY, .bits = CONFIG_UART4_BITS, .stopbits2 = CONFIG_UART4_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif .baud = CONFIG_UART4_BAUD, .apbclock = STM32_PCLK1_FREQUENCY, .usartbase = STM32_UART4_BASE, .tx_gpio = GPIO_UART4_TX, .rx_gpio = GPIO_UART4_RX, -#ifdef GPIO_UART4_CTS - .cts_gpio = GPIO_UART4_CTS, +#ifdef CONFIG_SERIAL_OFLOWCONROL + .cts_gpio = 0, #endif -#ifdef GPIO_UART4_RTS - .rts_gpio = GPIO_UART4_RTS, +#ifdef CONFIG_SERIAL_IFLOWCONROL + .rts_gpio = 0, #endif #ifdef CONFIG_UART4_RXDMA .rxdma_channel = DMAMAP_UART4_RX, @@ -732,16 +772,22 @@ static struct up_dev_s g_uart5priv = .parity = CONFIG_UART5_PARITY, .bits = CONFIG_UART5_BITS, .stopbits2 = CONFIG_UART5_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif .baud = CONFIG_UART5_BAUD, .apbclock = STM32_PCLK1_FREQUENCY, .usartbase = STM32_UART5_BASE, .tx_gpio = GPIO_UART5_TX, .rx_gpio = GPIO_UART5_RX, -#ifdef GPIO_UART5_CTS - .cts_gpio = GPIO_UART5_CTS, +#ifdef CONFIG_SERIAL_OFLOWCONROL + .cts_gpio = 0, #endif -#ifdef GPIO_UART5_RTS - .rts_gpio = GPIO_UART5_RTS, +#ifdef CONFIG_SERIAL_IFLOWCONROL + .rts_gpio = 0, #endif #ifdef CONFIG_UART5_RXDMA .rxdma_channel = DMAMAP_UART5_RX, @@ -792,15 +838,21 @@ static struct up_dev_s g_usart6priv = .parity = CONFIG_USART6_PARITY, .bits = CONFIG_USART6_BITS, .stopbits2 = CONFIG_USART6_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif .baud = CONFIG_USART6_BAUD, .apbclock = STM32_PCLK2_FREQUENCY, .usartbase = STM32_USART6_BASE, .tx_gpio = GPIO_USART6_TX, .rx_gpio = GPIO_USART6_RX, -#ifdef GPIO_USART6_CTS +#if defined(CONFIG_SERIAL_OFLOWCONROL) && defined(CONFIG_USART6_OFLOWCONTROL) .cts_gpio = GPIO_USART6_CTS, #endif -#ifdef GPIO_USART6_RTS +#if defined(CONFIG_SERIAL_IFLOWCONROL) && defined(CONFIG_USART6_IFLOWCONTROL) .rts_gpio = GPIO_USART6_RTS, #endif #ifdef CONFIG_USART6_RXDMA @@ -857,10 +909,10 @@ static struct up_dev_s g_uart7priv = .usartbase = STM32_UART7_BASE, .tx_gpio = GPIO_UART7_TX, .rx_gpio = GPIO_UART7_RX, -#ifdef GPIO_UART7_CTS +#if defined(CONFIG_SERIAL_OFLOWCONROL) && defined(CONFIG_USART7_OFLOWCONTROL) .cts_gpio = GPIO_UART7_CTS, #endif -#ifdef GPIO_UART7_RTS +#if defined(CONFIG_SERIAL_IFLOWCONROL) && defined(CONFIG_USART7_IFLOWCONTROL) .rts_gpio = GPIO_UART7_RTS, #endif #ifdef CONFIG_UART7_RXDMA @@ -917,10 +969,10 @@ static struct up_dev_s g_uart8priv = .usartbase = STM32_UART8_BASE, .tx_gpio = GPIO_UART8_TX, .rx_gpio = GPIO_UART8_RX, -#ifdef GPIO_UART8_CTS +#if defined(CONFIG_SERIAL_OFLOWCONROL) && defined(CONFIG_USART8_OFLOWCONTROL) .cts_gpio = GPIO_UART8_CTS, #endif -#ifdef GPIO_UART8_RTS +#if defined(CONFIG_SERIAL_IFLOWCONROL) && defined(CONFIG_USART8_IFLOWCONTROL) .rts_gpio = GPIO_UART8_RTS, #endif #ifdef CONFIG_UART8_RXDMA @@ -1091,23 +1143,24 @@ static int up_dma_nextrx(struct up_dev_s *priv) #endif /**************************************************************************** - * Name: up_setspeed + * Name: up_set_format * * Description: - * Set the serial line speed. + * Set the serial line format and speed. * ****************************************************************************/ #ifndef CONFIG_SUPPRESS_UART_CONFIG -static void up_setspeed(struct uart_dev_s *dev) +static void up_set_format(struct uart_dev_s *dev) { -#ifdef CONFIG_STM32_STM32F30XX + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint32_t regval; +#ifdef CONFIG_STM32_STM32F30XX /* This first implementation is for U[S]ARTs that support oversampling * by 8 in additional to the standard oversampling by 16. */ - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; uint32_t usartdiv8; uint32_t cr1; uint32_t brr; @@ -1163,7 +1216,6 @@ static void up_setspeed(struct uart_dev_s *dev) * dividers. */ - struct up_dev_s *priv = (struct up_dev_s*)dev->priv; uint32_t usartdiv32; uint32_t mantissa; uint32_t fraction; @@ -1197,10 +1249,60 @@ static void up_setspeed(struct uart_dev_s *dev) fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1; brr |= fraction << USART_BRR_FRAC_SHIFT; up_serialout(priv, STM32_USART_BRR_OFFSET, brr); +#endif + + /* Configure parity mode */ + + regval = up_serialin(priv, STM32_USART_CR1_OFFSET); + regval &= ~(USART_CR1_PCE|USART_CR1_PS); + + if (priv->parity == 1) /* Odd parity */ + { + regval |= (USART_CR1_PCE|USART_CR1_PS); + } + else if (priv->parity == 2) /* Even parity */ + { + regval |= USART_CR1_PCE; + } + + up_serialout(priv, STM32_USART_CR1_OFFSET, regval); + + /* Configure STOP bits */ + + regval = up_serialin(priv, STM32_USART_CR2_OFFSET); + regval &= ~(USART_CR2_STOP_MASK); + + if (priv->stopbits2) + { + regval |= USART_CR2_STOP2; + } + + up_serialout(priv, STM32_USART_CR2_OFFSET, regval); + + /* Configure hardware flow control */ + + regval = up_serialin(priv, STM32_USART_CR3_OFFSET); + regval &= ~(USART_CR3_CTSE|USART_CR3_RTSE); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow && (priv->rts_gpio != 0)) + { + regval |= USART_CR3_RTSE; + } +#endif + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->oflow && (priv->cts_gpio != 0)) + { + regval |= USART_CR3_CTSE; + } +#endif + + up_serialout(priv, STM32_USART_CR3_OFFSET, regval); #endif } -#endif +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ /**************************************************************************** * Name: up_setup @@ -1227,15 +1329,19 @@ static int up_setup(struct uart_dev_s *dev) stm32_configgpio(priv->tx_gpio); stm32_configgpio(priv->rx_gpio); +#ifdef CONFIG_SERIAL_OFLOWCONROL if (priv->cts_gpio != 0) { stm32_configgpio(priv->cts_gpio); } +#endif +#ifdef CONFIG_SERIAL_IFLOWCONROL if (priv->rts_gpio != 0) { stm32_configgpio(priv->rts_gpio); } +#endif #if HAVE_RS485 if (priv->rs485_dir_gpio != 0) @@ -1262,28 +1368,18 @@ static int up_setup(struct uart_dev_s *dev) up_serialout(priv, STM32_USART_CR2_OFFSET, regval); /* Configure CR1 */ - /* Clear M, PCE, PS, TE, REm and all interrupt enable bits */ + /* Clear M, TE, REm and all interrupt enable bits */ regval = up_serialin(priv, STM32_USART_CR1_OFFSET); - regval &= ~(USART_CR1_M|USART_CR1_PCE|USART_CR1_PS|USART_CR1_TE| - USART_CR1_RE|USART_CR1_ALLINTS); + regval &= ~(USART_CR1_M|USART_CR1_TE|USART_CR1_RE|USART_CR1_ALLINTS); - /* Configure word length and parity mode */ + /* Configure word length */ if (priv->bits == 9) /* Default: 1 start, 8 data, n stop */ { regval |= USART_CR1_M; /* 1 start, 9 data, n stop */ } - if (priv->parity == 1) /* Odd parity */ - { - regval |= (USART_CR1_PCE|USART_CR1_PS); - } - else if (priv->parity == 2) /* Even parity */ - { - regval |= USART_CR1_PCE; - } - up_serialout(priv, STM32_USART_CR1_OFFSET, regval); /* Configure CR3 */ @@ -1292,13 +1388,11 @@ static int up_setup(struct uart_dev_s *dev) regval = up_serialin(priv, STM32_USART_CR3_OFFSET); regval &= ~(USART_CR3_CTSIE|USART_CR3_CTSE|USART_CR3_RTSE|USART_CR3_EIE); - /* Configure hardware flow control -- Not yet supported */ - up_serialout(priv, STM32_USART_CR3_OFFSET, regval); - /* Configure the USART Baud Rate. */ + /* Configure the USART line format and speed. */ - up_setspeed(dev); + up_set_format(dev); /* Enable Rx, Tx, and the USART */ @@ -1306,8 +1400,6 @@ static int up_setup(struct uart_dev_s *dev) regval |= (USART_CR1_UE|USART_CR1_TE|USART_CR1_RE); up_serialout(priv, STM32_USART_CR1_OFFSET, regval); -#endif - /* Set up the cached interrupt enables value */ priv->ie = 0; @@ -1333,7 +1425,7 @@ static int up_dma_setup(struct uart_dev_s *dev) /* Do the basic UART setup first, unless we are the console */ if (!dev->isconsole) - { + { result = up_setup(dev); if (result != OK) { @@ -1665,7 +1757,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) up_serialout(priv, STM32_USART_CR3_OFFSET, cr); } - break; + break; #endif #ifdef CONFIG_SERIAL_TERMIOS @@ -1679,12 +1771,25 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) break; } - /* TODO: Other termios fields are not yet returned. - * Note that only cfsetospeed is not necessary because we have - * knowledge that only one speed is supported. + cfsetispeed(termiosp, priv->baud); + + /* Note that since we only support 8/9 bit modes and + * there is no way to report 9-bit mode, we always claim 8. */ - cfsetispeed(termiosp, priv->baud); + termiosp->c_cflag = + ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0) | + ((priv->stopbits2) ? CSTOPB : 0) | +#ifdef CONFIG_SERIAL_OFLOWCONTROL + ((priv->oflow) ? CCTS_OFLOW : 0) | +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + ((priv->iflow) ? CRTS_IFLOW : 0) | +#endif + CS8; + + /* TODO: CCTS_IFLOW, CCTS_OFLOW */ } break; @@ -1698,16 +1803,57 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) break; } - /* TODO: Handle other termios settings. - * Note that only cfgetispeed is used besued we have knowledge + /* Perform some sanity checks before accepting any changes */ + + if (((termiosp->c_cflag & CSIZE) != CS8) +#ifdef CONFIG_SERIAL_IFLOWCONROL + || ((termiosp->c_cflag & CCTS_OFLOW) && (priv->cts_gpio == 0)) +#endif +#ifdef CONFIG_SERIAL_IFLOWCONROL + || ((termiosp->c_cflag & CRTS_IFLOW) && (priv->rts_gpio == 0)) +#endif + ) + { + ret = -EINVAL; + break; + } + + if (termiosp->c_cflag & PARENB) + { + priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + priv->parity = 0; + } + + priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; +#ifdef CONFIG_SERIAL_OFLOWCONTROL + priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0; +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0; +#endif + + /* Note that since there is no way to request 9-bit mode + * and no way to support 5/6/7-bit modes, we ignore them + * all here. + */ + + /* Note that only cfgetispeed is used because we have knowledge * that only one speed is supported. */ priv->baud = cfgetispeed(termiosp); - up_setspeed(dev); + + /* effect the changes immediately - note that we do not implement + * TCSADRAIN / TCSAFLUSH + */ + + up_set_format(dev); } break; -#endif +#endif /* CONFIG_SERIAL_TERMIOS */ #ifdef CONFIG_USART_BREAKS case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */