You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by bt...@apache.org on 2020/12/04 06:43:05 UTC

[incubator-nuttx] 02/02: imxrt:serial support single-wire mode

This is an automated email from the ASF dual-hosted git repository.

btashton pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit b73026ee55569d384fbbb70171c700332fc30281
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Thu Dec 3 06:11:22 2020 -0800

    imxrt:serial support single-wire mode
---
 arch/arm/src/imxrt/Kconfig        |   8 +++
 arch/arm/src/imxrt/imxrt_serial.c | 104 ++++++++++++++++++++++++++++----------
 2 files changed, 85 insertions(+), 27 deletions(-)

diff --git a/arch/arm/src/imxrt/Kconfig b/arch/arm/src/imxrt/Kconfig
index c2657bb..4783121 100644
--- a/arch/arm/src/imxrt/Kconfig
+++ b/arch/arm/src/imxrt/Kconfig
@@ -419,6 +419,14 @@ config IMXRT_LPUART_INVERT
 		Enable signal inversion UART support. The option enables support for the
 		TIOCSINVERT ioctl in the IMXRT serial driver.
 
+config IMXRT_LPUART_SINGLEWIRE
+	bool "Single Wire Support"
+	default n
+	depends on IMXRT_HAVE_LPUART
+	---help---
+		Enable single wire UART support.  The option enables support for the
+		TIOCSSINGLEWIRE ioctl in the IMXRT serial driver.
+
 endmenu # LPUART Configuration
 
 menu "FLEXCAN Peripherals"
diff --git a/arch/arm/src/imxrt/imxrt_serial.c b/arch/arm/src/imxrt/imxrt_serial.c
index 1d713ab..2074c47 100644
--- a/arch/arm/src/imxrt/imxrt_serial.c
+++ b/arch/arm/src/imxrt/imxrt_serial.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * arch/arm/src/imxrt/imxrt_serial.c
  *
- *   Copyright (C) 2018, 2019 Gregory Nutt. All rights reserved.
- *   Author: Ivan Ucherdzhiev <iv...@gmail.com>
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -334,6 +319,9 @@ struct imxrt_uart_s
 #ifdef CONFIG_SERIAL_OFLOWCONTROL
   const uint32_t cts_gpio;  /* U[S]ART CTS GPIO pin configuration */
 #endif
+#ifdef CONFIG_IMXRT_LPUART_SINGLEWIRE
+  const uint32_t tx_gpio;   /* TX GPIO pin configuration */
+#endif
 
   uint8_t  stopbits2:1;     /* 1: Configure with 2 stop bits vs 1 */
 #ifdef CONFIG_SERIAL_IFLOWCONTROL
@@ -470,6 +458,9 @@ static struct imxrt_uart_s g_uart1priv =
    || (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART1_IFLOWCONTROL)))
   .rts_gpio     = GPIO_LPUART1_RTS,
 #endif
+#ifdef CONFIG_IMXRT_LPUART_SINGLEWIRE
+  .tx_gpio      = GPIO_LPUART1_TX,
+#endif
 
 #if (((defined(CONFIG_SERIAL_RS485CONTROL) || defined(CONFIG_SERIAL_IFLOWCONTROL))) \
     && defined(CONFIG_LPUART1_INVERTIFLOWCONTROL))
@@ -520,6 +511,9 @@ static struct imxrt_uart_s g_uart2priv =
    || (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART2_IFLOWCONTROL)))
   .rts_gpio     = GPIO_LPUART2_RTS,
 #endif
+#ifdef CONFIG_IMXRT_LPUART_SINGLEWIRE
+  .tx_gpio      = GPIO_LPUART2_TX,
+#endif
 #if (((defined(CONFIG_SERIAL_RS485CONTROL) || defined(CONFIG_SERIAL_IFLOWCONTROL))) \
     && defined(CONFIG_LPUART2_INVERTIFLOWCONTROL))
   .inviflow     = 1,
@@ -567,6 +561,9 @@ static struct imxrt_uart_s g_uart3priv =
    || (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART3_IFLOWCONTROL)))
   .rts_gpio     = GPIO_LPUART3_RTS,
 #endif
+#ifdef CONFIG_IMXRT_LPUART_SINGLEWIRE
+  .tx_gpio      = GPIO_LPUART3_TX,
+#endif
 #if (((defined(CONFIG_SERIAL_RS485CONTROL) || defined(CONFIG_SERIAL_IFLOWCONTROL))) \
     && defined(CONFIG_LPUART3_INVERTIFLOWCONTROL))
   .inviflow     = 1,
@@ -614,6 +611,9 @@ static struct imxrt_uart_s g_uart4priv =
    || (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART4_IFLOWCONTROL)))
   .rts_gpio     = GPIO_LPUART4_RTS,
 #endif
+#ifdef CONFIG_IMXRT_LPUART_SINGLEWIRE
+  .tx_gpio      = GPIO_LPUART4_TX,
+#endif
 #if (((defined(CONFIG_SERIAL_RS485CONTROL) || defined(CONFIG_SERIAL_IFLOWCONTROL))) \
     && defined(CONFIG_LPUART4_INVERTIFLOWCONTROL))
   .inviflow     = 1,
@@ -661,6 +661,9 @@ static struct imxrt_uart_s g_uart5priv =
    || (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART5_IFLOWCONTROL)))
   .rts_gpio     = GPIO_LPUART5_RTS,
 #endif
+#ifdef CONFIG_IMXRT_LPUART_SINGLEWIRE
+  .tx_gpio      = GPIO_LPUART5_TX,
+#endif
 #if (((defined(CONFIG_SERIAL_RS485CONTROL) || defined(CONFIG_SERIAL_IFLOWCONTROL))) \
     && defined(CONFIG_LPUART5_INVERTIFLOWCONTROL))
   .inviflow     = 1,
@@ -708,6 +711,9 @@ static struct imxrt_uart_s g_uart6priv =
    || (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART6_IFLOWCONTROL)))
   .rts_gpio     = GPIO_LPUART6_RTS,
 #endif
+#ifdef CONFIG_IMXRT_LPUART_SINGLEWIRE
+  .tx_gpio      = GPIO_LPUART6_TX,
+#endif
 #if (((defined(CONFIG_SERIAL_RS485CONTROL) || defined(CONFIG_SERIAL_IFLOWCONTROL))) \
     && defined(CONFIG_LPUART6_INVERTIFLOWCONTROL))
   .inviflow     = 1,
@@ -755,6 +761,9 @@ static struct imxrt_uart_s g_uart7priv =
    || (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART7_IFLOWCONTROL)))
   .rts_gpio     = GPIO_LPUART7_RTS,
 #endif
+#ifdef CONFIG_IMXRT_LPUART_SINGLEWIRE
+  .tx_gpio      = GPIO_LPUART7_TX,
+#endif
 #if (((defined(CONFIG_SERIAL_RS485CONTROL) || defined(CONFIG_SERIAL_IFLOWCONTROL))) \
     && defined(CONFIG_LPUART7_INVERTIFLOWCONTROL))
   .inviflow     = 1,
@@ -802,6 +811,9 @@ static struct imxrt_uart_s g_uart8priv =
    || (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART8_IFLOWCONTROL)))
   .rts_gpio     = GPIO_LPUART8_RTS,
 #endif
+#ifdef CONFIG_IMXRT_LPUART_SINGLEWIRE
+  .tx_gpio      = GPIO_LPUART8_TX,
+#endif
 #if (((defined(CONFIG_SERIAL_RS485CONTROL) || defined(CONFIG_SERIAL_IFLOWCONTROL))) \
     && defined(CONFIG_LPUART8_INVERTIFLOWCONTROL))
   .inviflow     = 1,
@@ -1315,6 +1327,44 @@ static int imxrt_ioctl(struct file *filep, int cmd, unsigned long arg)
       break;
 #endif /* CONFIG_SERIAL_TERMIOS */
 
+#ifdef CONFIG_IMXRT_LPUART_SINGLEWIRE
+    case TIOCSSINGLEWIRE:
+      {
+        uint32_t regval;
+        irqstate_t flags;
+        struct imxrt_uart_s *priv = (struct imxrt_uart_s *)dev->priv;
+
+        flags  = spin_lock_irqsave();
+        regval   = imxrt_serialin(priv, IMXRT_LPUART_CTRL_OFFSET);
+
+        if ((arg & SER_SINGLEWIRE_ENABLED) != 0)
+          {
+            uint32_t gpio_val = IOMUX_OPENDRAIN;
+            gpio_val |= (arg & SER_SINGLEWIRE_PULL_MASK) ==
+                         SER_SINGLEWIRE_PULLUP ?
+                                        IOMUX_PULL_UP_47K : IOMUX_PULL_NONE;
+            gpio_val |= (arg & SER_SINGLEWIRE_PULL_MASK) ==
+                         SER_SINGLEWIRE_PULLDOWN ?
+                                     IOMUX_PULL_DOWN_100K : IOMUX_PULL_NONE;
+            imxrt_config_gpio((priv->tx_gpio &
+                          ~(IOMUX_PULL_MASK | IOMUX_OPENDRAIN)) | gpio_val);
+            regval |= LPUART_CTRL_LOOPS | LPUART_CTRL_RSRC;
+          }
+        else
+          {
+            imxrt_config_gpio((priv->tx_gpio & ~(IOMUX_PULL_MASK |
+                                                 IOMUX_OPENDRAIN)) |
+                                                 IOMUX_PULL_NONE);
+            regval &= ~(LPUART_CTRL_LOOPS | LPUART_CTRL_RSRC);
+          }
+
+        imxrt_serialout(priv, IMXRT_LPUART_CTRL_OFFSET, regval);
+
+        spin_unlock_irqrestore(flags);
+      }
+      break;
+#endif
+
 #ifdef CONFIG_IMXRT_LPUART_INVERT
     case TIOCSINVERT:
       {