From b65afe028eb74a940efe396658ece41f44f0a867 Mon Sep 17 00:00:00 2001 From: jeromecoutant Date: Tue, 8 Sep 2020 11:40:02 +0200 Subject: [PATCH] STM32H7 ADC: clock selection lost after deepsleep --- .../TARGET_STM32H7/analogin_device.c | 56 +++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32H7/analogin_device.c b/targets/TARGET_STM/TARGET_STM32H7/analogin_device.c index 63904e71ef..027e860f6b 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/analogin_device.c +++ b/targets/TARGET_STM/TARGET_STM32H7/analogin_device.c @@ -36,6 +36,35 @@ #include "mbed_error.h" #include "PeripheralPins.h" + +void analogin_pll_configuration(void) +{ +#if defined(DUAL_CORE) + while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) { + } +#endif /* DUAL_CORE */ + + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC; + PeriphClkInitStruct.PLL2.PLL2M = 4; + PeriphClkInitStruct.PLL2.PLL2N = 240; + PeriphClkInitStruct.PLL2.PLL2P = 2; + PeriphClkInitStruct.PLL2.PLL2Q = 2; + PeriphClkInitStruct.PLL2.PLL2R = 2; + PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_1; + PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE; + PeriphClkInitStruct.PLL2.PLL2FRACN = 0; + PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { + error("analogin_init HAL_RCCEx_PeriphCLKConfig"); + } + +#if defined(DUAL_CORE) + LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, HSEM_CR_COREID_CURRENT); +#endif /* DUAL_CORE */ + +} + void analogin_init(analogin_t *obj, PinName pin) { uint32_t function = (uint32_t)NC; @@ -99,29 +128,7 @@ void analogin_init(analogin_t *obj, PinName pin) obj->handle.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; obj->handle.Init.OversamplingMode = DISABLE; -#if defined(DUAL_CORE) - while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) { - } -#endif /* DUAL_CORE */ - - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC; - PeriphClkInitStruct.PLL2.PLL2M = 4; - PeriphClkInitStruct.PLL2.PLL2N = 240; - PeriphClkInitStruct.PLL2.PLL2P = 2; - PeriphClkInitStruct.PLL2.PLL2Q = 2; - PeriphClkInitStruct.PLL2.PLL2R = 2; - PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_1; - PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE; - PeriphClkInitStruct.PLL2.PLL2FRACN = 0; - PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { - error("analogin_init HAL_RCCEx_PeriphCLKConfig"); - } - -#if defined(DUAL_CORE) - LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, HSEM_CR_COREID_CURRENT); -#endif /* DUAL_CORE */ + analogin_pll_configuration(); #if defined(ADC1) if ((ADCName)obj->handle.Instance == ADC_1) { @@ -163,6 +170,9 @@ uint16_t adc_read(analogin_t *obj) { ADC_ChannelConfTypeDef sConfig = {0}; + /* Reconfigure PLL as it could be lost during deepsleep */ + analogin_pll_configuration(); + // Configure ADC channel sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;