2024-03-01 03:14 PM
I'm working on some code to wake up from Sleep or Stop mode when a low ADC value happens.
I found this post which gets me almost all the way there https://community.st.com/t5/stm32-mcus-products/what-is-the-process-to-use-the-adc-on-stm32f745-to-wake-up-the/td-p/91522
I'm able to get an interrupt to trigger on a low ADC value while in sleep mode but the main loop does not restart. The main loop does restart when I trigger an interrupt from a digital GPIO.
Here are the relevant parts of the .ico file configuration
My code for going in and out of sleep state looks like this
LEDR_OFF();
LEDG_OFF();
LEDB_OFF();
HAL_GPIO_WritePin(VBAT_Gate_GPIO_Port, VBAT_Gate_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(ACC_EN_GPIO_Port, ACC_EN_Pin, GPIO_PIN_RESET);
HAL_NVIC_DisableIRQ(USART1_IRQn);
HAL_NVIC_DisableIRQ(I2C2_IRQn);
HAL_NVIC_DisableIRQ(TIM7_IRQn);
HAL_SuspendTick();
if (HAL_ADC_Start_IT(&hadc1) != HAL_OK)
{
Error_Handler();
}
//STOP mode uses less power but it also can make j-link programming difficult
//for now I'm using Sleep mode which uses more power but does not interfere with development
//HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
HAL_ResumeTick();
SystemClock_Config();
HAL_NVIC_EnableIRQ(USART1_IRQn);
HAL_NVIC_EnableIRQ(I2C2_IRQn);
HAL_NVIC_EnableIRQ(TIM7_IRQn);
HAL_GPIO_WritePin(VBAT_Gate_GPIO_Port, VBAT_Gate_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(ACC_EN_GPIO_Port, ACC_EN_Pin, GPIO_PIN_SET);
The interrupt handler for the ADC watchdog looks like this
bool wakeup=false;
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
{
wakeup=true;
}
As a test I set a breakpoint at the end just after the HAL_ResumeTick() in my sleep/wake up code and inside the HAL_ADC_LevelOutOfWindowCallback() function. If I trigger an interrupt with the digital GPIO which is configured like this
The breakpoint at the call to HAL_ResumeTick() is triggered and I see other indicators the device has come out of sleep mode.
If I put a low voltage on the ADC to trigger the interrupt and wake up from sleep the breakpoint inside the interrupt handler HAL_ADC_LevelOutOfWindowCallback() is called but the breakpoint at my HAL_ResumeTick does not get triggered and the device seems to immediately go back to sleep after the interrupt handler.
If anyone has some suggestion as to what I need to do to make the interrupt wake the device up from sleep completely it would be appreciated. It's a little weird because the documentation says the processor will wake up from sleep on any interrupt, and clearly the interrupt is getting triggered.
On a side note. Not sure if this is relevant information or not. When the device is operating normally I want the ADC to be done with a DMA that is started at the end of a PWM cycle. So I have an interrupt that triggers on the PWM and that starts the DMA. Once the device is turned off by the end user it will need to be in a sleep or stop state and should wake up on the ADC low value trigger. This happens when the device is plugged in for charging. The other time it would wake up is when the user pressed the button which also triggers an interrupt.
Thank You
2024-03-04 02:09 AM
Hello @marchold,
Have you checked the ADC clock configuration when waking up from Stop/Sleep mode ?
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2024-03-04 09:51 AM - edited 2024-03-04 11:42 AM
I have not. Can you provide any more details as to what I should do and how it may help the main loop wake up as well. Thanks
EDIT: I think I may have found the problem. The issue was that the Interrupt for HAL_ADC_LevelOutOfWindowCallback would keep getting called as the ADC value was still out of range. It seems that instead of calling HAL_ADC_Start_IT I should have been calling HAL_ADC_Start and more importantly inside the HAL_ADC_LevelOutOfWindowCallback its important to call HAL_ADC_Stop otherwise the interrupt keeps getting called.