Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd35fec3

Browse files
baftiifpistm
andauthored
fix(uart): HardwareSerial begin() causes Infinite Loop (#2785)
* fix(uart): uart clock prescaler configurationSigned-off-by: Bartu Özcan <bartu.ozcan2004@gmail.com>Co-authored-by: Frederic Pillon <frederic.pillon@st.com>
1 parente96c3a1 commitd35fec3

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

‎libraries/SrcWrapper/inc/uart.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,11 @@ void uart_enable_rx(serial_t *obj);
272272

273273
size_tuart_debug_write(uint8_t*data,uint32_tsize);
274274

275+
#if defined(UART_PRESCALER_DIV1)
276+
uint32_tuart_compute_prescaler(UART_HandleTypeDef*huart);
277+
uint32_tuart_get_clock_source_freq(UART_HandleTypeDef*huart);
278+
#endif
279+
275280
#endif/* HAL_UART_MODULE_ENABLED && !HAL_UART_MODULE_ONLY */
276281
#ifdef__cplusplus
277282
}

‎libraries/SrcWrapper/src/stm32/uart.c‎

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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_tuart_compute_prescaler(UART_HandleTypeDef*huart)
1438+
{
1439+
uint32_tprescaler=UART_PRESCALER_DIV1;
1440+
staticconstuint16_tpresc_div[12]= {1,2,4,6,8,10,12,16,32,64,128,256};
1441+
uint32_tfreq=uart_get_clock_source_freq(huart);
1442+
uint32_tusartdiv=0;
1443+
1444+
#if defined(UART_INSTANCE_LOWPOWER)
1445+
if (UART_INSTANCE_LOWPOWER(huart)) {
1446+
for (uint32_tidx=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_tidx=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+
returnprescaler;
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_tuart_get_clock_source_freq(UART_HandleTypeDef*huart)
1479+
{
1480+
uint32_tfreq=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_tclocksource;
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+
caseUART_CLOCKSOURCE_D2PCLK1:
1499+
#endif/* UART_CLOCKSOURCE_D2PCLK1*/
1500+
#if defined(UART_CLOCKSOURCE_PCLK1)
1501+
caseUART_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+
caseUART_CLOCKSOURCE_D2PCLK2:
1509+
#endif/* UART_CLOCKSOURCE_D2PCLK2*/
1510+
#if defined(UART_CLOCKSOURCE_PCLK2)
1511+
caseUART_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+
caseUART_CLOCKSOURCE_PCLK7:
1518+
freq=HAL_RCC_GetPCLK7Freq();
1519+
break;
1520+
#endif/* UART_CLOCKSOURCE_PCLK7 */
1521+
#if defined(UART_CLOCKSOURCE_PLL2)
1522+
caseUART_CLOCKSOURCE_PLL2:
1523+
HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
1524+
freq=pll2_clocks.PLL2_Q_Frequency;
1525+
break;
1526+
caseUART_CLOCKSOURCE_PLL3:
1527+
HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
1528+
freq=pll3_clocks.PLL3_Q_Frequency;
1529+
break;
1530+
#endif/* UART_CLOCKSOURCE_PLL2 */
1531+
caseUART_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+
caseUART_CLOCKSOURCE_CSI:
1547+
freq= (uint32_t)CSI_VALUE;
1548+
break;
1549+
#endif/* UART_CLOCKSOURCE_CSI */
1550+
#if defined(UART_CLOCKSOURCE_SYSCLK)
1551+
caseUART_CLOCKSOURCE_SYSCLK:
1552+
freq=HAL_RCC_GetSysClockFreq();
1553+
break;
1554+
#endif/* UART_CLOCKSOURCE_SYSCLK */
1555+
caseUART_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+
returnfreq;
1565+
}
1566+
#endif/* UART_PRESCALER_DIV1 */
1567+
14181568
#endif/* HAL_UART_MODULE_ENABLED && !HAL_UART_MODULE_ONLY */
14191569

14201570
#ifdef__cplusplus

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp