From e51d48ac338a7b6c6e331ed38d60e93412b79650 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 27 Aug 2017 22:17:52 +1000 Subject: [PATCH] L4_HAL/uart: Adapt UART HAL to avoid 64-bit integer division. 64-bit integer division brings a dependency on library functions. It is avoided here by dividing fck and baud by a common divisior. The error is the better (1/(2*0x300)) as with 64 bit division (1/(0x300)). This patch is originally from the MicroPython repository and due to Tobias Badertscher . --- STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h | 5 ++- STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c | 38 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h b/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h index ad73b48..8d5b579 100644 --- a/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h +++ b/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h @@ -1007,7 +1007,8 @@ typedef struct * @param __BAUD__: Baud rate set by the user. * @retval Division result */ -#define UART_DIV_LPUART(__PCLK__, __BAUD__) ((((uint64_t)(__PCLK__)*256) + ((__BAUD__)/2)) / (__BAUD__)) +/* FIXME tobbad Adapted to avoid 64 bit division. */ +#define UART_DIV_LPUART(__PCLK__, __BAUD__) HAL_UART_CalcBrr((__PCLK__), (__BAUD__)) /** @brief BRR division operation to set BRR register in 8-bit oversampling mode. * @param __PCLK__: UART clock. @@ -1425,6 +1426,8 @@ void UART_AdvFeatureConfig(UART_HandleTypeDef *huart); /** * @} */ +/* Functions added by MicroPython */ +uint32_t HAL_UART_CalcBrr(uint32_t fck, uint32_t baud); #ifdef __cplusplus } diff --git a/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c b/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c index 7c3bc1c..09fde8c 100644 --- a/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c +++ b/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c @@ -2767,6 +2767,44 @@ static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) } } + +/** + * @brief Calculate register BRR value without using uint64. + * @note This function is added by the MicroPython project. + * @param fck: Input clock frequency to the uart block in Hz. + * @param baud: baud rate should be one of {300, 600, 1200, 2400, 4800, 9600, 19200, 57600, 115200}. + * @retval BRR value + */ +uint32_t HAL_UART_CalcBrr(uint32_t fck, uint32_t baud) +{ + const struct + { + uint32_t limit; + uint32_t div; + } comDiv[]= { + {1<<31, 300 }, /* must be >= 256 */ + {1<<30, 150 }, /* must be >= 128 */ + {1<<29, 75 }, /* must be >= 64 */ + {1<<28, 50 }, /* must be >= 32 */ + {1<<27, 20 }, /* must be >= 16 */ + {1<<26, 10 }, /* must be >= 8 */ + {1<<25, 5 }, /* must be >= 4 */ + {1<<24, 2 } /* must be >= 2 */ + }; + const uint32_t comDivCnt = sizeof(comDiv)/sizeof(comDiv[0]); + uint8_t i; + for (i=0; i= comDiv[i].limit) + { + fck /= comDiv[i].div; + baud /= comDiv[i].div; + break; + } + } + return (fck<<8)/baud; +} + /** * @} */