refactor(st-uart): compute the over sampling dynamically
The parameter over_sampling of stm32_uart_init_s is not required
as it can be computed dynamically from clock rate of the serial
device and the requested baudrate.
Oversampling by 8 is allowed only for higher speed
(up to clock_rate / 8) to reduce the maximum receiver tolerance
to clock deviation.
This patch update the driver, the serial init struct and the
only user, the stm32cubeprogrammer over uart support.
Change-Id: I422731089730a288defeb7fa49886db65d0902b2
Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
diff --git a/drivers/st/uart/stm32_uart.c b/drivers/st/uart/stm32_uart.c
index e2e5405..08bd77b 100644
--- a/drivers/st/uart/stm32_uart.c
+++ b/drivers/st/uart/stm32_uart.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -106,7 +106,33 @@
{
uint32_t tmpreg;
unsigned long clockfreq;
+ unsigned long int_div;
uint32_t brrtemp;
+ uint32_t over_sampling;
+
+ /*---------------------- USART BRR configuration --------------------*/
+ clockfreq = uart_get_clock_freq(huart);
+ if (clockfreq == 0UL) {
+ return -ENODEV;
+ }
+
+ int_div = clockfreq / init->baud_rate;
+ if (int_div < 16U) {
+ uint32_t usartdiv = uart_div_sampling8(clockfreq,
+ init->baud_rate,
+ init->prescaler);
+
+ brrtemp = (usartdiv & USART_BRR_DIV_MANTISSA) |
+ ((usartdiv & USART_BRR_DIV_FRACTION) >> 1);
+ over_sampling = USART_CR1_OVER8;
+ } else {
+ brrtemp = uart_div_sampling16(clockfreq,
+ init->baud_rate,
+ init->prescaler) &
+ (USART_BRR_DIV_FRACTION | USART_BRR_DIV_MANTISSA);
+ over_sampling = 0x0U;
+ }
+ mmio_write_32(huart->base + USART_BRR, brrtemp);
/*
* ---------------------- USART CR1 Configuration --------------------
@@ -115,12 +141,12 @@
* - set the M bits according to init->word_length value,
* - set PCE and PS bits according to init->parity value,
* - set TE and RE bits according to init->mode value,
- * - set OVER8 bit according to init->over_sampling value.
+ * - set OVER8 bit according baudrate and clock.
*/
tmpreg = init->word_length |
init->parity |
init->mode |
- init->over_sampling |
+ over_sampling |
init->fifo_mode;
mmio_clrsetbits_32(huart->base + USART_CR1, STM32_UART_CR1_FIELDS, tmpreg);
@@ -161,27 +187,6 @@
mmio_clrsetbits_32(huart->base + USART_PRESC, USART_PRESC_PRESCALER,
init->prescaler);
- /*---------------------- USART BRR configuration --------------------*/
- clockfreq = uart_get_clock_freq(huart);
- if (clockfreq == 0UL) {
- return -ENODEV;
- }
-
- if (init->over_sampling == STM32_UART_OVERSAMPLING_8) {
- uint32_t usartdiv = uart_div_sampling8(clockfreq,
- init->baud_rate,
- init->prescaler);
-
- brrtemp = (usartdiv & USART_BRR_DIV_MANTISSA) |
- ((usartdiv & USART_BRR_DIV_FRACTION) >> 1);
- } else {
- brrtemp = uart_div_sampling16(clockfreq,
- init->baud_rate,
- init->prescaler) &
- (USART_BRR_DIV_FRACTION | USART_BRR_DIV_MANTISSA);
- }
- mmio_write_32(huart->base + USART_BRR, brrtemp);
-
return 0;
}