STM32: USART: Fix baudrate calculation for LPUART1

LPUART1 needs BRR to be 256 times the normal value.

Doing this with 64 bit math would work, but that pulls in quite a lot of
code for every platform, even if they don't have LPUART.

A little bit of maths, thanks to zyp on irc, lets us keep it in 32bit,
provided people don't try and use > 16MBaud on LPUARTs

Originally tracked via https://github.com/libopencm3/libopencm3/pull/888
This commit is contained in:
Christian Tacke
2018-03-04 14:19:19 +01:00
committed by Karl Palsson
parent 49a8c041ff
commit c55ec70f49

View File

@@ -42,6 +42,9 @@ USART1/6) or the APB low-speed prescaler clock (for other USARTs). These values
must be correctly set before calling this function (refer to the must be correctly set before calling this function (refer to the
rcc_clock_setup-* functions in RCC). rcc_clock_setup-* functions in RCC).
Note: For LPUART, baudrates over 2**24 (~16.7 Mbaud) may overflow
the calculation and are therefore not supported by this function.
@param[in] usart unsigned 32 bit. USART block register address base @ref @param[in] usart unsigned 32 bit. USART block register address base @ref
usart_reg_base usart_reg_base
@param[in] baud unsigned 32 bit. Baud rate specified in Hz. @param[in] baud unsigned 32 bit. Baud rate specified in Hz.
@@ -70,7 +73,15 @@ void usart_set_baudrate(uint32_t usart, uint32_t baud)
* Note: We round() the value rather than floor()ing it, for more * Note: We round() the value rather than floor()ing it, for more
* accurate divisor selection. * accurate divisor selection.
*/ */
USART_BRR(usart) = ((2 * clock) + baud) / (2 * baud); #ifdef LPUART1
if (usart == LPUART1) {
USART_BRR(usart) = (clock / baud) * 256
+ ((clock % baud) * 256 + baud / 2) / baud;
return;
}
#endif
USART_BRR(usart) = (clock + baud / 2) / baud;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/