@@ -413,6 +413,18 @@ 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+   huart -> Init .ClockPrescaler  =  uart_compute_prescaler (huart );
420+   if  (!IS_UART_PRESCALER (huart -> Init .ClockPrescaler )) {
421+     if  (obj  !=  & serial_debug ) {
422+       core_debug ("WARNING: [U(S)ART] wrong prescaler, reset to UART_PRESCALER_DIV1!\n" );
423+     }
424+     huart -> Init .ClockPrescaler  =  UART_PRESCALER_DIV1 ;
425+   }
426+ #endif 
427+ 
416428#if  defined(UART_ADVFEATURE_NO_INIT )
417429  // Default value 
418430  huart -> AdvancedInit .AdvFeatureInit  =  UART_ADVFEATURE_NO_INIT ;
@@ -1415,6 +1427,144 @@ void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
14151427  serial_t  * obj  =  get_serial_obj (huart );
14161428  HAL_UART_Receive_IT (huart ,  & (obj -> recv ), 1 );
14171429}
1430+ 
1431+ /** 
1432+   * @brief  Function called to set the uart clock prescaler 
1433+   * @param  huart : uart handle structure 
1434+   * @retval uint32_t clock prescaler 
1435+   */ 
1436+ #if  defined(UART_PRESCALER_DIV1 )
1437+ uint32_t  uart_compute_prescaler (UART_HandleTypeDef  * huart )
1438+ {
1439+   uint32_t  prescaler  =  UART_PRESCALER_DIV1 ;
1440+   static  const  uint16_t  presc_div [12 ] =  {1 , 2 , 4 , 6 , 8 , 10 , 12 , 16 , 32 , 64 , 128 , 256 };
1441+   uint32_t  freq  =  uart_get_clock_source_freq (huart );
1442+   uint32_t  usartdiv  =  0 ;
1443+ 
1444+ #if  defined(UART_INSTANCE_LOWPOWER )
1445+   if  (UART_INSTANCE_LOWPOWER (huart )) {
1446+     for  (uint32_t  idx  =  0 ; idx  <  12 ; idx ++ ) {
1447+       /* Check computed UsartDiv value is in allocated range 
1448+         (it is forbidden to write values lower than 0x300 in the LPUART_BRR register) */ 
1449+       usartdiv  =  (uint32_t )(UART_DIV_LPUART (freq , huart -> Init .BaudRate , presc_div [idx ]));
1450+       if  ((usartdiv  >= 0x00000300U ) &&  (usartdiv  <= 0x000FFFFFU )) {
1451+         prescaler  =  UART_PRESCALER_DIV1  +  idx ;
1452+         break ;
1453+       }
1454+     }
1455+   } else 
1456+ #endif  /* UART_INSTANCE_LOWPOWER */ 
1457+   {
1458+     for  (uint32_t  idx  =  0 ; idx  <  12 ; idx ++ ) {
1459+       if  (huart -> Init .OverSampling  ==  UART_OVERSAMPLING_8 ) {
1460+         usartdiv  =  (uint32_t )(UART_DIV_SAMPLING8 (freq , huart -> Init .BaudRate , presc_div [idx ]));
1461+       } else  {
1462+         usartdiv  =  (uint32_t )(UART_DIV_SAMPLING16 (freq , huart -> Init .BaudRate , presc_div [idx ]));
1463+       }
1464+       if  ((usartdiv  >= 0x10U ) &&  (usartdiv  <= 0x0000FFFFU )) {
1465+         prescaler  =  UART_PRESCALER_DIV1  +  idx ;
1466+         break ;
1467+       }
1468+     }
1469+   }
1470+   return  prescaler ;
1471+ }
1472+ 
1473+ /** 
1474+   * @brief  Function called to get the clock source frequency of the uart 
1475+   * @param  huart : uart handle structure 
1476+   * @retval uint32_t clock source frequency 
1477+   */ 
1478+ uint32_t  uart_get_clock_source_freq (UART_HandleTypeDef  * huart )
1479+ {
1480+   uint32_t  freq  =  0 ;
1481+ #if  defined(STM32WB0 )
1482+   freq  =  UART_PERIPHCLK ;
1483+   if  (UART_INSTANCE_LOWPOWER (huart )) {
1484+ #if  defined(RCC_CFGR_LPUCLKSEL )
1485+     freq  =  HAL_RCCEx_GetPeriphCLKFreq (RCC_PERIPHCLK_LPUART1 );
1486+ #endif  /* RCC_CFGR_LPUCLKSEL */ 
1487+   }
1488+ #else  /* !STM32WB0 */ 
1489+   uint32_t  clocksource ;
1490+   UART_GETCLOCKSOURCE (huart , clocksource );
1491+ #if  defined(STM32H5 ) ||  defined(STM32MP1 ) ||  defined(STM32U0 ) || \
1492+     defined(STM32U3 ) ||  defined(STM32U5 )
1493+   freq  =  HAL_RCCEx_GetPeriphCLKFreq (clocksource );
1494+ #else 
1495+   switch  (clocksource ) {
1496+ #if  defined(UART_CLOCKSOURCE_D2PCLK1 ) ||  defined(UART_CLOCKSOURCE_PCLK1 )
1497+ #if  defined(UART_CLOCKSOURCE_D2PCLK1 )
1498+     case  UART_CLOCKSOURCE_D2PCLK1 :
1499+ #endif  /* UART_CLOCKSOURCE_D2PCLK1*/ 
1500+ #if  defined(UART_CLOCKSOURCE_PCLK1 )
1501+     case  UART_CLOCKSOURCE_PCLK1 :
1502+ #endif  /* UART_CLOCKSOURCE_PCLK1 */ 
1503+       freq  =  HAL_RCC_GetPCLK1Freq ();
1504+       break ;
1505+ #endif  /* UART_CLOCKSOURCE_D2PCLK1 || UART_CLOCKSOURCE_PCLK1*/ 
1506+ #if  defined(UART_CLOCKSOURCE_D2PCLK2 ) ||  defined(UART_CLOCKSOURCE_PCLK2 )
1507+ #if  defined(UART_CLOCKSOURCE_D2PCLK2 )
1508+     case  UART_CLOCKSOURCE_D2PCLK2 :
1509+ #endif  /* UART_CLOCKSOURCE_D2PCLK2*/ 
1510+ #if  defined(UART_CLOCKSOURCE_PCLK2 )
1511+     case  UART_CLOCKSOURCE_PCLK2 :
1512+ #endif  /* UART_CLOCKSOURCE_PCLK2 */ 
1513+       freq  =  HAL_RCC_GetPCLK2Freq ();
1514+       break ;
1515+ #endif  /* UART_CLOCKSOURCE_D2PCLK2 || UART_CLOCKSOURCE_PCLK2*/ 
1516+ #if  defined(UART_CLOCKSOURCE_PCLK7 )
1517+     case  UART_CLOCKSOURCE_PCLK7 :
1518+       freq  =  HAL_RCC_GetPCLK7Freq ();
1519+       break ;
1520+ #endif  /* UART_CLOCKSOURCE_PCLK7 */ 
1521+ #if  defined(UART_CLOCKSOURCE_PLL2 )
1522+     case  UART_CLOCKSOURCE_PLL2 :
1523+       HAL_RCCEx_GetPLL2ClockFreq (& pll2_clocks );
1524+       freq  =  pll2_clocks .PLL2_Q_Frequency ;
1525+       break ;
1526+     case  UART_CLOCKSOURCE_PLL3 :
1527+       HAL_RCCEx_GetPLL3ClockFreq (& pll3_clocks );
1528+       freq  =  pll3_clocks .PLL3_Q_Frequency ;
1529+       break ;
1530+ #endif  /* UART_CLOCKSOURCE_PLL2 */ 
1531+     case  UART_CLOCKSOURCE_HSI :
1532+ #if  defined(__HAL_RCC_GET_HSIKER_DIVIDER )
1533+       freq  =  (HSI_VALUE  / ((__HAL_RCC_GET_HSIKER_DIVIDER () >> RCC_CR_HSIKERDIV_Pos ) +  1U ));
1534+ #else 
1535+ #if  defined(RCC_FLAG_HSIDIV )
1536+       if  (__HAL_RCC_GET_FLAG (RCC_FLAG_HSIDIV ) !=  0U ) {
1537+         freq  =  (uint32_t )(HSI_VALUE  >> (__HAL_RCC_GET_HSI_DIVIDER () >> 3U ));
1538+       } else 
1539+ #endif  /* RCC_FLAG_HSIDIV */ 
1540+       {
1541+         freq  =  (uint32_t ) HSI_VALUE ;
1542+       }
1543+ #endif 
1544+       break ;
1545+ #if  defined(UART_CLOCKSOURCE_CSI )
1546+     case  UART_CLOCKSOURCE_CSI :
1547+       freq  =  (uint32_t ) CSI_VALUE ;
1548+       break ;
1549+ #endif  /* UART_CLOCKSOURCE_CSI */ 
1550+ #if  defined(UART_CLOCKSOURCE_SYSCLK )
1551+     case  UART_CLOCKSOURCE_SYSCLK :
1552+       freq  =  HAL_RCC_GetSysClockFreq ();
1553+       break ;
1554+ #endif  /* UART_CLOCKSOURCE_SYSCLK */ 
1555+     case  UART_CLOCKSOURCE_LSE :
1556+       freq  =  (uint32_t ) LSE_VALUE ;
1557+       break ;
1558+     default :
1559+       freq  =  0U ;
1560+       break ;
1561+   }
1562+ #endif  /* STM32H5 */ 
1563+ #endif  /* STM32WB0 */ 
1564+   return  freq ;
1565+ }
1566+ #endif  /* UART_PRESCALER_DIV1 */ 
1567+ 
14181568#endif  /* HAL_UART_MODULE_ENABLED  && !HAL_UART_MODULE_ONLY */ 
14191569
14201570#ifdef  __cplusplus 
0 commit comments