Hi,
maybe it's a bit outdated, but I had the same problem and got it to work and maybe it will help someone other.
I use an STM32F303xC and tried to wake up from STOP-Mode.
I go into STOP-Mode using this function:
Code: Select all
/*
* voltage regulator selection
*/
typedef enum
{
PWR_MAINREGULATOR_ON = ((uint32_t)0x00000000), /* Voltage regulator on during STOP mode */
PWR_LOWPOWERREGULATOR_ON = PWR_CR_LPDS /* Voltage regulator in low-power mode during STOP mode */
} pwr_regulator_t;
/*
* Enter sleep mode selection
*/
typedef enum
{
LOW_PWR_ENTRY_WFI, /* enter SLEEP mode with WFI instruction *///!< LOW_PWR_ENTRY_WFI
LOW_PWR_ENTRY_WFE /* enter SLEEP mode with WFE instruction *///!< LOW_PWR_ENTRY_WFE
} low_pwr_entry_t;
bool enterStopMode(pwr_regulator_t reg, low_pwr_entry_t entry)
{
uint32_t tmpreg = 0;
/* Disable interrupts */
__disable_irq();
/* Select the regulator state in STOP mode */
tmpreg = PWR->CR;
/* Clear PDDS and LPDS bits */
tmpreg &= (uint32_t) ~(PWR_CR_PDDS | PWR_CR_LPDS);
/* Set LPDS bit according to Regulator value */
tmpreg |= (uint32_t) reg;
/* Store the new value */
PWR->CR = tmpreg;
/* Set SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR |= (uint32_t) SCB_SCR_SLEEPDEEP_Msk;
/* Enable interrupts back */
__enable_irq();
/* Select STOP mode entry */
if (entry == LOW_PWR_ENTRY_WFI)
{
/* Request Wait For Interrupt */
__WFI(); /** @attention: would expect, that instruction pointer stops here, but he doesn't... */
}
else
{
/* Request Wait For Event */
__SEV();
__WFE(); /** @attention: would expect, that instruction pointer stops here, but he doesn't... */
}
return true;
}
and to wakeup with RTC i use this:
First the RTC must be configured and then enabled:
Code: Select all
RTCWakeup wakeupspec;
/* ... */
void configure_rtc(void)
{
/* Reset EXTI_PR1 (pending) register */
EXTI->PR &= ~(0xE07FFFFF);
/* Reset RTC_ISR Register */
RTC->ISR &= ~(RTC_ISR_ALRBF | RTC_ISR_ALRAF | RTC_ISR_WUTF | RTC_ISR_TAMP1F | RTC_ISR_TSOVF | RTC_ISR_TSF);
/* set wakeup */
wakeupspec.wutr = ((uint32_t) (0x010)) << 16; /* select RTC/4 clock source */
wakeupspec.wutr |= 0x0FFF; /* set counter value to 500ms. */
/* turn on wakeup */
rtcSTM32SetPeriodicWakeup(&RTCD1, &wakeupspec);
}
But only with this, my µC does a software reset, as you mentioned.
To avoid this, you need to configure the EXTI-Driver and initialize it, because extStart() calls ext_lld_exti_irq_enable() which enables the NIVC-IRQs :
Code: Select all
void extcb(EXTDriver *extp, expchannel_t channel);
static const EXTConfig extcfg = {
{
{EXT_CH_MODE_DISABLED, NULL}, // 00
{EXT_CH_MODE_DISABLED, NULL}, // 01
{EXT_CH_MODE_DISABLED, NULL}, // 02
{EXT_CH_MODE_DISABLED, NULL}, // 03
{EXT_CH_MODE_DISABLED, NULL}, // 04
{EXT_CH_MODE_DISABLED, NULL}, // 05
{EXT_CH_MODE_DISABLED, NULL}, // 06
{EXT_CH_MODE_DISABLED, NULL}, // 07
{EXT_CH_MODE_DISABLED, NULL}, // 08
{EXT_CH_MODE_DISABLED, NULL}, // 09
{EXT_CH_MODE_DISABLED, NULL}, // 10
{EXT_CH_MODE_DISABLED, NULL}, // 11
{EXT_CH_MODE_DISABLED, NULL}, // 12
{EXT_CH_MODE_DISABLED, NULL}, // 13
{EXT_CH_MODE_DISABLED, NULL}, // 14
{EXT_CH_MODE_DISABLED, NULL}, // 15
{EXT_CH_MODE_DISABLED, NULL}, // 16
{EXT_CH_MODE_DISABLED, NULL}, // 17
{EXT_CH_MODE_DISABLED, NULL}, // 18
{EXT_CH_MODE_DISABLED, NULL}, // 19
{EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART, extcb}, // 20 RTC_WKUP
}
};
void extcb(EXTDriver *extp, expchannel_t channel)
{
(void) extp;
(void) channel;
/* Reset SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR &= (uint32_t) ~((uint32_t) SCB_SCR_SLEEPDEEP_Msk);
/* switch off wakeup */
rtcSTM32SetPeriodicWakeup(&RTCD1, NULL);
chSysLockFromISR();
/* we must reinit clocks after waking up ESPECIALLY if use HSE or HSI+PLL */
stm32_clock_init();
chSysUnlockFromISR();
}
int main(void)
{
/* ... */
extStart(&EXTD1, &extcfg);
/* ... */
}
But please note, that it is also recommend to stop all Drivers (as mentioned in
http://www.chibios.org/dokuwiki/doku.ph ... s:kb:power).
Its also recommend to to reduce power consumption by disabling the GPIO-Clocks and set the GPIOs to Analog Input, which you don't need.
Code: Select all
/* Disable GPIO clocks to reduce power consumption */
rccDisableAHB(STM32_GPIO_EN_MASK, TRUE);
/* Set GPIOs to AIN */
GPIOx->MODER = 0xFFFFFFFF; /*GPIOx could be: GPIOA, GPIOB, ... */
/* But note when you use debugging PA13 (SWDAT) and PA14 (SWCLK) should not be changed */
My Problem, what I have, is that my Instruction-Pointer does not stop at
or
and I don't know why?!
Does anybody have an idea why does this happen?
Maybe it is because I am connected to a debugger, but I tried also an "Release" but my µC still does not stop?
I searched a lot for this issue, but I found nothing regarding this issue...
