diff options
author | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-07-23 15:37:13 +0000 |
---|---|---|
committer | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-07-23 15:37:13 +0000 |
commit | cb068d372e6a41d74273984d3635d3b24dcec51f (patch) | |
tree | bdace79b95ff390c7c1b0ccdd005816be2c83e6c /nuttx/arch/arm/src/stm32 | |
parent | 75fe5b4be3d997da38669b2b50b263aba8515889 (diff) |
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: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4970 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx/arch/arm/src/stm32')
-rw-r--r-- | nuttx/arch/arm/src/stm32/Kconfig | 9 | ||||
-rw-r--r-- | nuttx/arch/arm/src/stm32/stm32_serial.c | 175 |
2 files changed, 139 insertions, 45 deletions
diff --git a/nuttx/arch/arm/src/stm32/Kconfig b/nuttx/arch/arm/src/stm32/Kconfig index efeb3c8556..5d0d48f880 100644 --- a/nuttx/arch/arm/src/stm32/Kconfig +++ b/nuttx/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/nuttx/arch/arm/src/stm32/stm32_serial.c b/nuttx/arch/arm/src/stm32/stm32_serial.c index a5864acb63..aaed6270fa 100644 --- a/nuttx/arch/arm/src/stm32/stm32_serial.c +++ b/nuttx/arch/arm/src/stm32/stm32_serial.c @@ -53,6 +53,10 @@ #include <nuttx/serial/serial.h> #include <nuttx/power/pm.h> +#ifdef CONFIG_SERIAL_TERMIOS +# include <termios.h> +#endif + #include <arch/serial.h> #include <arch/board/board.h> @@ -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); @@ -771,6 +788,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 * * Description: @@ -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 */ |