summaryrefslogtreecommitdiffstats
path: root/nuttx/arch/arm/src/stm32
diff options
context:
space:
mode:
authorpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2012-07-23 15:37:13 +0000
committerpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2012-07-23 15:37:13 +0000
commitcb068d372e6a41d74273984d3635d3b24dcec51f (patch)
treebdace79b95ff390c7c1b0ccdd005816be2c83e6c /nuttx/arch/arm/src/stm32
parent75fe5b4be3d997da38669b2b50b263aba8515889 (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/Kconfig9
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_serial.c175
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 */