diff --git a/targets/TARGET_STM/serial_api.c b/targets/TARGET_STM/serial_api.c index 065418c74bd..4a092784e17 100644 --- a/targets/TARGET_STM/serial_api.c +++ b/targets/TARGET_STM/serial_api.c @@ -32,6 +32,11 @@ #include "serial_api_hal.h" +// Possible choices of the LPUART_CLOCK_SOURCE configuration set in json file +#define USE_LPUART_CLK_LSE 0x01 +#define USE_LPUART_CLK_PCLK1 0x02 +#define USE_LPUART_CLK_HSI 0x04 + int stdio_uart_inited = 0; // used in platform/mbed_board.c and platform/mbed_retarget.cpp serial_t stdio_uart; @@ -367,29 +372,43 @@ void serial_baud(serial_t *obj, int baudrate) struct serial_s *obj_s = SERIAL_S(obj); obj_s->baudrate = baudrate; + #if defined(LPUART1_BASE) /* Note that LPUART clock source must be in the range [3 x baud rate, 4096 x baud rate], check Ref Manual */ if (obj_s->uart == LPUART_1) { - /* If baudrate is lower than 9600 try to change to LSE */ RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; +#if ((MBED_CONF_TARGET_LPUART_CLOCK_SOURCE) & USE_LPUART_CLK_LSE) if (baudrate <= 9600 && __HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY)) { - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_LSE; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); - } else { - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; - PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1; - HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + if (init_uart(obj) == HAL_OK) { + return; + } } +#endif +#if ((MBED_CONF_TARGET_LPUART_CLOCK_SOURCE) & USE_LPUART_CLK_PCLK1) + PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); if (init_uart(obj) == HAL_OK) { return; } - /* Change LPUART clock source and try again */ - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; +#endif +#if ((MBED_CONF_TARGET_LPUART_CLOCK_SOURCE) & USE_LPUART_CLK_HSI) + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY)) { + PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_HSI; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + if (init_uart(obj) == HAL_OK) { + return; + } + } +#endif + // Last chance using SYSCLK PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_SYSCLK; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); } #endif /* LPUART1_BASE */ + if (init_uart(obj) != HAL_OK) { debug("Cannot initialize UART with baud rate %u\n", baudrate); } diff --git a/targets/targets.json b/targets/targets.json index b39430eb64a..0b108ae1321 100755 --- a/targets/targets.json +++ b/targets/targets.json @@ -730,6 +730,10 @@ "help": "Define if a Low Speed External xtal (LSE) is available on the board (0 = No, 1 = Yes). If Yes, the LSE will be used to clock the RTC, LPUART, ... otherwise the Low Speed Internal clock (LSI) will be used", "value": "1" }, + "lpuart_clock_source": { + "help": "Define the LPUART clock source. Mask values: USE_LPUART_CLK_LSE, USE_LPUART_CLK_PCLK1, USE_LPUART_CLK_HSI", + "value": "USE_LPUART_CLK_LSE|USE_LPUART_CLK_PCLK1" + }, "stdio_uart_tx": { "help": "default TX STDIO pins is defined in PinNames.h file, but it can be overridden" },