arch/arm/src/imxrt/imxrt_serial.c: IMXRT1050 LPUART TERMIOS support added.

This commit is contained in:
Ivan Ucherdzhiev 2018-07-26 07:08:17 -06:00 committed by Gregory Nutt
parent 35fbaf7c4c
commit 579e984d8a
2 changed files with 173 additions and 0 deletions

View File

@ -86,48 +86,56 @@ config IMXRT_LPUART1
bool "LPUART1" bool "LPUART1"
default n default n
select LPUART1_SERIALDRIVER select LPUART1_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
select IMXRT_HAVE_LPUART select IMXRT_HAVE_LPUART
config IMXRT_LPUART2 config IMXRT_LPUART2
bool "LPUART2" bool "LPUART2"
default n default n
select LPUART2_SERIALDRIVER select LPUART2_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
select IMXRT_HAVE_LPUART select IMXRT_HAVE_LPUART
config IMXRT_LPUART3 config IMXRT_LPUART3
bool "LPUART3" bool "LPUART3"
default n default n
select LPUART3_SERIALDRIVER select LPUART3_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
select IMXRT_HAVE_LPUART select IMXRT_HAVE_LPUART
config IMXRT_LPUART4 config IMXRT_LPUART4
bool "LPUART4" bool "LPUART4"
default n default n
select LPUART4_SERIALDRIVER select LPUART4_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
select IMXRT_HAVE_LPUART select IMXRT_HAVE_LPUART
config IMXRT_LPUART5 config IMXRT_LPUART5
bool "LPUART5" bool "LPUART5"
default n default n
select LPUART5_SERIALDRIVER select LPUART5_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
select IMXRT_HAVE_LPUART select IMXRT_HAVE_LPUART
config IMXRT_LPUART6 config IMXRT_LPUART6
bool "LPUART6" bool "LPUART6"
default n default n
select LPUART6_SERIALDRIVER select LPUART6_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
select IMXRT_HAVE_LPUART select IMXRT_HAVE_LPUART
config IMXRT_LPUART7 config IMXRT_LPUART7
bool "LPUART7" bool "LPUART7"
default n default n
select LPUART7_SERIALDRIVER select LPUART7_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
select IMXRT_HAVE_LPUART select IMXRT_HAVE_LPUART
config IMXRT_LPUART8 config IMXRT_LPUART8
bool "LPUART8" bool "LPUART8"
default n default n
select LPUART8_SERIALDRIVER select LPUART8_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
select IMXRT_HAVE_LPUART select IMXRT_HAVE_LPUART
endmenu # LPUART Peripherals endmenu # LPUART Peripherals

View File

@ -48,6 +48,10 @@
#include <errno.h> #include <errno.h>
#include <debug.h> #include <debug.h>
#ifdef CONFIG_SERIAL_TERMIOS
# include <termios.h>
#endif
#include <nuttx/irq.h> #include <nuttx/irq.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/init.h> #include <nuttx/init.h>
@ -726,6 +730,7 @@ static inline void imxrt_restoreuartint(struct imxrt_uart_s *priv,
* enabled/disabled. * enabled/disabled.
*/ */
flags = spin_lock_irqsave();
regval = imxrt_serialin(priv, IMXRT_LPUART_CTRL_OFFSET); regval = imxrt_serialin(priv, IMXRT_LPUART_CTRL_OFFSET);
regval &= ~LPUART_ALL_INTS; regval &= ~LPUART_ALL_INTS;
regval |= ie; regval |= ie;
@ -952,6 +957,166 @@ static int imxrt_ioctl(struct file *filep, int cmd, unsigned long arg)
break; break;
#endif #endif
#ifdef CONFIG_SERIAL_TERMIOS
case TCGETS:
{
struct termios *termiosp = (struct termios *)arg;
struct imxrt_uart_s *priv = (struct imxrt_uart_s *)dev->priv;
if (!termiosp)
{
ret = -EINVAL;
break;
}
/* Return baud */
cfsetispeed(termiosp, priv->baud);
/* Return parity */
termiosp->c_cflag = ((priv->parity != 0) ? PARENB : 0) |
((priv->parity == 1) ? PARODD : 0);
/* Return stop bits */
termiosp->c_cflag |= (priv->stopbits2) ? CSTOPB : 0;
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL)
/* Return flow control */
termiosp->c_cflag |= (priv->flowc) ? (CCTS_OFLOW | CRTS_IFLOW): 0;
#endif
/* Return number of bits */
switch (priv->bits)
{
case 5:
termiosp->c_cflag |= CS5;
break;
case 6:
termiosp->c_cflag |= CS6;
break;
case 7:
termiosp->c_cflag |= CS7;
break;
default:
case 8:
termiosp->c_cflag |= CS8;
break;
case 9:
termiosp->c_cflag |= CS8 /* CS9 */;
break;
}
}
break;
case TCSETS:
{
struct termios *termiosp = (struct termios *)arg;
struct imxrt_uart_s *priv = (struct imxrt_uart_s *)dev->priv;
uint32_t baud;
uint32_t ie;
uint8_t parity;
uint8_t nbits;
bool stop2;
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL)
bool flowc;
#endif
if (!termiosp)
{
ret = -EINVAL;
break;
}
/* Decode baud. */
ret = OK;
baud = cfgetispeed(termiosp);
/* Decode number of bits */
switch (termiosp->c_cflag & CSIZE)
{
case CS5:
nbits = 5;
break;
case CS6:
nbits = 6;
break;
case CS7:
nbits = 7;
break;
case CS8:
nbits = 8;
break;
#if 0
case CS9:
nbits = 9;
break;
#endif
default:
ret = -EINVAL;
break;
}
/* Decode parity */
if ((termiosp->c_cflag & PARENB) != 0)
{
parity = (termiosp->c_cflag & PARODD) ? 1 : 2;
}
else
{
parity = 0;
}
/* Decode stop bits */
stop2 = (termiosp->c_cflag & CSTOPB) != 0;
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL)
/* Decode flow control */
flowc = (termiosp->c_cflag & (CCTS_OFLOW | CRTS_IFLOW)) != 0;
#endif
/* Verify that all settings are valid before committing */
if (ret == OK)
{
/* Commit */
priv->baud = baud;
priv->parity = parity;
priv->bits = nbits;
priv->stopbits2 = stop2;
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL)
priv->flowc = flowc;
#endif
/* effect the changes immediately - note that we do not
* implement TCSADRAIN / TCSAFLUSH
*/
imxrt_disableuartint(priv, &ie);
ret = imxrt_setup(dev);
/* Restore the interrupt state */
imxrt_restoreuartint(priv, ie);
priv->ie = ie;
}
}
break;
#endif /* CONFIG_SERIAL_TERMIOS */
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
default: default: