deep sleep and wake-up. WDT interrupt sample. see: http://mbed.org/users/okini3939/notebook/low-power-m0/

Dependencies:   mbed

main.cpp

Committer:
okini3939
Date:
2014-07-08
Revision:
0:766ef51c9b11

File content as of revision 0:766ef51c9b11:

#include "mbed.h"

DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);

Serial pc(USBTX, USBRX);

extern "C"
void WDT_IRQHandler(void) {
    LPC_WWDT->MOD |= (1<<3);
    LPC_WWDT->MOD &= ~(1<<2);
    led2 = !led2;
}

void initWDT (float s) {
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<15);
    LPC_SYSCON->PDRUNCFG &= ~(1<<6); // WDT on
    LPC_SYSCON->PDSLEEPCFG &= ~(1<<6); // WDT on
    LPC_SYSCON->WDTOSCCTRL = (1<<5)|(0x1f<<0); // 500kHz / 64

    LPC_WWDT->CLKSEL = (1<<0);               // Set CLK src to PCLK
    uint32_t clk = 500000 / 64 / 4;    // WD has a fixed /4 prescaler, PCLK default is /4
    LPC_WWDT->TC = s * (float)clk;
    LPC_WWDT->WARNINT = 0;
    LPC_WWDT->MOD = (1<<0);                   // Enabled but Reset disable

    LPC_WWDT->FEED = 0xAA;
    LPC_WWDT->FEED = 0x55;

    LPC_SYSCON->STARTERP1 |= (1<<12);
    NVIC_ClearPendingIRQ(WDT_IRQn);
    NVIC_EnableIRQ(WDT_IRQn);
}

void PowerDown () {
    LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG;
    LPC_PMU->PCON = (2<<0);
    SCB->SCR |= (1<<2);
    __WFI();
}

void DeepSleep () {
    LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG;
    LPC_PMU->PCON = (1<<0);
    SCB->SCR |= (1<<2);
    __WFI();
}

void Sleep () {
    LPC_PMU->PCON = 0;
    SCB->SCR &= ~(1<<2);
    __WFI();
}

int main() {
    int i;

    pc.baud(9600);
    pc.printf("low power\r\n");

    for (i = 0; i < 6; i ++) {
        led1 = !led1;
        wait(0.2);
    }

    for (;;) {
    
        pc.printf("enter sleep\r\n");
        wait_ms(10);

        initWDT(1);
        wait_ms(10);
//        Sleep();
        DeepSleep();
//        PowerDown();

        pc.printf("wake up\r\n");
        for (i = 0; i < 6; i ++) {
            led1 = !led1;
            wait(0.2);
        }

        for (;;);

    }
}