From 909ea5e8efbb57a9a37752dd1cae894fd051f1e8 Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Sat, 15 Oct 2016 03:55:48 -1000 Subject: [PATCH] F4 Support versampling by 8 --- arch/arm/src/stm32/stm32_serial.c | 58 +++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/arch/arm/src/stm32/stm32_serial.c b/arch/arm/src/stm32/stm32_serial.c index eeb5a846a7b..381df6c016f 100644 --- a/arch/arm/src/stm32/stm32_serial.c +++ b/arch/arm/src/stm32/stm32_serial.c @@ -1190,15 +1190,20 @@ static void up_set_format(struct uart_dev_s *dev) { struct up_dev_s *priv = (struct up_dev_s *)dev->priv; uint32_t regval; + uint32_t brr; + + /* Load CR1 */ + + regval = up_serialin(priv, STM32_USART_CR1_OFFSET); #if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) /* This first implementation is for U[S]ARTs that support oversampling * by 8 in additional to the standard oversampling by 16. + * With baud rate of fCK / Divider for oversampling by 16. + * and baud rate of 2 * fCK / Divider for oversampling by 8 */ uint32_t usartdiv8; - uint32_t cr1; - uint32_t brr; /* In case of oversampling by 8, the equation is: * @@ -1218,7 +1223,6 @@ static void up_set_format(struct uart_dev_s *dev) /* Use oversamply by 8 only if the divisor is small. But what is small? */ - cr1 = up_serialin(priv, STM32_USART_CR1_OFFSET); if (usartdiv8 > 100) { /* Use usartdiv16 */ @@ -1227,7 +1231,7 @@ static void up_set_format(struct uart_dev_s *dev) /* Clear oversampling by 8 to enable oversampling by 16 */ - cr1 &= ~USART_CR1_OVER8; + regval &= ~USART_CR1_OVER8; } else { @@ -1239,12 +1243,9 @@ static void up_set_format(struct uart_dev_s *dev) /* Set oversampling by 8 */ - cr1 |= USART_CR1_OVER8; + regval |= USART_CR1_OVER8; } - up_serialout(priv, STM32_USART_CR1_OFFSET, cr1); - up_serialout(priv, STM32_USART_BRR_OFFSET, brr); - #else /* This second implementation is for U[S]ARTs that support fractional @@ -1254,7 +1255,6 @@ static void up_set_format(struct uart_dev_s *dev) 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 @@ -1272,23 +1272,53 @@ static void up_set_format(struct uart_dev_s *dev) * usartdiv32 = 32 * usartdiv = fCK / (baud/2) */ - usartdiv32 = priv->apbclock / (priv->baud >> 1); + 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); + +#if defined(CONFIG_STM32_STM32F40XX) + + /* The F4 supports 8 X in oversampling additional to the + * standard oversampling by 16. + * With baud rate of fCK / (16 * Divider) for oversampling by 16. + * and baud rate of fCK / (8 * Divider) for oversampling by 8 + */ + + /* Check if 8x oversampling is necessary */ + + if (mantissa == 0) + { + regval |= USART_CR1_OVER8; + + /* Rescale the mantissa */ + + mantissa = usartdiv32 >> 4; + + /* The fractional remainder (with rounding) */ + + fraction = (usartdiv32 - (mantissa << 4) + 1) >> 1; + } + else + {/* Use 16x Oversampling */ + regval &= ~USART_CR1_OVER8; + } #endif + brr = mantissa << USART_BRR_MANT_SHIFT; + brr |= fraction << USART_BRR_FRAC_SHIFT; +#endif + + up_serialout(priv, STM32_USART_CR1_OFFSET, regval); + up_serialout(priv, STM32_USART_BRR_OFFSET, brr); + /* Configure parity mode */ - regval = up_serialin(priv, STM32_USART_CR1_OFFSET); regval &= ~(USART_CR1_PCE | USART_CR1_PS | USART_CR1_M); if (priv->parity == 1) /* Odd parity */