@@ -413,6 +413,17 @@ bool uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
413413 huart -> Init .Mode = UART_MODE_TX_RX ;
414414 huart -> Init .HwFlowCtl = flow_control ;
415415 huart -> Init .OverSampling = UART_OVERSAMPLING_16 ;
416+
417+ /* Configure UART Clock Prescaler */
418+ #if defined(UART_PRESCALER_DIV1 )
419+ // Default Value
420+ uint32_t clock_prescaler = UART_PRESCALER_DIV1 ;
421+
422+ uint32_t pclk = uart_getPCLK (huart );
423+ clock_prescaler = calculatePresc (pclk , baudrate , huart -> Init .OverSampling );
424+ huart -> Init .ClockPrescaler = clock_prescaler ;
425+ #endif
426+
416427#if defined(UART_ADVFEATURE_NO_INIT )
417428 // Default value
418429 huart -> AdvancedInit .AdvFeatureInit = UART_ADVFEATURE_NO_INIT ;
@@ -1415,6 +1426,162 @@ void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
14151426 serial_t * obj = get_serial_obj (huart );
14161427 HAL_UART_Receive_IT (huart , & (obj -> recv ), 1 );
14171428}
1429+
1430+ /**
1431+ * @brief Function called to set the uart clock prescaler
1432+ * @param pclk : supplied clock rate to related uart
1433+ * @retval uint32_t clock prescaler
1434+ */
1435+ #if defined(UART_PRESCALER_DIV1 )
1436+ uint32_t calculatePresc (uint32_t pclk , uint32_t baudrate , uint32_t oversampling )
1437+ {
1438+ static const uint16_t presc_div [12 ] = {1 , 2 , 4 , 6 , 8 , 10 , 12 , 16 , 32 , 64 , 128 , 256 };
1439+
1440+ uint32_t condition = 0 ;
1441+ if (oversampling == UART_OVERSAMPLING_16 ) {
1442+ condition = 16U ;
1443+ } else {
1444+ condition = 8U ;
1445+ }
1446+
1447+ for (uint32_t idx = 0 ; idx < 8 ; idx ++ ) {
1448+ uint32_t uartclk = pclk / presc_div [idx ];
1449+ uint32_t brr = 0 ;
1450+ if (oversampling == UART_OVERSAMPLING_16 ) {
1451+ brr = (uartclk + (baudrate / 2U )) / baudrate ;
1452+ } else {
1453+ brr = ((2U * uartclk ) + (baudrate / 2U )) / baudrate ;
1454+ }
1455+
1456+ if (brr >= condition && brr <= 0xFFFU ) {
1457+ return UART_PRESCALER_DIV1 + idx ;
1458+ }
1459+ }
1460+ return UART_PRESCALER_DIV1 ;
1461+ }
1462+ #endif
1463+
1464+ /**
1465+ * @brief Function called to get the clock source frequency of the uart
1466+ * @param huart : uart handle structure
1467+ * @retval uint32_t clock source frequency
1468+ */
1469+ uint32_t uart_getPCLK (UART_HandleTypeDef * huart )
1470+ {
1471+ #if defined(LPUART1 )
1472+ if (huart -> Instance == LPUART1 ) {
1473+ #if defined(STM32H5 ) || defined(STM32U3 ) || defined(STM32U5 )
1474+ return HAL_RCC_GetPCLK3Freq ();
1475+ #elif defined(STM32H7 )
1476+ uint32_t sysclk = HAL_RCC_GetSysClockFreq ();
1477+ uint32_t prescaler = (RCC -> D2CFGR & 18 ) >> 0x7 ;
1478+
1479+ uint32_t apb4 = 1 ;
1480+
1481+ switch (prescaler ) {
1482+ case 0b000 : prescaler = 1 ; break ;
1483+ case 0b100 : prescaler = 2 ; break ;
1484+ case 0b101 : prescaler = 4 ; break ;
1485+ case 0b110 : prescaler = 8 ; break ;
1486+ case 0b111 : prescaler = 16 ; break ;
1487+ default : break ;
1488+ }
1489+
1490+ return (sysclk / prescaler );
1491+ #elif defined(STM32G4 ) || defined(STM32L4 ) || defined(STM32L5 ) || defined(STM32WB )
1492+ return HAL_RCC_GetPCLK1Freq ();
1493+ #elif defined(STM32WL ) || defined(STM32WB0 )
1494+ return HAL_RCC_GetPCLK2Freq ();
1495+ #elif defined(STM32WBA )
1496+ return HAL_RCC_GetPCLK7Freq ();
1497+ #endif
1498+ }
1499+ #endif
1500+
1501+ #if defined(LPUART2 )
1502+ if (huart -> Instance == LPUART2 ) {
1503+ return HAL_RCC_GetPCLK1Freq ();
1504+ }
1505+ #endif
1506+
1507+ #if defined(LPUART3 )
1508+ if (huart -> Instance == LPUART3 ) {
1509+ return HAL_RCC_GetPCLK1Freq ();
1510+ }
1511+ #endif
1512+
1513+ #if defined(STM32F0 ) || defined(STM32G0 ) || defined(STM32L0 ) || defined(STM32C0 ) \
1514+ || defined(STM32WB )
1515+ return HAL_RCC_GetPCLK1Freq ();
1516+ #endif
1517+
1518+ #if defined(STM32WB0 )
1519+ RCC_ClkInitTypeDef clkconfig ;
1520+ uint32_t pFLatency ;
1521+
1522+ HAL_RCC_GetClockConfig (& clkconfig , & pFLatency );
1523+
1524+ uint32_t sysclk = HAL_RCC_GetSysClockFreq ();
1525+
1526+ uint32_t ppre2 = clkconfig .SYSCLKDivider ;
1527+ uint32_t apb2_div = (ppre2 == RCC_HCLK_DIV1 ) ? 1 :
1528+ (ppre2 == RCC_HCLK_DIV2 ) ? 2 :
1529+ (ppre2 == RCC_HCLK_DIV4 ) ? 4 :
1530+ (ppre2 == RCC_HCLK_DIV8 ) ? 8 : 16 ;
1531+
1532+ return (sysclk / apb2_div );
1533+ #endif
1534+
1535+ #if defined(STM32WL )
1536+ return HAL_RCC_GetPCLK2Freq ();
1537+ #endif
1538+
1539+ #if defined(STM32H7 )
1540+ if (huart -> Instance == USART1
1541+ #if defined(USART10 )
1542+ || huart -> Instance == USART10
1543+ #endif
1544+ #if defined(USART6 )
1545+ || huart -> Instance == USART6
1546+ #endif
1547+ #if defined(UART9 )
1548+ || huart -> Instance == UART9
1549+ #endif
1550+ ) {
1551+ return HAL_RCC_GetPCLK2Freq ();
1552+ }
1553+ return HAL_RCC_GetPCLK1Freq ();
1554+ #endif
1555+
1556+ #if defined(STM32MP1 )
1557+ if (huart -> Instance == USART1 ) {
1558+ return HAL_RCC_GetPCLK5Freq ();
1559+ }
1560+ else if (huart -> Instance == USART6 ) {
1561+ return HAL_RCC_GetPCLK2Freq ();
1562+ }
1563+ else {
1564+ return HAL_RCC_GetPCLK1Freq ();
1565+ }
1566+ #endif
1567+
1568+ #if defined(STM32F7 ) || defined(STM32F2 ) || defined(STM32F4 ) || defined(STM32F1 ) \
1569+ || defined(STM32U3 ) || defined(STM32F3 ) || defined(STM32H5 ) || defined(STM32G4 ) \
1570+ || defined(STM32L4 ) || defined(STM32L5 ) || defined(STM32WBA ) || defined(STM32U5 ) \
1571+ || defined(STM32L1 )
1572+ if (huart -> Instance == USART1
1573+ #if defined(USART6 ) && !defined(STM32H5 ) && !defined(STM32U5 )
1574+ || huart -> Instance == USART6
1575+ #endif
1576+ ) {
1577+ return HAL_RCC_GetPCLK2Freq ();
1578+ }
1579+ return HAL_RCC_GetPCLK1Freq ();
1580+ #endif
1581+
1582+ return 0 ;
1583+ }
1584+
14181585#endif /* HAL_UART_MODULE_ENABLED && !HAL_UART_MODULE_ONLY */
14191586
14201587#ifdef __cplusplus
0 commit comments