From 12581895158f0ff43f277d991c62ea7d0478a836 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 2 Mar 2022 15:29:08 +0100 Subject: [PATCH] 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 --- drivers/st/uart/stm32_uart.c | 53 +++++++++++++---------- include/drivers/st/stm32_uart.h | 13 +----- plat/st/common/stm32cubeprogrammer_uart.c | 3 +- 3 files changed, 31 insertions(+), 38 deletions(-) diff --git a/drivers/st/uart/stm32_uart.c b/drivers/st/uart/stm32_uart.c index e2e540511..08bd77b9a 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 @@ static int uart_set_config(struct stm32_uart_handle_s *huart, { 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 @@ static int uart_set_config(struct stm32_uart_handle_s *huart, * - 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 @@ static int uart_set_config(struct stm32_uart_handle_s *huart, 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; } diff --git a/include/drivers/st/stm32_uart.h b/include/drivers/st/stm32_uart.h index 212968f57..866e15890 100644 --- a/include/drivers/st/stm32_uart.h +++ b/include/drivers/st/stm32_uart.h @@ -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 */ @@ -34,10 +34,6 @@ #define STM32_UART_HWCONTROL_CTS USART_CR3_CTSE #define STM32_UART_HWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) -/* UART over sampling */ -#define STM32_UART_OVERSAMPLING_16 0x00000000U -#define STM32_UART_OVERSAMPLING_8 USART_CR1_OVER8 - /* UART prescaler */ #define STM32_UART_PRESCALER_DIV1 0x00000000U #define STM32_UART_PRESCALER_DIV2 0x00000001U @@ -112,13 +108,6 @@ struct stm32_uart_init_s { * value of @ref STM32_UARTHWCONTROL_*. */ - uint32_t over_sampling; /* - * Specifies whether the over sampling - * 8 is enabled or disabled. - * This parameter can be a value of - * @ref STM32_UART_OVERSAMPLING_*. - */ - uint32_t one_bit_sampling; /* * Specifies whether a single sample * or three samples' majority vote is diff --git a/plat/st/common/stm32cubeprogrammer_uart.c b/plat/st/common/stm32cubeprogrammer_uart.c index 46ac9cf17..95207030c 100644 --- a/plat/st/common/stm32cubeprogrammer_uart.c +++ b/plat/st/common/stm32cubeprogrammer_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 */ @@ -492,7 +492,6 @@ const struct stm32_uart_init_s init = { .parity = STM32_UART_PARITY_EVEN, .hw_flow_control = STM32_UART_HWCONTROL_NONE, .mode = STM32_UART_MODE_TX_RX, - .over_sampling = STM32_UART_OVERSAMPLING_16, .fifo_mode = STM32_UART_FIFOMODE_EN, }; -- 2.39.5