@@ -413,6 +413,18 @@ 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
+ 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
+
416
428
#if defined(UART_ADVFEATURE_NO_INIT )
417
429
// Default value
418
430
huart -> AdvancedInit .AdvFeatureInit = UART_ADVFEATURE_NO_INIT ;
@@ -1415,6 +1427,166 @@ void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
1415
1427
serial_t * obj = get_serial_obj (huart );
1416
1428
HAL_UART_Receive_IT (huart , & (obj -> recv ), 1 );
1417
1429
}
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
+
1443
+ uint32_t condition = 0 ;
1444
+ if (huart -> Init .OverSampling == UART_OVERSAMPLING_16 ) {
1445
+ condition = 16U ;
1446
+ } else {
1447
+ condition = 8U ;
1448
+ }
1449
+
1450
+ for (uint32_t idx = 0 ; idx < 12 ; idx ++ ) {
1451
+ uint32_t uartclk = freq / presc_div [idx ];
1452
+ uint32_t brr = 0 ;
1453
+ if (huart -> Init .OverSampling == UART_OVERSAMPLING_16 ) {
1454
+ brr = (uartclk + (huart -> Init .BaudRate / 2U )) / huart -> Init .BaudRate ;
1455
+ } else {
1456
+ brr = ((2U * uartclk ) + (huart -> Init .BaudRate / 2U )) / huart -> Init .BaudRate ;
1457
+ }
1458
+
1459
+ if (brr >= condition && brr <= 0xFFFU ) {
1460
+ prescaler = UART_PRESCALER_DIV1 + idx ;
1461
+ break ;
1462
+ }
1463
+ }
1464
+ return prescaler ;
1465
+ }
1466
+
1467
+ /**
1468
+ * @brief Function called to get the clock source frequency of the uart
1469
+ * @param huart : uart handle structure
1470
+ * @retval uint32_t clock source frequency
1471
+ */
1472
+ uint32_t uart_get_clock_source_freq (UART_HandleTypeDef * huart )
1473
+ {
1474
+ #if defined(LPUART1 )
1475
+ if (huart -> Instance == LPUART1 ) {
1476
+ #if defined(STM32H5 ) || defined(STM32U3 ) || defined(STM32U5 )
1477
+ return HAL_RCC_GetPCLK3Freq ();
1478
+ #elif defined(STM32H7 )
1479
+ uint32_t sysclk = HAL_RCC_GetSysClockFreq ();
1480
+ #if defined(STM32H7A3xx ) || defined (STM32H7A3xxQ ) || defined(STM32H7B3xx ) || defined(STM32H7B3xxQ ) || defined(STM32H7B0xx ) || defined(STM32H7B0xxQ )
1481
+ uint32_t prescaler = (RCC -> SRDCFGR & RCC_SRDCFGR_SRDPPRE ) >> RCC_SRDCFGR_SRDPPRE_Pos ;
1482
+ #else
1483
+ uint32_t prescaler = (RCC -> D3CFGR & RCC_D3CFGR_D3PPRE ) >> RCC_D3CFGR_D3PPRE_Pos ;
1484
+ #endif
1485
+
1486
+ uint32_t apb4 = 1 ;
1487
+
1488
+ switch (prescaler ) {
1489
+ case 0b000 : prescaler = 1 ; break ;
1490
+ case 0b100 : prescaler = 2 ; break ;
1491
+ case 0b101 : prescaler = 4 ; break ;
1492
+ case 0b110 : prescaler = 8 ; break ;
1493
+ case 0b111 : prescaler = 16 ; break ;
1494
+ default : break ;
1495
+ }
1496
+
1497
+ return (sysclk / prescaler );
1498
+ #elif defined(STM32G4 ) || defined(STM32L4 ) || defined(STM32L5 ) || defined(STM32WB )
1499
+ return HAL_RCC_GetPCLK1Freq ();
1500
+ #elif defined(STM32WL )
1501
+ return HAL_RCC_GetPCLK2Freq ();
1502
+ #elif defined(STM32WBA )
1503
+ return HAL_RCC_GetPCLK7Freq ();
1504
+ #endif
1505
+ }
1506
+ #endif
1507
+
1508
+ #if defined(LPUART2 )
1509
+ if (huart -> Instance == LPUART2 ) {
1510
+ return HAL_RCC_GetPCLK1Freq ();
1511
+ }
1512
+ #endif
1513
+
1514
+ #if defined(LPUART3 )
1515
+ if (huart -> Instance == LPUART3 ) {
1516
+ return HAL_RCC_GetPCLK1Freq ();
1517
+ }
1518
+ #endif
1519
+
1520
+ #if defined(STM32F0 ) || defined(STM32G0 ) || defined(STM32L0 ) || defined(STM32C0 ) \
1521
+ || defined(STM32WB )
1522
+ return HAL_RCC_GetPCLK1Freq ();
1523
+ #endif
1524
+
1525
+ #if defined(STM32WB0 )
1526
+ uint32_t sysclk = HAL_RCC_GetSysClockFreq ();
1527
+ uint32_t ppre2 = (RCC -> CFGR & RCC_CFGR_CLKSYSDIV ) >> RCC_CFGR_CLKSYSDIV_Pos ;
1528
+ uint32_t apb2_div = 1 ;
1529
+
1530
+ switch (ppre2 ) {
1531
+ case 0b000 : apb2_div = 1 ; break ;
1532
+ case 0b100 : apb2_div = 2 ; break ;
1533
+ case 0b101 : apb2_div = 4 ; break ;
1534
+ case 0b110 : apb2_div = 8 ; break ;
1535
+ case 0b111 : apb2_div = 16 ; break ;
1536
+ default : break ;
1537
+ }
1538
+ return (sysclk / apb2_div );
1539
+ #endif
1540
+
1541
+ #if defined(STM32WL )
1542
+ return HAL_RCC_GetPCLK2Freq ();
1543
+ #endif
1544
+
1545
+ #if defined(STM32H7 )
1546
+ if (huart -> Instance == USART1
1547
+ #if defined(USART10 )
1548
+ || huart -> Instance == USART10
1549
+ #endif
1550
+ #if defined(USART6 )
1551
+ || huart -> Instance == USART6
1552
+ #endif
1553
+ #if defined(UART9 )
1554
+ || huart -> Instance == UART9
1555
+ #endif
1556
+ ) {
1557
+ return HAL_RCC_GetPCLK2Freq ();
1558
+ }
1559
+ return HAL_RCC_GetPCLK1Freq ();
1560
+ #endif
1561
+
1562
+ #if defined(STM32MP1 )
1563
+ if (huart -> Instance == USART1 ) {
1564
+ return HAL_RCC_GetPCLK5Freq ();
1565
+ } else if (huart -> Instance == USART6 ) {
1566
+ return HAL_RCC_GetPCLK2Freq ();
1567
+ } else {
1568
+ return HAL_RCC_GetPCLK1Freq ();
1569
+ }
1570
+ #endif
1571
+
1572
+ #if defined(STM32F7 ) || defined(STM32F2 ) || defined(STM32F4 ) || defined(STM32F1 ) \
1573
+ || defined(STM32U3 ) || defined(STM32F3 ) || defined(STM32H5 ) || defined(STM32G4 ) \
1574
+ || defined(STM32L4 ) || defined(STM32L5 ) || defined(STM32WBA ) || defined(STM32U5 ) \
1575
+ || defined(STM32L1 )
1576
+ if (huart -> Instance == USART1
1577
+ #if defined(USART6 ) && !defined(STM32H5 ) && !defined(STM32U5 )
1578
+ || huart -> Instance == USART6
1579
+ #endif
1580
+ ) {
1581
+ return HAL_RCC_GetPCLK2Freq ();
1582
+ }
1583
+ return HAL_RCC_GetPCLK1Freq ();
1584
+ #endif
1585
+
1586
+ return 0 ;
1587
+ }
1588
+ #endif /* UART_PRESCALER_DIV1 */
1589
+
1418
1590
#endif /* HAL_UART_MODULE_ENABLED && !HAL_UART_MODULE_ONLY */
1419
1591
1420
1592
#ifdef __cplusplus
0 commit comments