Battery Charging Hysteresis Support 2024 (FW AMD)

I just found out ectool can (sort of) do this

I wrote a script, to set charge level to 40% after reaching 70%, and vice versa

ectool=<path-to-ectool>
charging=1
${ectool} fwchargelimit 70

while sleep 15 ; do
    battperc=$(${ectool} chargestate show | grep batt_state_of_charge | awk '{print $3}' | tr -d '%')
    if [ -z "${battperc}" ] ; then
        battperc=0
    fi
    if (( charging == 1 && battperc >=70 )) ; then
        ${ectool} fwchargelimit 40
        charging=0
    elif (( battperc <= 40 )) ; then
        ${ectool} fwchargelimit 70
        charging=1
    fi
done

But running into another problem, if fwchargelimit is lower than current battery SoC, FW13 AMD will stop drawing current from PD, and force discharge the battery.

1 Like

That’s pretty cool! I miss this feature from my Dells as well. I wonder if EC firmware can be modified to support this.

Edit, I was reading up on EC functionality, and found here that internally both min and max percentages can be sent to EC, but the firmware doesn’t use the min percentage at all right now. (Same for AMD FW)

1 Like

you can manipulate the “chargecurrentlimit” parameter. set this to 0 or 1 means 0mA or 1mA charging current to the battery when it reaches 70% but not reduced to 40%, when the battery discharged to 40% set “chargecurrentlimit” to 99999 to revert settings (charging speed capped by the battery not BIOS)

2 Likes

Yet another issue: my script is running, waiting for SoC to reach 70%, but somehow the charging limit is reset to 65%, which is the value in my cmos setup.

awesome!

but we want to keep the batt last longer under constant AC power, so:

  1. Keep SoC near 50% as possible
  2. Do not use charging current >0.5C

so, lets set “chargecurrentlimit” to 1800, when charging needed. :stuck_out_tongue:

1 Like

new code, with some other misc operation omitted

#!/usr/bin/env bash 

# better sudo this script to avoid extra password input
ectool=${fill_your_own_dir_in_case_not_in_PATH}/ectool

battMin=40
battMax=65
battChrgCur=1800

charging=0

while sleep 15 ; do
    battperc=$(${ectool} chargestate show | grep batt_state_of_charge | awk '{print $3}' | tr -d '%')
    if [ -z "${battperc}" ] ; then
        battperc=0
    fi
    ${ectool} fwchargelimit ${battMax}
    if (( charging == 1 && battperc >=${battMax} )) ; then
        charging=0
    elif (( battperc <= ${battMin} )) ; then
        charging=1
    fi
    if [ 0 -eq $charging ] ; then
        ${ectool} chargecurrentlimit 0
    else
        ${ectool} chargecurrentlimit ${battChrgCur}
    fi
done
1 Like