Skip to content

Commit fbaec0c

Browse files
author
Jamie Smith
authored
Fix STM32H7 LPUART clock source being incorrect for higher baudrates (#263)
* Fix STM32H7 LPUART clock source incorrect for higher baudrates * Add comment
1 parent 8926deb commit fbaec0c

File tree

2 files changed

+54
-37
lines changed

2 files changed

+54
-37
lines changed

targets/TARGET_STM/serial_api.c

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#define USE_LPUART_CLK_LSE 0x01
3737
#define USE_LPUART_CLK_PCLK1 0x02
3838
#define USE_LPUART_CLK_HSI 0x04
39+
#define USE_LPUART_CLK_PCLK3 0x08
40+
#define USE_LPUART_CLK_SYSCLK 0x10
3941

4042
int stdio_uart_inited = 0; // used in platform/mbed_board.c and platform/mbed_retarget.cpp
4143
serial_t stdio_uart;
@@ -376,8 +378,8 @@ void serial_baud(serial_t *obj, int baudrate)
376378
if (obj_s->uart == LPUART_1) {
377379
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
378380
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1;
379-
#if ((MBED_CONF_TARGET_LPUART_CLOCK_SOURCE) & USE_LPUART_CLK_LSE)
380-
if (baudrate <= 9600) {
381+
#if ((MBED_CONF_TARGET_LPUART_CLOCK_SOURCE) & USE_LPUART_CLK_LSE) && MBED_CONF_TARGET_LSE_AVAILABLE
382+
if (baudrate <= (int)(LSE_VALUE / 3)) {
381383
// Enable LSE in case it is not already done
382384
if (!__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY)) {
383385
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
@@ -417,46 +419,50 @@ void serial_baud(serial_t *obj, int baudrate)
417419
return;
418420
}
419421
#endif
420-
#if ((MBED_CONF_TARGET_LPUART_CLOCK_SOURCE) & USE_LPUART_CLK_PCLK3)
422+
#if ((MBED_CONF_TARGET_LPUART_CLOCK_SOURCE) & USE_LPUART_CLK_PCLK3) && defined(RCC_LPUART1CLKSOURCE_PCLK3)
421423
PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK3;
422424
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
423425
if (init_uart(obj) == HAL_OK) {
424426
return;
425427
}
426428
#endif
427429
#if ((MBED_CONF_TARGET_LPUART_CLOCK_SOURCE) & USE_LPUART_CLK_HSI)
428-
// Enable HSI in case it is not already done
429-
if (!__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY)) {
430-
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
431-
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
432-
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
433-
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_OFF;
434-
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
435-
#if defined(DUAL_CORE) && (TARGET_STM32H7)
436-
while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) {
430+
if (baudrate <= (int)(HSI_VALUE / 3)) {
431+
// Enable HSI in case it is not already done
432+
if (!__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY)) {
433+
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
434+
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
435+
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
436+
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_OFF;
437+
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
438+
#if defined(DUAL_CORE) && (TARGET_STM32H7)
439+
while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) {
440+
}
441+
#endif /* DUAL_CORE */
442+
HAL_RCC_OscConfig(&RCC_OscInitStruct);
443+
#if defined(DUAL_CORE) && (TARGET_STM32H7)
444+
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, HSEM_CR_COREID_CURRENT);
445+
#endif /* DUAL_CORE */
437446
}
438-
#endif /* DUAL_CORE */
439-
HAL_RCC_OscConfig(&RCC_OscInitStruct);
440-
#if defined(DUAL_CORE) && (TARGET_STM32H7)
441-
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, HSEM_CR_COREID_CURRENT);
442-
#endif /* DUAL_CORE */
443-
}
444-
// Keep it to verify if HAL_RCC_OscConfig didn't exit with a timeout
445-
if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY)) {
446-
PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_HSI;
447+
// Keep it to verify if HAL_RCC_OscConfig didn't exit with a timeout
448+
if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY)) {
449+
PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_HSI;
447450
#if defined(DUAL_CORE) && (TARGET_STM32H7)
448-
while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) {
449-
}
451+
while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) {
452+
}
450453
#endif /* DUAL_CORE */
451-
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
454+
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
452455
#if defined(DUAL_CORE) && (TARGET_STM32H7)
453-
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, HSEM_CR_COREID_CURRENT);
456+
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, HSEM_CR_COREID_CURRENT);
454457
#endif /* DUAL_CORE */
455-
if (init_uart(obj) == HAL_OK) {
456-
return;
458+
if (init_uart(obj) == HAL_OK) {
459+
return;
460+
}
457461
}
458462
}
459463
#endif
464+
465+
#if ((MBED_CONF_TARGET_LPUART_CLOCK_SOURCE) & USE_LPUART_CLK_SYSCLK)
460466
// Last chance using SYSCLK
461467
PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_SYSCLK;
462468
#if defined(DUAL_CORE) && (TARGET_STM32H7)
@@ -467,6 +473,15 @@ void serial_baud(serial_t *obj, int baudrate)
467473
#if defined(DUAL_CORE) && (TARGET_STM32H7)
468474
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, HSEM_CR_COREID_CURRENT);
469475
#endif /* DUAL_CORE */
476+
477+
if (init_uart(obj) == HAL_OK) {
478+
return;
479+
}
480+
else
481+
#endif
482+
{
483+
debug("Cannot initialize LPUART with baud rate %u using any enabled clock source\n", baudrate);
484+
}
470485
}
471486
#endif /* LPUART1_BASE */
472487

@@ -653,8 +668,8 @@ HAL_StatusTypeDef init_uart(serial_t *obj)
653668

654669
#if defined(LPUART1_BASE)
655670
if (huart->Instance == LPUART1) {
656-
if (obj_s->baudrate <= 9600) {
657-
#if ((MBED_CONF_TARGET_LPUART_CLOCK_SOURCE) & USE_LPUART_CLK_LSE) && defined(USART_CR3_UCESM)
671+
if (obj_s->baudrate <= (int)(LSE_VALUE / 3)) {
672+
#if ((MBED_CONF_TARGET_LPUART_CLOCK_SOURCE) & USE_LPUART_CLK_LSE) && MBED_CONF_TARGET_LSE_AVAILABLE && defined(USART_CR3_UCESM)
658673
HAL_UARTEx_EnableClockStopMode(huart);
659674
#endif
660675
HAL_UARTEx_EnableStopMode(huart);

targets/targets.json5

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,8 +1203,8 @@
12031203
"value": "USE_RTC_CLK_LSE_OR_LSI"
12041204
},
12051205
"lpuart_clock_source": {
1206-
"help": "Define the LPUART clock source. Mask values: USE_LPUART_CLK_LSE, USE_LPUART_CLK_PCLK1, USE_LPUART_CLK_HSI",
1207-
"value": "USE_LPUART_CLK_LSE|USE_LPUART_CLK_PCLK1|USE_LPUART_CLK_PCLK3"
1206+
"help": "Define the LPUART clock source. LSE clock source will only be used when baudrate is slow (<= LSE freq / 3). Mask values: USE_LPUART_CLK_LSE, USE_LPUART_CLK_PCLK1, USE_LPUART_CLK_PCLK3, USE_LPUART_CLK_HSI, USE_LPUART_CLK_SYSCLK.",
1207+
"value": "USE_LPUART_CLK_LSE|USE_LPUART_CLK_PCLK1|USE_LPUART_CLK_PCLK3|USE_LPUART_CLK_SYSCLK"
12081208
},
12091209
"stdio_uart_tx": {
12101210
"help": "default TX STDIO pins is defined in PinNames.h file, but it can be overridden"
@@ -3186,7 +3186,9 @@
31863186
"MBED_TICKLESS"
31873187
],
31883188
"overrides": {
3189-
"lpticker_delay_ticks": 0
3189+
"lpticker_delay_ticks": 0,
3190+
// Mbed's clock code does not initialize PLL2, so we have to disable USE_LPUART_CLK_PCLK1 here.
3191+
"lpuart_clock_source": "USE_LPUART_CLK_LSE|USE_LPUART_CLK_HSI|USE_LPUART_CLK_SYSCLK"
31903192
},
31913193
"device_has_add": [
31923194
"ANALOGOUT",
@@ -4264,7 +4266,7 @@
42644266
"STM32L475xG"
42654267
],
42664268
"overrides": {
4267-
"lpuart_clock_source": "USE_LPUART_CLK_HSI"
4269+
"lpuart_clock_source": "USE_LPUART_CLK_HSI|USE_LPUART_CLK_SYSCLK"
42684270
},
42694271
"macros_add": [
42704272
"STM32L475xx",
@@ -4308,7 +4310,7 @@
43084310
"STM32L476xG"
43094311
],
43104312
"overrides": {
4311-
"lpuart_clock_source": "USE_LPUART_CLK_HSI"
4313+
"lpuart_clock_source": "USE_LPUART_CLK_HSI|USE_LPUART_CLK_SYSCLK"
43124314
},
43134315
"macros_add": [
43144316
"STM32L476xx",
@@ -4370,7 +4372,7 @@
43704372
"STM32L486xG"
43714373
],
43724374
"overrides": {
4373-
"lpuart_clock_source": "USE_LPUART_CLK_HSI"
4375+
"lpuart_clock_source": "USE_LPUART_CLK_HSI|USE_LPUART_CLK_SYSCLK"
43744376
},
43754377
"macros_add": [
43764378
"STM32L486xx",
@@ -4420,7 +4422,7 @@
44204422
"STM32L496xG"
44214423
],
44224424
"overrides": {
4423-
"lpuart_clock_source": "USE_LPUART_CLK_HSI"
4425+
"lpuart_clock_source": "USE_LPUART_CLK_HSI|USE_LPUART_CLK_SYSCLK"
44244426
},
44254427
"macros_add": [
44264428
"STM32L496xx"
@@ -4781,7 +4783,7 @@
47814783
},
47824784
"overrides": {
47834785
"lpticker_delay_ticks": 0,
4784-
"lpuart_clock_source": "USE_LPUART_CLK_HSI"
4786+
"lpuart_clock_source": "USE_LPUART_CLK_HSI|USE_LPUART_CLK_SYSCLK"
47854787
},
47864788
"device_has_add": [
47874789
"ANALOGOUT",

0 commit comments

Comments
 (0)