mbed Power Control/Consumption
I wrote a library (really a header file of inline functions) to take control of the LPC1768 Power Control and Cortex-M3 Power control functions.
Update 1/26: Per paul's suggestion, I added an option to power down the PHY, which results in significant energy savings. I also realized that the PHY uses extra power with a ethernet cord plugged in, so I've updated the results below with the ethernet cord unplugged, as well as some interesting results with minimal and maximal clock.
Update 1/29: Per Ilya's suggestion, the library turns on/off the onboard oscillator as well, saving about ~9mA in power when the PHY is powered down. I'll update the results when I have some free time.
PowerControl
Consumption
Method
I tested the mbed with a calibrated Agilent E3615A power supply (NB: Last Calibration Date 2002). current readings are off a Protek 6300 DMM (NB: NOT calibrated). The mbed was disconnected from USB during the power reading and the power supply was connected to VIN on the mbed.
Normal mode was taken with the PHY on, essentially, compiling an application using the online compiler with just a while loop, unless otherwise noted, the PHY is on in all tests, with ethernet unplugged.
For information on how to control the clock and it's effect on power consumption, see http://mbed.org/users/no2chem/notebook/mbed-clock-control--benchmarks/
Results
mBed Power Supply consumption @ 5.00V Type | Draw (mA) | Consumption (W) | % Normal |
Normal mode (while(1){} loop) | 138.5 mA | 0.6925 W | 100% |
All Peripherals On (PHY on, ETH in) | 200.6 mA | 1.103 W | 144% |
128 MHz, All Peripherals On (PHY on, ETH in) | 220.6 mA | 1.003 W | 159% |
All Peripherals Off (PHY off) | 101.9 mA | 0.5095 W | 73.5% |
40MHz, All Peripherals Off (PHY off) | 81.6 mA | 0.408 W | 58.9% |
Brown Out Disabled (Normal) | 138.2 mA | 0.691 W | 99.7% |
Sleep | 127.0 mA | 0.635 W | 91.6% |
Deep Sleep | 96.5 mA | 0.4825 W | 69.7% |
Power Down | 96.3 mA | 0.4815 W | 69.5% |
Deep Power Down | 91.3 mA | 0.4564 W | 65.9% |
Deep Power Down (PHY off) | 57.7 mA | 0.2885 W | 41.6% |
mBed device consumption @ 5.00V Type | Draw (mA) | Consumption (W) |
DP83848 PHY, unplugged | 33 mA | 0.0165 W |
DP83848 PHY, plugged, energized | 76.1 mA | 0.0385 W |
Blue Power / Status LED | 2 mA | 0.010 W |
Brown Out Detection (BOD) | .2 mA | 0.001 W |
Data on the blue LED is from Ilya. http://mbed.org/forum/bugs-suggestions/topic/434/?page=1#comment-2222
Power consumption from the PHY is approximated since it wasn't actually possible to read from those values.
Discussion
Significant power savings are achieved using any of the sleep modes. It would be nice if it was possible to somehow turn off the mbed processor, as well as the blue "power" LED, especially if we wanted to stick the mbed in a remote sensing operation. The PHY draws significant amounts of power, even more when energized and plugged into ethernet. Turning off when it is not used results in significant power savings. In remote sensing applications where networking is required, it might be useful to turn the PHY off during a sleep period, and turn it on whenver results need to be read or data transmitted. WOL might be an option in this case, but we'll see a consumption of ~76mA from the PHY to maintain the network state, although PoE in these situations might alleviate those problems.
I attempted to implement the energy detection features of the PHY, but they seemed to have no effect on energy consumption. Looking further into the feature might improve energy consumption when there is no activity. Also, reducing link speed to 10Mbps might also offer significant power savings (I believe green energy switches do this when the link is idle).
Library
Usage
Add the PowerControl.h header to your library. For Ethernet power control, add EthernetPowerControl.h. See the LPC1768 user manual for definitons of each peripheral, though I think I've commented the header heavily enough so you should have an idea of what bit means what (in regard to the peripheral control register).
Functions
System Power
void Sleep(void)
Puts the Cortex-M3 into Sleep Mode.
void DeepSleep(void)
Puts the Cortex-M3 into Deep Sleep mode. Most clocks are stopped, the PLLs are turned off.
void PowerDown(void)
Puts the Cortex-M3 in Power Down mode. All clocks are stopped. Flash Memory is turned off.
void DeepPowerDown(void)
Puts the Cortex-M3 in Deep Power Down mode. Only the RTC, Reset, WIC, and RTC backup registers are powered.
void BrownOut_ReducedPowerMode_Enable(void)
Turns the Brown Out Detection (BOD) Circuit off in DeepSleep and PowerDown modes.
void BrownOut_ReducedPowerMode_Disable(void)
Leaves the Brown Out Detection (BOD) Circuit on in DeepSleep and PowerDown modes.
void BrownOut_Global_Disable(void)
Turns the Brown Out Detection (BOD) Circuit off in all modes.
void BrownOut_Global_Enable(void)
Leaves the Brown Out Detection (BOD) Circuit on in all modes.
void BrownOut_Reset_Disable(void)
Turns the Brown Out Detection (BOD) Reset Circuit off in all modes.
void BrownOut_Reset_Enable(void)
Leaves the Brown Out Detection (BOD) Reset Circuit on in all modes.
Peripheral Power
unsigned int Peripheral_PowerUp(unsigned int bitMask)
Turns the selected peripheral(s) on - see header for possible bitMask values.
unsigned int Peripheral_PowerDown(unsigned int bitMask)
Turns the selected peripheral(s) off - see header for possible bitMask values.
bool Peripheral_GetStatus(unsigned int peripheral)
Returns true if the peripheral is on, false otherwise.
Ethernet Power
void PHY_PowerDown(void);
Powers down the PHY and LPC1768 EMAC. Note that this function automatically turns ON the EMAC and initializes the PHY to power down the PHY via MII.
void PHY_PowerUp(void);
Powers up the PHY and LPC1768 EMAC.
void PHY_EnergyDetect_Enable(void);
Enables the energy detection feature on the PHY.
NB: Side effect - also turns on the PHY is it is off.
void PHY_EnergyDetect_Disable(void);
Disables the energy detection feature on the PHY.
NB: Side effect - also turns on the PHY is it is off.
Excellent page! I'll have to add page ratings soon so I can give pages like this 5 stars!
#
23 Jan 2010 . Edited: 24 Jan 2010
Great info, Michael!
Code comment: There are a number of "!" used with bit field constants in PowerControl.h (lines 58, 62, 72, 84, 96, 108, 180). I think it is an error - "!" will do logical negation, resulting in 0 (in most cases) or 1 only. "~" should be used (binary negation) from what I see the code intentions are. I wonder if you get different (better?) power numbers when you fix the code?
for example:
//Powers Down specified Peripheral(s)
inline unsigned int Peripheral_PowerDown(unsigned int bitMask)
{
return LPC_SC->PCONP &= !bitMask;
}
should be (also I don't think a set function should return a value):
//Powers Down specified Peripheral(s)
inline void Peripheral_PowerDown(unsigned int bitMask)
{
LPC_SC->PCONP &= ~bitMask;
}
Also, I think there is a typo at line 125 (same constant as on line 130)
// bit 4: PCUART1: UART 1 power/clock enable
#define LPC1768_PCONP_PCI2C0 0x10
should it be LPC1768_PCONP_PCUART1?
--
llya
Wow! This is really good work! I can definetly see this being useful in a remote telemetry or sensing application just like you said.
Good job!
Great info, Michael!
Code comment: There are a number of "!" used with bit field constants in PowerControl.h (lines 58, 62, 72, 84, 96, 108, 180). I think it is an error - "!" will do logical negation, resulting in 0 (in most cases) or 1 only. "~" should be used (binary negation) from what I see the code intentions are. I wonder if you get different (better?) power numbers when you fix the code?
for example:
//Powers Down specified Peripheral(s)
inline unsigned int Peripheral_PowerDown(unsigned int bitMask)
{
return LPC_SC->PCONP &= !bitMask;
}
should be (also I don't think a set function should return a value):
//Powers Down specified Peripheral(s)
inline void Peripheral_PowerDown(unsigned int bitMask)
{
LPC_SC->PCONP &= ~bitMask;
}
Also, I think there is a typo at line 125 (same constant as on line 130)
// bit 4: PCUART1: UART 1 power/clock enable
#define LPC1768_PCONP_PCI2C0 0x10
should it be LPC1768_PCONP_PCUART1?
--
llya
Thanks! Sometimes I get sloppy with my code and mix the boolean operators with the bitwise ones... mainly just the negation operator.
The reason I return a value is in case you wanted to check the result... Since it's in a inline function, it's going to end up on a register anyways, so might as well expose it... No changes to the power consumption data though, since the negations are mainly used to re-enable things.
Hi Michael,
Excellent work!
You might be able to reduce the power consumption by putting the Ethernet Phy into power down mode. According to the DP83848 datasheet:
5.5 POWER DOWN
The device can be put in a Power Down mode by setting bit 11 (Power Down) in the Basic Mode Control Register, BMCR (0x00h).
The Phy draws about 80 - 90mA when operational, so it would be worth doing. Before you ask, I don't know how you write to the Phy registers.
There is also the power taken by the Magic chip. I wouldn't be surprised if that is always running at full speed. Perhaps it could be put into Sleep mode if the host USB connection was not present and there were no files open in the local file system.
Paul
Hi Michael,
Excellent work!
You might be able to reduce the power consumption by putting the Ethernet Phy into power down mode. According to the DP83848 datasheet:
5.5 POWER DOWN
The device can be put in a Power Down mode by setting bit 11 (Power Down) in the Basic Mode Control Register, BMCR (0x00h).
The Phy draws about 80 - 90mA when operational, so it would be worth doing. Before you ask, I don't know how you write to the Phy registers.
There is also the power taken by the Magic chip. I wouldn't be surprised if that is always running at full speed. Perhaps it could be put into Sleep mode if the host USB connection was not present and there were no files open in the local file system.
Paul
Thanks Paul, I've figured it out and added it to the library.
Hi Michael,
Here's one more potential current improvement: P1.27/ETH_OSC_EN which turns on OSC2 chip (ASE-50-D-C-T). If it is not already off, it makes sense to turn this chip off when (after) the PHY is off.
It is Abracon part (http://www.abracon.com/Oscillators/ASEseries.pdf), it takes 6.5 to 19 mA for a 50MHz oscillator.
I think the pin should be easily accessible with DigitalOut class. You may be in a better position to measure the current delta.
#
28 Jan 2010 . Edited: 28 Jan 2010
Hi Michael,
Here's one more potential current improvement: P1.27/ETH_OSC_EN which turns on OSC2 chip (ASE-50-D-C-T). If it is not already off, it makes sense to turn this chip off when (after) the PHY is off.
It is Abracon part (http://www.abracon.com/Oscillators/ASEseries.pdf), it takes 6.5 to 19 mA for a 50MHz oscillator.
I think the pin should be easily accessible with DigitalOut class. You may be in a better position to measure the current delta.
Thanks Ilya,
Turns out that pin was the one, and it made for about a 9.1mA improvement...
From ~109mA (normal mode, PHY OFF) to 99.6 mA.
Turning the oscillator off before turning the PHY off causes erratic behavior though. I'll have to check if I can still talk to the PHY over MII after turning off/on the oscillator...
I'll add it to the library in a bit.
EDIT: seems okay... PHY powered right back up... had to wait for osc to get stable though. Maybe have a deeppowerdown function as well....
Turning the oscillator off before turning the PHY off causes erratic behavior though. I'll have to check if I can still talk to the PHY over MII after turning off/on the oscillator...
Sorry Michael, I was not very transparent. You should turn clock off after you turn of the PHY and turn it back on before turning the PHY back on. Also make some delay to let the oscillator start... I 'll have to read the datasheet to suggest appropriate delay time, but 100ms usually works.
Turning the oscillator off before turning the PHY off causes erratic behavior though. I'll have to check if I can still talk to the PHY over MII after turning off/on the oscillator...
Sorry Michael, I was not very transparent. You should turn clock off after you turn of the PHY and turn it back on before turning the PHY back on. Also make some delay to let the oscillator start... I 'll have to read the datasheet to suggest appropriate delay time, but 100ms usually works.
Yes, I think i used something like 200ms, I guess we can play around with it to see what works. I'll post later today, been busy with stuff, but clearing bit 27 from port1 works fine (i don't think you can use digitalout to turn this port on/off, so you'll need to use cmsis register access)
I've been reading LPC1768 errata, and it mentions another issue that might influence power consumption.
Problem
If the main PLL (PLL0) is enabled and connected before entering Deep Sleep or Power-down modes, it will remain enabled and connected after the chip enters Deep Sleep mode or Power-down mode causing the power consumption to be higher.
Workaround
In the software, user must disable and disconnect the main PLL (PLL0) before entering Deep Sleep and Power-down modes to reduce the power consumption. This must be done only if the main PLL (PLL0) was enabled and connected before entering Deep Sleep mode or Power-down mode.
The code below demonstrates the steps to disable and disconnect the main PLL0:
PLL0CON &= ~(1<<1); /* Disconnect the main PLL (PLL0) */
PLL0FEED = 0xAA; /* Feed */
PLL0FEED = 0x55; /* Feed */
while ((PLL0STAT & (1<<25)) != 0x00); /* Wait for main PLL (PLL0) to disconnect */
PLL0CON &= ~(1<<0); /* Turn off the main PLL (PLL0) */
PLL0FEED = 0xAA; /* Feed */
PLL0FEED = 0x55; /* Feed */
while ((PLL0STAT & (1<<24)) != 0x00); /* Wait for main PLL (PLL0) to shut down */
/************** Then enter into Deep sleep mode or Power-down mode **************************/
I've been reading LPC1768 errata, and it mentions another issue that might influence power consumption.
Problem
If the main PLL (PLL0) is enabled and connected before entering Deep Sleep or Power-down modes, it will remain enabled and connected after the chip enters Deep Sleep mode or Power-down mode causing the power consumption to be higher.
Workaround
In the software, user must disable and disconnect the main PLL (PLL0) before entering Deep Sleep and Power-down modes to reduce the power consumption. This must be done only if the main PLL (PLL0) was enabled and connected before entering Deep Sleep mode or Power-down mode.
The code below demonstrates the steps to disable and disconnect the main PLL0:
PLL0CON &= ~(1<<1); /* Disconnect the main PLL (PLL0) */
PLL0FEED = 0xAA; /* Feed */
PLL0FEED = 0x55; /* Feed */
while ((PLL0STAT & (1<<25)) != 0x00); /* Wait for main PLL (PLL0) to disconnect */
PLL0CON &= ~(1<<0); /* Turn off the main PLL (PLL0) */
PLL0FEED = 0xAA; /* Feed */
PLL0FEED = 0x55; /* Feed */
while ((PLL0STAT & (1<<24)) != 0x00); /* Wait for main PLL (PLL0) to shut down */
/************** Then enter into Deep sleep mode or Power-down mode **************************/
Interesting, I'll have to try this later... maybe this is why the power consumption difference between deep sleep and power-off are similar?
but then again, only ~5mA difference between power down and deep power-down...
Michael,
Here's the function I ""wrote"" based on that:
inline void NXP_LPC1768_ERRATA_PLL0_1(void) {
LPC_SC->PLL0CON &= ~(1<<1); /* Disconnect the main PLL (PLL0) */
LPC_SC->PLL0FEED = 0xAA; /* Feed */
LPC_SC->PLL0FEED = 0x55; /* Feed */
while ((LPC_SC->PLL0STAT & (1<<25)) != 0x00); /* Wait for main PLL (PLL0) to disconnect */
LPC_SC->PLL0CON &= ~(1<<0); /* Turn off the main PLL (PLL0) */
LPC_SC->PLL0FEED = 0xAA; /* Feed */
LPC_SC->PLL0FEED = 0x55; /* Feed */
while ((LPC_SC->PLL0STAT & (1<<24)) != 0x00); /* Wait for main PLL (PLL0) to shut down */
/************** Then enter into Deep sleep mode or Power-down mode **************************/
} // NXP_LPC1768_ERRATA_PLL01()
I inserted calls to it before __WFI() in DeepSleep(), PowerDown() and DeepPowerDown() in PowerControl.h (seems there is no need in Sleep()). Can't confirm it does any good or bad since I did not measure the current, but my sense it may save a couple of milliamps. PLLs need to be turned back on though if shut down, and here I did not spend any thought yet.
#
02 Feb 2010 . Edited: 02 Feb 2010
Michael,
Here's the function I ""wrote"" based on that:
inline void NXP_LPC1768_ERRATA_PLL0_1(void) {
LPC_SC->PLL0CON &= ~(1<<1); /* Disconnect the main PLL (PLL0) */
LPC_SC->PLL0FEED = 0xAA; /* Feed */
LPC_SC->PLL0FEED = 0x55; /* Feed */
while ((LPC_SC->PLL0STAT & (1<<25)) != 0x00); /* Wait for main PLL (PLL0) to disconnect */
LPC_SC->PLL0CON &= ~(1<<0); /* Turn off the main PLL (PLL0) */
LPC_SC->PLL0FEED = 0xAA; /* Feed */
LPC_SC->PLL0FEED = 0x55; /* Feed */
while ((LPC_SC->PLL0STAT & (1<<24)) != 0x00); /* Wait for main PLL (PLL0) to shut down */
/************** Then enter into Deep sleep mode or Power-down mode **************************/
} // NXP_LPC1768_ERRATA_PLL01()
I inserted calls to it before __WFI() in DeepSleep(), PowerDown() and DeepPowerDown() in PowerControl.h (seems there is no need in Sleep()). Can't confirm it does any good or bad since I did not measure the current, but my sense it may save a couple of milliamps. PLLs need to be turned back on though if shut down, and here I did not spend any thought yet.
cool, though we still have a problem waking up from powerdown anyway from SWD (the mbed team seems to be relatively silent on this still??).... measurements to come later...
we still have a problem waking up from powerdown anyway from SWD (the mbed team seems to be relatively silent on this still??)
I'm contemplating hacking one of my MBED boards some day to be able to disconnect JTAG from the magic mbed chip. Perhaps disconnecting just one pin (JTAG TMS) and power cycle will break the link and allow waking up the LPC1768. Before doing it I still want to hear some thoughts from MBED fathers. Simon, Chris?
Type | Draw (mA) | Consumption (W) |
DP83848 PHY, unplugged | 33 mA | 0.0165 W |
DP83848 PHY, plugged, energized | 76.1 mA | 0.0385 W |
Blue Power / Status LED | 2 mA | 0.010 W |
Brown Out Detection (BOD) | .2 mA | 0.001 W |
Hello Michael,
can you confirm (1) what the operating frequency was that you got the above readings and (2) was the mbed still executing the while{(1);}
Hi,
From this analysis, it seems that with pretty much everything off, ther mbed board still consumes 57mA. Reducing this by another 9mA by turning off the oscillator takes us to a 48mA current consumption. Is the magic chip consuming most of this ? Is there a way to put it in a low power mode when the USB is disconnected ? (as mentioned above)
Thanks,
Zainul.
Hi,
how can I wake up from deep-sleep or any other power-saving by the rtc-alarm?
br
Thomas
#
02 Dec 2010 . Edited: 02 Dec 2010
I noticed that http://mbed.org/users/simon/notebook/interface-powerdown/ has new firmware to power down the magic USB interface chip. Has anyone tried it with these power functions yet?
On my crude test setup, it seems to save another 30-40MA without going into Sleep modes when you call the new firmware magic chip powerdown function. It went from .15A to .11A on my $5 DMM running an LED blink program, but it was bouncing around a bit in the last digit.
#
03 Dec 2010 . Edited: 03 Dec 2010
I noticed that http://mbed.org/users/simon/notebook/interface-powerdown/ has new firmware to power down the magic USB interface chip. Has anyone tried it with these power functions yet?
On my crude test setup, it seems to save another 30-40MA without going into Sleep modes when you call the new firmware magic chip powerdown function. It went from .15A to .11A on my $5 DMM running an LED blink program, but it was bouncing around a bit in the last digit.
Thanks for pointing this out. I did some measurements today with interface powerdown and here's what I found:
Normal mode = 690mW
Ethernet OFF = 516mW (-175mW)
MBED USB OFF = 366mW (-150mW)
LPC Sleep = 294mW (-72mW)
LPC Deep Power Down = 134mW (-160mW)
Measurements were taken with synchronized dual Agilent 34401A multimeters.
Zainul.
Zoomed in version of the above.
#
30 Dec 2010 . Edited: 30 Dec 2010
we still have a problem waking up from powerdown anyway from SWD (the mbed team seems to be relatively silent on this still??)
I'm contemplating hacking one of my MBED boards some day to be able to disconnect JTAG from the magic mbed chip. Perhaps disconnecting just one pin (JTAG TMS) and power cycle will break the link and allow waking up the LPC1768. Before doing it I still want to hear some thoughts from MBED fathers. Simon, Chris?
I can't wake up from DeepSleep() neither PowerDown() through InterruptIn.
Is there any way to make it happen?
Hi Michael:
Thank for the wonderful page. CHAPTER 2: PIC® Microcontroller Low Power Tips ‘n Tricks contains useful method to save energy. From the chapter:
a) Unused Port Pins
If a port pin is unused, it may be left unconnected but configured as an output pin driving to either state (high or low), or it may be configured as an input with an external resistor (about 10 kΩ) pulling it to Vdd or Vss. If configured as an input, only the pin input leakage current will be drawn through the pin (the same current would flow if the pin was connected directly to Vdd or Vss). Both options allow the pin to be used later for either input or output without significant hardware modifications.
b) Digital Inputs
A digital input pin consumes the least amount of power when the input voltage is near Vdd or Vss. If the input voltage is near the midpoint between Vdd and Vss, the transistors inside the digital input buffer are biased in a linear region and they will consume a significant amount of current. If such a pin can be configured as an analog input, the digital buffer is turned off, reducing both the pin current as well as the total controller current.
c) Analog Inputs
Analog inputs have a very high-impedance so they consume very little current. They will consume less current than a digital input if the applied voltage would normally be centered between Vdd and Vss. Sometimes it is appropriate and possible to configure digital inputs as analog inputs when the digital input must go to a low power state.
Any one with the right setup to try? Thank
Hi Michael,
I had trouble trying to power the Ethernet down, up, down, up, etc. I would like to do this as part of a data collection station (Ethernet up while transferring data, down while taking data).
What would happen is that the MBED would stall upon the second EMAC_Init call, I believe at the line:
LPC_EMAC->MAC1 = MAC1_PASS_ALL;
This seems to be fixed by changing the PHY_PowerUp routine to start the clock before it might call EMAC_Init:
void PHY_PowerUp()
{
LPC_GPIO1->FIODIR |= 0x8000000;
LPC_GPIO1->FIOSET = 0x8000000;
//wait for osc to be stable
wait_ms(200);
if (!Peripheral_GetStatus(LPC1768_PCONP_PCENET))
EMAC_Init(); //init EMAC if it is not already init'd
I guess this is because the LPC_EMAC register will wait forever to receive a clock signal if EMAC_Init gets called after a power down?
I'm a bit surprised no one has seen this before.
Hi all,
These pages are fantastic, congratulations
I just wanted to know if anyone has succeeded when trying to wake the device up from DeepSleep mode. Diving into the LPC1768 user manual I found that debug modes may prevent power control modes to operate in a normal way.
Thank you all in advance,
Mario
#
31 Jul 2015 . Edited: 02 Aug 2015
I thought I'd confirm power measurements on mbed LPC1768 (96MHz). Measurements were OK for Sleep(), peripherals ON, peripherals OFF, PHY off, and DeepSleep(). I pasted in the semihost_powerdown(), but it seemed to have NO effect (5v power into Vin, USB not connected)??
PowerDown() and DeepPowerDown() measured the same as DeepSleep()
140.0 ma while(1); default settings (hacked USB cable for DMM current measurements)
127.9 ma Sleep()
91.6 ma PHY off
86.7 ma all peripherals OFF ( 109.5ma all ON)
59.6 ma DeepSleep()
Any thoughts on how to get semihost_powerdown() to work?
EDIT: the above results were with firmware 16457. Upgrading firmware to 141212 got semihost_powerdown working. Though overall power consumption rose with 141212 firmware. Sleep() with peripherals off and PHY off was 112.4 ma, then adding semihost_powerdown() dropped to 51.8ma, then 19.6ma with DeepSleep()
#
13 Sep 2016 . Edited: 13 Sep 2016
Dear Tom,
I got the same (more or less the same) results with you after I ungraded the firmware to 141212.
It looks like the power that saved by adopting the PHY off reduces a lot.
Any ideas? Thanks in advance.
You need to log in to post a comment
Excellent page! I'll have to add page ratings soon so I can give pages like this 5 stars!