From 58864cc6e9ca0b24298d8711cba806f23f6ec40d Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 23 Jul 2012 15:37:13 +0000 Subject: [PATCH] Baud definitions (B9600 for example) are again encoded; Now supports the BOTHER settings which allows specifying the baud via c_ispeed and c_ospeed termios fields git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4970 42af7a65-404d-4744-a932-0658087f49c3 --- ChangeLog | 9 +- arch/arm/src/lpc43xx/Kconfig | 10 +- arch/arm/src/stm32/Kconfig | 9 + arch/arm/src/stm32/stm32_serial.c | 175 ++++++++++++++----- arch/mips/src/pic32mx/Kconfig | 9 + configs/lpc4330-xplorer/nsh/defconfig | 12 +- include/termios.h | 231 +++++++++++++------------- lib/termios/lib_cfgetispeed.c | 15 +- lib/termios/lib_cfgetospeed.c | 15 +- lib/termios/lib_cfsetispeed.c | 18 +- lib/termios/lib_cfsetospeed.c | 18 +- 11 files changed, 316 insertions(+), 205 deletions(-) diff --git a/ChangeLog b/ChangeLog index 61a3ca386f..7445e62e19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3040,11 +3040,18 @@ termios. These are non-standard interfaces but have a precedence: There are similar interfaces in AIX. * include/sys/str_tty.h, lib/lib_setspeed.c, lib_getspeed.c, and lib_resetspeed.c: - Sigh... removed. We don't need any more almost standard interfaces. + Sigh... removed. We don't need any more almost standard interfaces! (SVN + revision 4968 if you want the short-lived code). * include/termios.h and lib/termios/*: Open the existing, standard termios interfaces to permit some non-standard baud settings. The new termios definitions still supports the POSIX standard except that it does not strictly enforce baud rate settings, permitting some non-portable, but useful baud rate settings (this is what the short-lived AIX-like interfaces would have accomplished as well). + * include/termios.h and lib/termios/*: Redesigned yet again (this is getting + painful. NuttX now supports the BOTHER baud setting just as Linux does. termios + Bxxx definitions are again encoded; cf[set|get][o|i]speed now deal with only the + encoded values. If the encoed baud is set to BOTHER, then the values in the (non- + standard) c_ispeed and c_ospeed baud values may be accessed directly. + diff --git a/arch/arm/src/lpc43xx/Kconfig b/arch/arm/src/lpc43xx/Kconfig index 706dab8a36..920b601c40 100644 --- a/arch/arm/src/lpc43xx/Kconfig +++ b/arch/arm/src/lpc43xx/Kconfig @@ -485,5 +485,11 @@ config USART3_2STOP endmenu - - +config SERIAL_TERMIOS + bool "Serial driver TERMIOS supported" + depends on LPC43_USART0 || LPC43_UART1 || LPC43_USART2 || LPC43_USART3 + default n + ---help--- + Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.). + If this is not defined, then the terminal settings (baud, parity, etc). + are not configurable at runtime; serial streams cannot be flushed, etc.. diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index efeb3c8556..5d0d48f880 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -1756,6 +1756,15 @@ config USART6_RXDMA endmenu +config SERIAL_TERMIOS + bool "Serial driver TERMIOS supported" + depends on STM32_USART1 || STM32_USART2 || STM32_USART3 || STM32_UART4 || STM32_UART5 || STM32_USART6 + default n + ---help--- + Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.). + If this is not defined, then the terminal settings (baud, parity, etc). + are not configurable at runtime; serial streams cannot be flushed, etc.. + menu "SPI Configuration" depends on STM32_SPI diff --git a/arch/arm/src/stm32/stm32_serial.c b/arch/arm/src/stm32/stm32_serial.c index a5864acb63..aaed6270fa 100644 --- a/arch/arm/src/stm32/stm32_serial.c +++ b/arch/arm/src/stm32/stm32_serial.c @@ -53,6 +53,10 @@ #include #include +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + #include #include @@ -149,11 +153,23 @@ struct up_dev_s uint16_t ie; /* Saved interrupt mask bits value */ uint16_t sr; /* Saved status bits */ - const uint8_t irq; /* IRQ associated with this USART */ + /* If termios are supported, then the following fields may vary at + * runtime. + */ + +#ifdef CONFIG_SERIAL_TERMIOS + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ + uint32_t baud; /* Configured baud */ +#else const uint8_t parity; /* 0=none, 1=odd, 2=even */ const uint8_t bits; /* Number of bits (7 or 8) */ const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ const uint32_t baud; /* Configured baud */ +#endif + + const uint8_t irq; /* IRQ associated with this USART */ const uint32_t apbclock; /* PCLK 1 or 2 frequency */ const uint32_t usartbase; /* Base address of USART registers */ const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */ @@ -181,6 +197,7 @@ struct up_dev_s * Private Function Prototypes ****************************************************************************/ +static void up_setspeed(struct uart_dev_s *dev); static int up_setup(struct uart_dev_s *dev); static void up_shutdown(struct uart_dev_s *dev); static int up_attach(struct uart_dev_s *dev); @@ -770,6 +787,54 @@ static int up_dma_nextrx(struct up_dev_s *priv) } #endif +/**************************************************************************** + * Name: up_setspeed + * + * Description: + * Set the serial line speed. + * + ****************************************************************************/ + +#ifndef CONFIG_SUPPRESS_UART_CONFIG +static void up_setspeed(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + uint32_t usartdiv32; + uint32_t mantissa; + uint32_t fraction; + uint32_t brr; + + /* Configure the USART Baud Rate. The baud rate for the receiver and + * transmitter (Rx and Tx) are both set to the same value as programmed + * in the Mantissa and Fraction values of USARTDIV. + * + * baud = fCK / (16 * usartdiv) + * usartdiv = fCK / (16 * baud) + * + * Where fCK is the input clock to the peripheral (PCLK1 for USART2, 3, 4, 5 + * or PCLK2 for USART1) + * + * First calculate (NOTE: all stand baud values are even so dividing by two + * does not lose precision): + * + * usartdiv32 = 32 * usartdiv = fCK / (baud/2) + */ + + usartdiv32 = priv->apbclock / (priv->baud >> 1); + + /* The mantissa part is then */ + + mantissa = usartdiv32 >> 5; + brr = mantissa << USART_BRR_MANT_SHIFT; + + /* The fractional remainder (with rounding) */ + + fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1; + brr |= fraction << USART_BRR_FRAC_SHIFT; + up_serialout(priv, STM32_USART_BRR_OFFSET, brr); +} +#endif + /**************************************************************************** * Name: up_setup * @@ -783,10 +848,6 @@ static int up_setup(struct uart_dev_s *dev) { struct up_dev_s *priv = (struct up_dev_s*)dev->priv; #ifndef CONFIG_SUPPRESS_UART_CONFIG - uint32_t usartdiv32; - uint32_t mantissa; - uint32_t fraction; - uint32_t brr; uint32_t regval; /* Note: The logic here depends on the fact that that the USART module @@ -858,34 +919,9 @@ static int up_setup(struct uart_dev_s *dev) up_serialout(priv, STM32_USART_CR3_OFFSET, regval); - /* Configure the USART Baud Rate. The baud rate for the receiver and - * transmitter (Rx and Tx) are both set to the same value as programmed - * in the Mantissa and Fraction values of USARTDIV. - * - * baud = fCK / (16 * usartdiv) - * usartdiv = fCK / (16 * baud) - * - * Where fCK is the input clock to the peripheral (PCLK1 for USART2, 3, 4, 5 - * or PCLK2 for USART1) - * - * First calculate (NOTE: all stand baud values are even so dividing by two - * does not lose precision): - * - * usartdiv32 = 32 * usartdiv = fCK / (baud/2) - */ + /* Configure the USART Baud Rate. */ - usartdiv32 = priv->apbclock / (priv->baud >> 1); - - /* The mantissa part is then */ - - mantissa = usartdiv32 >> 5; - brr = mantissa << USART_BRR_MANT_SHIFT; - - /* The fractional remainder (with rounding) */ - - fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1; - brr |= fraction << USART_BRR_FRAC_SHIFT; - up_serialout(priv, STM32_USART_BRR_OFFSET, brr); + up_setspeed(dev); /* Enable Rx, Tx, and the USART */ @@ -1182,26 +1218,75 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) { struct inode *inode = filep->f_inode; struct uart_dev_s *dev = inode->i_private; -#ifdef CONFIG_USART_BREAKS struct up_dev_s *priv = (struct up_dev_s*)dev->priv; -#endif int ret = OK; switch (cmd) { case TIOCSERGSTRUCT: { - struct up_dev_s *user = (struct up_dev_s*)arg; - if (!user) - { - ret = -EINVAL; - } - else - { - memcpy(user, dev, sizeof(struct up_dev_s)); - } - } - break; + struct up_dev_s *user = (struct up_dev_s*)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct up_dev_s)); + } + } + break; + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios*)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: (1) Note that only the BOTHER baud is returned; (2) Other + * termios fields are not yet initialized. Here we also exploit the + * internal knowledge that ctfsetospeed() is equivalent to + * cfsetispeed(). + */ + + cfsetispeed(termiosp, BOTHER); + termiosp->c_ispeed = priv->baud; + termiosp->c_ospeed = priv->baud; + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios*)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* TODO: Only the BOTHER speed setting is supported. Here we + * also exploit the internal knowledge that ctfgetospeed() is + * equivalent to cfgetispeed(). + */ + + if (cfgetospeed(termiosp) != BOTHER || + termiosp->c_ispeed != termiosp->c_ospeed) + { + ret = -ENOSYS; + break; + } + + priv->baud = termiosp->c_ispeed; + up_setspeed(dev); + } + break; +#endif #ifdef CONFIG_USART_BREAKS case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ diff --git a/arch/mips/src/pic32mx/Kconfig b/arch/mips/src/pic32mx/Kconfig index 26ec901a14..5c17f72c10 100644 --- a/arch/mips/src/pic32mx/Kconfig +++ b/arch/mips/src/pic32mx/Kconfig @@ -1188,6 +1188,15 @@ config UART6_2STOP endmenu +config SERIAL_TERMIOS + bool "Serial driver TERMIOS supported" + depends on PIC32MX_UART1 || PIC32MX_UART2 || PIC32MX_UART3 || PIC32MX_UART4 || PIC32MX_UART5 || PIC32MX_UART6 + default n + ---help--- + Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.). + If this is not defined, then the terminal settings (baud, parity, etc). + are not configurable at runtime; serial streams cannot be flushed, etc.. + choice prompt "PIC32MX PHY Selection" depends on PIC32MX_ETHERNET diff --git a/configs/lpc4330-xplorer/nsh/defconfig b/configs/lpc4330-xplorer/nsh/defconfig index 0fc8d93adb..27c434d53a 100644 --- a/configs/lpc4330-xplorer/nsh/defconfig +++ b/configs/lpc4330-xplorer/nsh/defconfig @@ -181,6 +181,11 @@ CONFIG_LPC43_WWDT=n # # LPC43xx specific serial device driver settings # +# CONFIG_SERIAL_TERMIOS - Serial driver supports termios.h interfaces (tcsetattr, +# tcflush, etc.). If this is not defined, then the terminal settings (baud, +# parity, etc.) are not configurable at runtime; serial streams cannot be +# flushed, etc. +# # CONFIG_U[S]ARTn_SERIAL_CONSOLE - selects the UARTn for the # console and ttys0 (default is the UART1). # CONFIG_U[S]ARTn_RXBUFSIZE - Characters are buffered as received. @@ -192,6 +197,8 @@ CONFIG_LPC43_WWDT=n # CONFIG_U[S]ARTn_PARTIY - 0=no parity, 1=odd parity, 2=even parity # CONFIG_U[S]ARTn_2STOP - Two stop bits # +CONFIG_SERIAL_TERMIOS=n + CONFIG_USART0_SERIAL_CONSOLE=y CONFIG_UART1_SERIAL_CONSOLE=n CONFIG_USART2_SERIAL_CONSOLE=n @@ -776,10 +783,6 @@ CONFIG_FTPD_CMDBUFFERSIZE=2048 # CONFIG_MB_ASCII_ENABLED - Modbus ASCII support # CONFIG_MB_RTU_ENABLED - Modbus RTU support # CONFIG_MB_TCP_ENABLED - Modbus TCP support -# CONFIG_MB_TERMIOS - Serial driver supports termios.h interfaces (tcsetattr, -# tcflush, etc.). If this is not defined, then the terminal settings (baud, -# parity, etc.) are not configurable at runtime; serial streams will not be -# flushed when closed. # CONFIG_MB_ASCII_TIMEOUT_SEC - Character timeout value for Modbus ASCII. The # character timeout value is not fixed for Modbus ASCII and is therefore # a configuration option. It should be set to the maximum expected delay @@ -826,7 +829,6 @@ CONFIG_MODBUS=n CONFIG_MB_ASCII_ENABLED=y CONFIG_MB_RTU_ENABLED=y CONFIG_MB_TCP_ENABLED=n -CONFIG_MB_TERMIOS=n CONFIG_MB_ASCII_TIMEOUT_SEC=1 CONFIG_MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS=0 CONFIG_MB_FUNC_HANDLERS_MAX=16 diff --git a/include/termios.h b/include/termios.h index 0a4a13b453..c34d9fbf82 100644 --- a/include/termios.h +++ b/include/termios.h @@ -50,131 +50,133 @@ /* Terminal input modes (c_iflag in the termios structure) */ -#define BRKINT (1 << 0) /* Signal interrupt on break */ -#define ICRNL (1 << 1) /* Map CR to NL on input */ -#define IGNBRK (1 << 2) /* Ignore break condition */ -#define IGNCR (1 << 3) /* Ignore CR */ -#define IGNPAR (1 << 4) /* Ignore characters with parity errors */ -#define INLCR (1 << 5) /* Map NL to CR on input */ -#define INPCK (1 << 6) /* Enable input parity check */ -#define ISTRIP (1 << 7) /* Strip character */ -#define IUCLC (1 << 8) /* Map upper-case to lower-case on input (LEGACY) */ -#define IXANY (1 << 9) /* Enable any character to restart output */ -#define IXOFF (1 << 10) /* Enable start/stop input control */ -#define IXON (1 << 11) /* Enable start/stop output control */ -#define PARMRK (1 << 12) /* Mark parity errors */ +#define BRKINT (1 << 0) /* Bit 0: Signal interrupt on break */ +#define ICRNL (1 << 1) /* Bit 1: Map CR to NL on input */ +#define IGNBRK (1 << 2) /* Bit 2: Ignore break condition */ +#define IGNCR (1 << 3) /* Bit 3: Ignore CR */ +#define IGNPAR (1 << 4) /* Bit 4: Ignore characters with parity errors */ +#define INLCR (1 << 5) /* Bit 5: Map NL to CR on input */ +#define INPCK (1 << 6) /* Bit 6: Enable input parity check */ +#define ISTRIP (1 << 7) /* Bit 7: Strip character */ +#define IUCLC (1 << 8) /* Bit 8: Map upper-case to lower-case on input (LEGACY) */ +#define IXANY (1 << 9) /* Bit 9: Enable any character to restart output */ +#define IXOFF (1 << 10) /* Bit 10: Enable start/stop input control */ +#define IXON (1 << 11) /* Bit 11: Enable start/stop output control */ +#define PARMRK (1 << 12) /* Bit 12: Mark parity errors */ /* Terminal output modes (c_oflag in the termios structure) */ -#define OPOST (1 << 0) /* Post-process output */ -#define OLCUC (1 << 1) /* Map lower-case to upper-case on output (LEGACY) */ -#define ONLCR (1 << 2) /* Map NL to CR-NL on output */ -#define OCRNL (1 << 3) /* Map CR to NL on output */ -#define ONOCR (1 << 4) /* No CR output at column 0 */ -#define ONLRET (1 << 5) /* NL performs CR function */ -#define OFILL (1 << 6) /* Use fill characters for delay */ -#define NLDLY (1 << 7) /* Select newline delays: */ -# define NL0 (0 << 7) /* Newline character type 0 */ -# define NL1 (1 << 7) /* Newline character type 1 */ -#define CRDLY (3 << 8) /* Select carriage-return delays: */ -# define CR0 (0 << 8) /* Carriage-return delay type 0 */ -# define CR1 (1 << 8) /* Carriage-return delay type 1 */ -# define CR2 (2 << 8) /* Carriage-return delay type 2 */ -# define CR3 (3 << 8) /* Carriage-return delay type 3 */ -#define TABDLY (3 << 10) /* Select horizontal-tab delays: */ -# define TAB0 (0 << 10) /* Horizontal-tab delay type 0 */ -# define TAB1 (1 << 10) /* Horizontal-tab delay type 1 */ -# define TAB2 (2 << 10) /* Horizontal-tab delay type 2 */ -# define TAB3 (3 << 10) /* Expand tabs to spaces */ -#define BSDLY (1 << 12) /* Select backspace delays: */ -# define BS0 (0 << 12) /* Backspace-delay type 0 */ -# define BS1 (1 << 12) /* Backspace-delay type 1 */ -#define VTDLY (1 << 13) /* Select vertical-tab delays: */ -# define VT0 (0 << 13) /* Vertical-tab delay type 0 */ -# define VT1 (1 << 13) /* Vertical-tab delay type 1 */ -#define FFDLY (1 << 14) /* Select form-feed delays: */ -# define FF0 (0 << 14) /* Form-feed delay type 0 */ -# define FF1 (1 << 14) /* Form-feed delay type 1 */ +#define OPOST (1 << 0) /* Bit 0: Post-process output */ +#define OLCUC (1 << 1) /* Bit 1: Map lower-case to upper-case on output (LEGACY) */ +#define ONLCR (1 << 2) /* Bit 2: Map NL to CR-NL on output */ +#define OCRNL (1 << 3) /* Bit 3: Map CR to NL on output */ +#define ONOCR (1 << 4) /* Bit 4: No CR output at column 0 */ +#define ONLRET (1 << 5) /* Bit 5: NL performs CR function */ +#define OFILL (1 << 6) /* Bit 6: Use fill characters for delay */ +#define NLDLY (1 << 7) /* Bit 7: Select newline delays: */ +# define NL0 (0 << 7) /* Newline character type 0 */ +# define NL1 (1 << 7) /* Newline character type 1 */ +#define CRDLY (3 << 8) /* Bits 8-9: Select carriage-return delays: */ +# define CR0 (0 << 8) /* Carriage-return delay type 0 */ +# define CR1 (1 << 8) /* Carriage-return delay type 1 */ +# define CR2 (2 << 8) /* Carriage-return delay type 2 */ +# define CR3 (3 << 8) /* Carriage-return delay type 3 */ +#define TABDLY (3 << 10) /* Bit 10-11: Select horizontal-tab delays: */ +# define TAB0 (0 << 10) /* Horizontal-tab delay type 0 */ +# define TAB1 (1 << 10) /* Horizontal-tab delay type 1 */ +# define TAB2 (2 << 10) /* Horizontal-tab delay type 2 */ +# define TAB3 (3 << 10) /* Expand tabs to spaces */ +#define BSDLY (1 << 12) /* Bit 12: Select backspace delays: */ +# define BS0 (0 << 12) /* Backspace-delay type 0 */ +# define BS1 (1 << 12) /* Backspace-delay type 1 */ +#define VTDLY (1 << 13) /* Bit 13: Select vertical-tab delays: */ +# define VT0 (0 << 13) /* Vertical-tab delay type 0 */ +# define VT1 (1 << 13) /* Vertical-tab delay type 1 */ +#define FFDLY (1 << 14) /* Bit 14: Select form-feed delays: */ +# define FF0 (0 << 14) /* Form-feed delay type 0 */ +# define FF1 (1 << 14) /* Form-feed delay type 1 */ /* Control Modes (c_cflag in the termios structure) */ -#define CSIZE (3 << 0) /* Character size: */ -# define CS5 (0 << 0) /* 5 bits */ -# define CS6 (1 << 0) /* 6 bits */ -# define CS7 (2 << 0) /* 7 bits */ -# define CS8 (3 << 0) /* 8 bits */ -#define CSTOPB (1 << 2) /* Send two stop bits, else one */ -#define CREAD (1 << 3) /* Enable receiver */ -#define PARENB (1 << 4) /* Parity enable */ -#define PARODD (1 << 5) /* Odd parity, else even */ -#define HUPCL (1 << 6) /* Hang up on last close */ -#define CLOCAL (1 << 7) /* Ignore modem status lines */ +#define CBAUD (0x0f) /* Bits 0-3: baud */ +#define CBAUDEX (1 << 4) /* Bit 4: Extended baud */ +#define CSIZE (3 << 5) /* Bits 5-6: Character size: */ +# define CS5 (0 << 5) /* 5 bits */ +# define CS6 (1 << 5) /* 6 bits */ +# define CS7 (2 << 5) /* 7 bits */ +# define CS8 (3 << 5) /* 8 bits */ +#define CSTOPB (1 << 7) /* Bit 7: Send two stop bits, else one */ +#define CREAD (1 << 8) /* Bit 8: Enable receiver */ +#define PARENB (1 << 9) /* Bit 9: Parity enable */ +#define PARODD (1 << 10) /* Bit 10: Odd parity, else even */ +#define HUPCL (1 << 11) /* Bit 11: Hang up on last close */ +#define CLOCAL (1 << 12) /* Bit 12: Ignore modem status lines */ /* Local Modes (c_lflag in the termios structure) */ -#define ECHO (1 << 0) /* Enable echo */ -#define ECHOE (1 << 1) /* Echo erase character as error-correcting backspace */ -#define ECHOK (1 << 2) /* Echo KILL */ -#define ECHONL (1 << 3) /* Echo NL */ -#define ICANON (1 << 4) /* Canonical input (erase and kill processing) */ -#define IEXTEN (1 << 5) /* Enable extended input character processing */ -#define ISIG (1 << 6) /* Enable signals */ -#define NOFLSH (1 << 7) /* Disable flush after interrupt or quit */ -#define TOSTOP (1 << 8) /* Send SIGTTOU for background output */ -#define XCASE (1 << 9) /* Canonical upper/lower presentation (LEGACY) */ +#define ECHO (1 << 0) /* Bit 0: Enable echo */ +#define ECHOE (1 << 1) /* Bit 1: Echo erase character as error-correcting backspace */ +#define ECHOK (1 << 2) /* Bit 2: Echo KILL */ +#define ECHONL (1 << 3) /* Bit 3: Echo NL */ +#define ICANON (1 << 4) /* Bit 4: Canonical input (erase and kill processing) */ +#define IEXTEN (1 << 5) /* Bit 5: Enable extended input character processing */ +#define ISIG (1 << 6) /* Bit 6: Enable signals */ +#define NOFLSH (1 << 7) /* Bit 7: Disable flush after interrupt or quit */ +#define TOSTOP (1 << 8) /* Bit 8: Send SIGTTOU for background output */ +#define XCASE (1 << 9) /* Bit 9: Canonical upper/lower presentation (LEGACY) */ /* The following are subscript names for the termios c_cc array */ -#define VEOF 0 /* EOF character (canonical mode) */ -#define VMIN VEOF /* MIN value (Non-canonical mode) */ -#define VEOL 1 /* EOL character (canonical mode) */ -#define VTIME VEOL /* TIME value (Non-canonical mode) */ -#define VERASE 2 /* ERASE character (canonical mode) */ -#define VINTR 3 /* INTR character */ -#define VKILL 4 /* KILL character (canonical mode) */ -#define VQUIT 5 /* QUIT character */ -#define VSTART 6 /* START character */ -#define VSTOP 7 /* STOP character */ -#define VSUSP 8 /* SUSP character */ -#define NCCS 9 /* Size of the array c_cc for control characters */ +#define VEOF 0 /* Bit 0: EOF character (canonical mode) */ +#define VMIN VEOF /* Bit 0: MIN value (Non-canonical mode) */ +#define VEOL 1 /* Bit 1: EOL character (canonical mode) */ +#define VTIME VEOL /* Bit 1: TIME value (Non-canonical mode) */ +#define VERASE 2 /* Bit 2: ERASE character (canonical mode) */ +#define VINTR 3 /* Bit 3: INTR character */ +#define VKILL 4 /* Bit 4: KILL character (canonical mode) */ +#define VQUIT 5 /* Bit 5: QUIT character */ +#define VSTART 6 /* Bit 6: START character */ +#define VSTOP 7 /* Bit 7: STOP character */ +#define VSUSP 8 /* Bit 8: SUSP character */ +#define NCCS 9 /* Bit 9: Size of the array c_cc for control characters */ -/* Baud Rate Selection (objects of type speed_t). NOTE that as a simplification - * in NuttX, the value of the baud symbol is the buad rate itself; not an encoded - * value as you will see in most implementations of termios.h. - */ +/* Baud Rate Selection. */ -#define B0 0 /* Hang up */ -#define B50 50 /* 50 baud */ -#define B75 75 /* 75 baud */ -#define B110 110 /* 110 baud */ -#define B134 134 /* 134.5 baud */ -#define B150 150 /* 150 baud */ -#define B200 200 /* 200 baud */ -#define B300 300 /* 300 baud */ -#define B600 600 /* 600 baud */ -#define B1200 1200 /* 1,200 baud */ -#define B1800 1800 /* 1,800 baud */ -#define B2400 2400 /* 2,400 baud */ -#define B4800 4800 /* 4,800 baud */ -#define B9600 9600 /* 9,600 baud */ -#define B19200 19200 /* 19,200 baud */ -#define B38400 38400 /* 38,400 baud */ +#define B0 (0x00) /* Hang up */ +#define B50 (0x01) /* 50 baud */ +#define B75 (0x02) /* 75 baud */ +#define B110 (0x03) /* 110 baud */ +#define B134 (0x04) /* 134.5 baud */ +#define B150 (0x05) /* 150 baud */ +#define B200 (0x06) /* 200 baud */ +#define B300 (0x07) /* 300 baud */ +#define B600 (0x08) /* 600 baud */ +#define B1200 (0x09) /* 1,200 baud */ +#define B1800 (0x0a) /* 1,800 baud */ +#define B2400 (0x0b) /* 2,400 baud */ +#define B4800 (0x0c) /* 4,800 baud */ +#define B9600 (0x0d) /* 9,600 baud */ +#define B19200 (0x0e) /* 19,200 baud */ +#define B38400 (0x0f) /* 38,400 baud */ -#define B57600 57600 /* 57,600 baud */ -#define B115200 115200 /* 115,200 baud */ -#define B128000 128000 /* 128,000 baud */ -#define B230400 230400 /* 230,400 baud */ -#define B256000 256000 /* 256,000 baud */ -#define B460800 460800 /* 460,800 baud */ -#define B500000 500000 /* 500,000 baud */ -#define B576000 576000 /* 576,000 baud */ -#define B921600 921600 /* 921,600 baud */ -#define B1000000 1000000 /* 1,000,000 baud */ -#define B1152000 1152000 /* 1,152,000 baud */ -#define B1500000 1500000 /* 1,500,000 baud */ -#define B2000000 2000000 /* 2,000,000 baud */ -#define B2500000 2500000 /* 2,500,000 baud */ -#define B3000000 3000000 /* 3,000,000 baud */ +/* "Extended" baud rates above 37K include the CBAUDEX bit */ + +#define BOTHER (CBAUDEX | 0x00) /* Use baud values in c_ispeed and c_ospeed */ +#define B57600 (CBAUDEX | 0x01) /* 57,600 baud */ +#define B115200 (CBAUDEX | 0x02) /* 115,200 baud */ +#define B128000 (CBAUDEX | 0x03) /* 128,000 baud */ +#define B230400 (CBAUDEX | 0x04) /* 230,400 baud */ +#define B256000 (CBAUDEX | 0x05) /* 256,000 baud */ +#define B460800 (CBAUDEX | 0x06) /* 460,800 baud */ +#define B500000 (CBAUDEX | 0x07) /* 500,000 baud */ +#define B576000 (CBAUDEX | 0x08) /* 576,000 baud */ +#define B921600 (CBAUDEX | 0x09) /* 921,600 baud */ +#define B1000000 (CBAUDEX | 0x0a) /* 1,000,000 baud */ +#define B1152000 (CBAUDEX | 0x0b) /* 1,152,000 baud */ +#define B1500000 (CBAUDEX | 0x0c) /* 1,500,000 baud */ +#define B2000000 (CBAUDEX | 0x0d) /* 2,000,000 baud */ +#define B2500000 (CBAUDEX | 0x0e) /* 2,500,000 baud */ +#define B3000000 (CBAUDEX | 0x0f) /* 3,000,000 baud */ /* Attribute Selection (used with tcsetattr()) */ @@ -220,13 +222,10 @@ struct termios tcflag_t c_lflag; /* Local modes */ cc_t c_cc[NCCS]; /* Control chars */ - /* Implementation specific fields. For portability reasons, these fields - * should not be accessed directly, but rather through only through the - * cf[set|get][o|i]speed() POSIX interfaces. - */ + /* If CBAUD == BOTHER, then these fields hold the input/output BAUD. */ - speed_t c_ispeed; /* Input speed */ - speed_t c_ospeed; /* Output speed */ + speed_t c_ispeed; /* Input speed (non-POSIX)*/ + speed_t c_ospeed; /* Output speed (non-POSIX) */ }; /**************************************************************************** diff --git a/lib/termios/lib_cfgetispeed.c b/lib/termios/lib_cfgetispeed.c index d7ca5f5a57..d52b83774f 100644 --- a/lib/termios/lib_cfgetispeed.c +++ b/lib/termios/lib_cfgetispeed.c @@ -70,24 +70,21 @@ * This function shall return exactly the value in the termios data * structure, without interpretation. * - * NON STANDARD BEHAVIOR. In Nuttx, the speed_t is defined to be uint32_t - * and the baud encodings of termios.h are the actual baud values - * themselves. Therefore, any baud value can be provided as the speed - * argument here. However, if you do so, your code will *NOT* be portable - * to other environments where speed_t is smaller and where the termios.h - * baud values are encoded! To avoid portability issues, use the baud - * definitions in termios.h! + * NOTE 1: NuttX does not not control input/output baud rates independently + * Hense, this function is *identical* to cfgetospeed. + * NOTE 2: If this function returns BOTHER and the more flexible input + * speed can be obtained from the Linux-like c_ispeed field. * * Input Parameters: * termiosp - The termiosp argument is a pointer to a termios structure. * * Returned Value: - * Baud value in the termios structure (not verified). + * Encoded baud value from the termios structure. * ****************************************************************************/ speed_t cfgetispeed(const struct termios *termios_p) { DEBUGASSERT(termios_p); - return termios_p->c_ispeed; + return (termios_p->c_cflag & (CBAUD | CBAUDEX)); } diff --git a/lib/termios/lib_cfgetospeed.c b/lib/termios/lib_cfgetospeed.c index 89b4d619c7..9043533329 100644 --- a/lib/termios/lib_cfgetospeed.c +++ b/lib/termios/lib_cfgetospeed.c @@ -70,24 +70,21 @@ * This function shall return exactly the value in the termios data * structure, without interpretation. * - * NON STANDARD BEHAVIOR. In Nuttx, the speed_t is defined to be uint32_t - * and the baud encodings of termios.h are the actual baud values - * themselves. Therefore, any baud value can be provided as the speed - * argument here. However, if you do so, your code will *NOT* be portable - * to other environments where speed_t is smaller and where the termios.h - * baud values are encoded! To avoid portability issues, use the baud - * definitions in termios.h! + * NOTE 1: NuttX does not not control input/output baud rates independently + * Hense, this function is *identical* to cfgetispeed. + * NOTE 2: If this function returns BOTHER and the more flexible input + * speed can be obtained from the Linux-like c_ospeed field. * * Input Parameters: * termiosp - The termiosp argument is a pointer to a termios structure. * * Returned Value: - * Baud value in the termios structure (not verified). + * Encoded baud value from the termios structure. * ****************************************************************************/ speed_t cfgetospeed(const struct termios *termios_p) { DEBUGASSERT(termios_p); - return termios_p->c_ospeed; + return (termios_p->c_cflag & (CBAUD | CBAUDEX)); } diff --git a/lib/termios/lib_cfsetispeed.c b/lib/termios/lib_cfsetispeed.c index 20a05e5017..2aefee0838 100644 --- a/lib/termios/lib_cfsetispeed.c +++ b/lib/termios/lib_cfsetispeed.c @@ -71,26 +71,26 @@ * There is no effect on the baud rates set in the hardware until a * subsequent successful call to tcsetattr() on the same termios structure. * - * NON STANDARD BEHAVIOR. In Nuttx, the speed_t is defined to be uint32_t - * and the baud encodings of termios.h are the actual baud values - * themselves. Therefore, any baud value can be provided as the speed - * argument here. However, if you do so, your code will *NOT* be portable - * to other environments where speed_t is smaller and where the termios.h - * baud values are encoded! To avoid portability issues, use the baud - * definitions in termios.h! + * NOTE 1: NuttX does not not control input/output baud rates independently + * Hense, this function is *identical* to cfsetospeed. + * NOTE 2: If the specia value BOTHER is used, then the actual input baud + * must also be provided in the (non-standard) c_ispeed field. * * Input Parameters: * termiosp - The termiosp argument is a pointer to a termios structure. * speed - The new input speed * * Returned Value: - * Baud is not checked... OK is always returned. + * Baud is not checked... OK is always returned (this is non-standard + * behavior). * ****************************************************************************/ int cfsetispeed(struct termios *termios_p, speed_t speed) { DEBUGASSERT(termios_p); - termios_p->c_ispeed = speed; + speed &= (CBAUD | CBAUDEX); + termios_p->c_cflag &= ~(CBAUD | CBAUDEX); + termios_p->c_cflag |= speed; return OK; } diff --git a/lib/termios/lib_cfsetospeed.c b/lib/termios/lib_cfsetospeed.c index 4a30699e90..cbf8e341ba 100644 --- a/lib/termios/lib_cfsetospeed.c +++ b/lib/termios/lib_cfsetospeed.c @@ -71,26 +71,26 @@ * There is no effect on the baud rates set in the hardware until a * subsequent successful call to tcsetattr() on the same termios structure. * - * NON STANDARD BEHAVIOR. In Nuttx, the speed_t is defined to be uint32_t - * and the baud encodings of termios.h are the actual baud values - * themselves. Therefore, any baud value can be provided as the speed - * argument here. However, if you do so, your code will *NOT* be portable - * to other environments where speed_t is smaller and where the termios.h - * baud values are encoded! To avoid portability issues, use the baud - * definitions in termios.h! + * NOTE 1: NuttX does not not control input/output baud rates independently + * Hense, this function is *identical* to cfsetispeed. + * NOTE 2: If the specia value BOTHER is used, then the actual input baud + * must also be provided in the (non-standard) c_ospeed field. * * Input Parameters: * termiosp - The termiosp argument is a pointer to a termios structure. * speed - The new output speed * * Returned Value: - * Baud is not checked... OK is always returned. + * Baud is not checked... OK is always returned (this is non-standard + * behavior). * ****************************************************************************/ int cfsetospeed(struct termios *termios_p, speed_t speed) { DEBUGASSERT(termios_p); - termios_p->c_ospeed = speed; + speed &= (CBAUD | CBAUDEX); + termios_p->c_cflag &= ~(CBAUD | CBAUDEX); + termios_p->c_cflag |= speed; return OK; }