Made using MichaelWei's PowerControl library and RTC timer library. This fails to wake up for some unknown reason
Fork of PowerControl by
main.cpp@1:9ec2b510c2b1, 2018-02-14 (annotated)
- Committer:
- Pointer_reference
- Date:
- Wed Feb 14 08:53:47 2018 +0000
- Revision:
- 1:9ec2b510c2b1
- Parent:
- 0:9bd5f1bdb845
This RTC interrupt fails for some unknown reason;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
no2chem | 0:9bd5f1bdb845 | 1 | #include "mbed.h" |
Pointer_reference | 1:9ec2b510c2b1 | 2 | #include "RTC.h" |
no2chem | 0:9bd5f1bdb845 | 3 | #include "PowerControl/PowerControl.h" |
no2chem | 0:9bd5f1bdb845 | 4 | #include "PowerControl/EthernetPowerControl.h" |
no2chem | 0:9bd5f1bdb845 | 5 | |
Pointer_reference | 1:9ec2b510c2b1 | 6 | #define USR_POWERDOWN (0x104) |
Pointer_reference | 1:9ec2b510c2b1 | 7 | int semihost_powerdown() { |
Pointer_reference | 1:9ec2b510c2b1 | 8 | uint32_t arg; |
Pointer_reference | 1:9ec2b510c2b1 | 9 | return __semihost(USR_POWERDOWN, &arg); |
Pointer_reference | 1:9ec2b510c2b1 | 10 | } |
Pointer_reference | 1:9ec2b510c2b1 | 11 | |
Pointer_reference | 1:9ec2b510c2b1 | 12 | |
Pointer_reference | 1:9ec2b510c2b1 | 13 | DigitalOut myled1(LED1); |
Pointer_reference | 1:9ec2b510c2b1 | 14 | DigitalOut myled2(LED2); |
Pointer_reference | 1:9ec2b510c2b1 | 15 | DigitalOut myled3(LED3); |
Pointer_reference | 1:9ec2b510c2b1 | 16 | DigitalOut myled4(LED4); |
Pointer_reference | 1:9ec2b510c2b1 | 17 | |
Pointer_reference | 1:9ec2b510c2b1 | 18 | int volatile count; |
Pointer_reference | 1:9ec2b510c2b1 | 19 | |
Pointer_reference | 1:9ec2b510c2b1 | 20 | // Simon's Watchdog code from |
Pointer_reference | 1:9ec2b510c2b1 | 21 | // http://mbed.org/forum/mbed/topic/508/ |
Pointer_reference | 1:9ec2b510c2b1 | 22 | class Watchdog { |
Pointer_reference | 1:9ec2b510c2b1 | 23 | public: |
Pointer_reference | 1:9ec2b510c2b1 | 24 | // Load timeout value in watchdog timer and enable //Register descriptions in the manual |
Pointer_reference | 1:9ec2b510c2b1 | 25 | void kick(float s) { |
Pointer_reference | 1:9ec2b510c2b1 | 26 | LPC_WDT->WDCLKSEL = 0x02; // Set CLK src to RTC for DeepSleep wakeup; RTC runs on 32kHz |
Pointer_reference | 1:9ec2b510c2b1 | 27 | LPC_WDT->WDTC = (s/4.0)*32768; // Timeout value in 32bit register in terms of RTC ticks |
Pointer_reference | 1:9ec2b510c2b1 | 28 | LPC_WDT->WDMOD = 0x3; // Enabled register(0) and Reset register(1) |
Pointer_reference | 1:9ec2b510c2b1 | 29 | kick(); |
Pointer_reference | 1:9ec2b510c2b1 | 30 | } |
Pointer_reference | 1:9ec2b510c2b1 | 31 | // "kick" or "feed" the dog - reset the watchdog timer |
Pointer_reference | 1:9ec2b510c2b1 | 32 | // by writing this required bit pattern. If wrong sequence is used, a RESET is triggeered |
Pointer_reference | 1:9ec2b510c2b1 | 33 | void kick() { |
Pointer_reference | 1:9ec2b510c2b1 | 34 | LPC_WDT->WDFEED = 0xAA; |
Pointer_reference | 1:9ec2b510c2b1 | 35 | LPC_WDT->WDFEED = 0x55; |
Pointer_reference | 1:9ec2b510c2b1 | 36 | } |
Pointer_reference | 1:9ec2b510c2b1 | 37 | }; |
Pointer_reference | 1:9ec2b510c2b1 | 38 | |
Pointer_reference | 1:9ec2b510c2b1 | 39 | // Setup the watchdog timer |
Pointer_reference | 1:9ec2b510c2b1 | 40 | Watchdog wdt; |
Pointer_reference | 1:9ec2b510c2b1 | 41 | |
Pointer_reference | 1:9ec2b510c2b1 | 42 | // Blink LED |
Pointer_reference | 1:9ec2b510c2b1 | 43 | void blink() { |
Pointer_reference | 1:9ec2b510c2b1 | 44 | myled4 = 0; |
Pointer_reference | 1:9ec2b510c2b1 | 45 | myled1 = 1; |
Pointer_reference | 1:9ec2b510c2b1 | 46 | } |
Pointer_reference | 1:9ec2b510c2b1 | 47 | Serial pc(USBTX, USBRX); |
no2chem | 0:9bd5f1bdb845 | 48 | int main() { |
Pointer_reference | 1:9ec2b510c2b1 | 49 | set_time(1256729737); |
Pointer_reference | 1:9ec2b510c2b1 | 50 | //RTC::attach(&blink, RTC::Second); |
Pointer_reference | 1:9ec2b510c2b1 | 51 | //Serial pc(USBTX, USBRX); |
Pointer_reference | 1:9ec2b510c2b1 | 52 | int result; |
Pointer_reference | 1:9ec2b510c2b1 | 53 | //Watchdog wdt; |
Pointer_reference | 1:9ec2b510c2b1 | 54 | //pc.printf("Hello World!\n"); |
Pointer_reference | 1:9ec2b510c2b1 | 55 | |
Pointer_reference | 1:9ec2b510c2b1 | 56 | // On reset, determine if a watchdog, power on reset or a pushbutton caused reset and display on LED 4 or 3 |
Pointer_reference | 1:9ec2b510c2b1 | 57 | // Check reset source register |
Pointer_reference | 1:9ec2b510c2b1 | 58 | result = LPC_SC->RSID; |
Pointer_reference | 1:9ec2b510c2b1 | 59 | if ((result & 0x03 )==0) { |
Pointer_reference | 1:9ec2b510c2b1 | 60 | // was not POR or reset pushbutton so |
Pointer_reference | 1:9ec2b510c2b1 | 61 | // Mbed is out of debug mode and reset so can enter DeepSleep now and wakeup using watchdog |
Pointer_reference | 1:9ec2b510c2b1 | 62 | //myled4 = 1; |
Pointer_reference | 1:9ec2b510c2b1 | 63 | wait(.0625); |
Pointer_reference | 1:9ec2b510c2b1 | 64 | //wdt.kick(2); |
Pointer_reference | 1:9ec2b510c2b1 | 65 | //blink(); |
Pointer_reference | 1:9ec2b510c2b1 | 66 | tm t = RTC::getDefaultTM(); |
Pointer_reference | 1:9ec2b510c2b1 | 67 | t.tm_sec = 5; |
Pointer_reference | 1:9ec2b510c2b1 | 68 | RTC::alarm(&blink, t); |
Pointer_reference | 1:9ec2b510c2b1 | 69 | DeepSleep(); |
Pointer_reference | 1:9ec2b510c2b1 | 70 | |
Pointer_reference | 1:9ec2b510c2b1 | 71 | myled4 = 0; |
Pointer_reference | 1:9ec2b510c2b1 | 72 | // Watch dog timer wakes it up with a reset |
Pointer_reference | 1:9ec2b510c2b1 | 73 | // |
Pointer_reference | 1:9ec2b510c2b1 | 74 | } else { |
Pointer_reference | 1:9ec2b510c2b1 | 75 | // Was an initial manual or Power on Reset |
Pointer_reference | 1:9ec2b510c2b1 | 76 | // This codes only executes the first time after initial POR or button reset |
Pointer_reference | 1:9ec2b510c2b1 | 77 | LPC_SC->RSID = 0x0F; |
Pointer_reference | 1:9ec2b510c2b1 | 78 | // Clear reset source register bits for next reset |
Pointer_reference | 1:9ec2b510c2b1 | 79 | myled3 = 1; |
Pointer_reference | 1:9ec2b510c2b1 | 80 | // LED3 on to indicate initial reset at full power level |
Pointer_reference | 1:9ec2b510c2b1 | 81 | // Normal mbed power level for this setup is around 690mW |
Pointer_reference | 1:9ec2b510c2b1 | 82 | // assuming 5V used on Vin pin |
Pointer_reference | 1:9ec2b510c2b1 | 83 | // Power down Ethernet interface - saves around 175mW -no cable as well |
Pointer_reference | 1:9ec2b510c2b1 | 84 | PHY_PowerDown(); |
Pointer_reference | 1:9ec2b510c2b1 | 85 | // Power down magic USB interface chip - saves around 150mW |
Pointer_reference | 1:9ec2b510c2b1 | 86 | // Needs new firmware (URL below) and Power need to be supplied from Vin pin not USB |
Pointer_reference | 1:9ec2b510c2b1 | 87 | // http://mbed.org/handbook/Beta |
Pointer_reference | 1:9ec2b510c2b1 | 88 | |
Pointer_reference | 1:9ec2b510c2b1 | 89 | // Also exits debug mode - must not be in debug mode for deep power down modes (Board limitation) |
Pointer_reference | 1:9ec2b510c2b1 | 90 | result = semihost_powerdown(); |
Pointer_reference | 1:9ec2b510c2b1 | 91 | |
Pointer_reference | 1:9ec2b510c2b1 | 92 | // Power consumption is now around half |
Pointer_reference | 1:9ec2b510c2b1 | 93 | // Turn off clock enables on unused I/O Peripherals (UARTs, Timers, PWM, SPI, CAN, I2C, A/D...) |
Pointer_reference | 1:9ec2b510c2b1 | 94 | // To save just a tiny bit more power - most are already off by default in this short code example |
Pointer_reference | 1:9ec2b510c2b1 | 95 | // See PowerControl.h for I/O device bit assignments |
Pointer_reference | 1:9ec2b510c2b1 | 96 | // Don't turn off GPIO - it is needed to blink the LEDs |
Pointer_reference | 1:9ec2b510c2b1 | 97 | Peripheral_PowerDown(0xFFFF7FFF); |
Pointer_reference | 1:9ec2b510c2b1 | 98 | // Now can do a reset to free mbed of debug mode |
Pointer_reference | 1:9ec2b510c2b1 | 99 | // NXP manual says must exit debug mode and reset for DeepSleep or lower power levels to wakeup |
Pointer_reference | 1:9ec2b510c2b1 | 100 | wait(1); |
Pointer_reference | 1:9ec2b510c2b1 | 101 | NVIC_SystemReset(); |
Pointer_reference | 1:9ec2b510c2b1 | 102 | } |
no2chem | 0:9bd5f1bdb845 | 103 | } |