Minimal version of mBuino Sleep

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mBuinoSleep.cpp Source File

mBuinoSleep.cpp

00001 #include "mBuinoSleep.h"
00002 
00003 void mBuinoSleep(enum sleepMode_t mode)
00004 {
00005 
00006     if ((mode == DeepPowerDown) && (LPC_PMU->PCON & 0x08)) // bit 3 high blocks deep power down.
00007         mode = PowerDown;
00008 
00009     switch (mode) {
00010         default:
00011         case Sleep:
00012             LPC_PMU->PCON = 0x0;
00013             SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
00014             __WFI();
00015             break;
00016 
00017         case DeepSleep:
00018         case PowerDown:
00019         case PowerDownWD:
00020         case DeepSleepWD: {
00021             if ((mode == PowerDown) || (mode == PowerDownWD))
00022                 LPC_PMU->PCON = 0x2;
00023             else
00024                 LPC_PMU->PCON = 0x1;
00025 
00026             LPC_SYSCON->PDSLEEPCFG |= 0x7f;  // shut off everything we can.
00027 
00028             if ((mode == DeepSleepWD) || (mode == PowerDownWD))
00029                 LPC_SYSCON->PDSLEEPCFG &= ~(1<<6);
00030 
00031             SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
00032 
00033             bool IRCPowered = (LPC_SYSCON->PDRUNCFG & 0x01); // only used for cleen shutdown but defined here for scope reasons.
00034             if (!IRCPowered)
00035                 LPC_SYSCON->PDRUNCFG &= 0xfffffffe; // power up the IRC
00036 
00037             if(sleep_CleanShutdown) {
00038                 LPC_SYSCON->MAINCLKSEL    = 0x00; // switch to IRC to avoid glitches
00039                 LPC_SYSCON->MAINCLKUEN    = 0x01;               /* Update MCLK Clock Source */
00040                 LPC_SYSCON->MAINCLKUEN    = 0x00;               /* Toggle Update Register   */
00041                 LPC_SYSCON->MAINCLKUEN    = 0x01;
00042                 while (!(LPC_SYSCON->MAINCLKUEN & 0x01));       /* Wait Until Updated       */
00043             }
00044 
00045             LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG; // switch on everything that is currently on when we wake up.
00046             __WFI();
00047 
00048             if(sleep_CleanShutdown) {
00049                 LPC_SYSCON->MAINCLKSEL    = 0x03; // switch to PLL output
00050                 LPC_SYSCON->MAINCLKUEN    = 0x01;               /* Update MCLK Clock Source */
00051                 LPC_SYSCON->MAINCLKUEN    = 0x00;               /* Toggle Update Register   */
00052                 LPC_SYSCON->MAINCLKUEN    = 0x01;
00053                 while (!(LPC_SYSCON->MAINCLKUEN & 0x01));       /* Wait Until Updated       */
00054             }
00055 
00056             if (!IRCPowered)
00057                 LPC_SYSCON->PDRUNCFG |= 0x01; // power down the IRC if it was off before
00058         }
00059         break;
00060         case DeepPowerDown:
00061             LPC_PMU->PCON = 0x3;
00062             LPC_SYSCON->PDSLEEPCFG |= 0x7f;  // shut off everything we can.
00063             SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
00064             __WFI();
00065     }
00066 }