Exploring the Embedded Controller

I love the EFI driver, but how can I do the mapping of ESC to caps look in the EC?

I too am getting:

$ sudo ./build/bds/util/ectool version
Cannot open lockfile /run/lock/cros_ec_lockCould not acquire GEC lock.
$ git log -n1
commit d5b5b5008d2f98400206deb182e8ce772b6df9df (HEAD -> main, origin/main, origin/HEAD)
Author: Dustin L. Howett <dustin@howett.net>
Date:   Tue Apr 12 08:14:25 2022 -0500

    Remove COMM_FWK, but keep --interface=fwk as an alias for lpc


UPDATE Without recompiling it started working. I suspect a kernel update.
For reference it is now working for me with kernel 5.15.0-52-generic

2 Likes

I finally set up this tool today and it’s great! It was so simple to set it up, and being able to change the charge threshold with a simple command in the terminal is incredibly useful.

I am stumped on one thing already though, which is how to use the one-shot full charge from the command line. I do get the impression it was implemented from different parts of the thread.

Here, it was discussed how there is a high bit which allows the charging limit to stay in place, but a one-off exception will be made to give it a full charge:

Here there is a screen snip of a GUI version of the tool which appears to have this feature as an available option:

I read through all the available commands in the built-in help tool and have poked around in the online documentation, but I still can’t quite figure out if this feature is available from the command line.

It’s no hardship to run sudo ectool fwchargelimit 100 and then just run it again to set the charge threshold back where you had it after the battery is fully charged, but since I saw it mentioned in the thread I thought I would ask in case I am just missing something.

2 Likes

Huh. I didn’t think to implement it in my slapped-together fork of ectool.

How’s this strike you?

ectool fwchargelimit 100 once

I just added it, so you may need to update!

11 Likes

Wow, nice one! Thank you. :blush:

Will do, thanks again for the speedy response!

2 Likes

I am getting this odd behavior of battery draining even while plugged (11th Gen).

I did try ectool fwchargelimit 100 once and it does seem to have happened after I used it.

I did have the bios updated to the latest (3.17).

Is there any inspection, setting I can do with ectool to troubleshoot this?

1 Like

So you are using a Windows OS?

What makes you say the battery is discharging.

Currently I have battery charge limit set to 100% though that is not the issue.

Whatever setting the computer will sometimes draw a high load very quickly and then the battery will provide some of the current so yes it will appear to charge a little and could be quite often.

Even if the usage jumps from 20w to 40w for soem milliseconds then the load will take what it can from the battery as it is being charged, but there will always be a blip when the battery feeds the demand and the power supply catches up.

1 Like

I am using Ubuntu 22.04.1.
I say the battery is discharging because I closed the lid with battery at 100% and 4 days later with usb cable plugged (and white light on when I opened it again), battery was at 0%

1 Like

Ok that’s a serious decline, did you you an auto sleep when you closed the lid?

Trying to get my head around it.

  • The light indicated the battery was full
  • fwchargelimit 100 hopefully you included the ‘1’
  • Have you tried setting to 90% since?
1 Like

Yes, here is my systemd config:

# cat /etc/systemd/sleep.conf /etc/systemd/sleep.conf.d/* | grep -v ^\#

[Sleep]
[Sleep]
HibernateDelaySec=30min
[Sleep]
SuspendMode=suspend
SuspendState=disk
HibernateMode=suspend
HibernateState=disk
# cat /etc/systemd/logind.conf /etc/systemd/logind.conf.d/* | grep -v ^\#

[Login]
[Login]
HandleLidSwitch=suspend-then-hibernate
HandleLidSwitchExternalPower=hybrid-sleep
HandleLidSwitchDocked=ignore
[Login]

I did do a full reboot and used the BIOS to reset the max charge to 70 since.
Will do more testing, but would appreciate any pointers to check what is happening, maybe from @DHowett given I used the latest from his ectool

2 Likes

The most useful thing you can do when something like this is happening would be to collect an EC console log by running ectool console (or by looking at the contents of /sys/kernel/debug/cros_ec/console_log). It routinely writes charging information to this log. It looks like this:

while charging

[89350.181131 Battery 56% (Display 57.0 %) / 2h:32 to full]
[89350.182021 Charge Limit mode = 0]

while discharging

[89387.088745 Battery 56% (Display 57.0 %) / 3h:8 to empty]
[89387.089613 Charge Limit mode = 0]

For what it’s worth, fwchargelimit sends the same commands to the EC as the firmware’s setup page option does; however, once has not been very well-tested by the community, and its use may uncover bugs in Framework Computer’s implementation of one-time charging.

3 Likes

I closed the lid and left the laptop hibernate, all this time with the charging cable connected.
Noticed side light turned off when went to resume.
And it was discharging after resume.

$ sudo ~/src/framework-ec/build/bds/util/ectool console
15473.814554 HC 0x98]
]
[15185.239242 Charge Limit mode = 0]
[15204.697404 Battery 65% (Display 66.8 %) / 3h:16 to empty]
[15204.698320 Charge Limit mode = 0]
[15226.056203 Battery 65% (Display 66.7 %) / 3h:53 to empty]
[15226.057098 Charge Limit mode = 0]
[15241.833095 Battery 65% (Display 66.6 %) / 2h:55 to empty]
[15241.833932 Charge Limit mode = 0]
[15257.236242 Battery 65% (Display 66.5 %) / 2h:59 to empty]
[15257.237054 Charge Limit mode = 0]
[15274.366333 Battery 65% (Display 66.4 %) / 3h:23 to empty]
[15274.367248 Charge Limit mode = 0]
[15283.985753 Battery 65% (Display 66.3 %) / 3h:1 to empty]
[15283.986636 Charge Limit mode = 0]
[15301.115822 Battery 65% (Display 66.2 %) / 3h:2 to empty]
[15301.116687 Charge Limit mode = 0]
[15317.871820 Battery 65% (Display 66.1 %) / 2h:34 to empty]
[15317.872645 Charge Limit mode = 0]
[15331.448195 Battery 65% (Display 66.0 %) / 2h:41 to empty]
[15331.449334 Charge Limit mode = 0]
[15348.548557 event set 0x0000000200000000]
[15348.549988 event clear 0x0000000200000000]
[15348.550560 ACPI query = 34]
PORT80: 0022
[15349.052992 Battery 64% (Display 65.9 %) / 2h:56 to empty]
[15349.054093 Charge Limit mode = 0]
[15358.771761 Battery 64% (Display 65.8 %) / 2h:51 to empty]
[15358.772677 Charge Limit mode = 0]
[15370.795292 Battery 64% (Display 65.7 %) / 2h:25 to empty]
[15370.796186 Charge Limit mode = 0]
[15386.973691 Battery 64% (Display 65.6 %) / 2h:37 to empty]
[15386.974529 Charge Limit mode = 0]

After disconnecting and reconnecting the cable:

$ sudo ~/src/framework-ec/build/bds/util/ectool console
15542.219925 HC 0x98]
811872 HC 0x97]
[15473.814554 HC 0x98]
+++(++)[15494.891590 Battery 64% (Display 65.0 %) / 4h:10 to empty]
[15494.892686 Charge Limit mode = 0]
[15519.194354 Battery 64% (Display 64.9 %) / 4h:20 to empty]
[15519.197136 Charge Limit mode = 0]
[15524.165946 HC 0x0b]
[15524.171124 HC 0x3e03]
[15524.171730 Charge Limit mode = 0]
[15532.139428 PD Source supply changed! old=0x0, new=0x08]
[15532.147621 CYPD_RESPONSE_PORT_CONNECT 3]
[15532.153088 Updating board_set_active_charge_port port 3]
[15532.156520 CL: p3 s1 i3000 v5000]
[15532.157068 TODO Implement pd_set_new_power_request port 3]
[15532.162367 cypd_update_power_status power_stat 0x8]
[15532.167807 INTR_REG CTRL:0 TODO Device 0x2]
[15532.170114 INTR_REG CTRL:1 TODO Device 0x2]
[15532.172584 Charge Limit mode = 0]
[15532.174946 update charger!!]
[15532.178027 AC on]
[15532.178498 event set 0x0000000000000008]
[15532.179572 event clear 0x0000000000000008]
[15532.180109 ACPI query = 4]
PORT80: 0004
[15532.416445 CYPD_RESPONSE_PD_CONTRACT_NEGOTIATION_COMPLETE 3]
[15532.422327 Updating board_set_active_charge_port port 3]
[15532.425563 CL: p3 s0 i5000 v20000]
[15532.426117 TODO Implement pd_set_new_power_request port 3]
[15532.428187 INTR_REG CTRL:0 TODO Device 0x2]
[15532.429154 cypd_update_power_status power_stat 0xe]
[15532.436493 INTR_REG CTRL:1 TODO Device 0x2]
[15532.522444 Updating SOC Power Limits: PL2 64, PL4 121, Psys 134, Adapter 100]
[15533.408872 Battery 64% (Display 64.9 %) / 4h:4 to empty]
[15533.409764 Charge Limit mode = 0]
[15533.412245 charge_request(17400mV, 3572mA)]
[15534.566067 event set 0x0000000000000080]
[15534.566966 event clear 0x0000000000000080]
[15534.567509 ACPI query = 8]
PORT80: 0008
[15535.921457 charge_request(17400mV, 2500mA)]
[15537.121339 Battery 64% (Display 65.0 %) / 2h:7 to full]
[15537.122348 Charge Limit mode = 0]
[15541.451481 Battery 64% (Display 65.1 %) / 1h:36 to full]
[15541.452387 Charge Limit mode = 0]
[15542.213791 HC 0x0b]
[15542.214759 HC 0x97]

It seems something is causing EC to disregard that there is an actual charging cable both on lid close and after open!

After another round where I did watch the light turn off and then I resumed:

$ sudo ~/src/framework-ec/build/bds/util/ectool console 
23901.440754 HC 0x98]
k ignored]
[23883.100118 AUX Callback ignored]
[23883.100533 AUX Callback ignored]
[23883.101289 AUX Callback ignored]
[23883.101705 AUX Callback ignored]
[23883.104955 AUX Callback ignored]
[23883.105498 AUX Callback ignored]
[23883.106065 AUX Callback ignored]
[23883.106609 AUX Callback ignored]
[23883.112308 AUX Callback ignored]
[23883.112874 AUX Callback ignored]
[23883.113290 AUX Callback ignored]
[23883.113982 AUX Callback ignored]
[23883.118911 AUX Callback ignored]
[23883.119455 AUX Callback ignored]
[23883.120022 AUX Callback ignored]
[23883.120566 AUX Callback ignored]
[23883.126217 AUX Callback ignored]
[23883.126739 AUX Callback ignored]
[23883.127198 AUX Callback ignored]
[23883.1[23883.133197 AUX Callback ignored]
[23883.133764 AUX Callback AUX Callback ign[23883.140001 AUX Callback ignored]
[23883.140416 AUX Callback [23883.146973 AUX Callback ignored]
[23883.147389 AUX Callback ignored]
[23883[23883.148191 AU[23884.637426 KB extra IRQ]
PORT80: 0001
PORT80: 0002
PORT80: 0003
PORT80: 0004
PORT80: 0003
[23885.125462 Updating SOC Power Limits: PL2 28, PL4 70, Psys 52, Adapter 100]
[23885.505793 event clear 0x0000000000000002]
[23885.506372 ACPI query = 2]
[23885.511831 event clear 0x0000000000000010]
[23885.512413 ACPI query = 5]
PORT80: 0002
[23885.523813 event clear 0x0000000000000080]
[23885.524397 ACPI query = 8]
PORT80: 0005
[23885.531858 event clear 0x0000000200000000]
[23885.532430 ACPI query = 34]
PORT80: 0008
PORT80: 0022
[23885.565791 KS disable]
[23885.566284 KB Clear Buffer]
[23885.568363 KS enable]
[23885.568839 KB Clear Buffer]
[23885.846852 PS2 unhandled data 0xe1]
[23886.065700 PS2M Detected host packet during interrupt handling]
[23886.451012 PS2 unhandled data 0xa]
[23886.456528 PS2 unhandled data 0x1]
[23886.457864 PS2 unhandled data 0x41]
[23886.986330 PS2 unhandled data 0x88]
[23886.989181 PS2 unhandled data 0x0]
[23887.004538 PS2M 5 Button Magic Knock!]
[23901.438839 HC 0x0b]
[23901.439837 HC 0x97]

It looks like on lid open it is not charging anymore, and again once I disconnect and reconnect the cable:

$ sudo ~/src/framework-ec/build/bds/util/ectool console 
24101.631834 HC 0x98]
885.568363 KS enable]
[23885.568839 KB Clear Buffer]
[23885.846852 PS2 unhandled data 0xe1]
[23886.065700 PS2M Detected host packet during interrupt handling]
[23886.451012 PS2 unhandled data 0xa]
[23886.456528 PS2 unhandled data 0x1]
[23886.457864 PS2 unhandled data 0x41]
[23886.986330 PS2 unhandled data 0x88]
[23886.989181 PS2 unhandled data 0x0]
[23887.004538 PS2M 5 Button Magic Knock!]
[23901.438839 HC 0x0b]
[23901.439837 HC 0x97]
[23901.440754 HC 0x98]
+++(++)[24084.118122 HC 0x0b]
[24084.119224 HC 0x3e03]
[24084.121774 Charge Limit mode = 1]
[[24096.554007 CYPD_RESPONSE_PORT_CONNECT 3]
24096.553057 PD Source supply changed! old=0x0, new=0x08]
[24096.559793 Updating board_set_active_charge_port port 3]
[24096.563211 CL: p3 s1 i3000 v5000]
[24096.563759 TODO Implement pd_set_new_power_request port 3]
[24096.565937 INTR_REG CTRL:0 TODO Device 0x2]
[24096.567000 cypd_update_power_status power_stat 0x8]
[24096.573615 INTR_REG CTRL:1 TODO Device 0x2]
[24096.583527 Charge Limit mode = 1]
[24096.585879 update charger!!]
[24096.589229 AC on]
[24096.589700 event set 0x0000000000000008]
[24096.590450 event clear 0x0000000000000008]
[24096.590988 ACPI query = 4]
PORT80: 0004
[24096.829981 CYPD_RESPONSE_PD_CONTRACT_NEGOTIATION_COMPLETE 3]
[24096.835753 Updating board_set_active_charge_port port 3]
[24096.839135 CL: p3 s0 i5000 v20000]
[24096.839688 TODO Implement pd_set_new_power_request port 3]
[24096.841866 INTR_REG CTRL:0 TODO Device 0x2]
[24096.842959 cypd_update_power_status power_stat 0xe]
[24096.850089 INTR_REG CTRL:1 TODO Device 0x2]
[24096.936393 Updating SOC Power Limits: PL2 64, PL4 121, Psys 134, Adapter 100]
[24097.719906 Battery 100% (Display 100.0 %) / 7h:36 to empty, not accepting current]
[24097.720956 Charge Limit mode = 1]
[24097.723428 charge_request(17600mV, 0mA)]
[24098.407295 Battery 100% (Display 100.0 %) / 7h:53 to empty, not accepting current]
[24098.410273 Charge Limit mode = 1]
[24101.625674 HC 0x0b]
[24101.626726 HC 0x97]

1 Like

Another example after a resume from hibernation without charging kicking in:

$ sudo ~/bin/ectool console
Place your right index finger on the fingerprint reader
600737.775202 HC 0x98]
27 AUX Callback ignored]
[600695.798463 AUX Callback ignored]
[600695.799071 AUX Callback ignored]
[600695.799807 AUX Callback ignored]
[600695.806918 AUX Callback ignored]
[600695.807526 AUX Callback ignored]
[600695.808262 AUX Callback ignored]
[600695.808870 AUX Callback ignored]
[600695.816633 AUX Callback ignored]
[600695.817369 AUX Callback ignored]
[600695.817977 AUX Callback ignored]
[600695.818585 AUX Callback ignored]
[600695.826417 AUX Callback ignored]
[600695.827293 AUX Callback ignored]
[600695.827901 AUX Callback ignored]
[600695.828785 AUX Callback ignored]
[600695.833263 AUX Callback ignored]
[600695.833871 AUX Callback ignored]
[600695.834766 AUX Callback ignored]
[600695.835503 AUX Callback ignored]
[600697.538408 Battery 61% (Display 62.0 %) / 1h:45 to empty]
[600697.539651 Charge Limit mode = 0]
PORT80: 0001
PORT80: 0002
PORT80: 0003
PORT80: 0004
PORT80: 0003
[600698.620632 Updating SOC Power Limits: PL2 28, PL4 70, Psys 52, Adapter 100]
[600698.766031 event clear 0x0000000000000004]
[600698.766802 ACPI query = 3]
[600698.769911 KS disable]
[600698.770751 KB Clea[600698.771273 event clear 0x0000000200000000]
[600698.772038 ACPI query = 34]
PORT80: 0003
r Buffer]
[600698.774979 KS enable]
[600698.775647 KB Clear Buffer]
PORT80: 0022
[600699.040396 PS2 unhandled data 0xe1]
[600699.550145 PS2 unhandled data 0xa]
[600699.552054 PS2 unhandled data 0x1]
[600699.553500 PS2 unhandled data 0x41]
[600700.061952 PS2 unhandled data 0x88]
[600700.065282 PS2 unhandled data 0x0]
[600700.080946 PS2M 5 Button Magic Knock!]
[600700.837918 PS2M Detected host packet during interrupt handling]
[600705.708540 Battery 61% (Display 61.9 %) / 1h:45 to empty]
[600705.709558 Charge Limit mode = 0]
[600715.962337 Battery 61% (Display 61.8 %) / 1h:52 to empty]
[600715.963445 Charge Limit mode = 0]
[600728.584885 Battery 61% (Display 61.7 %) / 1h:52 to empty]
[600728.585960 Charge Limit mode = 0]
[600737.772869 HC 0x0b]
[600737.773980 HC 0x97]
$ sudo ~/bin/ectool fwchargelimit
70

after unplugging / replugging the charge cable:

~$ sudo ~/bin/ectool console
600948.106649 HC 0x98]

[600916.068302 TODO Implement pd_set_new_power_request port 3]
[600916.070407 INTR_REG CTRL:0 TODO Device 0x2]
[600916.071791 cypd_update_power_status power_stat 0x8]
[600916.080106 INTR_REG CTRL:1 TODO Device 0x2]
[600916.088073 Charge Limit mode = 0]
[600916.090593 update charger!!]
[600916.093934 AC on]
[600916.094598 event set 0x0000000000000008]
[600916.095779 event clear 0x0000000000000008]
[600916.096509 ACPI query = 4]
PORT80: 0004
[600916.334023 CYPD_RESPONSE_PD_CONTRACT_NEGOTIATION_COMPLETE 3]
[600916.340043 Updating board_set_active_charge_port port 3]
[600916.343623 CL: p3 s0 i5000 v20000]
[600916.344488 TODO Implement pd_set_new_power_request port 3]
[600916.346836 INTR_REG CTRL:0 TODO Device 0x2]
[600916.348111 cypd_update_power_status power_stat 0xe]
[600916.355160 INTR_REG CTRL:1 TODO Device 0x2]
[600916.440161 Updating SOC Power Limits: PL2 64, PL4 121, Psys 134, Adapter 100]
[600917.236067 Battery 60% (Display 60.8 %) / 4h:10 to empty]
[600917.239021 Charge Limit mode = 0]
[600917.245477 charge_request(17400mV, 3572mA)]
[600918.434937 event set 0x0000000000000080]
[600918.436232 event clear 0x0000000000000080]
[600918.436956 ACPI query = 8]
PORT80: 0008
[600919.113979 charge_request(17400mV, 2500mA)]
[600921.017322 Battery 60% (Display 60.9 %) / 2h:23 to full]
[600921.018353 Charge Limit mode = 0]
[600925.194251 Battery 60% (Display 61.0 %) / 2h:5 to full]
[600925.195232 Charge Limit mode = 0]
[600928.960153 Battery 60% (Display 61.1 %) / 1h:46 to full]
[600928.961414 Charge Limit mode = 0]
[600934.553850 Battery 60% (Display 61.2 %) / 1h:31 to full]
[600934.554926 Charge Limit mode = 0]
[600938.621129 Battery 60% (Display 61.3 %) / 1h:25 to full]
[600938.622140 Charge Limit mode = 0]
[600942.531649 Battery 60% (Display 61.4 %) / 1h:21 to full]
[600942.532757 Charge Limit mode = 0]
[600947.597737 Battery 60% (Display 61.5 %) / 1h:18 to full]
[600947.598977 Charge Limit mode = 0]
[600948.100471 HC 0x0b]
[600948.103644 HC 0x97]

Something is definitely off with hibernate…
This does not occur 100% of time, but often enough it could lead to a drain to 0 situation even while lid closed and plugged in.

I was suddenly wondering.

On some systems, the EC controls the maximum power limit that the CPU/iGPU can use. I was wondering if the EC here can modify the behavior similar to how motherboard vendors on desktop increase how much power the CPU can use and/or boost durations such as PL2, which is higher than the Intel stock settings from factory.

Would be interesting to see how much we can push the system to hit the power limits with sufficient thermal headroom.

4 Likes

Interesting thought, however, if I read the readmes (havent found framework specific sources yet) This might also influence USB3, pci and display clock speeds?

Im not sure how much more power we can gain without breaking something. Am I reading it correctly we are running the Zephyr RTOS in our new Frameworks? or thats only the newer Chromebook version?

1 Like

Not sure if we can run throttlestop on Windows and see if we hit a locked power limit or a limited power limit especially for 12th gen.

Even if we can maintain 64W indefinitely with thermal headroom would be cool for those using as a mini PC. From my understanding is, generally these are vendor limited by firmware than hardware.

The Intel NUC with a 1260p with boost at full tilt can hit up to 85W from the wall, so I was wondering if we can push to get a 85W sustained (assuming the Framework’s VRMs can take it).
Review of various laptops with the same 1260p showed different performance due to thermal headroom and power limits too.

2 Likes

Wendell at Level1Tech showed that it is possible to push the 1240p harder with BIOS settings by adjusting the PL1 and more :smiley:

So the 12th Gen CPUs probably can do it, just need the the Firmware and check if the mainboard can take it :smiley:

Maybe CNC a mounting mechanism for a low profile desktop cooler or even a Tower cooler/AIO for direct die contact to give thermal headroom.

I would like to have the fan speed displayed in the Gnome extension vitals. I’m trying to understand what would have to be done to achieve this goal.

Whats the status of the ec driver did it get merged?

Checking with list modules on my system, there are several chrome os embedded controller kernel modules loaded:

$ lsmod | grep cros
cros_usbpd_charger     20480  0
cros_ec_sysfs          16384  0
cros_ec_debugfs        16384  0
cros_usbpd_logger      20480  0
cros_usbpd_notify      20480  1 cros_usbpd_charger
cros_ec_chardev        16384  0
cros_ec_dev            16384  0
cros_ec_lpcs           16384  0
cros_ec                20480  1 cros_ec_lpcs

The embedded controller is listed in sysfs under:
/sys/class/chromeos/cros_ec/

The file Version contains the following, which seems plausible.

RO version:    hx20_v0.0.1-03897d4
RW version:    
Firmware copy: RO
Build info:    hx20_v0.0.1-03897d4 2022-07-15 00:23:44 runner@fv-az252-782
Chip vendor:   mchp
Chip name:     unknown
Chip revision: 00
Board version: 12

According to kernelconfig.io one should use the kernel module cros_ec_sysfs to control the embedded controller and get information from it.

According to the Linux kernel documentation sensor information is reported in /sys/class/hwmon/hwmon*. This is the same directory from which vitals reads sensor values.

On my system there is no hwmon for fan speed.
Does the embedded controller report its sensor data to anywhere in the sysfs?

I’m new to the Framework world. On my current Thinkpad X230, I’m using the
charge_control_start_threshold and charge_control_stop_threshold in TLP and with these set to that there is no charging between 40 % and 80 %, my battery stays as new after 3 years. My wife has got a Thinkbook where only the charge_control_stop_threshold is available and after 1 year the battery capacity is already reduced by 5 %. That’s not a lot, but still quite a difference. I would love to see these two threshold available in the Framework EC firmware as I’m now saving to get a Framework 13 with AMD CPU as successor to my X230.

That’s unusual, dare I say unlikely, as batteries wear even when not used.

Have you tried a full discharge and recharge to reset the battery read out.

Whereas the Embedded controller does control it doesn’t read the state of the battery. The battery info is pushed from the battery and if that isn’t calculating over a range it will not have a lot to work on.

Coulomb counting is one thing but measuring coulombs from 0 to 100 is a base measurement for wear.

That’s based on my limited understanding of course :slight_smile:

I have daily measurements and after a year I have managed to find a reading that says there is no wear but on average there seems to be less than 2% given the 3.4% wear upon receipt.

I have a limit of 78% max and run mostly plugged in