Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BACKPORT] UART ioctl's #54

Merged
merged 2 commits into from
Jul 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions arch/arm/src/imxrt/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,19 @@ config IMXRT_LPUART8

endmenu # LPUART Peripherals

menu "LPUART Configuration"
depends on IMXRT_HAVE_LPUART

config IMXRT_LPUART_INVERT
bool "Signal Invert Support"
default n
depends on IMXRT_HAVE_LPUART
---help---
Enable signal inversion UART support. The option enables support for the
TIOCSINVERT ioctl in the IMXRT serial driver.

endmenu # LPUART Configuration

menu "LPI2C Peripherals"

menuconfig IMXRT_LPI2C1
Expand Down
47 changes: 47 additions & 0 deletions arch/arm/src/imxrt/imxrt_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,53 @@ static int imxrt_ioctl(struct file *filep, int cmd, unsigned long arg)
break;
#endif /* CONFIG_SERIAL_TERMIOS */

#ifdef CONFIG_IMXRT_LPUART_INVERT
case TIOCSINVERT:
{
uint32_t ctrl;
uint32_t stat;
uint32_t regval;
irqstate_t flags;

flags = spin_lock_irqsave();
ctrl = imxrt_serialin(priv, IMXRT_LPUART_CTRL_OFFSET);
stat = imxrt_serialin(priv, IMXRT_LPUART_STAT_OFFSET);
regval = ctrl;

/* {R|T}XINV bit field can only be written when the receiver is disabled (RE=0). */

regval &= ~LPUART_CTRL_RE;

imxrt_serialout(priv, IMXRT_LPUART_CTRL_OFFSET, regval);

/* Enable/disable signal inversion. */

if (arg & SER_INVERT_ENABLED_RX)
{
stat |= LPUART_STAT_RXINV;
}
else
{
stat &= ~LPUART_STAT_RXINV;
}

if (arg & SER_INVERT_ENABLED_TX)
{
ctrl |= LPUART_CTRL_TXINV;
}
else
{
ctrl &= ~LPUART_CTRL_TXINV;
}

imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, stat);
imxrt_serialout(priv, IMXRT_LPUART_CTRL_OFFSET, ctrl);

spin_unlock_irqrestore(flags);
}
break;
#endif

case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
default:
Expand Down
16 changes: 16 additions & 0 deletions arch/arm/src/stm32f7/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1940,6 +1940,22 @@ config STM32F7_USART_SINGLEWIRE
Enable single wire UART support. The option enables support for the
TIOCSSINGLEWIRE ioctl in the STM32F7 serial driver.

config STM32F7_USART_INVERT
bool "Signal Invert Support"
default n
depends on STM32F7_USART
---help---
Enable signal inversion UART support. The option enables support for the
TIOCSINVERT ioctl in the STM32F7 serial driver.

config STM32F7_USART_SWAP
bool "Swap RX/TX pins support"
default n
depends on STM32F7_USART
---help---
Enable RX/TX pin swapping support. The option enables support for the
TIOCSSWAP ioctl in the STM32F7 serial driver.

if PM

config STM32F7_PM_SERIAL_ACTIVITY
Expand Down
113 changes: 107 additions & 6 deletions arch/arm/src/stm32f7/stm32_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

/* Some sanity checks *******************************************************/

/* Total number of possible serial devices */

#define STM32_NSERIAL (STM32F7_NUSART + STM32F7_NUART)
Expand Down Expand Up @@ -1260,12 +1262,13 @@ static void up_set_format(struct uart_dev_s *dev)

/* Get the original state of UE */

cr1 = up_serialin(priv, STM32_USART_CR1_OFFSET);
cr1 = up_serialin(priv, STM32_USART_CR1_OFFSET);
cr1_ue = cr1 & USART_CR1_UE;
cr1 &= ~USART_CR1_UE;
cr1 &= ~USART_CR1_UE;

/* Disable UE as the format bits and baud rate registers can not be
* updated while UE = 1 */
* updated while UE = 1
*/

up_serialout(priv, STM32_USART_CR1_OFFSET, cr1);

Expand Down Expand Up @@ -1356,7 +1359,7 @@ static void up_set_format(struct uart_dev_s *dev)

/* Configure STOP bits */

regval = up_serialin(priv, STM32_USART_CR2_OFFSET);
regval = up_serialin(priv, STM32_USART_CR2_OFFSET);
regval &= ~(USART_CR2_STOP_MASK);

if (priv->stopbits2)
Expand Down Expand Up @@ -1685,6 +1688,7 @@ static int up_setup(struct uart_dev_s *dev)
#endif

/* Configure CR2 */

/* Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */

regval = up_serialin(priv, STM32_USART_CR2_OFFSET);
Expand All @@ -1701,6 +1705,7 @@ static int up_setup(struct uart_dev_s *dev)
up_serialout(priv, STM32_USART_CR2_OFFSET, regval);

/* Configure CR1 */

/* Clear TE, REm and all interrupt enable bits */

regval = up_serialin(priv, STM32_USART_CR1_OFFSET);
Expand All @@ -1709,6 +1714,7 @@ static int up_setup(struct uart_dev_s *dev)
up_serialout(priv, STM32_USART_CR1_OFFSET, regval);

/* Configure CR3 */

/* Clear CTSE, RTSE, and all interrupt enable bits */

regval = up_serialin(priv, STM32_USART_CR3_OFFSET);
Expand Down Expand Up @@ -2150,6 +2156,99 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
break;
#endif

#ifdef CONFIG_STM32F7_USART_INVERT
case TIOCSINVERT:
{
uint32_t cr1;
uint32_t cr1_ue;
irqstate_t flags;

flags = enter_critical_section();

/* Get the original state of UE */

cr1 = up_serialin(priv, STM32_USART_CR1_OFFSET);
cr1_ue = cr1 & USART_CR1_UE;
cr1 &= ~USART_CR1_UE;

/* Disable UE, {R,T}XINV can only be written when UE=0 */

up_serialout(priv, STM32_USART_CR1_OFFSET, cr1);

/* Enable/disable signal inversion. */

uint32_t cr = up_serialin(priv, STM32_USART_CR2_OFFSET);

if (arg & SER_INVERT_ENABLED_RX)
{
cr |= USART_CR2_RXINV;
}
else
{
cr &= ~USART_CR2_RXINV;
}

if (arg & SER_INVERT_ENABLED_TX)
{
cr |= USART_CR2_TXINV;
}
else
{
cr &= ~USART_CR2_TXINV;
}

up_serialout(priv, STM32_USART_CR2_OFFSET, cr);

/* Re-enable UE if appropriate */

up_serialout(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue);
leave_critical_section(flags);
}
break;
#endif

#ifdef CONFIG_STM32F7_USART_SWAP
case TIOCSSWAP:
{
uint32_t cr1;
uint32_t cr1_ue;
irqstate_t flags;

flags = enter_critical_section();

/* Get the original state of UE */

cr1 = up_serialin(priv, STM32_USART_CR1_OFFSET);
cr1_ue = cr1 & USART_CR1_UE;
cr1 &= ~USART_CR1_UE;

/* Disable UE, SWAP can only be written when UE=0 */

up_serialout(priv, STM32_USART_CR1_OFFSET, cr1);

/* Enable/disable Swap mode. */

uint32_t cr = up_serialin(priv, STM32_USART_CR2_OFFSET);

if (arg == SER_SWAP_ENABLED)
{
cr |= USART_CR2_SWAP;
}
else
{
cr &= ~USART_CR2_SWAP;
}

up_serialout(priv, STM32_USART_CR2_OFFSET, cr);

/* Re-enable UE if appropriate */

up_serialout(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue);
leave_critical_section(flags);
}
break;
#endif

#ifdef CONFIG_SERIAL_TERMIOS
case TCGETS:
{
Expand Down Expand Up @@ -2260,9 +2359,10 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)

up_txint(dev, false);

/* Configure TX as a GPIO output pin and Send a break signal*/
/* Configure TX as a GPIO output pin and Send a break signal */

tx_break = GPIO_OUTPUT | (~(GPIO_MODE_MASK|GPIO_OUTPUT_SET) & priv->tx_gpio);
tx_break = GPIO_OUTPUT |
(~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio);
stm32_configgpio(tx_break);

leave_critical_section(flags);
Expand Down Expand Up @@ -3000,6 +3100,7 @@ static int up_pm_prepare(struct pm_callback_s *cb, int domain,

default:
/* Should not get here */

break;
}

Expand Down
16 changes: 16 additions & 0 deletions arch/arm/src/stm32h7/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,22 @@ config STM32H7_USART_SINGLEWIRE
Enable single wire UART support. The option enables support for the
TIOCSSINGLEWIRE ioctl in the STM32H7 serial driver.

config STM32H7_USART_INVERT
bool "Signal Invert Support"
default n
depends on STM32H7_USART
---help---
Enable signal inversion UART support. The option enables support for the
TIOCSINVERT ioctl in the STM32H7 serial driver.

config STM32H7_USART_SWAP
bool "Swap RX/TX pins support"
default n
depends on STM32H7_USART
---help---
Enable RX/TX pin swapping support. The option enables support for the
TIOCSSWAP ioctl in the STM32H7 serial driver.

if PM

config STM32H7_PM_SERIAL_ACTIVITY
Expand Down
Loading