0
tkaiser

Marriage between A20 and H3, UPS mode, sunxi-pio utility

Recommended Posts

Let's start with a weird image first:

 

BPi_M2_Plus_fed_by_Lime2.jpg

 

In the plastic box is an Olimex A20-Lime2, a 2.5" HDD with 2TB and Olimex' largest battery with 6600mAh. Mounted on the top cover (box standing on the side) is a Banana Pi M2+ (to be replaced with NanoPi M1 or OPi One/PC in the future)

 

Why Lime2? Since this board from our friends at Olimex is designed intelligently and provides DC-DC step-up converters on the board providing the ability to power also the connected SATA disk when running from battery (unlike most other A10/A20 boards that do only provide 5V on USB ports in battery mode but not to the disk!). And since A20 is perfectly supported by mainline kernel (I run 4.6.4 on it with btrfs on both SD card and connected SATA disk. Since the Lime2 is used as monitoring/rsyslog host btrfs compression is active and the 2TB HDD might store up to 20TB of raw log/monitoring data)

 

Why BPi M2+? Since board was lying around and I have no other use for it (SinoVoip sent me a review sample a while ago). The idea to combine A20 with a H3 device was simply to add a camera capable and performant device that is ultra cheap (does not apply to BPi M2+ but to NanoPi M1 or OPi One for example). The H3 device will be used to off-load some stuff (eg. OpenVPN encryption), to capture images and do other hardware monitoring (eg. checking temperature in server racks using 1-Wire sensors)

 

Both boards in this mode run up to 8 hours on battery (6h when the 2 TB disk is also always spinning -- but I use a large 64GB Samsung EVO in the Lime2 and wake up the HDD only from time to time to move data over from SD card). And in this special mode the Lime2 is acting as UPS for the H3 board too since BPi M2+ is powered through Micro USB from Lime2's left USB type A receptacle. The same USB connection is also used as a 'private' network utilizing Ethernet gadget driver on the H3 device.

 

BPi M2+ is running our sun8i legacy kernel, g_ether module is active and configuration using a link local address as outlined in this thread. Therefore as soon as BPi M2+ boots and brings up his usb0 interface the board appears as Ethernet USB dongle on the Lime2 and can be used easily with the following settings as directly connected network device (providing ~120 Mbits/sec throughput over the USB cable):

 

 

 


root@lime2:~# grep -v "^#" /etc/network/interfaces
allow-hotplug eth0
no-auto-down eth0
iface eth0 inet dhcp

allow-hotplug usb0
iface usb0 inet static
address 169.254.2.2
netmask 255.255.0.0

auto lo
iface lo inet loopback

root@lime2:~# ifconfig 
eth0      Link encap:Ethernet  HWaddr 02:08:08:00:cc:fc  
          inet addr:192.168.83.190  Bcast:192.168.83.255  Mask:255.255.255.0
          inet6 addr: fe80::8:8ff:fe00:ccfc/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:153625 errors:0 dropped:0 overruns:0 frame:0
          TX packets:467659 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:13752690 (13.7 MB)  TX bytes:686630975 (686.6 MB)
          Interrupt:44 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:9 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:720 (720.0   TX bytes:720 (720.0 

usb0      Link encap:Ethernet  HWaddr 6e:2d:30:c9:5d:91  
          inet addr:169.254.2.2  Bcast:169.254.255.255  Mask:255.255.0.0
          inet6 addr: fe80::6c2d:30ff:fec9:5d91/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:384 (384.0   TX bytes:696 (696.0  

 

 

 

This USB connection can now be used as a directly wired network connection (BPI M2+ is 169.254.2.1 and Lime2 169.254.2.2 and both can interact through this connection or use it as 'heartbeat' connection to monitor network outages). And using BPi M2+ or NanoPi M1 or NEO the very same USB connection can also be used to power the H3 device (not with Oranges there a hardware mod is needed).

 

Now the fun part: In case the USB powered H3 device freezes or is shut down and has to be restarted... how to do so? Some/most A10/A20 boards provide the 5V on their USB ports not directly from DC-IN but through their AXP209 PMU. And if the board is designed that way, power can be switched on/off on request. This is where the sunxi-pio tool gets interesting since with this tool you can query and switch pin state.

 

In the above example BPi M2+ is powered through Lime2's left USB port. VDD_USB of this port can be controlled through PH06 pin. So to cut power from Lime2 to BPi M2+ all I have to do is

sunxi-pio -m PH06'<default><default<default><0>'

And to provide power again, it's the opposite:

sunxi-pio -m PH06'<default><default<default><1>'

(at least on my Lime2 the left USB port is more reliable than the right port that can be controlled through PH03 pin). To be able to use the sunxi-pio tool you need a recent sunxi-tools version. As Armbian user you don't have to care since we ship always the most recent version.

 

Not all A10/A20 boards support this and pin mappings differ between different boards. So where to look? In the fex files (don't trust them blindly, some vendors horribly suck providing documentation for their own hardware, compare the pin mappings in bananapiprolcd7.fex and bananapipro.fex for example).

 

EDIT: Checked with both Banana Pi and Banana Pro: The USB voltage pin mappings in the fex files are plain BS and do not work (obviously 'copy&paste gone wrong' when they copied all of CubieTech's work in the beginning)

 

I let a script check the fex files of all Allwinner boards we currently support. Two H3 devices show the ability to switch USB voltage (OPi 2 and Plus/Plus2 -- the pin here most probably controls power for the internal Terminus USB hub) but all the others are A10/A20 based:

 

 

 


root@armbian:/var/git/Armbian/lib/config/fex# grep -c "^usb_drv_vbus_gpio.*port" *.fex | grep -v ':1$' | while read ; do echo -e "\n$REPLY" | cut -f1 -d.; Fex=$(echo $REPLY | cut -f1 -d:); grep "^usb_drv_vbus_gpio.*port" $Fex | cut -f2 -d: | tail -n2; done

aw-som-a20
PB10<1><0><default><0>
PB11<1><0><default><0>

bananapi
PH06<1><0><default><0>
PH03<1><0><default><0>

bananapilcd7
PH06<1><0><default><0>
PH03<1><0><default><0>

bananapipro
PH00<1><0><default><0>
PH01<1><0><default><0>

bananapiprolcd7
PH06<1><0><default><0>
PH03<1><0><default><0>

cubieboard2dual
PH06<1><0><default><0>
PH03<1><0><default><0>

cubieboard2
PH06<1><0><default><0>
PH03<1><0><default><0>

cubieboard
PH06<1><0><default><0>
PH03<1><0><default><0>

cubietruck
PH06<1><0><default><0>
PH03<1><0><default><0>

lamobo-r1
PH06<1><0><default><0>
PH03<1><0><default><0>

lime2-emmc
PH06<1><0><default><0>
PH03<1><0><default><0>

lime2
PH06<1><0><default><0>
PH03<1><0><default><0>

lime-a10
PH06<1><0><default><0>
PH03<1><0><default><0>

lime
PH06<1><0><default><0>
PH03<1><0><default><0>

micro
PH06<1><0><default><0>
PH03<1><0><default><0>

olinux-som-a13
PG11<1><0><default><0>
PG12<1><0><default><0>

orangepi2
PL02<1><0><default><0>
PG13<1><0><default><0>

orangepi
PH26<1><0><default><0>
PH22<1><0><default><0>

orangepiplus
PL02<1><0><default><0>
PG13<1><0><default><0>

pcduino2
PD02<1><0><default><0>
PH03<1><0><default><0>

pcduino3
PH06<1><0><default><0>
PH03<1><0><default><0>

pcduino3nano
PH11<1><0><default><0>
PH03<1><0><default><0> 

 

 

Edit: But at least on H3 Orange Pi boards it's possible to toggle power available on Micro USB port from userspace.

 

So if you want to switch power on the USB ports of a Banana Pro you would not use PH03/PH06 but PH00/PH01 instead (and yes, sunxi-pio works with exactly these settings/syntax even when the board runs vanilla/mainline kernel). Since we're talking about A20 Bananas now: These devices do not provide power to a connected SATA disk when running on battery unlike Olimex' boards. So in case you want to ensure that a connected SATA disk keeps spinning when DC-IN is not available then you have to DIY a cable solution taking power from the 2 USB ports and feeding SATA power this way (the SATA power connector on Banana boards is directly wired to the Micro USB DC-IN jack so you can both provide DC-IN here more reliably and have to keep in mind that battery/AXP209 is not involved at all)

 

BTW: sunxi-pio can be used for more than just switching power on USB ports. Simply call it without arguments to get the idea / help text. Anyone trying to decrease consumption of his Allwinner board might love this tool since you're able to switch off on-board consumers from user space.

Share this post


Link to post
Share on other sites

Some more knowledge today. A10, A13 (called R8 on the C.H.I.P.) and A20 are defined as tablet SoCs and got a PMIC/PMU (power management IC / unit) companion called AXP209. 

 

AXP209 can deal with 3 different power sources:

  • DC-IN (on the aforementioned Olimex Lime2 available as a barrel plug for 5.5/2.1 mm jacks and some circuitry to filter noisy power input)
  • USB OTG (on the Lime2 in form of a Mini USB connector)
  • Battery (on the Lime2 available as a small JHT header to be connected to a 3.7V LiPo battery)

As already said the power design of the Olimex boards is made in a way that a connected SATA disk will also be powered when running from battery (the various Bananas for example do it differently and a SATA disk there is not powered through AXP209 but directly fed from DC-IN). AXP209 can be queried through I2C and when using Armbian the available data can be read out with both legacy and vanilla kernel (since Zador ported the necessary stuff to mainline kernel).

 

Input voltage can be read out as well as amperage (AXP209 can deal with some ADC -- analog to digital converters). But not every powering method provides identical data. When the Lime2 is powered the preferrable way (DC-IN / barrel connector) then a SATA disk's consumption for example or consumers of the USB ports do not add to the amperage/consumption that can be readout. But if powered through Mini USB then it adds to the consumption and you get a more complete picture.

 

Then it's the best idea to power Lime2 through the Mini USB connector? Nope for a couple of reasons:

  • Olimex 'noise immune' filter circuitry is only available through the DC-IN barrel
  • We might want to use the Mini USB port for data (either in OTG or host mode)
  • Powering through USB has a major drawback: Most USB cable simply suck due to resistance way to high (leading to severe voltage drops under load -- see below)

Therefore the best way is to use DC-IN for normal use cases and switch to USB OTG on AXP209 equipped boards only to test stuff out, eg. how a spinning disk, other peripherals or on-board components adds to the board's consumption.

 

On the following graph Lime2 is powered through USB OTG first and the 2TB SATA disk is spinning. After a couple of minutes I sent the disk to sleep (hdparm -Y /dev/sda) and immediately consumption drops also. A minute later I plugged in the barrel jack into the DC-IN port and immediately AXP209 switches from USB OTG to DC-IN as main power source. But consumption is reported lower since SATA disk (and other components) are not added when powered this way. A few minutes later I woke up the disk but the DC-IN consumption graph remained the same.

 

Then I unplugged DC-IN and AXP209 immediately switched back to USB OTG. At the same time I switched on the BPi M2+ that is powered from one of Lime2's USB type A ports and since the USB cable I used between Lime2's OTG port and the PSU is crap as most USB cables in this situation available voltage dropped below 4.8V and AXP209 decided to compensate by also using the battery partially. Later the disk went to sleep again and I shut the BPi M2+ down so consumption dropped as low as 350mA and available voltage on the OTG recovered back to 5.0V (that's the problem with bad USB cables: voltage drops only under load)

 

Bildschirmfoto%202016-07-17%20um%2010.42

 

This is Lime2 with power through USB OTG port and spinning SATA disk (voltage drops already down to 4.92V)

 

Bildschirmfoto%202016-07-17%20um%2009.52

 

Now the disk is in standby mode (sleep settings defined in /etc/rc.local), consumption drops and voltage is OK again:

 

Bildschirmfoto%202016-07-17%20um%2009.53

 

Now AXP209 chose the available DC-IN source (large PSU using good cable with low resistance). SATA disk is missing on consumption output:

 

Bildschirmfoto%202016-07-17%20um%2009.54

 

I let the SATA disk spin-up again and booted the USB powered BPi M2+, the crappy USB cable leads to voltage drops below 4.8V so AXP209 decides to rely also on battery:

 

Bildschirmfoto%202016-07-17%20um%2010.04

 

Consumption is back at normal level (both SATA disk and BPi M2+ idle) so AXP209 decides to re-charge the battery:

 

Bildschirmfoto%202016-07-17%20um%2010.11

Share this post


Link to post
Share on other sites

Yesterday I showed in the first post above how on some AXP209 equipped boards like Lime2 the 5V provided through the USB host ports can be switched on/off using the sunxi-pio utility. So if we use a battery equipped A10/A20 board we can use this also to power other consumers through the USB ports, can switch them off and on and provide an 'uninterruptable power supply' (UPS) mode.

 

The same way we can also cut power to on-board components that are controlled through AXP209, for example a connected SATA disk. The following graph shows Lime2 powered through USB OTG (to get the 'big picture' regarding consumption -- see the post before for reasons when to choose which powering mode). On the left the 2TB Samsung is in 'active/idle' state (spinning but doing nothing -- ~480 mA consumption), then my power management settings in /etc/rc.local let the disk switch to 'standby' mode after 5 minutes of inactivity (340 mA) and then I switched off power to the disk completely using sunxi-pio (230 mA):

 

Bildschirmfoto%202016-07-17%20um%2013.19

 

How to know which pin has to be toggled? I just looked into the fex file again:

sata_power_en = port:PC03<1><default><default><0>

So by using the following we can physically power off the disk after unmounting the filesystems of course (not available as device later until we power it on with sunxi-pio again or reboot the board):

sunxi-pio -m PC03'<default><default<default><0>' # off
sunxi-pio -m PC03'<default><default<default><1>' # on

Unfortunately from all our AXP209 equipped boards only a few support powering the disk through AXP209:

 

 

root@armbian:/var/git/Armbian/lib/config/fex# grep "sata_power_en.*port" *.fex
aw-som-a20.fex:sata_power_en = port:PB08<1><default><default><0>
cubieboard2dual.fex:sata_power_en       = port:PB08<1><default><default><0>
cubieboard2.fex:sata_power_en       = port:PB08<1><default><default><0>
cubieboard.fex:sata_power_en = port:PB08<1><default><default><0>
cubietruck.fex:sata_power_en       = port:PH12<1><default><default><0>
lamobo-r1.fex:sata_power_en = port:PB03<1><default><default><0>
lime2-emmc.fex:sata_power_en = port:PC03<1><default><default><0>
lime2.fex:sata_power_en = port:PC03<1><default><default><0>
lime-a10.fex:sata_power_en = port:PC03<1><default><default><0>
lime.fex:sata_power_en = port:PC03<1><default><default><0>
micro.fex:sata_power_en = port:PB08<1><default><default><0>
pcduino3.fex:sata_power_en = port:PH02<1><default><default><1>
pcduino3nano.fex:sata_power_en = port:PH02<1><default><default><1> 

 

 

 

But what about other onboard components that might not be used but are by default in 'powered on' state and add to the board's consumption while not needed. Let's search for the magical word '_power' inside the fex files:

 

 

root@armbian:/var/git/Armbian/lib/config/fex# grep "_power.*port" *.fex | grep -v ':;'
aw-som-a20.fex:lcd_power = port:PH08<1><0><default><1>
aw-som-a20.fex:csi_power_en = port:PH17<1><default><default><0>
aw-som-a20.fex:csi_power_en_b = port:PH17<1><default><default><0>
aw-som-a20.fex:csi_power_en = port:PH16<1><default><default><0>
aw-som-a20.fex:sata_power_en = port:PB08<1><default><default><0>
bananapi.fex:gmac_phy_power_en = port:PH23<1><default><default><0>
bananapi.fex:lcd_power = port:PH08<1><0><default><1>
bananapi.fex:csi_power_en = port:PH16<1><default><default><0>
bananapi.fex:csi_power_en = port:PH16<1><default><default><0>
bananapilcd7.fex:gmac_phy_power_en = port:PH23<1><default><default><0>
bananapilcd7.fex:lcd_power = port:PH12<1><0><default><1>
bananapilcd7.fex:csi_power_en = port:PH16<1><default><default><0>
bananapilcd7.fex:csi_power_en = port:PH16<1><default><default><0>
bananapim1plus.fex:gmac_phy_power_en = port:PH23<1><default><default><0>
bananapim1plus.fex:lcd_power = port:PH08<1><0><default><1>
bananapim1plus.fex:csi_power_en = port:PH16<1><default><default><0>
bananapim1plus.fex:csi_power_en = port:PH16<1><default><default><0>
bananapim1pluslcd7.fex:gmac_phy_power_en = port:PH23<1><default><default><0>
bananapim1pluslcd7.fex:lcd_power = port:PH12<1><0><default><1>
bananapim1pluslcd7.fex:csi_power_en = port:PH16<1><default><default><0>
bananapim1pluslcd7.fex:csi_power_en = port:PH16<1><default><default><0>
bananapim2plus.fex:gmac_phy_power_en   = port:PD06<1><default><default><0>
bananapim2plus.fex:vip_dev0_power_en        = port:PD14<1><default><default><default>
bananapipro.fex:gmac_phy_power_en = port:PH23<1><default><default><0>
bananapipro.fex:lcd_power = port:PH08<1><0><default><1>
bananapipro.fex:csi_power_en = port:PH16<1><default><default><0>
bananapipro.fex:csi_power_en = port:PH16<1><default><default><0>
bananapiprolcd7.fex:gmac_phy_power_en = port:PH23<1><default><default><0>
bananapiprolcd7.fex:lcd_power = port:PH12<1><0><default><1>
bananapiprolcd7.fex:csi_power_en = port:PH16<1><default><default><0>
bananapiprolcd7.fex:csi_power_en = port:PH16<1><default><default><0>
beelinkx2.fex:module_power0       = port:PL07<1><default><default><1>
beelinkx2.fex:module_power1       = port:PG13<1><default><default><0>
cubieboard2dual.fex:lcd_power               = port:PH08<1><0><default><1>
cubieboard2dual.fex:csi_power_en        = port:PH17<1><default><default><0>
cubieboard2dual.fex:csi_power_en_b      = port:PH17<1><default><default><0>
cubieboard2dual.fex:csi_power_en        = port:PH16<1><default><default><0>
cubieboard2dual.fex:sata_power_en       = port:PB08<1><default><default><0>
cubieboard2.fex:lcd_power               = port:PH08<1><0><default><1>
cubieboard2.fex:csi_power_en        = port:PH17<1><default><default><0>
cubieboard2.fex:csi_power_en_b      = port:PH17<1><default><default><0>
cubieboard2.fex:csi_power_en        = port:PH16<1><default><default><0>
cubieboard2.fex:sata_power_en       = port:PB08<1><default><default><0>
cubieboard.fex:lcd_power = port:PH08<1><0><default><1>
cubieboard.fex:sata_power_en = port:PB08<1><default><default><0>
cubietruck.fex:lcd_power               = port:PH08<1><0><default><1>
cubietruck.fex:csi_power_en        = port:PH17<1><default><default><0>
cubietruck.fex:csi_power_en_b      = port:PH17<1><default><default><0>
cubietruck.fex:csi_power_en        = port:PH16<1><default><default><0>
cubietruck.fex:sata_power_en       = port:PH12<1><default><default><0>
lamobo-r1.fex:gmac_phy_power_en = port:PH23<1><default><default><0>
lamobo-r1.fex:lcd_power = port:PH08<1><0><default><1>
lamobo-r1.fex:csi_power_en = port:PH16<1><default><default><0>
lamobo-r1.fex:csi_power_en = port:PH16<1><default><default><0>
lamobo-r1.fex:sata_power_en = port:PB03<1><default><default><0>
lime2-emmc.fex:lcd_power = port:PH08<1><0><default><1>
lime2-emmc.fex:csi_power_en = port:PC16<1><default><default><0>
lime2-emmc.fex:csi_power_en = port:PH16<1><default><default><0>
lime2-emmc.fex:sata_power_en = port:PC03<1><default><default><0>
lime2.fex:lcd_power = port:PH08<1><0><default><1>
lime2.fex:csi_power_en = port:PC16<1><default><default><0>
lime2.fex:csi_power_en = port:PH16<1><default><default><0>
lime2.fex:sata_power_en = port:PC03<1><default><default><0>
lime-a10.fex:lcd_power = port:PH08<1><0><default><1>
lime-a10.fex:sata_power_en = port:PC03<1><default><default><0>
lime.fex:lcd_power = port:PH08<1><0><default><1>
lime.fex:csi_power_en = port:PC16<1><default><default><0>
lime.fex:csi_power_en = port:PH16<1><default><default><0>
lime.fex:sata_power_en = port:PC03<1><default><default><0>
micro.fex:lcd_power = port:PH08<1><0><default><1>
micro.fex:sata_power_en = port:PB08<1><default><default><0>
nanopim1.fex:vip_dev0_power_en = port:PA17<1><default><default><1>
nanopineo.fex:vip_dev0_power_en = port:PA17<1><default><default><1>
olinux-som-a13.fex:lcd_power = port:PB10<1><0><default><1>
orangepi2.fex:vip_dev0_power_en        = port:PA17<1><default><default><1>
orangepi.fex:gmac_phy_power_en = port:PH23<1><default><default><0>
orangepi.fex:lcd_power = port:PH08<1><0><default><1>
orangepi.fex:csi_power_en = port:PH16<1><default><default><0>
orangepi.fex:csi_power_en = port:PH16<1><default><default><0>
orangepilite.fex:vip_dev0_power_en = port:PA17<1><default><default><1>
orangepione.fex:vip_dev0_power_en = port:PA17<1><default><default><1>
orangepipc.fex:vip_dev0_power_en = port:PA17<1><default><default><1>
orangepipcplus.fex:vip_dev0_power_en = port:PA17<1><default><default><1>
orangepiplus2e.fex:gmac_phy_power_en   = port:PD06<1><default><default><0>
orangepiplus2e.fex:vip_dev0_power_en = port:PA17<1><default><default><1>
orangepiplus.fex:gmac_phy_power_en   = port:PD06<1><default><default><0>
orangepiplus.fex:vip_dev0_power_en        = port:PA17<1><default><default><1>
pcduino2.fex:lcd_power = port:PH08<0><2><default><default>
pcduino3.fex:lcd_power = port:PH08<1><0><default><1>
pcduino3.fex:lcd_power = port:PH06<1><0><default><1>
pcduino3.fex:csi_power_en = port:PH26<1><default><default><0>
pcduino3.fex:sata_power_en = port:PH02<1><default><default><1>
pcduino3nano.fex:lcd_power = port:PH08<1><0><default><1>
pcduino3nano.fex:lcd_power = port:PH08<1><default><default><1>
pcduino3nano.fex:csi_power_en = port:PH26<1><default><default><0>
pcduino3nano.fex:sata_power_en = port:PH02<1><default><default><1> 

 

 

Would be interesting to play around with LCD and CSI power settings and to have a look whether switching those pins off where defined as on by default makes any difference regarding consumption (or for example the GBit Ethernet PHY on some boards when they do not need network connectivity). But this is stuff I leave for others to test and get back to this thread with results.

 

Since we're talking about disks. These are the two lines I add to /etc/rc.local to spin-down Samsung/Seagate SATA disks on A20 boards after 5 minutes of inactivity:

hdparm -B 254 /dev/sda
hdparm -S 60 /dev/sda

And to manually send SATA disks to sleep 'hdparm -Y /dev/sdX' can be used. Please keep in mind that this is SATA stuff and not every USB-to-SATA bridge contained in USB disk enclosures supports this. Also some disks ignore sleep and power management settings and then scripted approaches like hdd-spindown.sh are needed (as we can see above physically powering off a disk leads to further energy savings but without switching power on the disk won't come back when needed -- unlike sleeping since then the disk's controller simply wakes it up when a new disk access happens)

Share this post


Link to post
Share on other sites
0