tiva/serial: Allow changing CTS/RTS with termios

This is a follow-up to PR #6548, which added UART CTS/RTS support for
Tiva (TI TM4C12x) microcontrollers. This follow-up makes it possible,
when termios support is enabled with CONFIG_SERIAL_TERMIOS and CTS/RTS
support is enabled with CONFIG_SERIAL_OFLOWCONTROL and/or
CONFIG_SERIAL_IFLOWCONTROL, to query whether CTS/RTS are on/off at
runtime by utilizing ioctl TCGETS and to turn CTS/RTS on/off at runtime
by utilizing ioctl TCSETS.

* arch/arm/src/tiva/common/tiva_serial.c
  (up_set_format): Because this function is called from ioctl TCSETS to
   modify UART settings, and that IOCTL now respects CCTS_OFLOW and
   CRTS_IFLOW, move setting/clearing of Tiva UART's CTL register's RTSEN
   and CTSEN bits here...
  (up_setup): ...from here.
  (up_ioctl): For TCGETS, populate CCTS_OFLOW and CRTS_IFLOW bits as
   appropriate. For TCSETS, populate priv's oflow and iflow from
   supplied CCTS_OFLOW and CRTS_IFLOW bits.

Thanks to Petro Karashchenko for review and suggested fixes.

Co-authored-by: Petro Karashchenko <petro.karashchenko@gmail.com>
This commit is contained in:
Nathan Hartman 2023-02-01 17:17:13 -05:00 committed by Xiang Xiao
parent f2e15b431c
commit 5651940d02

View File

@ -871,12 +871,36 @@ static void up_set_format(struct uart_dev_s *dev)
up_serialout(priv, TIVA_UART_LCRH_OFFSET, lcrh);
/* Enable or disable CTS/RTS, if applicable */
#if defined(CONFIG_SERIAL_IFLOWCONTROL)
if (priv->iflow)
{
ctl |= UART_CTL_RTSEN;
}
else
{
ctl &= ~UART_CTL_RTSEN;
}
#endif
#if defined(CONFIG_SERIAL_OFLOWCONTROL)
if (priv->oflow)
{
ctl |= UART_CTL_CTSEN;
}
else
{
ctl &= ~UART_CTL_CTSEN;
}
#endif
if (was_active)
{
ctl = up_serialin(priv, TIVA_UART_CTL_OFFSET);
ctl |= UART_CTL_UARTEN;
up_serialout(priv, TIVA_UART_CTL_OFFSET, ctl);
}
up_serialout(priv, TIVA_UART_CTL_OFFSET, ctl);
}
/****************************************************************************
@ -923,33 +947,11 @@ static int up_setup(struct uart_dev_s *dev)
lcrh |= UART_LCRH_FEN;
up_serialout(priv, TIVA_UART_LCRH_OFFSET, lcrh);
/* Enable Rx, Tx, CTS/RTS (if requested), and the UART */
/* Enable Rx, Tx, and the UART */
ctl = up_serialin(priv, TIVA_UART_CTL_OFFSET);
ctl |= (UART_CTL_UARTEN | UART_CTL_TXE | UART_CTL_RXE);
#if defined(CONFIG_SERIAL_IFLOWCONTROL)
if (priv->iflow)
{
ctl |= UART_CTL_RTSEN;
}
else
{
ctl &= ~(UART_CTL_RTSEN);
}
#endif
#if defined(CONFIG_SERIAL_OFLOWCONTROL)
if (priv->oflow)
{
ctl |= UART_CTL_CTSEN;
}
else
{
ctl &= ~(UART_CTL_CTSEN);
}
#endif
up_serialout(priv, TIVA_UART_CTL_OFFSET, ctl);
/* Set up the cache IM value */
@ -1156,8 +1158,22 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
ccflag |= PARENB | PARODD;
}
/* TODO append support for HUPCL, CLOCAL and flow control bits
* as well as os-compliant break sequence
#ifdef CONFIG_SERIAL_OFLOWCONTROL
if (priv->oflow)
{
ccflag |= CCTS_OFLOW;
}
#endif
#ifdef CONFIG_SERIAL_IFLOWCONTROL
if (priv->iflow)
{
ccflag |= CRTS_IFLOW;
}
#endif
/* TODO append support for HUPCL and CLOCAL as well as os-compliant
* break sequence
*/
termiosp->c_cflag = ccflag;
@ -1201,6 +1217,13 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
priv->bits = (termiosp->c_cflag & CSIZE) + 5;
priv->baud = cfgetispeed(termiosp);
#ifdef CONFIG_SERIAL_OFLOWCONTROL
priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0;
#endif
#ifdef CONFIG_SERIAL_IFLOWCONTROL
priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0;
#endif
/* Effect the changes immediately - note that we do not implement
* TCSADRAIN / TCSAFLUSH
*/