Andy A / mBuino_Sleep

Dependents:   mBuDice SleepyCounting

mBuinoSleep.cpp

Committer:
AndyA
Date:
2014-09-21
Revision:
0:a03325b9f702
Child:
1:542283bfadf6

File content as of revision 0:a03325b9f702:

#include "mBuinoSleep.h"

#ifndef _DontSleepLEDs_
BusOut LEDs(LED1, LED2, LED3, LED4, LED5, LED6, LED7);
#endif

#ifndef _DontControlProgMode_
DigitalIn progMode(P0_3);
#endif

void mBuinoSleep(enum sleepMode_t mode)
{

#ifndef _DontSleepLEDs_
    static uint8_t oldLEDState = LEDs;
    LEDs = 0;
#endif

#ifndef _DontControlProgMode_
progMode.mode(PullNone);
#endif


    switch (mode) {
        default:
        case Sleep:
            LPC_PMU->PCON = 0x0;
            SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
            __WFI();
            break;

        case DeepSleep:
        case PowerDown: {
            if (mode == PowerDown)
                LPC_PMU->PCON = 0x2;
            else
                LPC_PMU->PCON = 0x1;

            LPC_SYSCON->PDSLEEPCFG |= 0x7f;  // shut off everything we can.
            SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

            bool IRCPowered = (LPC_SYSCON->PDRUNCFG & 0x01); // only used for cleen shutdown but defined here for scope reasons.
            if (!IRCPowered)
                LPC_SYSCON->PDRUNCFG &= 0xfffffffe; // power up the IRC

#if _CleanPowerDown_
            LPC_SYSCON->MAINCLKSEL    = 0x00; // switch to IRC to avoid glitches
            LPC_SYSCON->MAINCLKUEN    = 0x01;               /* Update MCLK Clock Source */
            LPC_SYSCON->MAINCLKUEN    = 0x00;               /* Toggle Update Register   */
            LPC_SYSCON->MAINCLKUEN    = 0x01;
            while (!(LPC_SYSCON->MAINCLKUEN & 0x01));       /* Wait Until Updated       */
#endif

            LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG; // switch on everything that is currently on when we wake up.
            __WFI();

#if _CleanPowerDown_
            LPC_SYSCON->MAINCLKSEL    = 0x03; // switch to PLL output
            LPC_SYSCON->MAINCLKUEN    = 0x01;               /* Update MCLK Clock Source */
            LPC_SYSCON->MAINCLKUEN    = 0x00;               /* Toggle Update Register   */
            LPC_SYSCON->MAINCLKUEN    = 0x01;
            while (!(LPC_SYSCON->MAINCLKUEN & 0x01));       /* Wait Until Updated       */
#endif

            if (!IRCPowered)
                LPC_SYSCON->PDRUNCFG |= 0x01; // power down the IRC if it was off before
        }
        break;
    }
}