Skip to content

Commit d4c3349

Browse files
Tobias Badertscherdpgeorge
authored andcommitted
stmhal: L4: 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)).
1 parent f4942db commit d4c3349

2 files changed

Lines changed: 42 additions & 1 deletion

File tree

stmhal/hal/l4/inc/stm32l4xx_hal_uart.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,8 @@ typedef struct
962962
* @param __BAUD__: Baud rate set by the user.
963963
* @retval Division result
964964
*/
965-
#define UART_DIV_LPUART(__PCLK__, __BAUD__) (((uint64_t)(__PCLK__)*256)/((__BAUD__)))
965+
/* FIXME tobbad Adapted to avoid 64 bit division. */
966+
#define UART_DIV_LPUART(__PCLK__, __BAUD__) HAL_UART_CalcBrr((__PCLK__), (__BAUD__))
966967

967968
/** @brief BRR division operation to set BRR register in 8-bit oversampling mode.
968969
* @param __PCLK__: UART clock.
@@ -1369,6 +1370,8 @@ void UART_AdvFeatureConfig(UART_HandleTypeDef *huart);
13691370
/**
13701371
* @}
13711372
*/
1373+
/* Functions added by micropython */
1374+
uint32_t HAL_UART_CalcBrr(uint32_t fck, uint32_t baud);
13721375

13731376
#ifdef __cplusplus
13741377
}

stmhal/hal/l4/src/stm32l4xx_hal_uart.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,6 +2101,44 @@ static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
21012101
}
21022102
}
21032103

2104+
2105+
/**
2106+
* @brief Calculate register BRR value without using uint64.
2107+
* @note This function is added by the micropython project.
2108+
* @param fck: Input clock frequency to the uart block in Hz.
2109+
* @param baud: baud rate should be one of {300, 600, 1200, 2400, 4800, 9600, 19200, 57600, 115200}.
2110+
* @retval BRR value
2111+
*/
2112+
uint32_t HAL_UART_CalcBrr(uint32_t fck, uint32_t baud)
2113+
{
2114+
const struct
2115+
{
2116+
uint32_t limit;
2117+
uint32_t div;
2118+
} comDiv[]= {
2119+
{1<<31, 300 }, /* must be >= 256 */
2120+
{1<<30, 150 }, /* must be >= 128 */
2121+
{1<<29, 75 }, /* must be >= 64 */
2122+
{1<<28, 50 }, /* must be >= 32 */
2123+
{1<<27, 20 }, /* must be >= 16 */
2124+
{1<<26, 10 }, /* must be >= 8 */
2125+
{1<<25, 5 }, /* must be >= 4 */
2126+
{1<<24, 2 } /* must be >= 2 */
2127+
};
2128+
const uint32_t comDivCnt = sizeof(comDiv)/sizeof(comDiv[0]);
2129+
uint8_t i;
2130+
for (i=0; i<comDivCnt ;i++)
2131+
{
2132+
if (fck >= comDiv[i].limit)
2133+
{
2134+
fck /= comDiv[i].div;
2135+
baud /= comDiv[i].div;
2136+
break;
2137+
}
2138+
}
2139+
return (fck<<8)/baud;
2140+
}
2141+
21042142
/**
21052143
* @}
21062144
*/

0 commit comments

Comments
 (0)