@@ -413,6 +413,17 @@ bool uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
413
413
huart -> Init .Mode = UART_MODE_TX_RX ;
414
414
huart -> Init .HwFlowCtl = flow_control ;
415
415
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
+
416
427
#if defined(UART_ADVFEATURE_NO_INIT )
417
428
// Default value
418
429
huart -> AdvancedInit .AdvFeatureInit = UART_ADVFEATURE_NO_INIT ;
@@ -1415,6 +1426,163 @@ void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
1415
1426
serial_t * obj = get_serial_obj (huart );
1416
1427
HAL_UART_Receive_IT (huart , & (obj -> recv ), 1 );
1417
1428
}
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
+ #if defined(STM32H7A3xx ) || defined (STM32H7A3xxQ ) || defined(STM32H7B3xx ) || defined(STM32H7B3xxQ ) || defined(STM32H7B0xx ) || defined(STM32H7B0xxQ )
1478
+ uint32_t prescaler = (RCC -> CDCFGR2 & (0x7UL << 9U )) >> 9U ;
1479
+ #else
1480
+ uint32_t prescaler = (RCC -> D2CFGR & (0x7UL << 9U )) >> 9U ;
1481
+ #endif
1482
+
1483
+ uint32_t apb4 = 1 ;
1484
+
1485
+ switch (prescaler ) {
1486
+ case 0b000 : prescaler = 1 ; break ;
1487
+ case 0b100 : prescaler = 2 ; break ;
1488
+ case 0b101 : prescaler = 4 ; break ;
1489
+ case 0b110 : prescaler = 8 ; break ;
1490
+ case 0b111 : prescaler = 16 ; break ;
1491
+ default : break ;
1492
+ }
1493
+
1494
+ return (sysclk / prescaler );
1495
+ #elif defined(STM32G4 ) || defined(STM32L4 ) || defined(STM32L5 ) || defined(STM32WB )
1496
+ return HAL_RCC_GetPCLK1Freq ();
1497
+ #elif defined(STM32WL )
1498
+ return HAL_RCC_GetPCLK2Freq ();
1499
+ #elif defined(STM32WBA )
1500
+ return HAL_RCC_GetPCLK7Freq ();
1501
+ #endif
1502
+ }
1503
+ #endif
1504
+
1505
+ #if defined(LPUART2 )
1506
+ if (huart -> Instance == LPUART2 ) {
1507
+ return HAL_RCC_GetPCLK1Freq ();
1508
+ }
1509
+ #endif
1510
+
1511
+ #if defined(LPUART3 )
1512
+ if (huart -> Instance == LPUART3 ) {
1513
+ return HAL_RCC_GetPCLK1Freq ();
1514
+ }
1515
+ #endif
1516
+
1517
+ #if defined(STM32F0 ) || defined(STM32G0 ) || defined(STM32L0 ) || defined(STM32C0 ) \
1518
+ || defined(STM32WB )
1519
+ return HAL_RCC_GetPCLK1Freq ();
1520
+ #endif
1521
+
1522
+ #if defined(STM32WB0 )
1523
+ uint32_t sysclk = HAL_RCC_GetSysClockFreq ();
1524
+ uint32_t ppre2 = (RCC -> CFGR & (0x7UL << 11U )) >> 11U ;
1525
+ uint32_t apb2_div = 1 ;
1526
+
1527
+ switch (ppre2 ) {
1528
+ case 0b000 : apb2_div = 1 ; break ;
1529
+ case 0b100 : apb2_div = 2 ; break ;
1530
+ case 0b101 : apb2_div = 4 ; break ;
1531
+ case 0b110 : apb2_div = 8 ; break ;
1532
+ case 0b111 : apb2_div = 16 ; break ;
1533
+ default : break ;
1534
+ }
1535
+ return (sysclk / apb2_div );
1536
+ #endif
1537
+
1538
+ #if defined(STM32WL )
1539
+ return HAL_RCC_GetPCLK2Freq ();
1540
+ #endif
1541
+
1542
+ #if defined(STM32H7 )
1543
+ if (huart -> Instance == USART1
1544
+ #if defined(USART10 )
1545
+ || huart -> Instance == USART10
1546
+ #endif
1547
+ #if defined(USART6 )
1548
+ || huart -> Instance == USART6
1549
+ #endif
1550
+ #if defined(UART9 )
1551
+ || huart -> Instance == UART9
1552
+ #endif
1553
+ ) {
1554
+ return HAL_RCC_GetPCLK2Freq ();
1555
+ }
1556
+ return HAL_RCC_GetPCLK1Freq ();
1557
+ #endif
1558
+
1559
+ #if defined(STM32MP1 )
1560
+ if (huart -> Instance == USART1 ) {
1561
+ return HAL_RCC_GetPCLK5Freq ();
1562
+ } else if (huart -> Instance == USART6 ) {
1563
+ return HAL_RCC_GetPCLK2Freq ();
1564
+ } else {
1565
+ return HAL_RCC_GetPCLK1Freq ();
1566
+ }
1567
+ #endif
1568
+
1569
+ #if defined(STM32F7 ) || defined(STM32F2 ) || defined(STM32F4 ) || defined(STM32F1 ) \
1570
+ || defined(STM32U3 ) || defined(STM32F3 ) || defined(STM32H5 ) || defined(STM32G4 ) \
1571
+ || defined(STM32L4 ) || defined(STM32L5 ) || defined(STM32WBA ) || defined(STM32U5 ) \
1572
+ || defined(STM32L1 )
1573
+ if (huart -> Instance == USART1
1574
+ #if defined(USART6 ) && !defined(STM32H5 ) && !defined(STM32U5 )
1575
+ || huart -> Instance == USART6
1576
+ #endif
1577
+ ) {
1578
+ return HAL_RCC_GetPCLK2Freq ();
1579
+ }
1580
+ return HAL_RCC_GetPCLK1Freq ();
1581
+ #endif
1582
+
1583
+ return 0 ;
1584
+ }
1585
+
1418
1586
#endif /* HAL_UART_MODULE_ENABLED && !HAL_UART_MODULE_ONLY */
1419
1587
1420
1588
#ifdef __cplusplus
0 commit comments