From a6f5881ea851383877b92b0b6fed1ba9ff9825d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Fri, 5 Jul 2019 14:24:52 +0000 Subject: [PATCH] [BACKPORT] Merged in bkueng/nuttx/uart_invert_ioctl_kinetis (pull request #937) kinetis: add uart signal inversion support Approved-by: Gregory Nutt --- arch/arm/src/kinetis/Kconfig | 8 ++++ arch/arm/src/kinetis/kinetis_serial.c | 60 +++++++++++++++++++++------ 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/arch/arm/src/kinetis/Kconfig b/arch/arm/src/kinetis/Kconfig index 0ca9414a269..cdc06651604 100644 --- a/arch/arm/src/kinetis/Kconfig +++ b/arch/arm/src/kinetis/Kconfig @@ -1059,6 +1059,14 @@ config KINETIS_UART_SINGLEWIRE Enable single wire UART and LPUART support. The option enables support for the TIOCSSINGLEWIRE ioctl in the Kinetis serial drivers. +config KINETIS_UART_INVERT + bool "Signal Invert Support" + default n + depends on KINETIS_UART || KINETIS_LPUART + ---help--- + Enable signal inversion UART support. The option enables support for the + TIOCSINVERT ioctl in the Kinetis serial driver. + endif # KINETIS_SERIALDRIVER || OTHER_SERIALDRIVER config KINETIS_UARTFIFOS diff --git a/arch/arm/src/kinetis/kinetis_serial.c b/arch/arm/src/kinetis/kinetis_serial.c index 58c4b575b93..51dab8f4108 100644 --- a/arch/arm/src/kinetis/kinetis_serial.c +++ b/arch/arm/src/kinetis/kinetis_serial.c @@ -1267,30 +1267,21 @@ static int up_interrupts(int irq, void *context, FAR void *arg) static int up_ioctl(struct file *filep, int cmd, unsigned long arg) { -#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) || \ - defined(CONFIG_KINETIS_SERIALBRK_BSDCOMPAT) - struct inode *inode; - struct uart_dev_s *dev; - uint8_t regval; -#endif #if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_KINETIS_SERIALBRK_BSDCOMPAT) - struct up_dev_s *priv; bool iflow = false; bool oflow = false; #endif + struct inode *inode; + struct uart_dev_s *dev; + uint8_t regval; + struct up_dev_s *priv; int ret = OK; -#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) || \ - defined(CONFIG_KINETIS_SERIALBRK_BSDCOMPAT) DEBUGASSERT(filep != NULL && filep->f_inode != NULL); inode = filep->f_inode; dev = inode->i_private; DEBUGASSERT(dev != NULL && dev->priv != NULL); -#endif - -#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_KINETIS_SERIALBRK_BSDCOMPAT) priv = (struct up_dev_s *)dev->priv; -#endif switch (cmd) { @@ -1501,11 +1492,54 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) break; #endif /* CONFIG_KINETIS_UART_BREAKS */ +#ifdef CONFIG_KINETIS_UART_INVERT + case TIOCSINVERT: + { + uint8_t s2; + uint8_t c3; + irqstate_t flags; + + flags = enter_critical_section(); + + s2 = up_serialin(priv, KINETIS_UART_S2_OFFSET); + c3 = up_serialin(priv, KINETIS_UART_C3_OFFSET); + + /* {R|T}XINV bit fields can written any time */ + + if (arg & SER_INVERT_ENABLED_RX) + { + s2 |= UART_S2_RXINV; + } + else + { + s2 &= ~UART_S2_RXINV; + } + + if (arg & SER_INVERT_ENABLED_TX) + { + c3 |= UART_C3_TXINV; + } + else + { + c3 &= ~UART_C3_TXINV; + } + + up_serialout(priv, KINETIS_UART_S2_OFFSET, s2); + up_serialout(priv, KINETIS_UART_C3_OFFSET, c3); + + leave_critical_section(flags); + } + break; +#endif + default: ret = -ENOTTY; break; } + UNUSED(regval); + UNUSED(priv); + return ret; }