Andy A / WakeUp

Fork of WakeUp by Erik -

Device/WakeUp_LPC11u24.cpp

Committer:
AndyA
Date:
2015-06-25
Revision:
19:c1fc9bb48d2b
Parent:
18:e71f388710b7
Child:
20:1bd0c314f043

File content as of revision 19:c1fc9bb48d2b:

/**
Due to lack of another option for the LPC11u24 the watchdog timer is used as wakeup source.
Since if the reset on watchdog event bit is set, I cannot remove it again, this means if you also got watchdog code running
the most likely result is that it just resets your board.
**/


#ifdef TARGET_LPC11U24

#include "WakeUp.h"

FunctionPointer WakeUp::callback;
float WakeUp::cycles_per_ms = 5.0;
uint32_t WakeUp::timeoutSet = 0;

void WakeUp::set_ms(uint32_t ms)
{
    if (ms != 0) {
        LPC_SYSCON->SYSAHBCLKCTRL |= 0x8000;
        LPC_SYSCON->PDRUNCFG &= ~(1<<6);
        LPC_SYSCON->PDSLEEPCFG &= ~(1<<6);
        LPC_SYSCON->STARTERP1 |= 1<<12;

        //Set oscillator for 20kHz = 5kHz after divide by 4 in WDT
        LPC_SYSCON->WDTOSCCTRL = 14 | (1<<5);

        LPC_WWDT->MOD = 1;      //Enable WDT
        timeoutSet = (uint32_t)((float)ms * cycles_per_ms);
        LPC_WWDT->TC = timeoutSet;
        LPC_WWDT->CLKSEL = 1;   //WDTOSC
        LPC_WWDT->WARNINT = 0;

        NVIC_SetVector(WDT_IRQn, (uint32_t)WakeUp::irq_handler);

        //Feeeeeed me
        LPC_WWDT->FEED = 0xAA;
        LPC_WWDT->FEED = 0x55;

        NVIC_EnableIRQ(WDT_IRQn);
    } else
        NVIC_DisableIRQ(WDT_IRQn);

}

void WakeUp::irq_handler(void)
{
    LPC_WWDT->MOD = 1<<3;
    callback.call();
}

void WakeUp::calibrate(void)
{
    cycles_per_ms = 5.0;
    set_ms(1100);
    wait_ms(10);    //Give time to sync
    uint32_t count1 = LPC_WWDT->TV;
    wait_ms(100);
    uint32_t count2 = LPC_WWDT->TV;
    set_ms(0);
    count1 = count1 - count2;

    cycles_per_ms = count1 / 100.0;
}

float WakeUp::timeRemaining(void)
{
    return (timeoutSet - LPC_WWDT->TV) / (cycles_per_ms*1000);
}

#endif