[TRACKING] Battery flipping between charging and discharging / Draws from battery even on AC

Not sure if sarcastic or insanely optimistic XD

I am rummaging around the charge controllers datasheet and found some interesting stuff.

It may be interesting to also dump control reg 2 and 3, the whole 2 step charger current limit thing may be useful, worst that could happen is the charger ocps and you get a system crash (probably not even that since the battery will just take over). But if not it will take some load spikes from the psu instead.

I also found learn mode which should make it relatively easy to implement a battery calibration routine like the thinkpads have so we have a bit of a gentler way to get somewhat accurate battery health info. May also be useful for framework support if people complain about high apparent battery wear.

So far found no mention of ever setting the bus voltage to the current battery voltage and not the desired battery voltage even for trickle charging, the controller has it’s own current limiting.

Really sucks that we don’t have actual schematics for the power section just a block daigram.

My FL16 has gone into ‘won’t charge battery’ mode, even though it says it is charging. Have you (@James3 ) identified anything in the EC code that relates to this happening?

Now off to attempt to find the destructions for how to reset things to make it charge again …

The work has already been done, so assuming 3.09 goes stable and the firmware team is properly engaged with James it could happen before the end of the summer?

@Alan_Pearce
The EC should just charge the battery if it needs it.
ectool chargecontrol
Tells you: Normal, IDLE, Discharge
The “Normal” is the one you need to charge.

We are in the 3rd attempt of trying to make the battery extender thing work.

While I hope this doesn’t get fully resolved soon I kind of doubt it.

With the way things are programmed now, does this mean VSys from the PSU passing through the charger can best-case scenario match but never exceed the value set by SysMaxV?

Is there a way to monitor the VSys and VBat values you’re referring to using Ectool?

Also, for my own understanding, what is the meaning of each of the three voltages shown by the ectool battery command? I’m getting a bit confused by the meaning of the voltage values it shows as outputs.

  1. Design output voltage
  2. Present voltage - Battery voltage as calculated by the BMS?
  3. Desired voltage

Sometimes I also get weird charging curves like this

You can see it getting plugged in (original FW charger)

  • charging with ~35W,
  • Hit 50% charge
  • Drop to 21W charging and slowly decrease to 6W
  • Hit 65% charge
  • charge with ~38W again

The laptop was at normal web browsing use during that time.

It’s nothing dramatic and this doesn’t always happen. But somehinglike this or similar happens every couple weeks.

I guess this could also be happening due to the complex EC code and race conditions?

Hi @mgcarlson

If you are using the my EC firmware and my “ectool”, just do a git pull to get the latest and install them.
I have added a new command:
sudo ectool chargegetregs

It retrieves all the registers of the charge controller and some other voltage/current sensors and then uses ectool to decode and display them.

If you have a 240W charger, I would be very interested to see what its output is for:

  1. The idle state, where not much CPU or GPU is being used.
  2. The heavy loaded state, so I can see how much current is being used and what for.

There is an additional experimental patch that might be worth a try, but I have not tested it.
That is one that tries to make the Vsysmax behave more like the chip datasheets describe.
I.e. using desired_voltage instead of current battery voltage that I mentioned previously.

diff --git a/common/charge_state.c b/common/charge_state.c
index 8f29c5ccc3..74377cee56 100644
--- a/common/charge_state.c
+++ b/common/charge_state.c
@@ -487,8 +487,10 @@ int charge_request(bool use_curr, bool is_full)
                 * otherwise the BGATE FET body diode would conduct and
                 * discharge the battery.
                 */
+               //voltage = charger_closest_voltage(
+               //      curr.batt.voltage + charger_get_info()->voltage_step);
                voltage = charger_closest_voltage(
-                       curr.batt.voltage + charger_get_info()->voltage_step);
+                       curr.batt.desired_voltage);
                /* If the battery is full, request the max voltage. */
                if (is_full)
                        voltage = battery_get_info()->voltage_max;

I am working on a further bit of work to look into PMF settings.
Its another possible cause of problems handling the 240W charger.

I am getting the following error when I try to build the azalea firmware ec.bin with the latest version of the git repo.

zmake -j8 build azalea
/chromium/src/platform/ec/build/zephyr/azalea/modules/ec/common/charge_state.c:2308: undefined reference to `ina2xx_get_voltage'
/chromium/src/platform/ec/build/zephyr/azalea/modules/ec/common/charge_state.c:2309: undefined reference to `ina2xx_get_current2'

I think I have all the prerequisites set up right. Running zmake -j8 build lotus generates an ec.bin file without error. Any troubleshooting suggestions?

Sorry about that.
Fixed now, please do another “git pull”.

The “ina236” chip is not present on the AZALEA board.

Thanks for the code fix! Just updated ectool and reflashed the latest modified azalea firmware. Will post a video in a bit with full outputs from sudo ectool chargegetregs using my 60W and 100W chargers.

Was unsure what chgnum the command wanted, but using 0 as an argument worked fine.

The output on the PD line seems bugged compared to the output you posted earlier, if that’s at all relevant. See below excerpt from the ectool chargegetregs output. Everything else seems to read correctly.

sudo ectool chargegetregs 0
PD: -99999.0 mV, I: -99999.00 mA, 9999.80 watts
ADP: 19488.0 mV, I: 3072.00 mA, 59.87 watts
BAT: 16320 mV, discharge: 0 mA, 0.00 W, charge 0 mA, 0.00 W
SYS: 16512.0 mV, I: Unknown, Max 16776 mV

I don’t intend to buy another charger at this time, so someone else will have to perform the 240W charger test. I am interested in trying the experimental patch code. Admittedly, I would feel more comfortable adding the code to charge_state.c if it was tested first.

Here is a video showing the ectool chargegetregs outputs.

With the 60W charger plugged in under performance mode, Vsys frequently drops below VBat. The “Active Control Loop” outputs rapidly alternate between the following two states when battery flipping occurs.

  • MaxSystemVoltage control loop is active
  • Input adapter current limit loop is active

With the 100W charger plugged in under performance mode, battery flipping still occurs, though much less frequently than with the 60W charger. The “Active Control Loop” mostly stays in the “MaxSystemVoltage” state, with momentary flashes of the “Input Adapter Current Limit” state.

What is the logic behind what triggers the “inlet adapter current limit” loop state? Does this occur when the charger can’t boost the PSU voltage in time to a level sufficient to meet laptop power demand?

The line:

PD: -99999.0 mV, I: -99999.00 mA, 9999.80 watts

That is only valid for the FW16 that has an extra Voltage/Current sensing chip.
You can ignore the PD line on the FW13.
I will probably update the ectool code to remove the PD line if its not needed.

In the video:
The ADP values look very variable. With a 60W charger it should not reach more than 60W.
My FW16 does not jump around nearly as much as your FW13.

It even jumps up to above 200W at some points.
What make and model are the 60W and 100W PSU?
I could be wrong, but it strikes me as maybe the PSUs are misbehaving.

The ADP values are between the USB-C connector and the charger chip. I.e. the Input from the Adapter (ADP).
So, it should show the volts and current that the PSU is outputting.
If the laptop is in idle, not doing much, do they still jump around so much?

Yeah, but mine isn’t. It has charged quite happily since new, and then the other day I had the charger disconnected and the battery ran down to 20% before going into power save by dimming screen (and popping up a notification about battery charge). Plugged charger in and screen brightness came back, battery indicator on bar at top right (using Fedora 41) shows ‘zap’ in battery symbol, but the percentage doesn’t increase. Charge indicator stays orange. I know people have had problems where the charging system gets its knickers in a twist and won’t charge until people have done a system reset.

Will leave charger disconnected with laptop powered off as first hit at reset.

The 60W PSU is the Framework one that came with the laptop. The 100W PSU is an Insignia NS-PW31XAC2W22B.

Both PSUs have similar idle ADP outputs. The 60W PSU output varies from ~40-60W, and the 100W PSU output varies from ~45-65W. Still just as jumpy within that range, from my standpoint.

I would be curious to see ADP outputs from other Framework 13 users in this thread to see if my laptop is an outlier. Hard to say what behavior is normal without more data points.

I applied the experimental patch to charge_state.c and flashed a new version of the Azalea firmware to my FW13. The change did cause Vsys to increase closer to the desired battery voltage. Unfortunately, the change did not solve the state flipping issue.

If anything, the change caused the CPU to run noticibly hotter than before. In particular, performing my refresh test in performance mode with the 100W charger plugged in caused the system fans to turn on almost full blast.

I ended up reverting my system back to the latest custom EC firmware that added the chargegetregs function. Using a 100W charger with that version has reduced the number of battery state flips under normal run conditions while still respecting my charge limit.

I will likely leave the firmware alone for now until a breakthrough is made in controlling power state with CPU spikes.

I will post a video with outputs from the experimental patch later.

Here is the a video with ectool outputs when running the experimental patch that sets VsysMax to the desired battery voltage. I recorded 60W and 100W PSU behavior under different power settings at idle, 100W behavior with browser refresh, and outputs when unplugging and plugging in my 100W PSU.

One difference I noticed (besides the higher CPU temps) was that the “Power Stage Operation Mode” changed state using the 60W PSU and any power profile besides “Power Saver” under idle conditions. I don’t believe that happened with VSysMax at the lower limit.

Those are useful videos.

The settings to watch are the following:
BAT: 15360 mV, discharge: 622 mA, 9.55 W, charge 0 mA, 0.00 W
The discharge , charge is values from the perspective of the charger chip.
So if they are both 0mA, the charger is not charging or discharging.

BGATE power good status: On
BGATE On means that the battery is connected.
BGATE Off means that the battery is not connected, (its impossible to charge in this state).

So, the aim is to watch the BGATE and try to keep it “Off”, thus ensuring no discharge/charge from the battery.

The experimental fixes, I think result in BGATE being “Off” for longer, thus ensuring that the battery is not getting charged or discharged unless it really needs to.

So, that is the theory.

Your video shows the ADP current (mA) all over the place, and I think this is confusing both the charger chip and the battery.

I can’t believe the PSU is actually jumping all over the place, so I am thinking there might be some noise problem on the Current sensing circuit for the charger chip.

See the following cut/paste from your video.


How can a 100W charger be delivering 352.25 Watts and 18.4 Amps. The answer is it cannot, and this is why I think it is most likely a sensor problem.

On my FW16, the ADP / PD current is much more stable and sticks around 80W when the CPU is running “stress-ng --cpu 16”.

I was sort of expecting the ADP to be similarly stable on the FW13, but it does not appear to be.

2 Likes

Like you said, it’s obvious the ADP power read from both my PSUs are unrealistically high. I am not electrically knowledgeable enough to know if the input power is being filtered properly before reaching the charger. I also don’t know if that sort of power filtering is a function the charger chip could be performing differently before taking a reading.

Given I just got the FW13 new 3 months ago, I would be disappointed if there’s a fault in the charger chip specific to my laptop already.

I figure further progress will be slow to address the battery flipping issue unless Framework releases more detailed schematics for the power section to the community, assuming that’s not considered proprietary. Perhaps positing some of the findings from this thread in the official Framework issues tracker on Github would be beneficial so they don’t get lost in the shuffle with other forum posts.

Above all, having more people with a FW13 who are reading this thread post realtime chargegetregs outputs from James3’s custom ectool would prove out if the PSU and charger behavior outputs from my laptop are typical.

1 Like