a test code to implement and test LP1768 power control mode

Dependencies:   mbed

This code implemented some LP1768 power mode : Sleep(), DeepSleep(), PowerDown(), DeepPowerDown(), BOGD_PowerDown(). It also has a test code to test these power modes and wakeup using watch dog. The wakeup part is based on Erik's code but add implementation for LP1768. As LP1768 has debug enabled in default, it cannot be waked up in DeepSleep mode. Therefore this code use WDC reset to wake up the chips from deep sleep. The test code also allow test the power under two clock frequency (96 MHz and 48MHz). Inspired by Paul and Michael Wang, I also tested the power reduction by power off PHY. The analysis could be found in http://mbed.org/users/steniu01/notebook/lp1768-power-mode-implementation-and-measurement-/#

Revision:
1:571258908570
Parent:
0:5c4169623549
Child:
2:15d9501bf5b3
--- a/main.cpp	Mon Jul 21 13:46:49 2014 +0000
+++ b/main.cpp	Thu Jul 24 08:53:44 2014 +0000
@@ -1,54 +1,25 @@
 #include "mbed.h"
-#include "CPU_Usage.h"
 #include "RTC.h"
 #include "PowerControl.h"
 #include "EthernetPowerControl.h"
 #include "WakeUp.h"
 #include "steven_powercontrol.h"
+#include "Pulses.h"
+
+
 DigitalOut myled1(LED1);
 DigitalOut myled2(LED2) ;
 DigitalOut myled3(LED3) ;
 Serial pc (USBTX, USBRX);
 Timer t;
-CPU_Usage cpu(t, 1);
+//CPU_Usage cpu(t, 1);
 
-class Watchdog {
-public:
-// Load timeout value in watchdog timer and enable
-    void kick(float s) {
-        LPC_WDT->WDCLKSEL = 0x02;               // Set CLK src to RTC for DeepSleep wakeup
-        LPC_WDT->WDTC = (s/4.0)*32768;
-        LPC_WDT->WDMOD = 0x3;                   // Enabled and Reset
-        kick();
-    }
-// "kick" or "feed" the dog - reset the watchdog timer
-// by writing this required bit pattern
-    void kick() {
-        LPC_WDT->WDFEED = 0xAA;
-        LPC_WDT->WDFEED = 0x55;
-    }
-};
- 
+AnalogOut multimeter(p18);
 
-Watchdog wdt;
-
-//test PLL***
-
-  // Define the register names that haven't been defined
-#define CLKSRCSEL LPC_SC->CLKSRCSEL
-#define PLL0CFG LPC_SC->PLL0CFG
-#define PLL0CON LPC_SC->PLL0CON
-#define CCLKCFG LPC_SC->CCLKCFG
-#define PLL0FEED LPC_SC->PLL0FEED
-#define PLL0STAT LPC_SC->PLL0STAT
-
-  // Other defines
-#define SYSCLK 96000000
-#define EXTCLK 12000000
-#define PLLCLK 288000000
-#define PLLMULT (PLLCLK/2/EXTCLK)-1
-//end test PLL***
-
+// Example for energy meter with SO interface.
+// SO output of energy meter is connected (over opto-coppler) to pin 8
+#define SO_PULSES 2000 // SO interface of energy meter with 2000 pulses per kWh
+Pulses pulses(p8, Pulses::FALL);
 
 void steven_get_string(){
    char input[50]; 
@@ -58,7 +29,7 @@
         pc.putc(ret);
         if (num >=50){
             pc.printf("Overflow \n");
-            exit ; 
+            break;
         }
         if (ret!=(char)NULL)
             input[num++]=ret;
@@ -69,39 +40,74 @@
     pc.printf ("you have input %s \n",input);
 }
 
+void power_measurement(void){
+    pulses.setFactor ( 3600.0f/SO_PULSES );   // Scale to kW; kWh
+    float averagePower = 0;    // Average energy since last call of get()
+    float minPower = 0;        // Min. energy since last call of get()
+    float maxPower = 0;        // Max. energy since last call of get()
+    float sumEnergy = 0;       // Sum of energy over all since start of mbed
+    
+    while(1) {
+        
+        pulses.get ( &averagePower, &minPower, &maxPower, &sumEnergy );
+        
+        pc.printf ( "Power: %.3f (%.3f...%.3f) [kW]   Energy: %.3f [kWh]   SO-pulses=%d\r\n", 
+            averagePower,
+            minPower,
+            maxPower,
+            sumEnergy / 3600.0f,
+            pulses.getCounter() );
 
- 
-void ledFunction( void )
-{
-    myled1 = !myled1;
-    RTC::detach(RTC::Second);
+        // wait(6);   // Example 6 seconds; typical 1 minute (60 sec) sample time
+        
+        // Additional feature: Output of actual power as analog voltage (1V==1kW; max3.3kW). Connect a multimeter to pin 18 and GND
+        for ( int i=0; i<20; i++ ) {
+            multimeter = pulses.getAct() / 3.3f;   // Scale to 1V==1kW
+            wait(0.3);   // Example 6 seconds; typical 1 minute (60 sec) sample time
+        }
+    }     
 }
- 
-void displayFunction( void )
+void profiling_PHY_PowerDown (void)
 {
-    time_t seconds = time(NULL);
-    printf("%s", ctime(&seconds));
+    //PHY_PowerUp();
+    if (!Peripheral_GetStatus(LPC1768_PCONP_PCENET))
+        EMAC_Init(); //init EMAC if it is not already init'd
+    
+    unsigned int regv;
+    wait (10);
+    myled1=1;
+    myled2=0;
+    myled2=0;
+    regv = read_PHY(PHY_REG_BMCR);
+    write_PHY(PHY_REG_BMCR, regv | (1 << PHY_REG_BMCR_POWERDOWN));
+    regv = read_PHY(PHY_REG_BMCR);
+    wait (10);
+    myled1=0;
+    myled2=1;
+    myled3=0;
+    //shouldn't need the EMAC now.
+    LPC_SC->PCONP &=~LPC1768_PCONP_PCENET;
+    wait (10);
+    myled1=0;
+    myled2=0;
+    myled3=1;
+    //and turn off the PHY OSC
+    LPC_GPIO1->FIODIR |= 0x8000000;
+    LPC_GPIO1->FIOCLR = 0x8000000;
+    while(1);
+
 }
- 
-void alarmFunction( void )
-{    
-     
-    wait(2);
-    myled3=1; // add debug information
-    printf("Not most useful alarm function");
-    set_time(0000000000);
-    RTC::alarmOff();
-}
- 
+
 int main()
 {
-    PHY_PowerUp();// power up PHY because it was powerred up as default. We might power it down when test "Turn off PHY".
+    //profiling_PHY_PowerDown();
+    //PHY_PowerUp();// power up PHY because it was powerred up as default. We might power it down when test "Turn off PHY".
     myled1=1;
     wait(0.5);
     myled1=0;
     char char_get=0;
     int num_get=0;
-    char* powermode[7]={ "[1] no low power", "[2] sleep mode", "[3] deep sleep mode", "[4] power down mode", "[5] Brown-out Reduced Power mode", "[6] Turn off PHY", "[7] Deep Power Down"};
+    char* powermode[7]={ "[1] no low power", "[2] sleep mode", "[3] deep sleep mode", "[4] power down mode", "[5] Brown-out Reduced Power mode", "[6] Deep Power Down", "[7] Turn off PHY"};
     while (num_get>7 || num_get<1){
         printf("Which power mode you want to choose: \r\n");
         for (int a=0;a<7;a++)
@@ -115,15 +121,16 @@
     myled2=1;
     wait(0.5);
     myled2=0;
-    WakeUp::set(10);
+    //WakeUp::set(10);
+    WakeUp::set(70);
     switch (num_get){
         case  1: break;
         case  2: steven_Sleep();break;
         case  3: steven_DeepSleep(); break;
         case  4: steven_PowerDown();break;
         case  5: steven_BOGD_PowerDown();break;
-        case  6: PHY_PowerDown(); break;
-        case  7: steven_PowerDown(); break;
+        case  6: steven_DeepPowerDown(); break;
+        case  7: profiling_PHY_PowerDown(); break;
         default: pc.printf("Not valid input\n"); break;          
     }     
    while (1);