diff options
author | Patrick Delaunay <patrick.delaunay@foss.st.com> | 2022-03-02 15:29:08 +0100 |
---|---|---|
committer | Yann Gautier <yann.gautier@st.com> | 2022-09-23 15:17:43 +0200 |
commit | 12581895158f0ff43f277d991c62ea7d0478a836 (patch) | |
tree | 23ff3b22c7edd4a70a8adac4b1e148c58517c717 /drivers/st | |
parent | 278bc857d8a6a317f8598ee5ade04a8914e6d110 (diff) | |
download | arm-trusted-firmware-12581895158f0ff43f277d991c62ea7d0478a836.tar.gz |
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>
Diffstat (limited to 'drivers/st')
-rw-r--r-- | drivers/st/uart/stm32_uart.c | 53 |
1 files changed, 29 insertions, 24 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; } |