From 3c423e7dff566512144a1ce15501512ad5426360 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 8 May 2014 09:00:33 -0600 Subject: Add serial method so that lower half driver can provide RX flow control information. From Jussi Kivilinna --- nuttx/Documentation/NuttxPortingGuide.html | 5 +- nuttx/arch/arm/src/a1x/a1x_serial.c | 3 + nuttx/arch/arm/src/c5471/c5471_serial.c | 3 + nuttx/arch/arm/src/calypso/calypso_serial.c | 3 + nuttx/arch/arm/src/dm320/dm320_serial.c | 3 + nuttx/arch/arm/src/imx/imx_serial.c | 3 + nuttx/arch/arm/src/kinetis/kinetis_serial.c | 3 + nuttx/arch/arm/src/kl/kl_serial.c | 3 + nuttx/arch/arm/src/lpc17xx/lpc17_serial.c | 3 + nuttx/arch/arm/src/lpc214x/lpc214x_serial.c | 3 + nuttx/arch/arm/src/lpc2378/lpc23xx_serial.c | 3 + nuttx/arch/arm/src/lpc31xx/lpc31_serial.c | 3 + nuttx/arch/arm/src/lpc43xx/lpc43_serial.c | 3 + nuttx/arch/arm/src/nuc1xx/nuc_serial.c | 3 + nuttx/arch/arm/src/sam34/sam_serial.c | 3 + nuttx/arch/arm/src/sama5/sam_dbgu.c | 3 + nuttx/arch/arm/src/sama5/sam_serial.c | 3 + nuttx/arch/arm/src/samd/sam_serial.c | 3 + nuttx/arch/arm/src/stm32/stm32_serial.c | 186 +++++++++++++++++++++++---- nuttx/arch/arm/src/str71x/str71x_serial.c | 3 + nuttx/arch/arm/src/tiva/tiva_serial.c | 3 + nuttx/arch/avr/src/at32uc3/at32uc3_serial.c | 3 + nuttx/arch/avr/src/at90usb/at90usb_serial.c | 5 +- nuttx/arch/avr/src/atmega/atmega_serial.c | 3 + nuttx/arch/hc/src/m9s12/m9s12_serial.c | 3 + nuttx/arch/mips/src/pic32mx/pic32mx-serial.c | 3 + nuttx/arch/rgmp/src/x86/com.c | 3 + nuttx/arch/sh/src/m16c/m16c_serial.c | 3 + nuttx/arch/sh/src/sh1/sh1_serial.c | 3 + nuttx/arch/z16/src/z16f/z16f_serial.c | 3 + nuttx/arch/z80/src/ez80/ez80_serial.c | 3 + nuttx/arch/z80/src/z180/z180_scc.c | 3 + nuttx/arch/z80/src/z8/z8_serial.c | 3 + nuttx/configs/xtrs/src/xtr_serial.c | 3 + nuttx/configs/z80sim/src/z80_serial.c | 3 + nuttx/drivers/serial/serialirq.c | 23 +++- nuttx/drivers/serial/uart_16550.c | 3 + nuttx/drivers/usbdev/cdcacm.c | 3 + nuttx/drivers/usbdev/pl2303.c | 3 + nuttx/include/nuttx/serial/serial.h | 11 ++ 40 files changed, 305 insertions(+), 30 deletions(-) (limited to 'nuttx') diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html index dad21f6cd..ee7913447 100644 --- a/nuttx/Documentation/NuttxPortingGuide.html +++ b/nuttx/Documentation/NuttxPortingGuide.html @@ -12,7 +12,7 @@

NuttX RTOS Porting Guide

-

Last Updated: January 25, 2014

+

Last Updated: May 8, 2014

@@ -3059,6 +3059,9 @@ void board_led_off(int led); int receive(FAR struct uart_dev_s *dev, unsigned int *status);
void rxint(FAR struct uart_dev_s *dev, bool enable);
bool rxavailable(FAR struct uart_dev_s *dev);
+ #ifdef CONFIG_SERIAL_IFLOWCONTROL
+ bool rxflowcontrol(FAR struct uart_dev_s *dev);
+ #endif
void send(FAR struct uart_dev_s *dev, int ch);
void txint(FAR struct uart_dev_s *dev, bool enable);
bool txready(FAR struct uart_dev_s *dev);
diff --git a/nuttx/arch/arm/src/a1x/a1x_serial.c b/nuttx/arch/arm/src/a1x/a1x_serial.c index 1c93fb1a2..d2cc36642 100644 --- a/nuttx/arch/arm/src/a1x/a1x_serial.c +++ b/nuttx/arch/arm/src/a1x/a1x_serial.c @@ -157,6 +157,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/c5471/c5471_serial.c b/nuttx/arch/arm/src/c5471/c5471_serial.c index b993ee8bc..f1b9f7b70 100644 --- a/nuttx/arch/arm/src/c5471/c5471_serial.c +++ b/nuttx/arch/arm/src/c5471/c5471_serial.c @@ -133,6 +133,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/calypso/calypso_serial.c b/nuttx/arch/arm/src/calypso/calypso_serial.c index ddb37201d..d3f9cf590 100644 --- a/nuttx/arch/arm/src/calypso/calypso_serial.c +++ b/nuttx/arch/arm/src/calypso/calypso_serial.c @@ -147,6 +147,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/dm320/dm320_serial.c b/nuttx/arch/arm/src/dm320/dm320_serial.c index daf711d69..be74e227f 100644 --- a/nuttx/arch/arm/src/dm320/dm320_serial.c +++ b/nuttx/arch/arm/src/dm320/dm320_serial.c @@ -114,6 +114,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/imx/imx_serial.c b/nuttx/arch/arm/src/imx/imx_serial.c index d5423ff4a..b5939fad7 100644 --- a/nuttx/arch/arm/src/imx/imx_serial.c +++ b/nuttx/arch/arm/src/imx/imx_serial.c @@ -136,6 +136,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/kinetis/kinetis_serial.c b/nuttx/arch/arm/src/kinetis/kinetis_serial.c index 4cf414fd6..5446ffe80 100644 --- a/nuttx/arch/arm/src/kinetis/kinetis_serial.c +++ b/nuttx/arch/arm/src/kinetis/kinetis_serial.c @@ -280,6 +280,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/kl/kl_serial.c b/nuttx/arch/arm/src/kl/kl_serial.c index 2622e0db0..262167e1f 100644 --- a/nuttx/arch/arm/src/kl/kl_serial.c +++ b/nuttx/arch/arm/src/kl/kl_serial.c @@ -196,6 +196,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_serial.c b/nuttx/arch/arm/src/lpc17xx/lpc17_serial.c index 7c0f0e04a..86e5b2187 100644 --- a/nuttx/arch/arm/src/lpc17xx/lpc17_serial.c +++ b/nuttx/arch/arm/src/lpc17xx/lpc17_serial.c @@ -129,6 +129,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_serial.c b/nuttx/arch/arm/src/lpc214x/lpc214x_serial.c index 5df5264fe..214eb0347 100644 --- a/nuttx/arch/arm/src/lpc214x/lpc214x_serial.c +++ b/nuttx/arch/arm/src/lpc214x/lpc214x_serial.c @@ -113,6 +113,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/lpc2378/lpc23xx_serial.c b/nuttx/arch/arm/src/lpc2378/lpc23xx_serial.c index dcd630eee..17b6bc0b2 100644 --- a/nuttx/arch/arm/src/lpc2378/lpc23xx_serial.c +++ b/nuttx/arch/arm/src/lpc2378/lpc23xx_serial.c @@ -121,6 +121,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/lpc31xx/lpc31_serial.c b/nuttx/arch/arm/src/lpc31xx/lpc31_serial.c index 46e91aba4..e4d6941ca 100644 --- a/nuttx/arch/arm/src/lpc31xx/lpc31_serial.c +++ b/nuttx/arch/arm/src/lpc31xx/lpc31_serial.c @@ -113,6 +113,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/lpc43xx/lpc43_serial.c b/nuttx/arch/arm/src/lpc43xx/lpc43_serial.c index df68c1301..896e1f738 100644 --- a/nuttx/arch/arm/src/lpc43xx/lpc43_serial.c +++ b/nuttx/arch/arm/src/lpc43xx/lpc43_serial.c @@ -126,6 +126,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/nuc1xx/nuc_serial.c b/nuttx/arch/arm/src/nuc1xx/nuc_serial.c index ee774b9ae..25b7f6060 100644 --- a/nuttx/arch/arm/src/nuc1xx/nuc_serial.c +++ b/nuttx/arch/arm/src/nuc1xx/nuc_serial.c @@ -126,6 +126,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/sam34/sam_serial.c b/nuttx/arch/arm/src/sam34/sam_serial.c index f74d9be71..aa1e56db8 100644 --- a/nuttx/arch/arm/src/sam34/sam_serial.c +++ b/nuttx/arch/arm/src/sam34/sam_serial.c @@ -381,6 +381,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/sama5/sam_dbgu.c b/nuttx/arch/arm/src/sama5/sam_dbgu.c index f86cd89a0..919260616 100644 --- a/nuttx/arch/arm/src/sama5/sam_dbgu.c +++ b/nuttx/arch/arm/src/sama5/sam_dbgu.c @@ -116,6 +116,9 @@ static const struct uart_ops_s g_uart_ops = .receive = dbgu_receive, .rxint = dbgu_rxint, .rxavailable = dbgu_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = dbgu_send, .txint = dbgu_txint, .txready = dbgu_txready, diff --git a/nuttx/arch/arm/src/sama5/sam_serial.c b/nuttx/arch/arm/src/sama5/sam_serial.c index 4cbcf5f50..26c3b9acb 100644 --- a/nuttx/arch/arm/src/sama5/sam_serial.c +++ b/nuttx/arch/arm/src/sama5/sam_serial.c @@ -376,6 +376,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/samd/sam_serial.c b/nuttx/arch/arm/src/samd/sam_serial.c index 65092a0db..d6c448e56 100644 --- a/nuttx/arch/arm/src/samd/sam_serial.c +++ b/nuttx/arch/arm/src/samd/sam_serial.c @@ -300,6 +300,9 @@ static const struct uart_ops_s g_uart_ops = .receive = sam_receive, .rxint = sam_rxint, .rxavailable = sam_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = sam_send, .txint = sam_txint, .txready = sam_txempty, diff --git a/nuttx/arch/arm/src/stm32/stm32_serial.c b/nuttx/arch/arm/src/stm32/stm32_serial.c index ef624b870..d5333de90 100644 --- a/nuttx/arch/arm/src/stm32/stm32_serial.c +++ b/nuttx/arch/arm/src/stm32/stm32_serial.c @@ -161,7 +161,7 @@ # if defined(CONFIG_UART4_RXDMA) # ifndef CONFIG_STM32_DMA2 -# error STM32 USART4 receive DMA requires CONFIG_STM32_DMA2 +# error STM32 UART4 receive DMA requires CONFIG_STM32_DMA2 # endif # endif @@ -170,7 +170,7 @@ # define DMAMAP_USART1_RX DMACHAN_USART1_RX # define DMAMAP_USART2_RX DMACHAN_USART2_RX # define DMAMAP_USART3_RX DMACHAN_USART3_RX -# define DMAMAP_UART4_RX DMACHAN_USART4_RX +# define DMAMAP_UART4_RX DMACHAN_UART4_RX # endif @@ -326,6 +326,9 @@ static int up_receive(struct uart_dev_s *dev, uint32_t *status); static void up_rxint(struct uart_dev_s *dev, bool enable); static bool up_rxavailable(struct uart_dev_s *dev); #endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool up_rxflowcontrol(struct uart_dev_s *dev); +#endif static void up_send(struct uart_dev_s *dev, int ch); static void up_txint(struct uart_dev_s *dev, bool enable); static bool up_txready(struct uart_dev_s *dev); @@ -385,6 +388,11 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#else + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, @@ -508,21 +516,17 @@ 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, #if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART1_OFLOWCONTROL) + .oflow = true, .cts_gpio = GPIO_USART1_CTS, #endif #if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART1_IFLOWCONTROL) + .iflow = true, .rts_gpio = GPIO_USART1_RTS, #endif #ifdef CONFIG_USART1_RXDMA @@ -574,21 +578,17 @@ 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, #if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART2_OFLOWCONTROL) + .oflow = true, .cts_gpio = GPIO_USART2_CTS, #endif #if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART2_IFLOWCONTROL) + .iflow = true, .rts_gpio = GPIO_USART2_RTS, #endif #ifdef CONFIG_USART2_RXDMA @@ -640,21 +640,17 @@ 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, #if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART3_OFLOWCONTROL) + .oflow = true, .cts_gpio = GPIO_USART3_CTS, #endif #if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART3_IFLOWCONTROL) + .iflow = true, .rts_gpio = GPIO_USART3_RTS, #endif #ifdef CONFIG_USART3_RXDMA @@ -838,21 +834,17 @@ 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, #if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART6_OFLOWCONTROL) + .oflow = true, .cts_gpio = GPIO_USART6_CTS, #endif #if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART6_IFLOWCONTROL) + .iflow = true, .rts_gpio = GPIO_USART6_RTS, #endif #ifdef CONFIG_USART6_RXDMA @@ -910,9 +902,11 @@ static struct up_dev_s g_uart7priv = .tx_gpio = GPIO_UART7_TX, .rx_gpio = GPIO_UART7_RX, #if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART7_OFLOWCONTROL) + .oflow = true, .cts_gpio = GPIO_UART7_CTS, #endif #if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART7_IFLOWCONTROL) + .iflow = true, .rts_gpio = GPIO_UART7_RTS, #endif #ifdef CONFIG_UART7_RXDMA @@ -970,9 +964,11 @@ static struct up_dev_s g_uart8priv = .tx_gpio = GPIO_UART8_TX, .rx_gpio = GPIO_UART8_RX, #if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART8_OFLOWCONTROL) + .oflow = true, .cts_gpio = GPIO_UART8_CTS, #endif #if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART8_IFLOWCONTROL) + .iflow = true, .rts_gpio = GPIO_UART8_RTS, #endif #ifdef CONFIG_UART8_RXDMA @@ -1308,6 +1304,92 @@ static void up_set_format(struct uart_dev_s *dev) } #endif /* CONFIG_SUPPRESS_UART_CONFIG */ +/**************************************************************************** + * Name: up_set_apb_clock + * + * Description: + * Enable or disable APB clock for the USART peripheral + * + * Input parameters: + * dev - A reference to the UART driver state structure + * on - Enable clock if 'on' is 'true' and disable if 'false' + * + ****************************************************************************/ + +static void up_set_apb_clock(struct uart_dev_s *dev, bool on) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint32_t rcc_en; + uint32_t regaddr; + + /* Determine which USART to configure */ + + switch (priv->usartbase) + { + default: + return; +#ifdef CONFIG_STM32_USART1 + case STM32_USART1_BASE: + rcc_en = RCC_APB2ENR_USART1EN; + regaddr = STM32_RCC_APB2ENR; + break; +#endif +#ifdef CONFIG_STM32_USART2 + case STM32_USART2_BASE: + rcc_en = RCC_APB1ENR_USART2EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32_USART3 + case STM32_USART3_BASE: + rcc_en = RCC_APB1ENR_USART3EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32_UART4 + case STM32_UART4_BASE: + rcc_en = RCC_APB1ENR_UART4EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32_UART5 + case STM32_UART5_BASE: + rcc_en = RCC_APB1ENR_UART5EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32_USART6 + case STM32_USART6_BASE: + rcc_en = RCC_APB2ENR_USART6EN; + regaddr = STM32_RCC_APB2ENR; + break; +#endif +#ifdef CONFIG_STM32_UART7 + case STM32_UART7_BASE: + rcc_en = RCC_APB1ENR_USART5EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif +#ifdef CONFIG_STM32_UART8 + case STM32_UART8_BASE: + rcc_en = RCC_APB1ENR_USART5EN; + regaddr = STM32_RCC_APB1ENR; + break; +#endif + } + + /* Enable/disable APB 1/2 clock for USART */ + + if (on) + { + modifyreg32(regaddr, 0, rcc_en); + } + else + { + modifyreg32(regaddr, rcc_en, 0); + } +} + /**************************************************************************** * Name: up_setup * @@ -1328,6 +1410,10 @@ static int up_setup(struct uart_dev_s *dev) * was enabled in stm32_lowsetup(). */ + /* Enable USART APB1/2 clock */ + + up_set_apb_clock(dev, true); + /* Configure pins for USART use */ stm32_configgpio(priv->tx_gpio); @@ -1404,6 +1490,8 @@ 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 /* CONFIG_SUPPRESS_UART_CONFIG */ + /* Set up the cached interrupt enables value */ priv->ie = 0; @@ -1490,6 +1578,10 @@ static void up_shutdown(struct uart_dev_s *dev) up_disableusartint(priv, NULL); + /* Disable USART APB1/2 clock */ + + up_set_apb_clock(dev, false); + /* Disable Rx, Tx, and the UART */ regval = up_serialin(priv, STM32_USART_CR1_OFFSET); @@ -2006,6 +2098,46 @@ static bool up_rxavailable(struct uart_dev_s *dev) } #endif +/**************************************************************************** + * Name: up_rxflowcontrol + * + * Description: + * Called when Rx buffer is full. Return true if the Rx interrupt was + * disabled. + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool up_rxflowcontrol(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint16_t ie; + + if (priv->iflow) + { + /* Disable Rx interrupt to prevent more data being from peripheral. + * When hardware RTS is enabled, this will prevent more data from + * coming in. + * + * This function is only called when UART recv buffer is full, that + * is: "dev->recv.head + 1 == dev->recv.tail". + * + * Logic in "uart_read" will automatically toggle Rx interrupts when + * buffer is read empty and thus we do not have to re-enable Rx + * interrupts in any other place. + */ + + ie = priv->ie; + ie &= ~USART_CR1_RXNEIE; + up_restoreusartint(priv, ie); + + return true; + } + + return false; +} +#endif + /**************************************************************************** * Name: up_dma_receive * @@ -2568,6 +2700,8 @@ void stm32_serial_dma_poll(void) * ****************************************************************************/ +#ifdef USE_SERIALDRIVER + int up_putc(int ch) { #if CONSOLE_UART > 0 diff --git a/nuttx/arch/arm/src/str71x/str71x_serial.c b/nuttx/arch/arm/src/str71x/str71x_serial.c index a3351eb5f..d4599574d 100644 --- a/nuttx/arch/arm/src/str71x/str71x_serial.c +++ b/nuttx/arch/arm/src/str71x/str71x_serial.c @@ -279,6 +279,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/arm/src/tiva/tiva_serial.c b/nuttx/arch/arm/src/tiva/tiva_serial.c index c14edfad0..868976b8a 100644 --- a/nuttx/arch/arm/src/tiva/tiva_serial.c +++ b/nuttx/arch/arm/src/tiva/tiva_serial.c @@ -344,6 +344,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/avr/src/at32uc3/at32uc3_serial.c b/nuttx/arch/avr/src/at32uc3/at32uc3_serial.c index 1ddb9901b..0425e7e04 100644 --- a/nuttx/arch/avr/src/at32uc3/at32uc3_serial.c +++ b/nuttx/arch/avr/src/at32uc3/at32uc3_serial.c @@ -184,6 +184,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/avr/src/at90usb/at90usb_serial.c b/nuttx/arch/avr/src/at90usb/at90usb_serial.c index 8d906a915..854cbb4c3 100644 --- a/nuttx/arch/avr/src/at90usb/at90usb_serial.c +++ b/nuttx/arch/avr/src/at90usb/at90usb_serial.c @@ -107,7 +107,7 @@ static bool usart1_txempty(struct uart_dev_s *dev); ****************************************************************************/ struct uart_ops_s g_uart1_ops = -{ +{O .setup = usart1_setup, .shutdown = usart1_shutdown, .attach = usart1_attach, @@ -116,6 +116,9 @@ struct uart_ops_s g_uart1_ops = .receive = usart1_receive, .rxint = usart1_rxint, .rxavailable = usart1_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = usart1_send, .txint = usart1_txint, .txready = usart1_txready, diff --git a/nuttx/arch/avr/src/atmega/atmega_serial.c b/nuttx/arch/avr/src/atmega/atmega_serial.c index ec8a9b6f5..90bb7f0d8 100644 --- a/nuttx/arch/avr/src/atmega/atmega_serial.c +++ b/nuttx/arch/avr/src/atmega/atmega_serial.c @@ -158,6 +158,9 @@ struct uart_ops_s g_usart0_ops = .receive = usart0_receive, .rxint = usart0_rxint, .rxavailable = usart0_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = usart0_send, .txint = usart0_txint, .txready = usart0_txready, diff --git a/nuttx/arch/hc/src/m9s12/m9s12_serial.c b/nuttx/arch/hc/src/m9s12/m9s12_serial.c index b83659f3f..a0ce5a5fc 100644 --- a/nuttx/arch/hc/src/m9s12/m9s12_serial.c +++ b/nuttx/arch/hc/src/m9s12/m9s12_serial.c @@ -146,6 +146,9 @@ struct uart_ops_s g_sci_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-serial.c b/nuttx/arch/mips/src/pic32mx/pic32mx-serial.c index 0a03b98a9..436a52c43 100644 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-serial.c +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-serial.c @@ -198,6 +198,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/rgmp/src/x86/com.c b/nuttx/arch/rgmp/src/x86/com.c index 5a946db52..99e970e3f 100644 --- a/nuttx/arch/rgmp/src/x86/com.c +++ b/nuttx/arch/rgmp/src/x86/com.c @@ -152,6 +152,9 @@ static struct uart_ops_s g_com_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/sh/src/m16c/m16c_serial.c b/nuttx/arch/sh/src/m16c/m16c_serial.c index b0afc22fe..4bfeb1194 100644 --- a/nuttx/arch/sh/src/m16c/m16c_serial.c +++ b/nuttx/arch/sh/src/m16c/m16c_serial.c @@ -292,6 +292,9 @@ static const struct uart_ops_s g_uart_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/sh/src/sh1/sh1_serial.c b/nuttx/arch/sh/src/sh1/sh1_serial.c index 3719e0d5f..2c8d64888 100644 --- a/nuttx/arch/sh/src/sh1/sh1_serial.c +++ b/nuttx/arch/sh/src/sh1/sh1_serial.c @@ -180,6 +180,9 @@ struct uart_ops_s g_sci_ops = .receive = up_receive, .rxint = up_rxint, .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, diff --git a/nuttx/arch/z16/src/z16f/z16f_serial.c b/nuttx/arch/z16/src/z16f/z16f_serial.c index aa3bdcb63..90fbafe9a 100644 --- a/nuttx/arch/z16/src/z16f/z16f_serial.c +++ b/nuttx/arch/z16/src/z16f/z16f_serial.c @@ -121,6 +121,9 @@ static const struct uart_ops_s g_uart_ops = z16f_receive, /* receive */ z16f_rxint, /* rxint */ z16f_rxavailable, /* rxavailable */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, /* rxflowcontrol */ +#endif z16f_send, /* send */ z16f_txint, /* txint */ z16f_txready, /* txready */ diff --git a/nuttx/arch/z80/src/ez80/ez80_serial.c b/nuttx/arch/z80/src/ez80/ez80_serial.c index 06ca2753e..f071b1e62 100644 --- a/nuttx/arch/z80/src/ez80/ez80_serial.c +++ b/nuttx/arch/z80/src/ez80/ez80_serial.c @@ -110,6 +110,9 @@ static const struct uart_ops_s g_uart_ops = ez80_receive, /* receive */ ez80_rxint, /* rxint */ ez80_rxavailable, /* rxavailable */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, /* rxflowcontrol */ +#endif ez80_send, /* send */ ez80_txint, /* txint */ ez80_txready, /* txready */ diff --git a/nuttx/arch/z80/src/z180/z180_scc.c b/nuttx/arch/z80/src/z180/z180_scc.c index 29d0c5239..d0334258f 100644 --- a/nuttx/arch/z80/src/z180/z180_scc.c +++ b/nuttx/arch/z80/src/z180/z180_scc.c @@ -114,6 +114,9 @@ static const struct uart_ops_s g_uart_ops = z180_receive, /* receive */ z180_rxint, /* rxint */ z180_rxavailable, /* rxavailable */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, /* rxflowcontrol */ +#endif z180_send, /* send */ z180_txint, /* txint */ z180_txready, /* txready */ diff --git a/nuttx/arch/z80/src/z8/z8_serial.c b/nuttx/arch/z80/src/z8/z8_serial.c index 7dcf2f258..98fa554e6 100644 --- a/nuttx/arch/z80/src/z8/z8_serial.c +++ b/nuttx/arch/z80/src/z8/z8_serial.c @@ -122,6 +122,9 @@ static const struct uart_ops_s g_uart_ops = z8_receive, /* receive */ z8_rxint, /* rxint */ z8_rxavailable, /* rxavailable */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, /* rxflowcontrol */ +#endif z8_send, /* send */ z8_txint, /* txint */ z8_txready, /* txready */ diff --git a/nuttx/configs/xtrs/src/xtr_serial.c b/nuttx/configs/xtrs/src/xtr_serial.c index d42128352..7aa99a87d 100644 --- a/nuttx/configs/xtrs/src/xtr_serial.c +++ b/nuttx/configs/xtrs/src/xtr_serial.c @@ -132,6 +132,9 @@ static const struct uart_ops_s g_uart_ops = up_receive, /* receive */ up_rxint, /* rxint */ up_rxavailable, /* rxavailable */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, /* rxflowcontrol */ +#endif up_send, /* send */ up_txint, /* txint */ up_txready, /* txready */ diff --git a/nuttx/configs/z80sim/src/z80_serial.c b/nuttx/configs/z80sim/src/z80_serial.c index 4df2e0672..7a13ea69b 100644 --- a/nuttx/configs/z80sim/src/z80_serial.c +++ b/nuttx/configs/z80sim/src/z80_serial.c @@ -97,6 +97,9 @@ static const struct uart_ops_s g_uart_ops = up_receive, /* receive */ up_rxint, /* rxint */ up_rxavailable, /* rxavailable */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, /* rxflowcontrol */ +#endif up_send, /* send */ up_txint, /* txint */ up_txready, /* txready */ diff --git a/nuttx/drivers/serial/serialirq.c b/nuttx/drivers/serial/serialirq.c index 074129aad..1c76dfe5e 100644 --- a/nuttx/drivers/serial/serialirq.c +++ b/nuttx/drivers/serial/serialirq.c @@ -153,7 +153,26 @@ void uart_recvchars(FAR uart_dev_t *dev) while (uart_rxavailable(dev)) { - char ch = uart_receive(dev, &status); + bool is_full = (nexthead == dev->recv.tail); + char ch; + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + /* Check if RX buffer is full and allow serial low-level driver to pause + * processing. This allows proper utilization of hardware flow control. + */ + + if (is_full) + { + if (uart_rxflowcontrol(dev)) + { + /* Low-level driver activated RX flow control, exit loop now. */ + + break; + } + } +#endif + + ch = uart_receive(dev, &status); /* If the RX buffer becomes full, then the serial data is discarded. This is * necessary because on most serial hardware, you must read the data in order @@ -163,7 +182,7 @@ void uart_recvchars(FAR uart_dev_t *dev) * some large internal buffering). */ - if (nexthead != dev->recv.tail) + if (!is_full) { /* Add the character to the buffer */ diff --git a/nuttx/drivers/serial/uart_16550.c b/nuttx/drivers/serial/uart_16550.c index ac025bcfa..8489cc001 100644 --- a/nuttx/drivers/serial/uart_16550.c +++ b/nuttx/drivers/serial/uart_16550.c @@ -119,6 +119,9 @@ static const struct uart_ops_s g_uart_ops = .receive = u16550_receive, .rxint = u16550_rxint, .rxavailable = u16550_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif .send = u16550_send, .txint = u16550_txint, .txready = u16550_txready, diff --git a/nuttx/drivers/usbdev/cdcacm.c b/nuttx/drivers/usbdev/cdcacm.c index df66011d9..2243c769b 100644 --- a/nuttx/drivers/usbdev/cdcacm.c +++ b/nuttx/drivers/usbdev/cdcacm.c @@ -238,6 +238,9 @@ static const struct uart_ops_s g_uartops = NULL, /* receive */ cdcuart_rxint, /* rxinit */ NULL, /* rxavailable */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, /* rxflowcontrol */ +#endif NULL, /* send */ cdcuart_txint, /* txinit */ NULL, /* txready */ diff --git a/nuttx/drivers/usbdev/pl2303.c b/nuttx/drivers/usbdev/pl2303.c index 8c36ade4c..9788734c5 100644 --- a/nuttx/drivers/usbdev/pl2303.c +++ b/nuttx/drivers/usbdev/pl2303.c @@ -401,6 +401,9 @@ static const struct uart_ops_s g_uartops = NULL, /* receive */ usbser_rxint, /* rxinit */ NULL, /* rxavailable */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, /* rxflowcontrol */ +#endif NULL, /* send */ usbser_txint, /* txinit */ NULL, /* txready */ diff --git a/nuttx/include/nuttx/serial/serial.h b/nuttx/include/nuttx/serial/serial.h index 9a3d9098a..2a32e416b 100644 --- a/nuttx/include/nuttx/serial/serial.h +++ b/nuttx/include/nuttx/serial/serial.h @@ -78,6 +78,11 @@ #define uart_send(dev,ch) dev->ops->send(dev,ch) #define uart_receive(dev,s) dev->ops->receive(dev,s) +#ifdef CONFIG_SERIAL_IFLOWCONTROL +#define uart_rxflowcontrol(dev) \ + (dev->ops->rxflowcontrol && dev->ops->rxflowcontrol(dev)) +#endif + /************************************************************************************ * Public Types ************************************************************************************/ @@ -159,6 +164,12 @@ struct uart_ops_s CODE bool (*rxavailable)(FAR struct uart_dev_s *dev); +#ifdef CONFIG_SERIAL_IFLOWCONTROL + /* Return true if UART activated RX flow control to block more incoming data. */ + + CODE bool (*rxflowcontrol)(FAR struct uart_dev_s *dev); +#endif + /* This method will send one byte on the UART */ CODE void (*send)(FAR struct uart_dev_s *dev, int ch); -- cgit v1.2.3