* Add NCT6687DR fan control support with bit mapping and configuration phase handling * NCT6687DR: emulate CC_Engine SetManualFAN protocol - System fans (index > 8): skip manual mode bit (0xA00), use flat SmartFAN curve instead - Change commit value from 0x40 to 0xC0 (REQ|DONE) matching CC_Engine - Write 7-point temp curve (all 0x20/32C) alongside duty curve for system fans - Add Sleep(10ms) after request (0x80) and commit (0xC0) per CC_Engine timing - Restore: only clear manual mode bit for CPU/Pump/Chipset/EZ-Connect fans * NCT6687DR: add INVALID bit check with retry after EC commit - FinishFanCfgUpdate now returns bool: false if EC sets INVALID (0xCF8 & 0x10) - SetControl and RestoreDefaultFanControl retry up to 3 times on INVALID - Matches CC_Engine's post-commit validation behavior * fix(NCT6687DR): bypass SmartFAN engine for system fans — use direct PWM System fans (SYSFAN1-7) now use the same direct PWM mechanism as CPU/Pump/Chipset fans, completely bypassing the SmartFAN curve engine and its inherent ~2%/sec PWM smoothing. Key changes: - FAN_PWM_COMMAND_REG: system fans now point to direct PWM registers (SYSFAN7: 08:E9, SYSFAN1-6: 02:65..02:60) instead of SmartFAN curve base addresses (0xBE0..0xC70) - FAN_CONTROL_MODE_REG: system fans use 08:0F (not 0xA00) for their manual-mode enable bits - FAN_CONTROL_MODE_BIT: corrected per-channel bit positions derived from BIOS unk_104C0 table (sub_2F50 / sub_2BDC analysis) - Set6687DRControl: simplified to single WriteByte for all fans (no more 7-point flat curve + step/rate writes) - SetControl: unified path — all fans set manual-mode bit + direct PWM - RestoreDefaultFanControl: clear manual-mode bit to return to SmartFAN Register mapping discovered via IDA analysis of BIOS firmware: - Extended unk_101E0 table at 0x103AC contains channels 10-15 - sub_2BDC configures 5 register operations per channel before curve write - Entry[1] in unk_104C0 = manual-mode enable register + bit position * review: Stopwatch, engineSts rename, CompleteFanConfigUpdate * refactor: PreciseWait via SpinWait, DateTime to Stopwatch in ReadByte/WriteByte * review: remove regions, revert PreciseWait to Thread.Sleep
LibreHardwareMonitor
Libre Hardware Monitor is free software that can monitor the temperature sensors, fan speeds, voltages, load and clock speeds of your computer.
What's included?
What can it do?
You can read information from devices such as:
- Motherboards
- Intel and AMD processors
- NVIDIA, AMD and Intel graphics cards
- HDD, SSD and NVMe hard drives
- Network cards
Where can I download it?
You can download the latest release here. You can also install it using WinGet:
winget install LibreHardwareMonitor.LibreHardwareMonitor
Nightly builds
If you have a GitHub account, you can download nightly builds here. Otherwise, you can download the latest nightly build here.
How can I help improve it?
The LibreHardwareMonitor team welcomes feedback and contributions!
You can check if it works properly on your motherboard. For many manufacturers, the way of reading data differs a bit, so if you notice any inaccuracies, please send us a pull request. If you have any suggestions or improvements, don't hesitate to create an issue.
Developer information
Integrate the library in own application
- Add the LibreHardwareMonitorLib NuGet package to your application.
- Use the sample code below.
Sample code
public class UpdateVisitor : IVisitor
{
public void VisitComputer(IComputer computer)
{
computer.Traverse(this);
}
public void VisitHardware(IHardware hardware)
{
hardware.Update();
foreach (IHardware subHardware in hardware.SubHardware) subHardware.Accept(this);
}
public void VisitSensor(ISensor sensor) { }
public void VisitParameter(IParameter parameter) { }
}
public void Monitor()
{
Computer computer = new Computer
{
IsCpuEnabled = true,
IsGpuEnabled = true,
IsMemoryEnabled = true,
IsMotherboardEnabled = true,
IsControllerEnabled = true,
IsNetworkEnabled = true,
IsStorageEnabled = true
};
computer.Open();
computer.Accept(new UpdateVisitor());
foreach (IHardware hardware in computer.Hardware)
{
Console.WriteLine("Hardware: {0}", hardware.Name);
foreach (IHardware subhardware in hardware.SubHardware)
{
Console.WriteLine("\tSubhardware: {0}", subhardware.Name);
foreach (ISensor sensor in subhardware.Sensors)
{
Console.WriteLine("\t\tSensor: {0}, value: {1}", sensor.Name, sensor.Value);
}
}
foreach (ISensor sensor in hardware.Sensors)
{
Console.WriteLine("\tSensor: {0}, value: {1}", sensor.Name, sensor.Value);
}
}
computer.Close();
}
Administrator rights
Some sensors require administrator privileges to access the data. Restart your IDE with admin privileges, or add an app.manifest file to your project with requestedExecutionLevel on requireAdministrator.
Warning
We're not affiliated with librehardwaremonitor.com.
For your safety, please avoid using that site.
License
LibreHardwareMonitor is free and open source software licensed under MPL 2.0. Some parts of LibreHardwareMonitor are licensed under different terms, see THIRD-PARTY-LICENSES.