From 1edec0aaa180311bcc29cbebec714a451d23c34d Mon Sep 17 00:00:00 2001 From: Nathan Hartman <59230071+hartmannathan@users.noreply.github.com> Date: Wed, 1 Feb 2023 17:17:13 -0500 Subject: [PATCH] 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 --- arch/arm/src/tiva/common/tiva_serial.c | 77 +++++++++++++++++--------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/arch/arm/src/tiva/common/tiva_serial.c b/arch/arm/src/tiva/common/tiva_serial.c index df4b7903adb..220ff827fc5 100644 --- a/arch/arm/src/tiva/common/tiva_serial.c +++ b/arch/arm/src/tiva/common/tiva_serial.c @@ -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 */