Skip to main content
Senior
May 30, 2025
Solved

ADC conversion not work after wakeup from STOP2 mode

  • May 30, 2025
  • 5 replies
  • 619 views

Hello,

My agenda is to work with ADC1 with STOP2 mode.

Using LPTIMER1 to wakeup system, from STOP2 mode and once wakeup then reinit adc, calibrate and start adc interrupt. but still I can see adc interrupt not called.

void handleConversion()
{
 ReInit_ADC1();
 HAL_ADCEx_Calibration_Start(&hadc_);
 HAL_StatusTypeDef status = HAL_ADC_Start_IT(&hadc1);
 if (status != HAL_OK) {
 HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
 }

 // LED toggle if we put out of IF statement, so interrupt is register successfully. 
}
 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
 {
 __IO uint16_t adcRawValue = HAL_ADC_GetValue(hadc);
 uint16_t adcVoltage_mVolt = __LL_ADC_CALC_DATA_TO_VOLTAGE(VDDA_APPLI, adcRawValue, LL_ADC_RESOLUTION_12B);
 InternalBatteryDriver::setVoltageCallback(adcVoltage_mVolt);
// HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
 scheduler_push_event(EVENT_ADC_CONVERSION_COMPLETE);
 }
//Here as final result, trying to glow LED which is not blinking

and here is the ADC_Init code for reference

static void MX_ADC1_Init(void)
{
 ADC_ChannelConfTypeDef sConfig = {0};
 hadc1.Instance = ADC1;
 hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
 hadc1.Init.Resolution = ADC_RESOLUTION_12B;
 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
 hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
 hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
 hadc1.Init.LowPowerAutoWait = ENABLE;
 hadc1.Init.LowPowerAutoPowerOff = ENABLE;
 hadc1.Init.ContinuousConvMode = DISABLE;
 hadc1.Init.NbrOfConversion = 1;
 hadc1.Init.DiscontinuousConvMode = DISABLE;
 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
 hadc1.Init.DMAContinuousRequests = DISABLE;
 hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
 hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_79CYCLES_5;
 hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_79CYCLES_5;
 hadc1.Init.OversamplingMode = DISABLE;
 hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
 if (HAL_ADC_Init(&hadc1) != HAL_OK)
 {
 Error_Handler();
 }

 sConfig.Channel = ADC_CHANNEL_4;
 sConfig.Rank = ADC_REGULAR_RANK_1;
 sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }
}

Help me if I'm missing anything here.

FYI, this works when we try to disable stop2 mode.

Here is the wakeup details,

void enterLowPowerMode()
{
 HAL_UARTEx_EnableStopMode(&hlpuart1);
 HAL_SuspendTick();
 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
 HAL_ResumeTick();
 Reset_SystemClock();
}
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2);

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
 RCC_OscInitStruct.LSIState = RCC_LSI_ON;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
 {
 Error_Handler();
 }
}

Thanks,

Nitin

This topic has been closed for replies.
Best answer by npatil15

Hello,

It is working now; I have missed the ADC interrupt handler to set.

Thanks,

Nitin

5 replies

Andrew Neil
Super User
May 30, 2025

Was the ADC working before going to sleep? 

EDIT: Sorry - I missed where you said it did work.

 


@npatil15 wrote:

Here is the wakeup details,

void enterLowPowerMode()
{
 HAL_UARTEx_EnableStopMode(&hlpuart1);
 HAL_SuspendTick();
 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
 HAL_ResumeTick();
 Reset_SystemClock();
}

 


You haven't shown the code of Reset_SystemClock()

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
npatil15Author
Senior
June 2, 2025

actually Reset_SystemClock() is just the wrapper for SystemClock_Config() function.

void Reset_SystemClock(void)
{
 SystemClock_Config()
}

And ReInit_ADC1() is also a wrapper function for MX_ADC1_Init()

void ReInit_ADC1(void)
{
 MX_ADC1_Init();
}

Thanks,

Nitin

Andrew Neil
Super User
June 2, 2025

Seems like unnecessary obfuscation - why not just call the functions direct?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
npatil15Author
Senior
June 3, 2025

This I have done for purpose, as have multiple CPP and C file. 

npatil15AuthorBest answer
Senior
June 3, 2025

Hello,

It is working now; I have missed the ADC interrupt handler to set.

Thanks,

Nitin