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.
mBuinoSleep.cpp@2:9c5cd0f7aa8a, 2014-09-28 (annotated)
- Committer:
- AndyA
- Date:
- Sun Sep 28 09:24:32 2014 +0000
- Revision:
- 2:9c5cd0f7aa8a
- Parent:
- 1:219e1147c6fa
Added watchdog modes
Who changed what in which revision?
User | Revision | Line number | New 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 | 2:9c5cd0f7aa8a | 18 | case PowerDown: |
AndyA | 2:9c5cd0f7aa8a | 19 | case PowerDownWD: |
AndyA | 2:9c5cd0f7aa8a | 20 | case DeepSleepWD: { |
AndyA | 2:9c5cd0f7aa8a | 21 | if ((mode == PowerDown) || (mode == PowerDownWD)) |
AndyA | 0:af76f9a302ea | 22 | LPC_PMU->PCON = 0x2; |
AndyA | 0:af76f9a302ea | 23 | else |
AndyA | 0:af76f9a302ea | 24 | LPC_PMU->PCON = 0x1; |
AndyA | 0:af76f9a302ea | 25 | |
AndyA | 0:af76f9a302ea | 26 | LPC_SYSCON->PDSLEEPCFG |= 0x7f; // shut off everything we can. |
AndyA | 2:9c5cd0f7aa8a | 27 | |
AndyA | 2:9c5cd0f7aa8a | 28 | if ((mode == DeepSleepWD) || (mode == PowerDownWD)) |
AndyA | 2:9c5cd0f7aa8a | 29 | LPC_SYSCON->PDSLEEPCFG &= ~(1<<6); |
AndyA | 2:9c5cd0f7aa8a | 30 | |
AndyA | 0:af76f9a302ea | 31 | SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; |
AndyA | 0:af76f9a302ea | 32 | |
AndyA | 0:af76f9a302ea | 33 | bool IRCPowered = (LPC_SYSCON->PDRUNCFG & 0x01); // only used for cleen shutdown but defined here for scope reasons. |
AndyA | 0:af76f9a302ea | 34 | if (!IRCPowered) |
AndyA | 0:af76f9a302ea | 35 | LPC_SYSCON->PDRUNCFG &= 0xfffffffe; // power up the IRC |
AndyA | 0:af76f9a302ea | 36 | |
AndyA | 0:af76f9a302ea | 37 | if(sleep_CleanShutdown) { |
AndyA | 0:af76f9a302ea | 38 | LPC_SYSCON->MAINCLKSEL = 0x00; // switch to IRC to avoid glitches |
AndyA | 0:af76f9a302ea | 39 | LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */ |
AndyA | 0:af76f9a302ea | 40 | LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */ |
AndyA | 0:af76f9a302ea | 41 | LPC_SYSCON->MAINCLKUEN = 0x01; |
AndyA | 0:af76f9a302ea | 42 | while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */ |
AndyA | 0:af76f9a302ea | 43 | } |
AndyA | 0:af76f9a302ea | 44 | |
AndyA | 0:af76f9a302ea | 45 | LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG; // switch on everything that is currently on when we wake up. |
AndyA | 0:af76f9a302ea | 46 | __WFI(); |
AndyA | 0:af76f9a302ea | 47 | |
AndyA | 0:af76f9a302ea | 48 | if(sleep_CleanShutdown) { |
AndyA | 0:af76f9a302ea | 49 | LPC_SYSCON->MAINCLKSEL = 0x03; // switch to PLL output |
AndyA | 0:af76f9a302ea | 50 | LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */ |
AndyA | 0:af76f9a302ea | 51 | LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */ |
AndyA | 0:af76f9a302ea | 52 | LPC_SYSCON->MAINCLKUEN = 0x01; |
AndyA | 0:af76f9a302ea | 53 | while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */ |
AndyA | 0:af76f9a302ea | 54 | } |
AndyA | 0:af76f9a302ea | 55 | |
AndyA | 0:af76f9a302ea | 56 | if (!IRCPowered) |
AndyA | 0:af76f9a302ea | 57 | LPC_SYSCON->PDRUNCFG |= 0x01; // power down the IRC if it was off before |
AndyA | 0:af76f9a302ea | 58 | } |
AndyA | 0:af76f9a302ea | 59 | break; |
AndyA | 1:219e1147c6fa | 60 | case DeepPowerDown: |
AndyA | 1:219e1147c6fa | 61 | LPC_PMU->PCON = 0x3; |
AndyA | 1:219e1147c6fa | 62 | LPC_SYSCON->PDSLEEPCFG |= 0x7f; // shut off everything we can. |
AndyA | 1:219e1147c6fa | 63 | SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; |
AndyA | 1:219e1147c6fa | 64 | __WFI(); |
AndyA | 0:af76f9a302ea | 65 | } |
AndyA | 0:af76f9a302ea | 66 | } |