I like this board more and more :-)
Ok I needed to read the voltage of a large external power source (6S lipo or similar) up to about 30V. I was looking at the various ADC options and here's a nice easy one:
AX209 info http://linux-sunxi.org/AXP209
Ok so... I'll explain this in some detail if you're new to this and interested...
The AXP209 has pins GPIO0 and 1 that can be ADC inputs into a perfectly nice 12-bit ADC, which you can then read over i2c.
On the BPi, GPIO0 is unconnected (and a bit hard to solder to, though possible) but easier than that;
a) GPIO1 is used to measure VBUS on the USB OTG connector (see schematic, search for VBUS_WK), goes from the OTG connector VBUS line to AXP209 GPIO1 via a voltage divider (R22 100k on top, R26 200k on the bottom)
b) Bless the silkscreen gods, they're easy to locate on the board (yay!) - On the back of the BPi board, right next to the USB OTG connector, you see R26 and R22 right next to each other. Handy!
c) The divider on the board is 100k/200k. If you do the simple math; it's 200k / (100k+200k) = 0.6666, so if the OTG vbus is 5V, should get, 3.3v into GPIO1. This is actually higher than the ADC can read (and if you plug in an OTG cable to a host you see the ADC reads 0xfff = max value) but that's not important for the original use; they just want to know if a voltage is there or not.
c) I want to measure up to 30V, and the GPIO1 ADC range has two options (see register 0x85) I'll use " 0.7-2.7475v" range. If I leave R26 on the board and feed in my external voltage via a 2M resistor, the divider will be 200k/(2000k+200k) = 0.0909 , so 30V will be 2.727v.. perfect!
d) In theory, because it's a 12-bit ADC and I've selected 0.7-2.7475v range, that's 12 bits over 2.0475v so /(1<<12) = 0.0049987 (call it 0.005v or 5mv per count). In practice it won't be that good of course, but that's the idea.
e) Call me paranoid, but if I'm brining 30V anywhere near my BPi, I'd like to be pretty sure things don't get toasted in case of accident. Hence I'm going to put a 3v zener diode to ground (so; 30V comes in, via 2M resistor, then to the anode of a 3v zener (cathode to ground), and then on to R26. This is optional of course.
f) Then the software side; I'm just going to use "i2cget" and "i2cset" from "i2c-tools" package, like so...
#One time setup... set gpio1 to adc in mode
i2cset -f -y 0 0x34 0x92 4
#enable ADC on on gpio1
i2cset -f -y 0 0x34 0x83 0x84
#set range 0.7-2.7475v
i2cset -f -y 0 0x34 0x85 2
#..then to read.. read hi byte on 0x66, low 0x67 (low 4 bits)
i2cget -f -y 0 0x34 0x66
i2cget -f -y 0 0x34 0x67
Stick those two values back together into a 12-bit value, divide by 0.0909 and then add 0.7 and that should be your voltage.
FYI you can read stuff like the current draw of the whole board by reading "ACIN Current" registers (0x58/0x59) and voltage (0x56/0x57) and so on.
I've not done the hw mod yet - I thought I'd come type this up to share while I have a cup of coffee - but I verified this works on an unmodified board by doing the register setup as above and plugging in power to the OTG port; as expected I get 0 , 0 unplugged and 0xff, 0xf when plugged in (i.e. the divider is turning 5v into 3.3v which is above the 2.7v range so reads as 0xfff).