Skip to content

Commit 08029ab

Browse files
committed
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 <[email protected]>.
1 parent ef994d7 commit 08029ab

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1290,7 +1290,8 @@ typedef void (*pUART_RxEventCallbackTypeDef)(struct __UART_HandleTypeDef *huart
12901290
* @param __BAUD__ Baud rate set by the user.
12911291
* @retval Division result
12921292
*/
1293-
#define UART_DIV_LPUART(__PCLK__, __BAUD__) (((((uint64_t)(__PCLK__)*256U)) + ((__BAUD__)/2U)) / (__BAUD__))
1293+
/* FIXME tobbad Adapted to avoid 64 bit division. */
1294+
#define UART_DIV_LPUART(__PCLK__, __BAUD__) HAL_UART_CalcBrr((__PCLK__), (__BAUD__))
12941295

12951296
/** @brief BRR division operation to set BRR register in 8-bit oversampling mode.
12961297
* @param __PCLK__ UART clock.
@@ -1771,6 +1772,8 @@ HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pDa
17711772
/**
17721773
* @}
17731774
*/
1775+
/* Functions added by MicroPython */
1776+
uint32_t HAL_UART_CalcBrr(uint32_t fck, uint32_t baud);
17741777

17751778
#ifdef __cplusplus
17761779
}

STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4394,6 +4394,44 @@ static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
43944394
}
43954395
}
43964396

4397+
4398+
/**
4399+
* @brief Calculate register BRR value without using uint64.
4400+
* @note This function is added by the MicroPython project.
4401+
* @param fck: Input clock frequency to the uart block in Hz.
4402+
* @param baud: baud rate should be one of {300, 600, 1200, 2400, 4800, 9600, 19200, 57600, 115200}.
4403+
* @retval BRR value
4404+
*/
4405+
uint32_t HAL_UART_CalcBrr(uint32_t fck, uint32_t baud)
4406+
{
4407+
const struct
4408+
{
4409+
uint32_t limit;
4410+
uint32_t div;
4411+
} comDiv[]= {
4412+
{1<<31, 300 }, /* must be >= 256 */
4413+
{1<<30, 150 }, /* must be >= 128 */
4414+
{1<<29, 75 }, /* must be >= 64 */
4415+
{1<<28, 50 }, /* must be >= 32 */
4416+
{1<<27, 20 }, /* must be >= 16 */
4417+
{1<<26, 10 }, /* must be >= 8 */
4418+
{1<<25, 5 }, /* must be >= 4 */
4419+
{1<<24, 2 } /* must be >= 2 */
4420+
};
4421+
const uint32_t comDivCnt = sizeof(comDiv)/sizeof(comDiv[0]);
4422+
uint8_t i;
4423+
for (i=0; i<comDivCnt ;i++)
4424+
{
4425+
if (fck >= comDiv[i].limit)
4426+
{
4427+
fck /= comDiv[i].div;
4428+
baud /= comDiv[i].div;
4429+
break;
4430+
}
4431+
}
4432+
return (fck<<8)/baud;
4433+
}
4434+
43974435
/**
43984436
* @brief RX interrupt handler for 9 bits data word length .
43994437
* @note Function is called under interruption only, once

0 commit comments

Comments
 (0)