Skip to content

Commit f58a2b4

Browse files
committed
fixup: attempt to harden clock prescaler configuration
Signed-off-by: Bartu Özcan <[email protected]> Co-authored-by: Frederic Pillon <[email protected]>
1 parent 336f5a6 commit f58a2b4

File tree

1 file changed

+107
-129
lines changed
  • libraries/SrcWrapper/src/stm32

1 file changed

+107
-129
lines changed

libraries/SrcWrapper/src/stm32/uart.c

Lines changed: 107 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,26 +1439,32 @@ uint32_t uart_compute_prescaler(UART_HandleTypeDef *huart)
14391439
uint32_t prescaler = UART_PRESCALER_DIV1;
14401440
static const uint16_t presc_div[12] = {1, 2, 4, 6, 8, 10, 12, 16, 32, 64, 128, 256};
14411441
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;
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+
}
14571454
}
1458-
1459-
if (brr >= condition && brr <= 0xFFFU) {
1460-
prescaler = UART_PRESCALER_DIV1 + idx;
1461-
break;
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+
}
14621468
}
14631469
}
14641470
return prescaler;
@@ -1471,119 +1477,91 @@ uint32_t uart_compute_prescaler(UART_HandleTypeDef *huart)
14711477
*/
14721478
uint32_t uart_get_clock_source_freq(UART_HandleTypeDef *huart)
14731479
{
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-
1480+
uint32_t freq = 0;
15251481
#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
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+
}
15791543
#endif
1580-
) {
1581-
return HAL_RCC_GetPCLK2Freq();
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;
15821561
}
1583-
return HAL_RCC_GetPCLK1Freq();
1584-
#endif
1585-
1586-
return 0;
1562+
#endif /* STM32H5 */
1563+
#endif /* STM32WB0 */
1564+
return freq;
15871565
}
15881566
#endif /* UART_PRESCALER_DIV1 */
15891567

0 commit comments

Comments
 (0)