diff --git a/targets/TARGET_STM/sleep.c b/targets/TARGET_STM/sleep.c index fa4e8603b2..3dd90a3477 100644 --- a/targets/TARGET_STM/sleep.c +++ b/targets/TARGET_STM/sleep.c @@ -49,38 +49,16 @@ static void wait_loop(uint32_t timeout) return; } + // On L4 platforms we've seen unstable PLL CLK configuraiton // when DEEP SLEEP exits just few µs after being entered // So we need to force MSI usage before setting clocks again -static void ForceClockOutofDeepSleep(void) +static void ForcePeriphOutofDeepSleep(void) { - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; uint32_t pFLatency = 0; - - /* Enable Power Control clock */ - __HAL_RCC_PWR_CLK_ENABLE(); - -#ifdef PWR_FLAG_VOS - /* Poll VOSF bit of in PWR_CSR. Wait until it is reset to 0 */ - //while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOS) != RESET) {}; -#endif - - /* Get the Oscillators configuration according to the internal RCC registers */ - HAL_RCC_GetOscConfig(&RCC_OscInitStruct); + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; #if (TARGET_STM32L4 || TARGET_STM32L1) /* MSI used for L4 */ - /**Initializes the CPU, AHB and APB busses clocks - */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI; - RCC_OscInitStruct.MSIState = RCC_MSI_ON; - RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; - RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_4; // Intermediate freq, 1MHz range - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { - error("clock issue\r\n"); - } - /* Get the Clocks configuration according to the internal RCC registers */ HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency); @@ -100,16 +78,6 @@ static void ForceClockOutofDeepSleep(void) error("clock issue\r\n"); } #else /* HSI used on others */ - /**Initializes the CPU, AHB and APB busses clocks - */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.HSICalibrationValue = 16; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { - error("clock issue"); - } - /* Get the Clocks configuration according to the internal RCC registers */ HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency); @@ -132,6 +100,50 @@ static void ForceClockOutofDeepSleep(void) #endif // TARGET_STM32L4 } +static void ForceOscOutofDeepSleep(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* Get the Oscillators configuration according to the internal RCC registers */ + HAL_RCC_GetOscConfig(&RCC_OscInitStruct); + +#if (TARGET_STM32L4 || TARGET_STM32L1) /* MSI used for L4 */ + /**Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI; + RCC_OscInitStruct.MSIState = RCC_MSI_ON; + RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; + RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_4; // Intermediate freq, 1MHz range + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + error("clock issue\r\n"); + } +#else /* HSI used on others */ + /**Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = 16; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + error("clock issue"); + } +#endif // TARGET_STM32L4 +} + +/* The content of this function has been split into 2 separate functions + so that the involved structures are not allocated on the stack in parallel. + This will reduce the maximum stack usage in case on non-optimized / debug + compilers settings */ +static void ForceClockOutofDeepSleep(void) +{ + ForceOscOutofDeepSleep(); + ForcePeriphOutofDeepSleep(); +} + void hal_sleep(void) { // Disable IRQs