Extremely Slow Battery Charging

Currently using the CM4 version of DevTerm and it looks like by default the battery charge current is set at 300mA, this can be confirmed using these commands:

cat /sys/class/power_supply/axp20x-battery/constant_charge_current_max
cat /sys/class/power_supply/axp20x-battery/constant_charge_current

I used a USB power meter and changed the values in these files to “1800000” which should correspond to 1800 mA and noticed that the DevTerm started drawing a lot more power immediately (About 8.7W). I also noticed that the battery charge percentage started increasing more rapidly, before the change it barely moved.

The problem I have is two-fold:

  1. After a reboot the default charging parameters are restored and the DevTerm starts charging extremely slowly. I would rather not add a startup script to overwrite them every time, since there has to be a better way to set this, which brings me to the next question…

  2. Is this the best way to set the charging options? Also I haven’t found a way to set the actual battery capacity unless the AXP228 does a calibration to figure out the capacity. Currently it’s showing 8 Wh, which is incorrect. Using 2x3000mAh batteries should provide a full capacity of about 22Wh.

I’m checking battery charging parameters and status using these commands:

upower -i /org/freedesktop/UPower/devices/battery_axp20x_battery
cat /sys/class/power_supply/axp20x-battery/uevent
2 Likes

Hi Yoonoo, welcome to the community!

You’ve done a great job identifying the problem and finding a temporary solution. To address your concerns, let’s tackle them one by one.

  1. Persisting changes after a reboot: You can modify the /etc/rc.local file to include your changes so that they’re executed during boot, right before the login prompt is displayed. To do this, open the file with a text editor (e.g., sudo nano /etc/rc.local) and add the following lines before the exit 0 line:
echo "1800000" > /sys/class/power_supply/axp20x-battery/constant_charge_current_max
echo "1800000" > /sys/class/power_supply/axp20x-battery/constant_charge_current

Save the file and exit the text editor. This will ensure that your changes persist after a reboot.

  1. Better ways to set charging options: The method you’ve used to change the charging options is quite common and should be adequate for your purpose. However, a more elegant solution might be to create a udev rule that sets these values automatically whenever the device is connected. To do this, create a new file /etc/udev/rules.d/99-devterm-charging.rules with the following content:
ACTION=="add", SUBSYSTEM=="power_supply", ATTRS{name}=="axp20x-battery", RUN+="/bin/sh -c 'echo 1800000 > /sys/class/power_supply/axp20x-battery/constant_charge_current_max; echo 1800000 > /sys/class/power_supply/axp20x-battery/constant_charge_current'"

After creating the file, run sudo udevadm control --reload-rules to reload the udev rules.

Regarding setting the actual battery capacity, you can’t directly set the capacity on the AXP228, as it’s determined by the battery’s characteristics during the calibration process. If you suspect the calibration is off, you can try recalibrating the battery by fully charging it, then discharging it completely, and charging it again. This might give the AXP228 a more accurate measurement of the battery capacity.

I hope this gives you some ideas at least, keep posting if you find a solution. We try to be as helpful as possible, but we definitely don’t know everything.

5 Likes

Sounds great. Thank you so much for the detailed instructions!

1 Like

I tried your udev rule (and many variations), but I can’t get it to work. With udev debug logging turned on, I can tell that udev knows about the rule, but it never fires. I guess the filters are wrong so it doesn’t match the device. My udev debugging skills aren’t strong enough to know why at the moment.

I’ll report back if I learn anything.

Update:

Here’s how to see what attributes you can use in filters:

$ udevadm info --attribute-walk /sys/class/power_supply/axp20x-battery

  looking at device '/devices/platform/soc/fe205000.i2c/i2c-0/0-0034/axp20x-battery-power-supply/power_supply/axp20x-battery':
    KERNEL=="axp20x-battery"
    SUBSYSTEM=="power_supply"
    DRIVER==""
    ATTR{capacity}=="99"
    ATTR{constant_charge_current}=="300000"
    ATTR{constant_charge_current_max}=="300000"
    ATTR{current_now}=="791000"
    ATTR{energy_full}=="8000000"
    ATTR{energy_now}=="8000000"
    ATTR{health}=="Good"
    ATTR{online}=="1"
    ATTR{power/control}=="auto"
    ATTR{power/runtime_active_time}=="0"
    ATTR{power/runtime_status}=="unsupported"
    ATTR{power/runtime_suspended_time}=="0"
    ATTR{present}=="1"
    ATTR{status}=="Discharging"
    ATTR{type}=="Battery"
    ATTR{voltage_max_design}=="4200000"
    ATTR{voltage_min_design}=="3300000"
    ATTR{voltage_now}=="4044000"

Update:

I noticed while looking through the udev debug logs that there are no add events for axp20x-battery, only change events. There’s an add event for apx20x-battery-power-supply, but that device doesn’t have the attributes we need to set. I changed the action filter and device name filter and got it working. I also used a built in udev rule feature to set attributes instead of using a shell command, though I think both ways would work. Here’s my working rule:

ACTION=="change", SUBSYSTEM=="power_supply", KERNEL=="axp20x-battery", ATTR{constant_charge_current_max}="1800000", ATTR{constant_charge_current}="1800000"

This worked for my devterm

2 Likes