summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--stmhal/hal/l4/inc/stm32l4xx_hal_uart.h5
-rw-r--r--stmhal/hal/l4/src/stm32l4xx_hal_uart.c38
2 files changed, 42 insertions, 1 deletions
diff --git a/stmhal/hal/l4/inc/stm32l4xx_hal_uart.h b/stmhal/hal/l4/inc/stm32l4xx_hal_uart.h
index e56aa9ef94..b890c3d987 100644
--- a/stmhal/hal/l4/inc/stm32l4xx_hal_uart.h
+++ b/stmhal/hal/l4/inc/stm32l4xx_hal_uart.h
@@ -962,7 +962,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__)))
+/* 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.
@@ -1369,6 +1370,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/stmhal/hal/l4/src/stm32l4xx_hal_uart.c b/stmhal/hal/l4/src/stm32l4xx_hal_uart.c
index e35c4db8e5..2b0d76d301 100644
--- a/stmhal/hal/l4/src/stm32l4xx_hal_uart.c
+++ b/stmhal/hal/l4/src/stm32l4xx_hal_uart.c
@@ -2101,6 +2101,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;
+}
+
/**
* @}
*/