Electronic – Sleep on Arm Cortex

cortex-mcortex-m3low-power

I'm trying to put a cortex m4 processor (m3 with dsp extensions) to sleep for a little less than a second. I want to be able to tell it to sleep, then a second later, or when a button is pressed, pick up right where I left off. I've looked in the reference manual and VLPS or LLS modes look like it would fit my needs. Ideally I'd like a glorified delay function, for it to sleep for a second. I don't know how to begin to enter that mode or how to program the NVIC. I'm using C on bare metal.

Any help would be greatly appreciated.

Here's the code:

#include "IntervalTimer.h"

//The following is where the SLEEPDEEP flag is at
#define SCR         (*((volatile unsigned long *) 0xE000ED10))

volatile uint32_t timerCounter0;
boolean printNow = false;

void timerCallback0() {
  timerCounter0++;
  printNow = true;
}

void setup() {
  SCR = SCR | 0x04;    //Set SLEEPDEEP
  Serial.begin(true);
  IntervalTimer timer0;
  timer0.begin(timerCallback0, 1000000);
}

void loop() {
  if (printNow) {
    Serial.println(timerCounter0);
    printNow = false;
    asm("wfi\n");
  }
}

Best Answer

You are counting many periods of a fairly short timer, each expiration of which requires you to wake up. To get maximum power savings, you need to put the timing entirely in hardware, so that you only generate an interrupt at the end of the desired period, or at least fairly infrequently. You should probably look at using a larger value in the timer register, and possibly using a prescalar divisor. (Even if you are waking up only a few times a second and so not wasting much power, this will make it a pain to measure power consumption unless you use a scope to measure across a series resistor)

However, even then you would likely still be running on a fast PLL clock, which consumes a lot of power. So for more power savings you will want to switch to a low power clock source such as an internal or external KHz-range backup clock, or at least disable the PLL and possibly crank up any system-wide clock prescale divider.

And you also likely have many parts of the chip powered up and clocked which are not needed in sleep mode - likely you want to power down and de-clock everything except the GPIO, interrupt controller, counter module and RAM.

Additionally, you need to audit your circuit design for any cases where you are driving a signal against a pullup or pulldown resistor, or even letting a digital input float in the vicinity of a logic transition.

Getting a system down to microamp standby modes can be an involved project, as you eliminate one power leach after another. Also watch out for debugger, serial, USB, etc connections - not only as potential loads, but also potential stealth power sources for the system to get power while bypassing whatever you are measuring with (yes, you can get energy from data pins).