Keeping the Battery cool for better charging / discharging performance

I have a FW16 AMD and it has a 85W Lithium Ion Battery.
According to a web search, optimal operating range is 15°C to 35°C
The EC makes some effort to keep the charge/discharge within some limits.
atl,framework85w.yaml ← The FW16 85W battery charge max = 55 C, discharge max = 70 C
But, those limits are way outside the optimal operating range, optimal being the least lightly to damage or age the battery.

I have been experimenting.

  1. I modified my EC source code to retrieve the battery temperature from the battery with a new “ectool batterytemp” command.
  2. using ectool for force the fans on, to see if I can use that to cool the battery.
    This worked, turning on the fans did cool the battery.

The ambient temperature in the room I am in is 17-18 C.
Leaving the FW16 switched on and mostly idle, web browsing, watching youtube, but no gaming. The battery temp sits at about 35 C.
Using the fans, I could get that down to about 30 C.

I am thinking that it might be useful to have an ectool command that would cause the fans to turn on, if the battery temp hits >= 35 C, and then switch off when it reaches down to 30 C.

There are only 2 ways currently to read the battery temp:

  1. Using a EC CCD “battery” command (not available with ectool)
  2. Modifying the EC source code to return it in an ectool command.

What do people think? Would it be helpful to have this feature that might extend the life of the battery, or are people content to ignore it and just buy a new battery when it fails earlier than you expect it to.

Feature being: If battery gets too hot, it turns on the fans.

1 Like

First of all, your work on extending EC functionality is super cool! I’m following it and looking forward to any updates :slight_smile:

For the functionality here, I’m not sure it would be useful for me, for example, as my ambient is significantly higher than 17°C. My fingers start freezing off if the ambient is lower than 18°C, so in winter my ambient is more like 22°C, while in summer anything up to 28°C is possible.

If I’d be doing this, I’d rather start throttling load on CPU/GPU to clamp the draw from the battery, if it’s discharging. And if it’s charging, I think, EC can limit the charging current so that battery doesn’t heat up as much. But in practice it might mean that your system is throttling for no apparent reason, which isn’t always nice to experience and debug.

My biggest battery-related ask personally would be battery charging hysteresis - let me specify (and change during system runtime) two points where charging starts and ends and let the battery discharge between those points. I think, it’s much healthier for the battery to charge and discharge for 25% instead of 1%. Of course, I am unsure if EC has the ability to implement this, or if BIOS or a separate controller on the board is responsible for that.

All battery charge control is done by the EC. The EC reads from BBRAM the values you entered into the BIOS, like battery limit, but the BIOS does nothing else really in relation to controlling the charge / discharge on the batter.

So, everything you are looking for is possible with the EC software which is open source.
Once I get the safe install instructions written up for my EC source code changes, you could try my changes also.
I will be putting the instructions (currently about 10% written) here:

1 Like

Sounds terrific, thank you!

Wait, the EC didn’t know the battery temperature? Could you investigate why the battery charges very slowly at 19C? I would like to learn about this as well. Thank you

That is highly dependent where those are XD.

1 Like

It may be purely physical, if you apply the same voltage to a “too cold” battery less current will flow than if it was warmer, that can be overcome by raising the voltage but quite likely is not done here.

In the EC source code:
./chromium/src/platform/ec/zephyr/dts/bindings/battery:
atl,framework55w.yaml ← The FW13 55W battery charge max = 55 C, discharge max = 70 C
atl,framework61w.yaml ← The FW13 61W battery charge max = 55 C, discharge max = 70 C
atl,framework85w.yaml ← The FW16 85W battery charge max = 55 C, discharge max = 70 C

The battery charge min = 0 C, discharge min = 0 C
This is where the EC uses the battery temp to limit what it does.
You can look in those files for more details of the limits.

If the battery is charging slowly at 19C, as none of the limits identified above relate to 19C, I don’t think it is slow due to temperature.
It might be slow based on buggy EC charge/discharge code.
Also, looking at that other thread, the 19C is not the temp of the battery. It is not reading the temp from the battery, so in those cases, the battery could be any temp, as it is warmed by the CPU.
The problem is the EC code, as it stands, reads the battery temp and uses it in its charging decisions. It does not pass the battery temp to user space, so the user can view it.
I have a modified EC source code that does give the battery temp to the user.
I have seen, ambient temp 17C, battery temp 35C when the CPU is mostly idle.
If the CPU is being used, I could see this battery temp reaching 55C, and thus the EC would stop charging until the temp drops again.

1 Like

In that bug, as I explained in that other topic, if you sudo ectool battery on the results you’ll get a line Desired current 783 mA, this is a very low value. Can you find “783” in the EC code?

This is not the case, the “Desired Current” jumped from 783mA to 2740mA suddenly after being charged for a while, and my USB meter reflected this, wattage jumped from 15-ish to 54-ish watts. With another resent discovery of Desired Voltage changed from 17800mV to 17600mV, it makes me think the EC(or the battery) has a mind of it’s own, with an emphasis of “Desired”

Desired current is read directly from the Battery BMS.
It gives the EC what the max charge current can possibly be at that instant in time. The EC will never exceed this.

src/platform/ec/driver/battery/smart.c:

      if (sb_read(SB_CHARGING_CURRENT, &batt_new.desired_current))
                batt_new.flags |= BATT_FLAG_BAD_DESIRED_CURRENT;

The sb_read() is reading a register from the BMS.

So, in answer to your question:
" In that bug, as I explained in that other topic, if you sudo ectool battery on the results you’ll get a line Desired current 783 mA, this is a very low value. Can you find “783” in the EC code?"

The answer is the battery itself is telling the EC to limit the charge to 783 mA in that instance.
So, the cause is the battery and not the EC, maybe indicating a failing battery, but could also just mean that it is doing some sort of cell balancing, and cannot take full charge at this moment in time.

For example, my FW16 85W battery has this:
Battery 0 info:
OEM name: NVT
Model number: FRANDBAT01
Chemistry : LION
Serial number: 0084
Design capacity: 5491 mAh
Last full charge: 5763 mAh
Design output voltage 15480 mV
Cycle count 79
Present voltage 15361 mV
Present current -621 mA
Remaining capacity 2972 mAh
Desired voltage 17800 mV
Desired current 5491 mA
Flags 0x06 BATT_PRESENT DISCHARGING

So, it is happy to charge at 5491 mA if the PSU was plugged in.

The usb meter would also reflect phscial limitations but the desired current value which is a software thing and the infos from james definitely point in a software direction.

Both the battery and the charge controller do certainly have their own logics going on, the ec is just wrangling them XD.

If possible, please pay close attention to these values, when the cycle count reaches a value between 100 to 140, the “Desired voltage” can suddenly change, mine changed to 17600mV and the battery health on upower(or the UI of your OS) dropped about 5%


The 783mA is not very often as I haven’t seen it in recent months, but the 17600mV stayed so I attempted to hack into the BMS, unfortunately I need the UNSEAL code to read the “desired” value and possibly change it, I looked up everywhere but I cannot find the correct one. Is this thing behind an NDA of some sort? At least I can see the voltages that the cells are not unbalanced. I read from somewhere in this forum that third party batteries are not officially supported, which kind of make sense. According to this EC code, the max voltage and normal voltage are hard coded, so if you put LFP(3.65V/cell) NCA(4.2V/cell), NMC(4.2~4.3V/cell) batteries it can cause malfunction.

Also there is a topic of battery stopped charging during a heatwave, I don’t think a heatwave can heat up the battery to 55C, it’s prbably blocked by the battery circuit, not the computer

In that thread:

The mention of “cycle” is and was an EC source code bug.
I explain it over here:

I have a version of the EC source code that completely fixed the charge/discharge cycles.
FW have also been working on this, so it will improve at some point.

I am going to put instructions together, so others can safely experiment with my code on their EC.

But, regarding battery temp.
If the battery has fallen to a “Desired Current” of 783 mA, I would have liked to see what the battery temp was at the time.

I put the laptop in 18~20 Celsius for about five hours so the whole computer was that temperature. After I plugged in the 783 went away a few minutes after if booted up idling, it won’t go away if I use a fan to blow wind into it, fixing the temperature.

Sorry I can’t get the most accurate reading as AMD mainboard doesn’t record battery temperature without modifying the EC code. On Intel mainboards (on FL13) you can simply read the battery temperature by sudo ectool temps all or sudo ectool thermalget

@Charlie_6
That app has a multitude of battery statistics and measurements.
With a few changes to the FW EC, we could surface all those to the user if it was useful.
I would just need a list of register offsets to read them.

How to acquire these?

Regarding that part.
I have only looked at the FW16 EC code, which is this branch: fwk-lotus-azalea-19573
The FW16 EC code handled the battery differently from the FW13 EC code.
FW13: fwk-hx20-hx30-4410
FW16: fwk-lotus-azalea-19573

I am not a battery expert, but isn’t the only way to handle more battery types, is to create a large lookup table, or does the battery itself contain this information?

Pretty sure you could just ask the bms. There may even be a generic smbus command to get that information from all kinds of different bms manufactureers.