Enables lower power Sleep and power down modes for LPC11U24 systems than the mbed API supports directly.

Dependents:   mBuDice SleepyCounting

Provides a clean method to put the mBuino into various power save modes while minimizing power draw. This code is specifically for the mBuino, for other LPC11U24 based systems use this version.

When the mBuino was released the mbed library Sleep() and DeepSleep() commands causes the system to crash, even if fixed in a later release of the library the mBed API doesn't allow access to the lowest power modes that you need when running from a watch battery. Hence this library.

When commanded to sleep the system will pause in a power saving state until it receives an interrupt at which point things carry on as before.

The basic use is

#include "mBuinoSleep.h"

main() {
mBuinoSleep(PowerDown);
}

In order to shut off the LEDs the library will create a BusOut object called LEDs containing all 7 mBuino LEDs in order. When entering sleep mode the LEDs will be turned off, when waking the previous state will be restored. Within your code you can set the state of all 7 LEDs by setting the value of LEDs directly e.g. LEDs = 0x7f would turn them all on. LEDs=0x2A would turn LEDs 2,4 and 6 on. See BusOut for more details.

Similarly a DigitalIn called progMode is created on port pin 0_3 in order to disable the internal pullup on this pin (required to reduce power consumption).

If either of these cause a problem in your code then use the mBuino_Sleep_Minimal library which has the same sleep code but without any IO control. If doing this ensure you disable the pullup and turn off the LEDs in your code.

Finally if you add the line

sleep_CleanShutdown = true;

to your code anywhere before entering sleep mode then the system clock will be switched from the PLL to the IRC before entering DeepSleep or PowerDown and switched back after waking up. This is recommended by the CPU user manual in order to avoid clock glitches but in practice doesn't seem necessary. The down side to doing this is that any code in the interrupt routine that wakes the system up again will run at the IRC frequency not the normal clock frequency.

The supported sleep modes are:

  • Sleep - About a 50% power saving. All timers run as normal.
  • DeepSleep - Power consumption in the 350uA region (a few weeks or so on a watch battery). All timers are disabled, only external interrupts can wake the system.
  • DeepSleepWD - As DeepSleep but also keeping the Watch Dog timer powered up. Tiny increase in power (4uA) but the watchdog wakeup library can be used to wake the system on a timer.
  • PowerDown - Power consumption in the 3uA region (Battery life in the decades range, in practice battery life will be determined by other factors). Similar to DeepSleep but takes a few ms longer to wake up.
  • PowerDownWD - PowerDown but with the watch dog timer running resulting in a power consumption of 7uA.
  • DeepPowerDown - Sub uA power consumption but can only wake from the reset or wakeup pin (which also causes a reset).

In DeepSleep or PowerDown modes it is NOT is possible to use a normal Ticker or Timeout to wake up from sleep mode. To wake up on a timer use the modes ending in WD and use this library to configure the watchdog. See this program for an example.

An IO interrupt (i.e. anything triggered by a pin that is defined as an InterruptIn) will wake the system up from all sleep modes other than DeepPowerDown.

NOTES:

DO NOT enter sleep mode from within an interrupt (that includes Timers, Tickers, Timeouts etc...) unless your wakeup interrupt is higher priority (this is not the mbed default, if you aren't sure or don't know what I'm talking about then it isn't). If you do this you will never wake up.

DeepPowerDown requires an external pullup on the wakeup pin, without this the system will wake up as soon as it enters power down. On the mBuino this resistor is not there, you need to add it. For other platforms check the schematic.

All deepsleep and powerdown modes currently disable the brownout detection circuit. Keeping this powered would add about 50uA to the power consumption. If for some reason you need this circuit active then this would require a minor change to the library, specifically the value programmed into PDSLEEPCFG around line 40.

Committer:
AndyA
Date:
Sun Sep 28 09:16:33 2014 +0000
Revision:
7:bcb4ed255791
Parent:
6:23973d4b6b34
Fix stupid typo;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AndyA 0:a03325b9f702 1 #ifndef __mBuinoSleep__
AndyA 0:a03325b9f702 2 #define __mBuinoSleep__
AndyA 0:a03325b9f702 3
AndyA 0:a03325b9f702 4 #include "mbed.h"
AndyA 0:a03325b9f702 5
AndyA 1:542283bfadf6 6 extern BusOut LEDs;
AndyA 0:a03325b9f702 7
AndyA 1:542283bfadf6 8 extern DigitalIn progMode;
AndyA 0:a03325b9f702 9
AndyA 5:1bbdf41ca1e4 10 /// set true to do a clean PLL shutdown. Wakeup IRQ will run slow.
AndyA 1:542283bfadf6 11 extern bool sleep_CleanShutdown;
AndyA 0:a03325b9f702 12
AndyA 6:23973d4b6b34 13 /// List of supported sleep modes. WD suffix indicates the watchdog remains powered.
AndyA 5:1bbdf41ca1e4 14 /// Take care when using deep power down.
AndyA 6:23973d4b6b34 15 enum sleepMode_t {Sleep, DeepSleep, DeepSleepWD, PowerDown, PowerDownWD, DeepPowerDown};
AndyA 0:a03325b9f702 16
AndyA 1:542283bfadf6 17 /// Enters the selected sleep mode
AndyA 0:a03325b9f702 18 void mBuinoSleep(enum sleepMode_t mode);
AndyA 0:a03325b9f702 19
AndyA 1:542283bfadf6 20 #endif