Add flow control support to the STM32 serial driver; Fix some issues with UART2 and 5. From Lorenz Meier and Mike Smith

This commit is contained in:
Gregory Nutt 2013-06-06 14:49:14 -06:00
parent 38c7818ea8
commit 3edec35c51
9 changed files with 831 additions and 361 deletions

View File

@ -4912,5 +4912,13 @@
logic to enabled/disable SAM4L peripheral clocking (2013-6-5). logic to enabled/disable SAM4L peripheral clocking (2013-6-5).
* nuttx/arch/arm/src/sam34/chip/sam4l_bpm.h and sam4l_scif.h: Add * nuttx/arch/arm/src/sam34/chip/sam4l_bpm.h and sam4l_scif.h: Add
register definitions for the SAM4L BMP and SCIF blocks (2013-6-6). register definitions for the SAM4L BMP and SCIF blocks (2013-6-6).
* nuttx/arch/arm/src/sam34/sam4l_clockconfig.c: New selects an * nuttx/arch/arm/src/sam34/sam4l_clockconfig.c: Now selects an
optimal power scaling mode (2013-6-6). optimal power scaling mode (2013-6-6).
* modified: nuttx/arch/arm/src/stm32/stm32_serial.c
# modified: nuttx/drivers/serial/Kconfig
# modified: nuttx/include/nuttx/serial/serial.h
# modified: nuttx/include/termios.h
A:wq\
A

View File

@ -335,20 +335,6 @@ config SERIAL_TERMIOS
If this is not defined, then the terminal settings (baud, parity, etc). If this is not defined, then the terminal settings (baud, parity, etc).
are not configurable at runtime; serial streams cannot be flushed, 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 config UART1_RINGINDICATOR
bool "UART1 ring indicator" bool "UART1 ring indicator"
depends on LPC17_UART1 depends on LPC17_UART1
@ -356,20 +342,6 @@ config UART1_RINGINDICATOR
---help--- ---help---
Enable UART1 ring indicator 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 endmenu
menu "ADC driver options" menu "ADC driver options"

View File

@ -359,7 +359,7 @@ void lpc17_lowsetup(void)
#elif defined(CONFIG_UART1_SERIAL_CONSOLE) #elif defined(CONFIG_UART1_SERIAL_CONSOLE)
lpc17_configgpio(GPIO_UART1_TXD); lpc17_configgpio(GPIO_UART1_TXD);
lpc17_configgpio(GPIO_UART1_RXD); 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_CTS);
lpc17_configgpio(GPIO_UART1_DCD); lpc17_configgpio(GPIO_UART1_DCD);
lpc17_configgpio(GPIO_UART1_DSR); lpc17_configgpio(GPIO_UART1_DSR);

View File

@ -736,7 +736,7 @@ static inline void lpc17_uart1config(void)
lpc17_configgpio(GPIO_UART1_TXD); lpc17_configgpio(GPIO_UART1_TXD);
lpc17_configgpio(GPIO_UART1_RXD); 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_CTS);
lpc17_configgpio(GPIO_UART1_RTS); lpc17_configgpio(GPIO_UART1_RTS);
lpc17_configgpio(GPIO_UART1_DCD); 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 */ /* 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 (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)); 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 #endif

View File

@ -1,7 +1,7 @@
/************************************************************************************ /************************************************************************************
* arch/arm/src/lpc17xx/lpc17_serial.h * 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 <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -96,11 +96,15 @@
/* Check UART flow control (Only supported by UART1) */ /* Check UART flow control (Only supported by UART1) */
# undef CONFIG_UART0_FLOWCONTROL # undef CONFIG_UART0_IFLOWCONTROL
# undef CONFIG_UART2_FLOWCONTROL # undef CONFIG_UART0_OFLOWCONTROL
# undef CONFIG_UART3_FLOWCONTROL # undef CONFIG_UART2_IFLOWCONTROL
# undef CONFIG_UART2_OFLOWCONTROL
# undef CONFIG_UART3_IFLOWCONTROL
# undef CONFIG_UART3_OFLOWCONTROL
#ifndef CONFIG_LPC17_UART1 #ifndef CONFIG_LPC17_UART1
# undef CONFIG_UART1_FLOWCONTROL # undef CONFIG_UART1_IFLOWCONTROL
# undef CONFIG_UART1_OFLOWCONTROL
#endif #endif
/* We cannot allow the DLM/DLL divisor to become to small or will will lose too /* We cannot allow the DLM/DLL divisor to become to small or will will lose too

View File

@ -257,11 +257,23 @@ struct up_dev_s
uint8_t parity; /* 0=none, 1=odd, 2=even */ uint8_t parity; /* 0=none, 1=odd, 2=even */
uint8_t bits; /* Number of bits (7 or 8) */ uint8_t bits; /* Number of bits (7 or 8) */
bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ 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 */ uint32_t baud; /* Configured baud */
#else #else
const uint8_t parity; /* 0=none, 1=odd, 2=even */ const uint8_t parity; /* 0=none, 1=odd, 2=even */
const uint8_t bits; /* Number of bits (7 or 8) */ const uint8_t bits; /* Number of bits (7 or 8) */
const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ 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 */ const uint32_t baud; /* Configured baud */
#endif #endif
@ -270,8 +282,12 @@ struct up_dev_s
const uint32_t usartbase; /* Base address of USART registers */ const uint32_t usartbase; /* Base address of USART registers */
const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */ const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */
const uint32_t rx_gpio; /* U[S]ART RX 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 */ 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 */ const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */
#endif
#ifdef SERIAL_HAVE_DMA #ifdef SERIAL_HAVE_DMA
const unsigned int rxdma_channel; /* DMA channel assigned */ const unsigned int rxdma_channel; /* DMA channel assigned */
@ -298,7 +314,7 @@ struct up_dev_s
* Private Function Prototypes * 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 int up_setup(struct uart_dev_s *dev);
static void up_shutdown(struct uart_dev_s *dev); static void up_shutdown(struct uart_dev_s *dev);
static int up_attach(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, .parity = CONFIG_USART1_PARITY,
.bits = CONFIG_USART1_BITS, .bits = CONFIG_USART1_BITS,
.stopbits2 = CONFIG_USART1_2STOP, .stopbits2 = CONFIG_USART1_2STOP,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
.iflow = false,
#endif
#ifdef CONFIG_SERIAL_OFLOWCONTROL
.oflow = false,
#endif
.baud = CONFIG_USART1_BAUD, .baud = CONFIG_USART1_BAUD,
.apbclock = STM32_PCLK2_FREQUENCY, .apbclock = STM32_PCLK2_FREQUENCY,
.usartbase = STM32_USART1_BASE, .usartbase = STM32_USART1_BASE,
.tx_gpio = GPIO_USART1_TX, .tx_gpio = GPIO_USART1_TX,
.rx_gpio = GPIO_USART1_RX, .rx_gpio = GPIO_USART1_RX,
#ifdef GPIO_USART1_CTS #if defined(CONFIG_SERIAL_OFLOWCONROL) && defined(CONFIG_USART1_OFLOWCONTROL)
.cts_gpio = GPIO_USART1_CTS, .cts_gpio = GPIO_USART1_CTS,
#endif #endif
#ifdef GPIO_USART1_RTS #if defined(CONFIG_SERIAL_IFLOWCONROL) && defined(CONFIG_USART1_IFLOWCONTROL)
.rts_gpio = GPIO_USART1_RTS, .rts_gpio = GPIO_USART1_RTS,
#endif #endif
#ifdef CONFIG_USART1_RXDMA #ifdef CONFIG_USART1_RXDMA
@ -552,15 +574,21 @@ static struct up_dev_s g_usart2priv =
.parity = CONFIG_USART2_PARITY, .parity = CONFIG_USART2_PARITY,
.bits = CONFIG_USART2_BITS, .bits = CONFIG_USART2_BITS,
.stopbits2 = CONFIG_USART2_2STOP, .stopbits2 = CONFIG_USART2_2STOP,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
.iflow = false,
#endif
#ifdef CONFIG_SERIAL_OFLOWCONTROL
.oflow = false,
#endif
.baud = CONFIG_USART2_BAUD, .baud = CONFIG_USART2_BAUD,
.apbclock = STM32_PCLK1_FREQUENCY, .apbclock = STM32_PCLK1_FREQUENCY,
.usartbase = STM32_USART2_BASE, .usartbase = STM32_USART2_BASE,
.tx_gpio = GPIO_USART2_TX, .tx_gpio = GPIO_USART2_TX,
.rx_gpio = GPIO_USART2_RX, .rx_gpio = GPIO_USART2_RX,
#ifdef GPIO_USART2_CTS #if defined(CONFIG_SERIAL_OFLOWCONROL) && defined(CONFIG_USART2_OFLOWCONTROL)
.cts_gpio = GPIO_USART2_CTS, .cts_gpio = GPIO_USART2_CTS,
#endif #endif
#ifdef GPIO_USART2_RTS #if defined(CONFIG_SERIAL_IFLOWCONROL) && defined(CONFIG_USART2_IFLOWCONTROL)
.rts_gpio = GPIO_USART2_RTS, .rts_gpio = GPIO_USART2_RTS,
#endif #endif
#ifdef CONFIG_USART2_RXDMA #ifdef CONFIG_USART2_RXDMA
@ -612,15 +640,21 @@ static struct up_dev_s g_usart3priv =
.parity = CONFIG_USART3_PARITY, .parity = CONFIG_USART3_PARITY,
.bits = CONFIG_USART3_BITS, .bits = CONFIG_USART3_BITS,
.stopbits2 = CONFIG_USART3_2STOP, .stopbits2 = CONFIG_USART3_2STOP,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
.iflow = false,
#endif
#ifdef CONFIG_SERIAL_OFLOWCONTROL
.oflow = false,
#endif
.baud = CONFIG_USART3_BAUD, .baud = CONFIG_USART3_BAUD,
.apbclock = STM32_PCLK1_FREQUENCY, .apbclock = STM32_PCLK1_FREQUENCY,
.usartbase = STM32_USART3_BASE, .usartbase = STM32_USART3_BASE,
.tx_gpio = GPIO_USART3_TX, .tx_gpio = GPIO_USART3_TX,
.rx_gpio = GPIO_USART3_RX, .rx_gpio = GPIO_USART3_RX,
#ifdef GPIO_USART3_CTS #if defined(CONFIG_SERIAL_OFLOWCONROL) && defined(CONFIG_USART3_OFLOWCONTROL)
.cts_gpio = GPIO_USART3_CTS, .cts_gpio = GPIO_USART3_CTS,
#endif #endif
#ifdef GPIO_USART3_RTS #if defined(CONFIG_SERIAL_IFLOWCONROL) && defined(CONFIG_USART3_IFLOWCONTROL)
.rts_gpio = GPIO_USART3_RTS, .rts_gpio = GPIO_USART3_RTS,
#endif #endif
#ifdef CONFIG_USART3_RXDMA #ifdef CONFIG_USART3_RXDMA
@ -672,16 +706,22 @@ static struct up_dev_s g_uart4priv =
.parity = CONFIG_UART4_PARITY, .parity = CONFIG_UART4_PARITY,
.bits = CONFIG_UART4_BITS, .bits = CONFIG_UART4_BITS,
.stopbits2 = CONFIG_UART4_2STOP, .stopbits2 = CONFIG_UART4_2STOP,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
.iflow = false,
#endif
#ifdef CONFIG_SERIAL_OFLOWCONTROL
.oflow = false,
#endif
.baud = CONFIG_UART4_BAUD, .baud = CONFIG_UART4_BAUD,
.apbclock = STM32_PCLK1_FREQUENCY, .apbclock = STM32_PCLK1_FREQUENCY,
.usartbase = STM32_UART4_BASE, .usartbase = STM32_UART4_BASE,
.tx_gpio = GPIO_UART4_TX, .tx_gpio = GPIO_UART4_TX,
.rx_gpio = GPIO_UART4_RX, .rx_gpio = GPIO_UART4_RX,
#ifdef GPIO_UART4_CTS #ifdef CONFIG_SERIAL_OFLOWCONROL
.cts_gpio = GPIO_UART4_CTS, .cts_gpio = 0,
#endif #endif
#ifdef GPIO_UART4_RTS #ifdef CONFIG_SERIAL_IFLOWCONROL
.rts_gpio = GPIO_UART4_RTS, .rts_gpio = 0,
#endif #endif
#ifdef CONFIG_UART4_RXDMA #ifdef CONFIG_UART4_RXDMA
.rxdma_channel = DMAMAP_UART4_RX, .rxdma_channel = DMAMAP_UART4_RX,
@ -732,16 +772,22 @@ static struct up_dev_s g_uart5priv =
.parity = CONFIG_UART5_PARITY, .parity = CONFIG_UART5_PARITY,
.bits = CONFIG_UART5_BITS, .bits = CONFIG_UART5_BITS,
.stopbits2 = CONFIG_UART5_2STOP, .stopbits2 = CONFIG_UART5_2STOP,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
.iflow = false,
#endif
#ifdef CONFIG_SERIAL_OFLOWCONTROL
.oflow = false,
#endif
.baud = CONFIG_UART5_BAUD, .baud = CONFIG_UART5_BAUD,
.apbclock = STM32_PCLK1_FREQUENCY, .apbclock = STM32_PCLK1_FREQUENCY,
.usartbase = STM32_UART5_BASE, .usartbase = STM32_UART5_BASE,
.tx_gpio = GPIO_UART5_TX, .tx_gpio = GPIO_UART5_TX,
.rx_gpio = GPIO_UART5_RX, .rx_gpio = GPIO_UART5_RX,
#ifdef GPIO_UART5_CTS #ifdef CONFIG_SERIAL_OFLOWCONROL
.cts_gpio = GPIO_UART5_CTS, .cts_gpio = 0,
#endif #endif
#ifdef GPIO_UART5_RTS #ifdef CONFIG_SERIAL_IFLOWCONROL
.rts_gpio = GPIO_UART5_RTS, .rts_gpio = 0,
#endif #endif
#ifdef CONFIG_UART5_RXDMA #ifdef CONFIG_UART5_RXDMA
.rxdma_channel = DMAMAP_UART5_RX, .rxdma_channel = DMAMAP_UART5_RX,
@ -792,15 +838,21 @@ static struct up_dev_s g_usart6priv =
.parity = CONFIG_USART6_PARITY, .parity = CONFIG_USART6_PARITY,
.bits = CONFIG_USART6_BITS, .bits = CONFIG_USART6_BITS,
.stopbits2 = CONFIG_USART6_2STOP, .stopbits2 = CONFIG_USART6_2STOP,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
.iflow = false,
#endif
#ifdef CONFIG_SERIAL_OFLOWCONTROL
.oflow = false,
#endif
.baud = CONFIG_USART6_BAUD, .baud = CONFIG_USART6_BAUD,
.apbclock = STM32_PCLK2_FREQUENCY, .apbclock = STM32_PCLK2_FREQUENCY,
.usartbase = STM32_USART6_BASE, .usartbase = STM32_USART6_BASE,
.tx_gpio = GPIO_USART6_TX, .tx_gpio = GPIO_USART6_TX,
.rx_gpio = GPIO_USART6_RX, .rx_gpio = GPIO_USART6_RX,
#ifdef GPIO_USART6_CTS #if defined(CONFIG_SERIAL_OFLOWCONROL) && defined(CONFIG_USART6_OFLOWCONTROL)
.cts_gpio = GPIO_USART6_CTS, .cts_gpio = GPIO_USART6_CTS,
#endif #endif
#ifdef GPIO_USART6_RTS #if defined(CONFIG_SERIAL_IFLOWCONROL) && defined(CONFIG_USART6_IFLOWCONTROL)
.rts_gpio = GPIO_USART6_RTS, .rts_gpio = GPIO_USART6_RTS,
#endif #endif
#ifdef CONFIG_USART6_RXDMA #ifdef CONFIG_USART6_RXDMA
@ -857,10 +909,10 @@ static struct up_dev_s g_uart7priv =
.usartbase = STM32_UART7_BASE, .usartbase = STM32_UART7_BASE,
.tx_gpio = GPIO_UART7_TX, .tx_gpio = GPIO_UART7_TX,
.rx_gpio = GPIO_UART7_RX, .rx_gpio = GPIO_UART7_RX,
#ifdef GPIO_UART7_CTS #if defined(CONFIG_SERIAL_OFLOWCONROL) && defined(CONFIG_USART7_OFLOWCONTROL)
.cts_gpio = GPIO_UART7_CTS, .cts_gpio = GPIO_UART7_CTS,
#endif #endif
#ifdef GPIO_UART7_RTS #if defined(CONFIG_SERIAL_IFLOWCONROL) && defined(CONFIG_USART7_IFLOWCONTROL)
.rts_gpio = GPIO_UART7_RTS, .rts_gpio = GPIO_UART7_RTS,
#endif #endif
#ifdef CONFIG_UART7_RXDMA #ifdef CONFIG_UART7_RXDMA
@ -917,10 +969,10 @@ static struct up_dev_s g_uart8priv =
.usartbase = STM32_UART8_BASE, .usartbase = STM32_UART8_BASE,
.tx_gpio = GPIO_UART8_TX, .tx_gpio = GPIO_UART8_TX,
.rx_gpio = GPIO_UART8_RX, .rx_gpio = GPIO_UART8_RX,
#ifdef GPIO_UART8_CTS #if defined(CONFIG_SERIAL_OFLOWCONROL) && defined(CONFIG_USART8_OFLOWCONTROL)
.cts_gpio = GPIO_UART8_CTS, .cts_gpio = GPIO_UART8_CTS,
#endif #endif
#ifdef GPIO_UART8_RTS #if defined(CONFIG_SERIAL_IFLOWCONROL) && defined(CONFIG_USART8_IFLOWCONTROL)
.rts_gpio = GPIO_UART8_RTS, .rts_gpio = GPIO_UART8_RTS,
#endif #endif
#ifdef CONFIG_UART8_RXDMA #ifdef CONFIG_UART8_RXDMA
@ -1091,23 +1143,24 @@ static int up_dma_nextrx(struct up_dev_s *priv)
#endif #endif
/**************************************************************************** /****************************************************************************
* Name: up_setspeed * Name: up_set_format
* *
* Description: * Description:
* Set the serial line speed. * Set the serial line format and speed.
* *
****************************************************************************/ ****************************************************************************/
#ifndef CONFIG_SUPPRESS_UART_CONFIG #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 /* This first implementation is for U[S]ARTs that support oversampling
* by 8 in additional to the standard oversampling by 16. * 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 usartdiv8;
uint32_t cr1; uint32_t cr1;
uint32_t brr; uint32_t brr;
@ -1163,7 +1216,6 @@ static void up_setspeed(struct uart_dev_s *dev)
* dividers. * dividers.
*/ */
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
uint32_t usartdiv32; uint32_t usartdiv32;
uint32_t mantissa; uint32_t mantissa;
uint32_t fraction; uint32_t fraction;
@ -1197,10 +1249,60 @@ static void up_setspeed(struct uart_dev_s *dev)
fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1; fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1;
brr |= fraction << USART_BRR_FRAC_SHIFT; brr |= fraction << USART_BRR_FRAC_SHIFT;
up_serialout(priv, STM32_USART_BRR_OFFSET, brr); 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 #endif /* CONFIG_SUPPRESS_UART_CONFIG */
/**************************************************************************** /****************************************************************************
* Name: up_setup * Name: up_setup
@ -1227,15 +1329,19 @@ static int up_setup(struct uart_dev_s *dev)
stm32_configgpio(priv->tx_gpio); stm32_configgpio(priv->tx_gpio);
stm32_configgpio(priv->rx_gpio); stm32_configgpio(priv->rx_gpio);
#ifdef CONFIG_SERIAL_OFLOWCONROL
if (priv->cts_gpio != 0) if (priv->cts_gpio != 0)
{ {
stm32_configgpio(priv->cts_gpio); stm32_configgpio(priv->cts_gpio);
} }
#endif
#ifdef CONFIG_SERIAL_IFLOWCONROL
if (priv->rts_gpio != 0) if (priv->rts_gpio != 0)
{ {
stm32_configgpio(priv->rts_gpio); stm32_configgpio(priv->rts_gpio);
} }
#endif
#if HAVE_RS485 #if HAVE_RS485
if (priv->rs485_dir_gpio != 0) 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); up_serialout(priv, STM32_USART_CR2_OFFSET, regval);
/* Configure CR1 */ /* 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 = up_serialin(priv, STM32_USART_CR1_OFFSET);
regval &= ~(USART_CR1_M|USART_CR1_PCE|USART_CR1_PS|USART_CR1_TE| regval &= ~(USART_CR1_M|USART_CR1_TE|USART_CR1_RE|USART_CR1_ALLINTS);
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 */ if (priv->bits == 9) /* Default: 1 start, 8 data, n stop */
{ {
regval |= USART_CR1_M; /* 1 start, 9 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); up_serialout(priv, STM32_USART_CR1_OFFSET, regval);
/* Configure CR3 */ /* Configure CR3 */
@ -1292,13 +1388,11 @@ static int up_setup(struct uart_dev_s *dev)
regval = up_serialin(priv, STM32_USART_CR3_OFFSET); regval = up_serialin(priv, STM32_USART_CR3_OFFSET);
regval &= ~(USART_CR3_CTSIE|USART_CR3_CTSE|USART_CR3_RTSE|USART_CR3_EIE); 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); 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 */ /* 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); regval |= (USART_CR1_UE|USART_CR1_TE|USART_CR1_RE);
up_serialout(priv, STM32_USART_CR1_OFFSET, regval); up_serialout(priv, STM32_USART_CR1_OFFSET, regval);
#endif
/* Set up the cached interrupt enables value */ /* Set up the cached interrupt enables value */
priv->ie = 0; 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 */ /* Do the basic UART setup first, unless we are the console */
if (!dev->isconsole) if (!dev->isconsole)
{ {
result = up_setup(dev); result = up_setup(dev);
if (result != OK) 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); up_serialout(priv, STM32_USART_CR3_OFFSET, cr);
} }
break; break;
#endif #endif
#ifdef CONFIG_SERIAL_TERMIOS #ifdef CONFIG_SERIAL_TERMIOS
@ -1679,12 +1771,25 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
break; break;
} }
/* TODO: Other termios fields are not yet returned. cfsetispeed(termiosp, priv->baud);
* Note that only cfsetospeed is not necessary because we have
* knowledge that only one speed is supported. /* 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; break;
@ -1698,16 +1803,57 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
break; break;
} }
/* TODO: Handle other termios settings. /* Perform some sanity checks before accepting any changes */
* Note that only cfgetispeed is used besued we have knowledge
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. * that only one speed is supported.
*/ */
priv->baud = cfgetispeed(termiosp); priv->baud = cfgetispeed(termiosp);
up_setspeed(dev);
/* effect the changes immediately - note that we do not implement
* TCSADRAIN / TCSAFLUSH
*/
up_set_format(dev);
} }
break; break;
#endif #endif /* CONFIG_SERIAL_TERMIOS */
#ifdef CONFIG_USART_BREAKS #ifdef CONFIG_USART_BREAKS
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */

File diff suppressed because it is too large Load Diff

View File

@ -278,7 +278,7 @@ void uart_recvchars(FAR uart_dev_t *dev);
* Name: uart_datareceived * Name: uart_datareceived
* *
* Description: * Description:
* This function is called from uart_recvchars when new serial data is place in * This function is called from uart_recvchars when new serial data is place in
* the driver's circular buffer. This function will wake-up any stalled read() * the driver's circular buffer. This function will wake-up any stalled read()
* operations that are waiting for incoming data. * operations that are waiting for incoming data.
* *

View File

@ -109,6 +109,9 @@
#define PARODD (1 << 5) /* Bit 5: Odd parity, else even */ #define PARODD (1 << 5) /* Bit 5: Odd parity, else even */
#define HUPCL (1 << 6) /* Bit 6: Hang up on last close */ #define HUPCL (1 << 6) /* Bit 6: Hang up on last close */
#define CLOCAL (1 << 7) /* Bit 7: Ignore modem status lines */ #define CLOCAL (1 << 7) /* Bit 7: Ignore modem status lines */
#define CCTS_OFLOW (1 << 8) /* Bit 8: CTS flow control of output */
#define CRTSCTS CCTS_OFLOW
#define CRTS_IFLOW (1 << 9) /* Bit 9: RTS flow control of input */
/* Local Modes (c_lflag in the termios structure) */ /* Local Modes (c_lflag in the termios structure) */