STM32F4 Enter Stop Mode

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

Moderator: RoccoMarco

Post Reply
Tabulous
Posts: 518
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 18 times

STM32F4 Enter Stop Mode

Post by Tabulous »

Trying to enter stop mode, as when the unit looses power and switches to battery i dont need to keep things running. So I've tried this, and it stops the device, but then the debugger (openOCD) bomb outs and stop
communicating with the MCU.

Code: Select all

static void cmd_sleep(BaseSequentialStream *chp, int argc, char *argv[]) {
uint8_t status;

  (void)argv;
  if (argc > 0)
  {
      if (strstr(argv[0], "zzzz") != NULL)
      {
          chThdSleepMilliseconds(1000);
          chprintf(chp, "Entering sleep mode..... \r\n");
          chThdSleepMilliseconds(1000);

          PWR->CR &= ~PWR_CR_PDDS;
          PWR->CR |= (PWR_CR_LPDS | PWR_CR_CSBF | PWR_CR_CWUF);

          SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
          __WFI();
          return;
      }
  }
}


Will this put the MCU to sleep ? and will it wait for EXT interrupt ?
Tabulous
Posts: 518
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 18 times

Re: STM32F4 Enter Stop Mode

Post by Tabulous »

This stops the debugger from bombing

Code: Select all

DBGMCU->CR |= DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP;


But still cant get it to wakeup with EXTi

Code: Select all

static const EXTConfig extcfg = {
  {
    {EXT_CH_MODE_BOTH_EDGES | EXT_MODE_GPIOE, extcb3},  // IGN_IN
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_BOTH_EDGES | EXT_MODE_GPIOH, extcb1},  // INPUT_1
    {EXT_CH_MODE_BOTH_EDGES | EXT_MODE_GPIOH, extcb2},  // INPUT_2
    {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}
  }
};

    /*
     * Activates the EXT driver.
     */
    extStart(&EXTD1, &extcfg);

    extChannelEnable(&EXTD1, 0);
    extChannelEnable(&EXTD1, 2);
    extChannelEnable(&EXTD1, 3);


User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F4 Enter Stop Mode

Post by Giovanni »

Hi,

I never tested it personally, I think barthess experimented with it for a while.

Anyway, the EXT driver is able to enable Cortex "events" instead of interrupts when the callback is set to NULL, is it possible this is the mode you need?

Giovanni
Tabulous
Posts: 518
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 18 times

Re: STM32F4 Enter Stop Mode

Post by Tabulous »

Giovanni wrote:Hi,

I never tested it personally, I think barthess experimented with it for a while.

Anyway, the EXT driver is able to enable Cortex "events" instead of interrupts when the callback is set to NULL, is it possible this is the mode you need?

Giovanni


I want to wake on EXTI interrupt, but from what i can see it enters stop mode but never wakes on the the EXTI trigger. I know the EXTI are working correctly as when running normally if i press my button connected to these the light a LED via the callback.
Tabulous
Posts: 518
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 18 times

Re: STM32F4 Enter Stop Mode

Post by Tabulous »

Can somebody try this for me, this in my view should put the MCU into STOP mode.

In ST ref manual STOP mode is entered with PDDS and LPDS bits set and DEEPSLEEP bit set. But once in this mode i cannot exit. The MCU does not wake using EXTI. As state above i know my EXTi driver is working ok as it normally flashes a LED and this works ok.

Can somebody test this and concur they get the same ?

Code: Select all

static void cmd_sleep(BaseSequentialStream *chp, int argc, char *argv[]) {
uint8_t status;


  (void)argv;
  if (argc > 0)
  {
      if (strstr(argv[0], "zzz") != NULL)
      {
          chThdSleepMilliseconds(1000);
          chprintf(chp, "Entering sleep mode..... \r\n");
          chThdSleepMilliseconds(1000);

          /* Setup the deepsleep mask */
          SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

          /* clear PDDS and LPDS bits */
          PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS);

          /* set LPDS and clear  */
          PWR->CR |= (PWR_CR_LPDS | PWR_CR_PDDS | \
                              PWR_CR_CSBF | PWR_CR_CWUF);

          __WFI();

          /* clear the deepsleep mask */
          SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;

          /* re-configure the clocks */
          stm32_clock_init();
          return;
      }
  }
}
Tabulous
Posts: 518
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 18 times

Re: STM32F4 Enter Stop Mode

Post by Tabulous »

Just for future people who may encounter these issues. Below is the code that works to put MCU into STOP mode. Using __WFI(); i found was impossible to use has the system kernel tick wakes it up instantly. So you can only use __WFE(); Note ! ensure your EXTi are configured with NULL as the callback other it will not work.

Also you'll see i have had to disable interrupts prior to entering __WFE(); im not sure why this is but if you dont it will not work......

Also you'll see i have to call __WFE(); twice, this is i believe a silicon issue, as for some reason the event register is set, so when you call __WFE(); all this does is clear it and return straight away.....Hence when you call it a second time it s clear and thus enters STOP mode......

Also you'll see call to __SEV();, this is to ensure the event bit is set, as if for some reason its not and you call __WFE(); twice you will enter sleep twice.......

All in all this as been a ball ache, hopefully this will stop anyone else having the same issue.

Code: Select all

          /* clear PDDS and LPDS bits */
          PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS);

          /* set LPDS and clear  */
          PWR->CR |= (PWR_CR_LPDS | PWR_CR_CSBF | PWR_CR_CWUF);

          /* Setup the deepsleep mask */
          SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

          __disable_irq();

          __SEV();
          __WFE();
          __WFE();

          __enable_irq();

          /* clear the deepsleep mask */
          SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;


And finally dont for get to restart your clks as when you wake you'll be running on HSI very slowly :-)
Post Reply