Skip to content

Commit

Permalink
L4_HAL/uart: Adapt UART HAL to avoid 64-bit integer division.
Browse files Browse the repository at this point in the history
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 <python@baerospace.ch>.
  • Loading branch information
dpgeorge committed Aug 29, 2017
1 parent a6f64fe commit d2bcfda
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
5 changes: 4 additions & 1 deletion STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
}
Expand Down
38 changes: 38 additions & 0 deletions STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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<comDivCnt ;i++)
{
if (fck >= comDiv[i].limit)
{
fck /= comDiv[i].div;
baud /= comDiv[i].div;
break;
}
}
return (fck<<8)/baud;
}

/**
* @}
*/
Expand Down

0 comments on commit d2bcfda

Please sign in to comment.