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:
{