summaryrefslogtreecommitdiff
path: root/nuttx/arch
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/arch
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/arch')
-rw-r--r--nuttx/arch/arm/src/stm32/Kconfig10
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_serial.c39
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;
}