I have code below that is intended to put an STM32F415 into STOP mode, and then wake it using the RTC Wakeup Interrupt 5 seconds later.
The result of running this code is that the STM32 boots (LED is Off, current is ~11mA), after 1 second enters STOP mode (LED goes On, current drops to ~5mA). 5 seconds later exits STOP mode (LED goes Off, a loop fast-toggling the LED also works here), however other threads do not run and any call to chThdSleep..() never completes. In addition the current does not rise above 7mA. (LED current is excluded from measurements.)
.
This happens in both ticked and tickless modes, I am wondering if the systick timer (or the virtual timer used in tickless) is not being started back up correctly?
Any help is greatly appreciated.
Thanks,
Phil
Code: Select all
#include "ch.h"
#include "hal.h"
static RTCWakeup wakeupspec;
static void ext_cb(EXTDriver *extp, expchannel_t channel);
static const EXTConfig extcfg = {
{
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART, ext_cb},
}
};
static void Chibi_DeepSleep(void)
{
/* Clear RTC Interrupt flags */
RTC->ISR &= ~(RTC_ISR_ALRBF | RTC_ISR_ALRAF | RTC_ISR_WUTF | RTC_ISR_TAMP1F |
RTC_ISR_TSOVF | RTC_ISR_TSF);
/* Set regulator to low-power and clear wakeup flags */
PWR->CR |= (PWR_CR_LPDS | PWR_CR_CSBF | PWR_CR_CWUF);
/* Set deep-sleep mode */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
}
static void ext_cb(EXTDriver *extp, expchannel_t channel)
{
(void)extp;
(void)channel;
chSysLockFromISR();
stm32_clock_init();
RTC->ISR &= ~RTC_ISR_WUTF;
EXTI->PR &= ~(1 << 22);
chSysUnlockFromISR();
}
int main(void)
{
halInit();
chSysInit();
/* Set LED Off */
palClearPad(GPIOA, GPIOA_STM_LED_DRIVE);
extStart(&EXTD1, &extcfg);
nvicEnableVector(RTC_WKUP_IRQn, STM32_EXT_EXTI22_IRQ_PRIORITY);
/* set wakeup */
wakeupspec.wutr = ((uint32_t)4) << 16; /* select 1 Hz clock source */
wakeupspec.wutr |= ((5)); /* Period in seconds */
rtcSTM32SetPeriodicWakeup(&RTCD1, &wakeupspec);
chThdSleepMilliseconds(1000);
/* Set LED On */
palSetPad(GPIOA, GPIOA_STM_LED_DRIVE);
Chibi_DeepSleep(); /* Sleep for 5s */
halInit();
chSysInit();
while (true) {
/* Toggle LED to indicate wakeup - this works */
palTogglePad(GPIOA, GPIOA_STM_LED_DRIVE);
/* Sleep - this never completes */
chThdSleepMilliseconds(200);
}
}