summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-12-27 18:58:18 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-12-27 18:58:18 -0600
commitbd90f2ddfcb38af03ff369eccce76178ef42e0d0 (patch)
tree6f2b7711482b28be07fc682c462eabaebaa035f9 /nuttx
parent419a64187953a1302ac16bee0125637d8f9bef8a (diff)
downloadnuttx-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')
-rw-r--r--nuttx/arch/arm/src/stm32/Kconfig10
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_serial.c39
-rw-r--r--nuttx/drivers/serial/Kconfig3
-rw-r--r--nuttx/include/nuttx/serial/serial.h30
4 files changed, 76 insertions, 6 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;
}
diff --git a/nuttx/drivers/serial/Kconfig b/nuttx/drivers/serial/Kconfig
index e3c7856b5..65131f2b0 100644
--- a/nuttx/drivers/serial/Kconfig
+++ b/nuttx/drivers/serial/Kconfig
@@ -539,7 +539,8 @@ config SERIAL_IFLOWCONTROL_WATERMARKS
Call the "lower half" rxflowcontrol method whenever the number of
characters in the serial RX buffer falls above an upper water mark
level or below a lower watermark level. The default behavior is to
- call the rxflowcontrol method only when the RX buffer is full.
+ call the rxflowcontrol method only when the RX buffer is empty or
+ full.
if SERIAL_IFLOWCONTROL_WATERMARKS
diff --git a/nuttx/include/nuttx/serial/serial.h b/nuttx/include/nuttx/serial/serial.h
index 34eb1cc6d..710345511 100644
--- a/nuttx/include/nuttx/serial/serial.h
+++ b/nuttx/include/nuttx/serial/serial.h
@@ -1,7 +1,7 @@
/************************************************************************************
* include/nuttx/serial/serial.h
*
- * Copyright (C) 2007-2008, 2012-2013 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2008, 2012-2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -53,7 +53,7 @@
#include <nuttx/fs/fs.h>
/************************************************************************************
- * Definitions
+ * Pre-processor Definitions
************************************************************************************/
/* Maximum number of threads than can be waiting for POLL events */
@@ -62,6 +62,32 @@
# define CONFIG_SERIAL_NPOLLWAITERS 2
#endif
+/* RX flow control */
+
+#ifndef CONFIG_SERIAL_IFLOWCONTROL
+# undef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
+#endif
+
+#ifndef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
+# undef CONFIG_SERIAL_IFLOWCONTROL_LOWER_WATERMARK
+# undef CONFIG_SERIAL_IFLOWCONTROL_UPPER_WATERMARK
+#endif
+
+#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
+# ifndef CONFIG_SERIAL_IFLOWCONTROL_LOWER_WATERMARK
+# define CONFIG_SERIAL_IFLOWCONTROL_LOWER_WATERMARK 10
+# endif
+
+# ifndef CONFIG_SERIAL_IFLOWCONTROL_UPPER_WATERMARK
+# define CONFIG_SERIAL_IFLOWCONTROL_UPPER_WATERMARK 90
+# endif
+
+# if CONFIG_SERIAL_IFLOWCONTROL_LOWER_WATERMARK > \
+ CONFIG_SERIAL_IFLOWCONTROL_UPPER_WATERMARK
+# warning Lower watermark pct exceeds upper watermark pct
+# endif
+#endif
+
/* vtable access helpers */
#define uart_setup(dev) dev->ops->setup(dev)