Skip to content

Commit

Permalink
[BACKPORT] Merged in bkueng/nuttx/uart_invert_ioctl_kinetis (pull req…
Browse files Browse the repository at this point in the history
…uest #937)

kinetis: add uart signal inversion support

Approved-by: Gregory Nutt <gnutt@nuttx.org>
  • Loading branch information
bkueng committed Jul 9, 2019
1 parent b3a14ce commit a6f5881
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 13 deletions.
8 changes: 8 additions & 0 deletions arch/arm/src/kinetis/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
60 changes: 47 additions & 13 deletions arch/arm/src/kinetis/kinetis_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit a6f5881

Please sign in to comment.