imxrt:serial support single-wire mode

This commit is contained in:
David Sidrane
2020-12-03 06:11:22 -08:00
committed by Brennan Ashton
parent 4aa7ba827b
commit b73026ee55
2 changed files with 85 additions and 27 deletions
+8
View File
@@ -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"
+77 -27
View File
@@ -1,35 +1,20 @@
/****************************************************************************
* arch/arm/src/imxrt/imxrt_serial.c
*
* Copyright (C) 2018, 2019 Gregory Nutt. All rights reserved.
* Author: Ivan Ucherdzhiev <ivanucherdjiev@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:
{