Skip to content

About

FanControl plugin for MSI laptops

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

15 Commits

Folders and files

Repository files navigation

FanControl.MsiEc

FanControl plugin that adds fan monitoring and direct fan control for MSI laptops — the missing piece for machines whose fans are normally only adjustable through MSI Center / Creator Center (requested here).

Verified hardware: EC firmware family 14B3EMS1 — MSI PS42 Modern 8MO/8RA, Modern 14 A10M/A10RB. Other MSI laptops with the standard EC layout can opt in via the config file (see below).

Install (no compilation needed)

  1. Install FanControl (the standard .NET build, V271+).
  2. Make sure the PawnIO driver is installed — FanControl itself offers to install it, or grab the installer from pawnio.eu.
  3. Drop FanControl.MsiEc.dll into FanControl's Plugins folder and restart FanControl.

That's it. You get:

  • CPU Fan (MSI EC) control — ready for a curve or the calibration assistant,
  • CPU (MSI EC) temperature and CPU Fan (MSI EC) RPM sensors (polled slowly; disable them with "ecSensors": "off"), plus GPU ones on dual-fan models.

Controls accept 0–100 %.

Recommended setup: keep temperatures off the EC

The plugin's job is writing fan speed; for reading temperature there is a better source. Point your fan curve at a LibreHardwareMonitor CPU temperature (FanControl ships with it — "CPU Package", "Core Average", …). Those come from the CPU's own MSRs, a completely different bus, so they update instantly and cost zero EC traffic. That single change removes the most frequent EC access; the default "ecSensors": "slow" then costs only 4 bytes per 30 s and keeps the RPM readout.

If you want literally zero steady-state EC traffic, set "ecSensors": "off" — but first remove every reference to the plugin's sensors from FanControl (curve temperature source, control pairing, tray icons). FanControl validates saved sensor references on startup and refuses to refresh when they disappear.

Safety design

  • The plugin reads the EC firmware version first (register 0xA0) and disables itself on anything not in the verified list — it never writes to an unknown EC.
  • Writes go only to the documented fan registers (curve tables + fan mode), every byte is read back and verified.
  • Thermal failsafe: the two hottest bands of the EC's own curve table are never written below their floors (≥ ~80 °C: min 80 % duty; top band: always 100 %). Even if the OS or FanControl freezes while a quiet duty is set, an overheating CPU/GPU still gets full airflow — this logic lives in the EC, not in software.
  • The factory fan curve and mode are captured at startup and restored when you disable the control, close FanControl, or the plugin unloads.
  • Worst case (a frozen EC — never observed): power the laptop off and hold the power button ~30 s; the EC resets with factory behavior.
  • EC access uses the signed, HVCI-compatible PawnIO driver with the official LpcACPIEC module (port I/O restricted to the ACPI EC ports 0x62/0x66), so it works with Windows Memory Integrity (HVCI) enabled. Transactions are serialized through the system-wide Access_EC mutex shared with other monitoring tools.
  • ACPI-driver coexistence (v1.2+): the Windows kernel EC driver shares the same ports and cannot be locked out, so the plugin never consumes a pending EC response that may belong to the kernel (that desyncs battery/thermal reporting), skips its cycle instead of interfering, keeps traffic minimal (sensor poll every 5 s, duty writes within ±2 % coalesced, mode re-check once a minute) and backs off exponentially when the EC misbehaves.
  • EC health watchdog (v1.3): every write anomaly, timeout or implausible reading counts as evidence of bus contention; two within 10 minutes suspend all EC writes for 15 minutes (the fan keeps its last duty, the EC-side thermal failsafe stays active). Implausible sensor samples are discarded so garbage never reaches your fan curves.
  • Sleep/resume aware (v1.3): resume is when the kernel talks to the EC the most, so after any suspend/hang gap the plugin stays off the bus for 45 s, then gently re-asserts control. All boost-register writes are absolute values from a known-good startup snapshot — never read-modify-write — and boost toggles at most once a minute with a wide 10 % hysteresis.
  • Boot- and resume-aware startup (v1.5): FanControl re-creates plugin objects (the plugin lives in FanControl.Service, which reloads them e.g. when the UI reconnects after resume), so a fresh instance used to repeat the whole startup read burst — right after a resume, the worst possible moment. The "stay off the EC bus" deadline, the verified firmware string and the GPU detection result are now process-wide: a re-created instance re-identifies the machine without a single EC read, and the factory snapshot waits out the first minute after boot and 45 s after resume before it is taken.
  • Minimal contact (v1.4): requested duty is quantized (default 5 %) and rate-limited (default one write per 10 s), only the table bytes that actually changed are written, the fan-mode register is re-checked every 5 minutes instead of every minute, Cooler Boost is off by default, and with "ecSensors": "off" a steady fan speed means zero EC transactions.

EC traffic budget (defaults, single-fan laptop)

Situation EC bytes
Startup (firmware check + factory snapshot) ~20 reads, once
Steady state, ecSensors: "off" none
Steady state, ecSensors: "slow" 4 reads / 30 s
Fan speed change ≤5 writes + 1 read, at most once per 10 s
Fan-mode re-check while controlling 1 read / 5 min

Configuration (optional)

Create FanControl.MsiEc.json next to the dll (see FanControl.MsiEc.json.example):

{
  // Opt-in for EC firmwares not in the built-in verified list.
  // Check yours first (e.g. HWiNFO → Embedded Controller, or MSI's EC update
  // package name). Only do this if you know your model uses the standard
  // MSI EC layout (most 2018+ consumer/creator models do).
  "additionalFirmwarePrefixes": [],

  // "auto" (default): GPU fan sensors appear if the EC reports GPU activity
  // at startup. "on"/"off" to force.
  "gpuFan": "auto",

  // Engage MSI Cooler Boost when a control is asked for at least this duty %
  // (1..100, 0 = disable). Default 100: full-speed requests act instantly.
  "coolerBoostAtDuty": 100
}

About fan response speed

The MSI EC ramps the actual PWM toward the requested duty at only ~1 %/s (measured: 3000→5900 RPM takes ~56 s through the curve-table path) — firmware behavior, same under MSI Center, not adjustable through documented registers. The plugin compensates for the case that matters: when FanControl requests coolerBoostAtDuty % or more, it flips MSI's Cooler Boost bit, which bypasses the ramp entirely (3000→6200 RPM in ~2 s, slightly above the normal 100 % speed). Below the threshold (with 5 % hysteresis) boost is released and the fan follows the normal slow ramp down.

If your firmware isn't listed, the plugin shows exactly what to put in this file — and please open an issue with your model + firmware string so it can be added to the verified list.

Technical notes

Register map (standard MSI layout, confirmed live on 14B3EMS1.102):

Register Meaning
0xA0..0xAB EC firmware version string
0x68 / 0x80 CPU / GPU temperature, °C
0x71 / 0x89 current fan duty, %
0xCC/0xCD, 0xCA/0xCB fan tachometer, RPM = 478000 / raw (big-endian)
0x72..0x78, 0x8A..0x90 fan curve duty tables (7 temperature bands)
0xF4 fan mode: 0x0D auto, 0x8D advanced

Control works like MSI Center's advanced mode: the plugin switches the EC to advanced fan mode and writes a flat duty table, so the value FanControl asks for applies at any temperature (except the failsafe bands above).

Build from source

dotnet build src/FanControl.MsiEc/FanControl.MsiEc.csproj -c Release -p:FanControlDir=<path to FanControl>

Українською (коротко)

  1. Встановіть FanControl і драйвер PawnIO (FanControl сам запропонує).
  2. Покладіть FanControl.MsiEc.dll у папку Plugins FanControl і перезапустіть програму.
  3. З'являться датчики температури/обертів та керування вентилятором — далі звичайні криві FanControl.

Licensing

Plugin code: MIT (see LICENSE). The embedded LpcACPIEC.bin PawnIO module is LGPL-2.1-or-later, © namazso — source: PawnIO.Modules (see THIRD-PARTY-NOTICES.md).

About

FanControl plugin for MSI laptops

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages