# Measuring Power Consumption

Hi,

Does anyone have any linux code which can use the ADC's on the TWL4030 to measure the power consumption of the beagleboard?

Thanks,
Etienne Le Sueur

I've been looking at the exact same thing - I've not quite got the
solution working yet - but I'm pretty close... Here's my summary...
If anyone can spot any mistakes in the calculations, or knows why all

First lets look at the electronics. In the Rev. C boards there is a
resistor (R6) which can be used to measure the BeagleBoard's current.
R6 is 0.1 ohms which means the current going through it is 10 times
the voltage drop across it. Either side of R6 is connected (using a
resistor bridge is a 10K/12K bridge which means approx. 46% of the
real voltage is seen by the TWL4030. The TWL4030's ADC is 10-bit
which means 1024 distinct values from 0V to 2.5V. The TWL4030 is
connected via an I2C bus to the OMAP CPU and the Multichannel ADC
(MADC) component of the TWL4030 uses I2C device 0x4a.

Okay, next step some mathematics. If "x" is the difference in the
values measured by the ADC, then the voltage difference at the ADC
input is: x*2.5/1024. Taking into account the resistor bridge, the
real voltage across R6 is x*2.5/1024*(10+12)/10, which when simplified
becomes x*11/2048. So, the current usage is x*110/2048 which
simplifies down to x*55/1024. Okay, we've got the formula we need to
use on the ADC input values as seen by the software.

Now a little note on accuracy. I haven't looked up the accuracy of
the resistors or the ADC's accuracy but these too will have an
impact. A change in value of x by just 1 equates to a current change
of around 54mA. So the accuracy of the current drawn is going to be
approximate...! If the TWL's MADC is anything like others I've used
then they tend to fluctuate/jitter quite a lot - so a nice idea to
measure the board's current usage might end up being effectively
useless...

comprehensive support for the TWL4030 in the linux kernel. There is
even a module (twl4030-madc.ko) that provides an interface for the
MADC functionality. However, I've not been having much luck it. I
added some printk() debug statements to drivers/i2c/chips/twl4030-
the driver's probe function twl4030_madc_driver() is not being
called...?! That said, the module has a lot of code in it that shows
how to use the twl4030-core module's function to perform the I2C
communication and talk to the MADC. Being somewhat impatient, I just
knocked up my own kernel module...

Now, my module fails to get any useful values from any of the ADCIN
pins... everything works, but all the ADCIN come back as zero. Since
R6 is pretty much at supply voltage I would have expected values at or

You don't have to code I2C communications in the kernel (although for
complex devices its probably a good idea) - so I installed i2c-tools
and started poking the TWL4030 from userland. Again, I can't seem to
get anything useful back from the MADC other than zeros. I've got the
TWL4030 datasheet/manual, so I'm going to take a read of that later
on... I will post back here if, no WHEN, I get it working

I've got a lot further now and I'm getting proper readings from the
bit of the CARKIT_ANA_CTRL register so the ADCIN3 through 6 pins
weren't connected anywhere useful. From the U-Boot command you can
issue the following commands and from a booted linux if you have "i2c-
tools" installed there are equivalent i2cget and i2cset commands:

imw 0x4a 0x00 0x01 1
imw 0x48 0xbb 0x08 1

imw 0x4a 0x06 0x28 1
imw 0x4a 0x07 0x00 1
imw 0x4a 0x08 0x28 1
imw 0x4a 0x09 0x00 1

# start read and get results
imw 0x4a 0x12 0x20 1
imd 0x4a 0x3d 2
imd 0x4a 0x41 2

To convert the output to the ADC value divide the first number by 64
and add on the second number multiplied by 4. So, if the imd command
produced "0047: c0 b2" as the output then the ADC value would be
192/64 + 178*4 = 715.

As I originally feared, the accuracy is pretty poor and compared to a
volt-meter across J2 it is around +/- 75mA.

Now here's a surprise...! ADCIN5 is connected to the output of the
TPS2141 chip (which manages the power from the USB-OTG port and the DC
plug). The voltage out from the TPS2141 chip drops off as the current
drawn increases and this can be measured by ADCIN5 alone. However,
the real surprise is that this method proved to be more accurate than
around +/- 25mA.

Finally, for my project I actually need to know the current drawn by
the USB devices attached to the non-OTG port. ADCIN8 on the TWL4030's
MADC provides a measurement of VBUS which again drops out as the
current drawn increases and so can be used to measure the load.
(Note: ADCIN8 is an internal connection within the TWL4030 and there
is no need to set the pinmux before reading ADCIN8. Also, the
measured range for ADCIN8 is 0-7volts)

are consistent although I haven't yet tried a different power supply
(or indeed a number of them yet). Anyone out there want to try these
tests to see if they get similar results...? If so, let me know.

The accuracy is not that great because of three reasons.

1. The C2 uses 5% resistors. On rev C3 we changed to 1% resistors.
2. The current is constantly changing which causes the voltage across the resistors to change making for a delta from when you read the first ADC and then the second. The current is calculated on the delta of those two voltages. In affect the current you are measuring is affected by the code you are running.
3. The voltage delta is very small. If we made the resistor larger, it would in affect be easier to read the voltage drop across the resistor, but the voltage drop would be greater causing a lower voltage to be presented to the system.

Gerald
.

After reading the post by horse_dung it got me thinking of a way to
increase the precision of the current reading. I looked at different
high-side current measure ICs and then I ordered some INA138 from TI.

Required HW mods:
-Remove R70
-Change R71 from 10k to 62k
-Connect INA138 V+ to MAIN_DC
-Mount INA138 across J2 on the bottom side of the PCB
-Connect a wire on the bottom side, from INA138 OUT to R71

This will give a precision of 2mA per LSB on ADCIN3, which should be
acceptable in most cases.

While waiting for the INA138 to arrive I been have looking at i2c-
tools. But I am prohibited from communicating with I2C-bus 1. Does
anybody have experience with i2c-tools and I2C-bus 1?

Comments and thoughts are very welcome!

Quist

When I try to turn on the MADC this is what i get:
root@beagleboard:~# i2cset 1 0x4a 0x00 0x01
Error: Could not set address to 0x4a: Device or resource busy

Is the kernel limitting me from writing to the register in the
TWL5030?

Quist

Now I have mounted the INA138, and a 61k9 resistor instead of the 62k.

OMAP3 beagleboard.org # imd 0x4a 0x3d 2
003d: 80 30 .0

The value 0x3080 needs to be shifted left 6 bits and converted to
decimal which gives 194. With 2mA/LSB this gives 388mA where my
voltmeter measures 38.3mV -> 383mA. So the ADC reads a current a
little over 1% too high, which is fine!

Below is a link to a pic of the modification
http://img201.yfrog.com/i/beagle.jpg/

Now I just need to find a way to read the ADC with a shell script. If
you have experience with that please post!

Quist

Hi,
I am also trying to measure beagleboard current for my project. I
have a REV C2 beagleboard. I have not modified my board. I have
entered following commands at U-Boot prompt:

Hit any key to stop autoboot:
0
OMAP3 beagleboard.org # imw 0x4a 0x00 0x01
1
OMAP3 beagleboard.org # imw 0x48 0xbb 0x08
1
OMAP3 beagleboard.org # imw 0x4a 0x06 0x28
1
OMAP3 beagleboard.org # imw 0x4a 0x07 0x00
1
OMAP3 beagleboard.org # imw 0x4a 0x08 0x28
1
OMAP3 beagleboard.org # imw 0x4a 0x09 0x00
1
OMAP3 beagleboard.org # imw 0x4a 0x12 0x20
1
OMAP3 beagleboard.org # imd 0x4a 0x3d
2
003d: 00
f4 ..
OMAP3 beagleboard.org # imd 0x4a 0x41
2
0041: c0 f5 ..

Could you please tell me how to calculate current values? I have got
two data values : 0x00f4 and 0xc0f5 .

Tapas

Your best bet it to read up on the TPS65950 manual. There is a conversion that needs to to take place it is described in Section 9.4.7

http://focus.ti.com/lit/ug/swcu050d/swcu050d.pdf

Gerald

Hi

If you take my example from above:
OMAP3 beagleboard.org # imd 0x4a 0x3d 2
003d: 80 30 .0

The ADC has a 10 Bit resolution and 0x80 is the two least sinificant
bits shifted 6 bit left, 0x30 is the most significant bits. If you
then combine the two byte to 0x3080 and then shift it 6 bit to the
right(or devide by 64 dec or 40 hex) you have the value.

Quist

I don't want to rewire my REV C board as u did. As I said in my
earlier post , I have got two data values : 0x00f4 and 0xc0f5. I
interpreted this two value using your method and divided by 40h. Then
I got 0xf400/0x40=0x3D0 = 976 in dec and 0xf5c0/0x40=0x3D7 =983 in
dec.
Could you please tell me what is board current? I am not worried about
accuracy of my result. I just want to calculate board current using
software method.

Thanks
Tapas

Hi Quist,
I don't want to rewire my REV C board as u did. As I said in my
earlier post , I have got two data values : 0x00f4 and 0xc0f5. I
interpreted this two value using your method and divided by 40h. Then
I got 0xf400/0x40=0x3D0 = 976 in dec and 0xf5c0/0x40=0x3D7 =983 in
dec.
Could you please tell me what is board current? I am not worried about
accuracy of my result. I just want to calculate board current using
software method.

Thanks
Tapas

Hi Tapas

voltages are:
976/1024*2.5V=2.383V
983/1024*2.5V=2.400V

The input voltage is devided by the voltage devider connected to the
voltages at each side of R6:
2.383V*(10k+22k)/10k=5.242V
2.400V*(10k+22k)/10k=5.280V

So your current through R6 (0R1 resistor) is:
(5.280V-5.242V)/0.1R=0.38A=380mA

Don't expect a good resolution on the current measurement, since you
have 54mA per LSB on the ADC.

I guess you should try to lower you input voltage, since it is not
recommended to go above 5.2V, take a look here:
http://beagleboard.org/static/BBSRM_latest.pdf

/Quist

I don't want to rewire my REV C board as u did. As I said in my
earlier post , I have got two data values : 0x00f4 and 0xc0f5. I
interpreted this two value using your method and divided by 40h.
Then
I got 0xf400/0x40=0x3D0 = 976 in dec and 0xf5c0/0x40=0x3D7 =983
in
dec.
Could you please tell me what is board current? I am not worried
accuracy of my result. I just want to calculate board current
using
software method.

Thanks
Tapas

Hi all.,

If I wish to measure the power consumption without SW
intervention., is there any tap point on the BeagleBoard to measure
VDD1?

I am assuming if i measure VDD1 and also the current (using R6) .,
i can say power consumed is the product of these two. Am i missing
something here?

-hari

If I remember correctly VDD1 is only the core voltage, and I guess you
want to measure the power consumption of the entire board. Correct?

If you measure the voltage across R6 you will get 1mV/10mA, and this
is the current consumption of the entire board.

Quist

No, there are no taps on Beagle to measure VDD1. The only measuremnt point is the total board power.

Gerald

The only measuremnt point is the total board power.

I guess you are talking about R6 here? As per the responses above.,
this will give me the current consumed by the board. Should I just
multiply with 5V to get the power consumed by the entire board (even
though the software might be changing vdd1 periodically)?

I am planning to have a system with the power-management branch and
would want to measure the power consumed under different conditions
(including vdd1 changes). Is there any better way to go about it?
The total power consumed by the board would be an ideal measurement
variable. Power consumption of individual components (chiefly that of
the core) might also suffice if the former is not possible.

-hari

This is tough to do beacuse it is so dymanic and hard to collect the short bursts of low current. The best way is to define states and put the board in these states and then measure the total power for each state.

Gerald

That looks clean. I guess the power states offered by the kernel would
be a good place to start looking at....

However, even with each state (which would probably decide what is the
state of each HW unit), wouldn't the power consumption vary depending
on how much usage each unit is being subject to? Or does it stay
fixed?

and assuming the current consumption at each state stays fixed., how
would I measure the power for each state?

-hari

Current will always be fluctuating. That is the main point. You can’t pin it down because it depends on what is running. In essence what you will get if you were to capture the current in real time is a waveform that looks like noise on a power supplying. It will be constantly changing. So, you would need to average it. In reality you are not talking about current here, but overall power consumption that would be an average based over time and during a particular state. The state would dictate what types of things are available and which ones are turned off not to be used.

Gerald