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>.work-f1-1.10.2
| @@ -1007,7 +1007,8 @@ typedef struct | |||||
| * @param __BAUD__: Baud rate set by the user. | * @param __BAUD__: Baud rate set by the user. | ||||
| * @retval Division result | * @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. | /** @brief BRR division operation to set BRR register in 8-bit oversampling mode. | ||||
| * @param __PCLK__: UART clock. | * @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 | #ifdef __cplusplus | ||||
| } | } | ||||
| @@ -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; | |||||
| } | |||||
| /** | /** | ||||
| * @} | * @} | ||||
| */ | */ | ||||