STM32F103 wake-up from stop mode

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

alexblack
Posts: 277
Joined: Mon Sep 24, 2012 3:52 pm
Been thanked: 33 times

Re: STM32F103 wake-up from stop mode

Post by alexblack »

Hello.
I have STM32F103 MCU, latest ChibiOS 2.7.0 and a problem: MCU can't enter to STOP MODE.
After __WFI() it resets without waiting a wake up interrupt from RTC Alarm.
If I using stadby mode - all works fine. Is anybody sucsessfully used STOP MODE and wake up from RTC?
To enter to STOP MODE I used following code:

Code: Select all

   PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS);
   PWR->CR |= (PWR_CR_CSBF | PWR_CR_CWUF);
   SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    __WFI();
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F103 wake-up from stop mode

Post by Giovanni »

Barthess is the expert of this thing, I never tried it personally. I think something like this has already been answered by him on the forum, do a search.

Giovanni
alexblack
Posts: 277
Joined: Mon Sep 24, 2012 3:52 pm
Been thanked: 33 times

Re: STM32F103 wake-up from stop mode

Post by alexblack »

I searched everywhere on forum and internet - no answer.
DBS06
Posts: 3
Joined: Wed Nov 30, 2016 1:45 pm

Re: STM32F103 wake-up from stop mode

Post by DBS06 »

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

Code: Select all

__WFI() 
or

Code: Select all

__WFE() 
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... :(
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F103 wake-up from stop mode

Post by Giovanni »

Hi,

Look at the test application \testhal\STM32\STM32F1xx\RTC

There is some sleep mode handling in there created by barthess, maybe it can give you an idea.

Giovanni
DBS06
Posts: 3
Joined: Wed Nov 30, 2016 1:45 pm

Re: STM32F103 wake-up from stop mode

Post by DBS06 »

Thanks Giovanni,

I already know this examples, and already tested it, but especially the STM32F1xx RTC examples does not fit for the STM32F3xx, because the STM32F3xx uses the RTCv2 (in hal/ports/STM32/LLD/) and STM32F1xx the RTCv1. The RTC examples from the STM32F4xx are more similar und useful. But in all RTC-examples the EXTI config is missing and are doing a software-reset, when the RTC-IRQ is triggered.

BTW: Giovanni you and your "Team" did/doing a really good job at ChibiOS!!! I love it and besides some starting problems (didn't find examples), it is my most preferred RTOS!!!
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F103 wake-up from stop mode

Post by Giovanni »

Thanks :)

The problem is that we cannot explore all the possible use cases, I never tried the stop mode on the F3.

Giovanni
chrismerck
Posts: 21
Joined: Fri Mar 14, 2014 12:35 am
Been thanked: 4 times

Re: STM32F103 wake-up from stop mode

Post by chrismerck »

Hi @DBS06, I'm not sure if you are still having trouble with STOP mode on your STM32F4x.. but I just had a bear of a time getting it to work on my STM32L151. But eventually I did, and added some notes in the linked post that may help you...

viewtopic.php?t=3381#p28349
Post Reply