Minimal version of mBuino Sleep

This is a cut down version of mBuino_Sleep that doesn't control any IO lines.

This version should work fine on any NXP LPC11Uxx CPUs although you will need to check the external pin pullup/down status, any conflicts between external and internal pulls will increase power usage.

If using this version on an mBuino ensure you disable the pullup on P0_3 (on by default for any unconfigured GPIO lines) and turn all the LEDs off before entering sleep. Failing to do so will increase the sleep mode power draw.

See mBuino_Sleep for usage details.

Committer:
AndyA
Date:
Mon Sep 22 09:15:52 2014 +0000
Revision:
1:219e1147c6fa
Parent:
0:af76f9a302ea
Child:
2:9c5cd0f7aa8a
Added DeepPowerDown

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AndyA 0:af76f9a302ea 1 #include "mBuinoSleep.h"
AndyA 0:af76f9a302ea 2
AndyA 0:af76f9a302ea 3 void mBuinoSleep(enum sleepMode_t mode)
AndyA 0:af76f9a302ea 4 {
AndyA 1:219e1147c6fa 5
AndyA 1:219e1147c6fa 6 if ((mode == DeepPowerDown) && (LPC_PMU->PCON & 0x08)) // bit 3 high blocks deep power down.
AndyA 1:219e1147c6fa 7 mode = PowerDown;
AndyA 1:219e1147c6fa 8
AndyA 0:af76f9a302ea 9 switch (mode) {
AndyA 0:af76f9a302ea 10 default:
AndyA 0:af76f9a302ea 11 case Sleep:
AndyA 0:af76f9a302ea 12 LPC_PMU->PCON = 0x0;
AndyA 0:af76f9a302ea 13 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
AndyA 0:af76f9a302ea 14 __WFI();
AndyA 0:af76f9a302ea 15 break;
AndyA 0:af76f9a302ea 16
AndyA 0:af76f9a302ea 17 case DeepSleep:
AndyA 0:af76f9a302ea 18 case PowerDown: {
AndyA 0:af76f9a302ea 19 if (mode == PowerDown)
AndyA 0:af76f9a302ea 20 LPC_PMU->PCON = 0x2;
AndyA 0:af76f9a302ea 21 else
AndyA 0:af76f9a302ea 22 LPC_PMU->PCON = 0x1;
AndyA 0:af76f9a302ea 23
AndyA 0:af76f9a302ea 24 LPC_SYSCON->PDSLEEPCFG |= 0x7f; // shut off everything we can.
AndyA 0:af76f9a302ea 25 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
AndyA 0:af76f9a302ea 26
AndyA 0:af76f9a302ea 27 bool IRCPowered = (LPC_SYSCON->PDRUNCFG & 0x01); // only used for cleen shutdown but defined here for scope reasons.
AndyA 0:af76f9a302ea 28 if (!IRCPowered)
AndyA 0:af76f9a302ea 29 LPC_SYSCON->PDRUNCFG &= 0xfffffffe; // power up the IRC
AndyA 0:af76f9a302ea 30
AndyA 0:af76f9a302ea 31 if(sleep_CleanShutdown) {
AndyA 0:af76f9a302ea 32 LPC_SYSCON->MAINCLKSEL = 0x00; // switch to IRC to avoid glitches
AndyA 0:af76f9a302ea 33 LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */
AndyA 0:af76f9a302ea 34 LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */
AndyA 0:af76f9a302ea 35 LPC_SYSCON->MAINCLKUEN = 0x01;
AndyA 0:af76f9a302ea 36 while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */
AndyA 0:af76f9a302ea 37 }
AndyA 0:af76f9a302ea 38
AndyA 0:af76f9a302ea 39 LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG; // switch on everything that is currently on when we wake up.
AndyA 0:af76f9a302ea 40 __WFI();
AndyA 0:af76f9a302ea 41
AndyA 0:af76f9a302ea 42 if(sleep_CleanShutdown) {
AndyA 0:af76f9a302ea 43 LPC_SYSCON->MAINCLKSEL = 0x03; // switch to PLL output
AndyA 0:af76f9a302ea 44 LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */
AndyA 0:af76f9a302ea 45 LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */
AndyA 0:af76f9a302ea 46 LPC_SYSCON->MAINCLKUEN = 0x01;
AndyA 0:af76f9a302ea 47 while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */
AndyA 0:af76f9a302ea 48 }
AndyA 0:af76f9a302ea 49
AndyA 0:af76f9a302ea 50 if (!IRCPowered)
AndyA 0:af76f9a302ea 51 LPC_SYSCON->PDRUNCFG |= 0x01; // power down the IRC if it was off before
AndyA 0:af76f9a302ea 52 }
AndyA 0:af76f9a302ea 53 break;
AndyA 1:219e1147c6fa 54 case DeepPowerDown:
AndyA 1:219e1147c6fa 55 LPC_PMU->PCON = 0x3;
AndyA 1:219e1147c6fa 56 LPC_SYSCON->PDSLEEPCFG |= 0x7f; // shut off everything we can.
AndyA 1:219e1147c6fa 57 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
AndyA 1:219e1147c6fa 58 __WFI();
AndyA 0:af76f9a302ea 59 }
AndyA 0:af76f9a302ea 60 }