diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-12-27 18:58:18 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-12-27 18:58:18 -0600 |
commit | bd90f2ddfcb38af03ff369eccce76178ef42e0d0 (patch) | |
tree | 6f2b7711482b28be07fc682c462eabaebaa035f9 /nuttx/arch | |
parent | 419a64187953a1302ac16bee0125637d8f9bef8a (diff) | |
download | nuttx-bd90f2ddfcb38af03ff369eccce76178ef42e0d0.tar.gz nuttx-bd90f2ddfcb38af03ff369eccce76178ef42e0d0.tar.bz2 nuttx-bd90f2ddfcb38af03ff369eccce76178ef42e0d0.zip |
STM32 Serial: PX4 HW workarround for flaky STM32 RTS. From David Sidrane
Diffstat (limited to 'nuttx/arch')
-rw-r--r-- | nuttx/arch/arm/src/stm32/Kconfig | 10 | ||||
-rw-r--r-- | nuttx/arch/arm/src/stm32/stm32_serial.c | 39 |
2 files changed, 46 insertions, 3 deletions
diff --git a/nuttx/arch/arm/src/stm32/Kconfig b/nuttx/arch/arm/src/stm32/Kconfig index 0a3f971fc..354e1fad0 100644 --- a/nuttx/arch/arm/src/stm32/Kconfig +++ b/nuttx/arch/arm/src/stm32/Kconfig @@ -3109,6 +3109,16 @@ config SERIAL_DISABLE_REORDERING want the side effect of having all serial port names change when just the console is moved from serial to USB. +config STM32_FLOWCONTROL_BROKEN + bool "Use Software UART RTS flow control" + depends on STM32_USART + default n + ---help--- + Enable UART RTS flow control using Software. Because STM + Current STM32 have broken HW based RTS behavior (they assert + nRTS after every byte received) Enable this setting workaround + this issue by useing software based management of RTS + endmenu config STM32_USART_SINGLEWIRE diff --git a/nuttx/arch/arm/src/stm32/stm32_serial.c b/nuttx/arch/arm/src/stm32/stm32_serial.c index 4dd764c19..d0f80f7ce 100644 --- a/nuttx/arch/arm/src/stm32/stm32_serial.c +++ b/nuttx/arch/arm/src/stm32/stm32_serial.c @@ -410,6 +410,9 @@ static const struct uart_ops_s g_uart_dma_ops = .receive = up_dma_receive, .rxint = up_dma_rxint, .rxavailable = up_dma_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#endif .send = up_send, .txint = up_txint, .txready = up_txready, @@ -1294,7 +1297,7 @@ static void up_set_format(struct uart_dev_s *dev) regval = up_serialin(priv, STM32_USART_CR3_OFFSET); regval &= ~(USART_CR3_CTSE|USART_CR3_RTSE); -#ifdef CONFIG_SERIAL_IFLOWCONTROL +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && !defined(CONFIG_STM32_FLOWCONTROL_BROKEN) if (priv->iflow && (priv->rts_gpio != 0)) { regval |= USART_CR3_RTSE; @@ -1437,8 +1440,15 @@ static int up_setup(struct uart_dev_s *dev) #ifdef CONFIG_SERIAL_IFLOWCONTROL if (priv->rts_gpio != 0) { - stm32_configgpio(priv->rts_gpio); - } + uint32_t config = priv->rts_gpio; + +#ifdef CONFIG_STM32_FLOWCONTROL_BROKEN + /* Instead of letting hw manage this pin, we will bitbang */ + + config = (config & ~GPIO_MODE_MASK) | GPIO_OUTPUT; +#endif + stm32_configgpio(config); + } #endif #if HAVE_RS485 @@ -2140,6 +2150,18 @@ static bool up_rxavailable(struct uart_dev_s *dev) * Return true if UART activated RX flow control to block more incoming * data * + * Input parameters: + * dev - UART device instance + * nbuffered - the number of characters currently buffered + * (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is + * not defined the value will be 0 for an empty buffer or the + * defined buffer size for a full buffer) + * upper - true indicates the upper watermark was crossed where + * false indicates the lower watermark has been crossed + * + * Returned Value: + * true if RX flow control activated. + * ****************************************************************************/ #ifdef CONFIG_SERIAL_IFLOWCONTROL @@ -2149,6 +2171,16 @@ static bool up_rxflowcontrol(struct uart_dev_s *dev, struct up_dev_s *priv = (struct up_dev_s*)dev->priv; uint16_t ie; +#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) && defined(CONFIG_STM32_FLOWCONTROL_BROKEN) + if (priv->iflow && (priv->rts_gpio != 0)) + { + /* Assert/de-assert nRTS set it high resume/stop sending */ + + stm32_gpiowrite(priv->rts_gpio, upper); + return upper; + } + +#else if (priv->iflow) { /* Is the RX buffer full? */ @@ -2185,6 +2217,7 @@ static bool up_rxflowcontrol(struct uart_dev_s *dev, up_rxint(dev, true); } } +#endif return false; } |