Nct677x Make the Debug,WriteLine opt in with a symbol define (#2048)

* Make the Debug,WriteLine opt in with a symbol define

Having all these Debug,WriteLine made the update method painfully slow and the running process laggy during a debug session.

* Update Nct677X.cs

* Update Nct677X.cs

* Update Nct677X.cs

---------

Co-authored-by: PhyxionNL <7643972+PhyxionNL@users.noreply.github.com>
This commit is contained in:
Rémi Mercier
2025-11-18 10:34:05 +01:00
committed by GitHub
co-authored by PhyxionNL
parent 47baee1207
commit 0ed17c77ce
@@ -4,37 +4,20 @@
// Partial Copyright (C) Michael Möller <mmoeller@openhardwaremonitor.org> and Contributors.
// All Rights Reserved.
//#define DEBUG_LOG
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Text;
using System.Threading;
using static System.Net.WebRequestMethods;
namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc;
internal class Nct677X : ISuperIO
{
private readonly struct TemperatureSourceData
{
public TemperatureSourceData(Enum source, ushort register, ushort halfRegister = 0, int halfBit = -1, ushort sourceRegister = 0, ushort? alternateRegister = null)
{
Source = source;
Register = register;
HalfRegister = halfRegister;
HalfBit = halfBit;
SourceRegister = sourceRegister;
AlternateRegister = alternateRegister;
}
public readonly Enum Source;
public readonly ushort Register;
public readonly ushort HalfRegister;
public readonly int HalfBit;
public readonly ushort SourceRegister;
public readonly ushort? AlternateRegister;
}
private readonly ushort[] _fanCountRegister;
private readonly ushort[] _fanRpmRegister;
private readonly byte[] _initialFanControlMode = new byte[7];
@@ -64,25 +47,26 @@ internal class Nct677X : ISuperIO
VENDOR_ID_HIGH_REGISTER = 0x80FE;
VENDOR_ID_LOW_REGISTER = 0x00FE;
FAN_PWM_OUT_REG = new ushort[] { 0x04A, 0x04B, 0x04C };
FAN_PWM_COMMAND_REG = new ushort[] { 0x119, 0x129, 0x139 };
FAN_CONTROL_MODE_REG = new ushort[] { 0x113, 0x123, 0x133 };
FAN_PWM_OUT_REG = [0x04A, 0x04B, 0x04C];
FAN_PWM_COMMAND_REG = [0x119, 0x129, 0x139];
FAN_CONTROL_MODE_REG = [0x113, 0x123, 0x133];
_vBatMonitorControlRegister = 0x0318;
}
else if (chip is Chip.NCT6683D or Chip.NCT6686D or Chip.NCT6687D) //These work on older NCT6687D boards, but only fans 0, 1 and 3 on newer (X870 and Z890) motherboards. Unsure of controls for "next pack of 8".
else if (chip is Chip.NCT6683D or Chip.NCT6686D
or Chip.NCT6687D) //These work on older NCT6687D boards, but only fans 0, 1 and 3 on newer (X870 and Z890) motherboards. Unsure of controls for "next pack of 8".
{
FAN_PWM_OUT_REG = new ushort[] { 0x160, 0x161, 0x162, 0x163, 0x164, 0x165, 0x166, 0x167 }; // Next 8 fans will be 0xE00, 0xE01, 0xE02, 0xE03, 0xE04, 0xE05, 0xE06, 0xE07
FAN_PWM_COMMAND_REG = new ushort[] { 0xA28, 0xA29, 0xA2A, 0xA2B, 0xA2C, 0xA2D, 0xA2E, 0xA2F }; // Possibly 0X260, 0X261, 0X262, 0X263, 0X264, 0X265, 0X266, 0X267 but can't confirm
FAN_CONTROL_MODE_REG = new ushort[] { 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00 }; // Not sure of next 8, MSI won't provide info
FAN_PWM_REQUEST_REG = new ushort[] { 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01 }; // Not sure of next 8, MSI won't provide info
FAN_PWM_OUT_REG = [0x160, 0x161, 0x162, 0x163, 0x164, 0x165, 0x166, 0x167]; // Next 8 fans will be 0xE00, 0xE01, 0xE02, 0xE03, 0xE04, 0xE05, 0xE06, 0xE07
FAN_PWM_COMMAND_REG = [0xA28, 0xA29, 0xA2A, 0xA2B, 0xA2C, 0xA2D, 0xA2E, 0xA2F]; // Possibly 0X260, 0X261, 0X262, 0X263, 0X264, 0X265, 0X266, 0X267 but can't confirm
FAN_CONTROL_MODE_REG = [0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00]; // Not sure of next 8, MSI won't provide info
FAN_PWM_REQUEST_REG = [0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01]; // Not sure of next 8, MSI won't provide info
}
else if (chip is Chip.NCT6687DR) // MSI AM5/LGA1851 Motherboards
{
FAN_PWM_OUT_REG = new ushort[] { 0x160, 0x161, 0xE05, 0xE04, 0xE03, 0xE02, 0xE01, 0xE00 }; // Duty Cycle Sensors
FAN_PWM_COMMAND_REG = new ushort[] { 0xA28, 0xA29, 0xC70, 0xC58, 0xC40, 0xC28, 0xC10, 0xBF8 }; // Control Registers for CPU/Pump, Initial Fan Curve Registers for System Fans
FAN_CONTROL_MODE_REG = new ushort[] { 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00 };
FAN_PWM_REQUEST_REG = new ushort[] { 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01 };
FAN_PWM_OUT_REG = [0x160, 0x161, 0xE05, 0xE04, 0xE03, 0xE02, 0xE01, 0xE00]; // Duty Cycle Sensors
FAN_PWM_COMMAND_REG = [0xA28, 0xA29, 0xC70, 0xC58, 0xC40, 0xC28, 0xC10, 0xBF8]; // Control Registers for CPU/Pump, Initial Fan Curve Registers for System Fans
FAN_CONTROL_MODE_REG = [0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00];
FAN_PWM_REQUEST_REG = [0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01];
}
else
{
@@ -93,8 +77,8 @@ internal class Nct677X : ISuperIO
? new ushort[] { 0x001, 0x003, 0x011, 0x013, 0x015, 0xA09, 0xB09 }
: new ushort[] { 0x001, 0x003, 0x011, 0x013, 0x015, 0x017, 0x029 };
FAN_PWM_COMMAND_REG = new ushort[] { 0x109, 0x209, 0x309, 0x809, 0x909, 0xA09, 0xB09 };
FAN_CONTROL_MODE_REG = new ushort[] { 0x102, 0x202, 0x302, 0x802, 0x902, 0xA02, 0xB02 };
FAN_PWM_COMMAND_REG = [0x109, 0x209, 0x309, 0x809, 0x909, 0xA09, 0xB09];
FAN_CONTROL_MODE_REG = [0x102, 0x202, 0x302, 0x802, 0x902, 0xA02, 0xB02];
_vBatMonitorControlRegister = 0x005D;
}
@@ -130,14 +114,14 @@ internal class Nct677X : ISuperIO
Controls = new float?[3];
Voltages = new float?[9];
_voltageRegisters = new ushort[] { 0x020, 0x021, 0x022, 0x023, 0x024, 0x025, 0x026, 0x550, 0x551 };
_voltageRegisters = [0x020, 0x021, 0x022, 0x023, 0x024, 0x025, 0x026, 0x550, 0x551];
_voltageVBatRegister = 0x551;
_temperaturesSource = new TemperatureSourceData[]
{
new(chip == Chip.NCT6771F ? SourceNct6771F.PECI_0 : SourceNct6776F.PECI_0, 0x027, 0, -1, 0x621),
new(chip == Chip.NCT6771F ? SourceNct6771F.CPUTIN : SourceNct6776F.CPUTIN, 0x073, 0x074, 7, 0x100),
new(chip == Chip.NCT6771F ? SourceNct6771F.AUXTIN : SourceNct6776F.AUXTIN, 0x075, 0x076, 7, 0x200),
new(chip == Chip.NCT6771F ? SourceNct6771F.SYSTIN : SourceNct6776F.SYSTIN, 0x077, 0x078, 7, 0x300),
new(chip == Chip.NCT6771F ? SourceNct6771F.PECI_0 : SourceNct6776F.PECI_0, 0x027, 0, -1, 0x621),
new(chip == Chip.NCT6771F ? SourceNct6771F.CPUTIN : SourceNct6776F.CPUTIN, 0x073, 0x074, 7, 0x100),
new(chip == Chip.NCT6771F ? SourceNct6771F.AUXTIN : SourceNct6776F.AUXTIN, 0x075, 0x076, 7, 0x200),
new(chip == Chip.NCT6771F ? SourceNct6771F.SYSTIN : SourceNct6776F.SYSTIN, 0x077, 0x078, 7, 0x300),
new(null, 0x150, 0x151, 7, 0x622),
new(null, 0x250, 0x251, 7, 0x623),
new(null, 0x62B, 0x62E, 0, 0x624),
@@ -186,7 +170,7 @@ internal class Nct677X : ISuperIO
break;
}
_fanCountRegister = new ushort[] { 0x4B0, 0x4B2, 0x4B4, 0x4B6, 0x4B8, 0x4BA, 0x4CC };
_fanCountRegister = [0x4B0, 0x4B2, 0x4B4, 0x4B6, 0x4B8, 0x4BA, 0x4CC];
// max value for 13-bit fan counter
_maxFanCount = 0x1FFF;
@@ -195,7 +179,7 @@ internal class Nct677X : ISuperIO
_minFanCount = 0x15;
Voltages = new float?[16];
_voltageRegisters = new ushort[] { 0x480, 0x481, 0x482, 0x483, 0x484, 0x485, 0x486, 0x487, 0x488, 0x489, 0x48A, 0x48B, 0x48C, 0x48D, 0x48E, 0x48F };
_voltageRegisters = [0x480, 0x481, 0x482, 0x483, 0x484, 0x485, 0x486, 0x487, 0x488, 0x489, 0x48A, 0x48B, 0x48C, 0x48D, 0x48E, 0x48F];
_voltageVBatRegister = 0x488;
var temperaturesSources = new List<TemperatureSourceData>();
@@ -221,23 +205,24 @@ internal class Nct677X : ISuperIO
new(SourceNct67Xxd.AUXTIN4, 0x027, 0, -1, 0x621),
new(SourceNct67Xxd.PCH_CHIP_CPU_MAX_TEMP, 0x674, 0, -1, 0xC28, 0x400),
new(SourceNct67Xxd.PCH_CHIP_TEMP, 0x676, 0, -1, 0xC29, 0x401),
new(SourceNct67Xxd.PCH_CPU_TEMP, 0x678, 0, -1, 0xC2A, 0x402),
new(SourceNct67Xxd.PCH_CPU_TEMP, 0x678, 0, -1, 0xC2A, 0x402),
new(SourceNct67Xxd.PCH_MCH_TEMP, 0x67A, 0, -1, 0xC2B, 0x404),
new(SourceNct67Xxd.AGENT0_DIMM0, 0x405, 0, -1),
new(SourceNct67Xxd.AGENT0_DIMM1,0x406, 0, -1),
new(SourceNct67Xxd.AGENT1_DIMM0, 0x407, 0, -1),
new(SourceNct67Xxd.AGENT1_DIMM1, 0x408, 0, -1),
new(SourceNct67Xxd.AGENT0_DIMM0, 0x405),
new(SourceNct67Xxd.AGENT0_DIMM1, 0x406),
new(SourceNct67Xxd.AGENT1_DIMM0, 0x407),
new(SourceNct67Xxd.AGENT1_DIMM1, 0x408),
new(SourceNct67Xxd.SMBUSMASTER0, 0x150, 0x151, 7, 0x622),
new(SourceNct67Xxd.SMBUSMASTER1, 0x670, 0, -1, 0xC26),
new(SourceNct67Xxd.PECI_1, 0x672, 0, -1, 0xC27),
new(SourceNct67Xxd.BYTE_TEMP0, 0x419, 0, -1),
new(SourceNct67Xxd.BYTE_TEMP1, 0x41A, 0, -1),
new(SourceNct67Xxd.PECI_0_CAL, 0x4F4, 0, -1),
new(SourceNct67Xxd.PECI_1_CAL, 0x4F5, 0, -1),
new(SourceNct67Xxd.BYTE_TEMP0, 0x419),
new(SourceNct67Xxd.BYTE_TEMP1, 0x41A),
new(SourceNct67Xxd.PECI_0_CAL, 0x4F4),
new(SourceNct67Xxd.PECI_1_CAL, 0x4F5),
new(SourceNct67Xxd.VIRTUAL_TEMP, 0),
new(SourceNct67Xxd.SPARE_TEMP, 0),
new(SourceNct67Xxd.SPARE_TEMP2, 0)
});
break;
case Chip.NCT6798D:
@@ -258,37 +243,40 @@ internal class Nct677X : ISuperIO
new(SourceNct67Xxd.PECI_1, 0x672, 0, -1, 0xC27),
new(SourceNct67Xxd.PCH_CHIP_CPU_MAX_TEMP, 0x674, 0, -1, 0xC28, 0x400),
new(SourceNct67Xxd.PCH_CHIP_TEMP, 0x676, 0, -1, 0xC29, 0x401),
new(SourceNct67Xxd.PCH_CPU_TEMP, 0x678, 0, -1, 0xC2A, 0x402),
new(SourceNct67Xxd.PCH_CPU_TEMP, 0x678, 0, -1, 0xC2A, 0x402),
new(SourceNct67Xxd.PCH_MCH_TEMP, 0x67A, 0, -1, 0xC2B, 0x404),
new(SourceNct67Xxd.AGENT0_DIMM0, 0x405, 0, -1),
new(SourceNct67Xxd.AGENT0_DIMM1,0x406, 0, -1),
new(SourceNct67Xxd.AGENT1_DIMM0, 0x407, 0, -1),
new(SourceNct67Xxd.AGENT1_DIMM1, 0x408, 0, -1),
new(SourceNct67Xxd.BYTE_TEMP0, 0x419, 0, -1),
new(SourceNct67Xxd.BYTE_TEMP1, 0x41A, 0, -1),
new(SourceNct67Xxd.PECI_0_CAL, 0x4F4, 0, -1),
new(SourceNct67Xxd.PECI_1_CAL, 0x4F5, 0, -1),
new(SourceNct67Xxd.AGENT0_DIMM0, 0x405),
new(SourceNct67Xxd.AGENT0_DIMM1, 0x406),
new(SourceNct67Xxd.AGENT1_DIMM0, 0x407),
new(SourceNct67Xxd.AGENT1_DIMM1, 0x408),
new(SourceNct67Xxd.BYTE_TEMP0, 0x419),
new(SourceNct67Xxd.BYTE_TEMP1, 0x41A),
new(SourceNct67Xxd.PECI_0_CAL, 0x4F4),
new(SourceNct67Xxd.PECI_1_CAL, 0x4F5),
new(SourceNct67Xxd.VIRTUAL_TEMP, 0),
new(SourceNct67Xxd.SPARE_TEMP, 0),
new(SourceNct67Xxd.SPARE_TEMP2, 0)
});
break;
case Chip.NCT6796DS:
temperaturesSources.AddRange(new TemperatureSourceData[]
{//https://github.com/LibreHardwareMonitor/LibreHardwareMonitor/pull/2012
new(SourceNct67Xxd.CPUTIN, 0x073, 0x074, 7, 0x100, 0x491),
new(SourceNct67Xxd.SYSTIN, 0x075, 0x076, 7, 0x200, 0x490),
{
//https://github.com/LibreHardwareMonitor/LibreHardwareMonitor/pull/2012
new(SourceNct67Xxd.CPUTIN, 0x073, 0x074, 7, 0x100, 0x491),
new(SourceNct67Xxd.SYSTIN, 0x075, 0x076, 7, 0x200, 0x490),
new(SourceNct67Xxd.AUXTIN0, 0x077, 0x078, 7, 0x300, 0x492),
new(SourceNct67Xxd.AUXTIN1, 0x079, 0x07A, 7, 0x800, 0x493),
new(SourceNct67Xxd.AUXTIN2, 0x07B, 0x07C, 7, 0x900, 0x494),
new(SourceNct67Xxd.AUXTIN3, 0x07D, 0x07E, 7, 0xA00, 0x495),
new(SourceNct67Xxd.AUXTIN4, 0x027, 0, 4,0xC16 ,0x496),
new(SourceNct67Xxd.AUXTIN4, 0x027, 0, 4, 0xC16, 0x496),
new(SourceNct67Xxd.AUXTIN5, 0x449, 0, 4, 0x100, 0x4A2),
new(SourceNct67Xxd.SMBUSMASTER0, 0x150, 0x151, 7, 0x622),
new(SourceNct67Xxd.PECI_0, 0x0720, 0, -1, 0),
new(SourceNct67Xxd.PECI_0, 0x0720),
new(SourceNct67Xxd.VIRTUAL_TEMP, 0)
});
break;
case Chip.NCT5585D:
@@ -299,6 +287,7 @@ internal class Nct677X : ISuperIO
new(SourceNct67Xxd.AUXTIN1, 0x07B, 0x07C, 7, 0x900, 0x493),
new(SourceNct67Xxd.AUXTIN3, 0x4A0, 0x49E, 6, 0xB00, 0x495),
});
break;
default:
@@ -312,6 +301,7 @@ internal class Nct677X : ISuperIO
new(SourceNct67Xxd.AUXTIN2, 0x07B, 0x07C, 7, 0x900, 0x494),
new(SourceNct67Xxd.AUXTIN3, 0x150, 0x151, 7, 0x622, 0x495)
});
break;
}
@@ -331,18 +321,20 @@ internal class Nct677X : ISuperIO
_minFanRpm = (int)(1.35e6 / 0x1FFF);
Voltages = new float?[9];
_voltageRegisters = new ushort[] { 0x300, 0x301, 0x302, 0x303, 0x304, 0x305, 0x307, 0x308, 0x309 };
_voltageRegisters = [0x300, 0x301, 0x302, 0x303, 0x304, 0x305, 0x307, 0x308, 0x309];
_voltageVBatRegister = 0x308;
Temperatures = new float?[7];
_temperaturesSource = new TemperatureSourceData[] {
new(SourceNct610X.PECI_0, 0x06b, 0, -1, 0x621),
new(SourceNct610X.AUXTIN, 0x010, 0x016, 0),
new(SourceNct610X.CPUTIN, 0x011, 0x01B, 1),
new(SourceNct610X.SYSTIN0, 0x012, 0x01B, 2),
new(SourceNct610X.SYSTIN1, 0x013, 0x016, 3),
new(SourceNct610X.SYSTIN2, 0x014, 0x01B, 4),
new(SourceNct610X.SYSTIN3, 0x015, 0x01B, 5)
};
_temperaturesSource =
[
new TemperatureSourceData(SourceNct610X.PECI_0, 0x06b, 0, -1, 0x621),
new TemperatureSourceData(SourceNct610X.AUXTIN, 0x010, 0x016, 0),
new TemperatureSourceData(SourceNct610X.CPUTIN, 0x011, 0x01B, 1),
new TemperatureSourceData(SourceNct610X.SYSTIN0, 0x012, 0x01B, 2),
new TemperatureSourceData(SourceNct610X.SYSTIN1, 0x013, 0x016, 3),
new TemperatureSourceData(SourceNct610X.SYSTIN2, 0x014, 0x01B, 4),
new TemperatureSourceData(SourceNct610X.SYSTIN3, 0x015, 0x01B, 5)
];
break;
case Chip.NCT6683D:
@@ -364,19 +356,20 @@ internal class Nct677X : ISuperIO
// PCIE_2
// M2_1
// M2_4
_temperaturesSource = new TemperatureSourceData[] {
new(null, 0x100),
new(null, 0x102),
new(null, 0x104),
new(null, 0x106),
new(null, 0x108),
new(null, 0x10A),
new(null, 0x10C),
new(null, 0x10E),
new(null, 0x110),
new(null, 0x112),
new(null, 0x114)
};
_temperaturesSource =
[
new TemperatureSourceData(null, 0x100),
new TemperatureSourceData(null, 0x102),
new TemperatureSourceData(null, 0x104),
new TemperatureSourceData(null, 0x106),
new TemperatureSourceData(null, 0x108),
new TemperatureSourceData(null, 0x10A),
new TemperatureSourceData(null, 0x10C),
new TemperatureSourceData(null, 0x10E),
new TemperatureSourceData(null, 0x110),
new TemperatureSourceData(null, 0x112),
new TemperatureSourceData(null, 0x114)
];
// VIN0 +12V
// VIN1 +5V
@@ -392,7 +385,7 @@ internal class Nct677X : ISuperIO
// SIO VSB
// SIO AVSB
// SIO VBAT
_voltageRegisters = new ushort[] { 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x13A, 0x13E, 0x136, 0x138, 0x13C };
_voltageRegisters = [0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x13A, 0x13E, 0x136, 0x138, 0x13C];
// CPU Fan
// PUMP Fan
@@ -408,7 +401,7 @@ internal class Nct677X : ISuperIO
// SYS Fan 3 on newer NCT6687Ds
// SYS Fan 2 on newer NCT6687Ds
// SYS Fan 1 on newer NCT6687Ds
_fanRpmRegister = new ushort[] { 0x140, 0x142, 0x144, 0x146, 0x148, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E };
_fanRpmRegister = [0x140, 0x142, 0x144, 0x146, 0x148, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E];
_restoreDefaultFanControlRequired = new bool[_fanRpmRegister.Length];
_initialFanControlMode = new byte[_fanRpmRegister.Length];
@@ -436,15 +429,16 @@ internal class Nct677X : ISuperIO
Voltages = new float?[14];
Temperatures = new float?[7];
_temperaturesSource = new TemperatureSourceData[] {
new(null, 0x100), // CPU
new(null, 0x102), // System
new(null, 0x104), // MOS
new(null, 0x106), // PCH
new(null, 0x108), // CPU Socket
new(null, 0x10A), // PCIE_1
new(null, 0x10C) // M2_1
};
_temperaturesSource =
[
new TemperatureSourceData(null, 0x100), // CPU
new TemperatureSourceData(null, 0x102), // System
new TemperatureSourceData(null, 0x104), // MOS
new TemperatureSourceData(null, 0x106), // PCH
new TemperatureSourceData(null, 0x108), // CPU Socket
new TemperatureSourceData(null, 0x10A), // PCIE_1
new TemperatureSourceData(null, 0x10C) // M2_1
];
// VIN0 +12V
// VIN1 +5V
@@ -460,7 +454,7 @@ internal class Nct677X : ISuperIO
// SIO VSB
// SIO AVSB
// SIO VBAT
_voltageRegisters = new ushort[] { 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x13A, 0x13E, 0x136, 0x138, 0x13C };
_voltageRegisters = [0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x13A, 0x13E, 0x136, 0x138, 0x13C];
// CPU Fan 0x140
// PUMP Fan 0x142
@@ -470,7 +464,7 @@ internal class Nct677X : ISuperIO
// SYS Fan 4 0x158
// SYS Fan 5 0x156
// SYS Fan 6 0x154
_fanRpmRegister = new ushort[] { 0x140, 0x142, 0x15E, 0x15C, 0x15A, 0x158, 0x156, 0x154 };
_fanRpmRegister = [0x140, 0x142, 0x15E, 0x15C, 0x15A, 0x158, 0x156, 0x154];
_restoreDefaultFanControlRequired = new bool[_fanRpmRegister.Length];
_initialFanControlMode = new byte[_fanRpmRegister.Length];
@@ -616,7 +610,7 @@ internal class Nct677X : ISuperIO
}
}
System.Diagnostics.Debug.WriteLine("Updating temperatures.");
Log("Updating temperatures.");
long temperatureSourceMask = 0;
for (int i = 0; i < _temperaturesSource.Length; i++)
{
@@ -629,7 +623,7 @@ internal class Nct677X : ISuperIO
{
case Chip.NCT610XD:
value = (sbyte)ReadByte(ts.Register);
int half = (ReadByte((ushort)(ts.HalfRegister)) >> ts.HalfBit) & 0x1;
int half = (ReadByte(ts.HalfRegister) >> ts.HalfBit) & 0x1;
temperature = value + (0.5f * half);
Temperatures[i] = temperature;
break;
@@ -652,47 +646,47 @@ internal class Nct677X : ISuperIO
case Chip.NCT5585D:
if (_temperaturesSource[i].Register == 0)
{
System.Diagnostics.Debug.WriteLine("Temperature register {0} skipped, address 0.", i);
Log("Temperature register {0} skipped, address 0.", i);
continue;
}
value = (sbyte)ReadByte(_temperaturesSource[i].Register) << 1;
System.Diagnostics.Debug.WriteLine("Temperature register {0} at 0x{1:X3} value (integer): {2}/2", i, ts.Register, value);
Log("Temperature register {0} at 0x{1:X3} value (integer): {2}/2", i, ts.Register, value);
if (_temperaturesSource[i].HalfBit > 0)
{
value |= (ReadByte(_temperaturesSource[i].HalfRegister) >> ts.HalfBit) & 0x1;
System.Diagnostics.Debug.WriteLine("Temperature register {0} value updated from 0x{1:X3} (fractional): {2}/2", i, ts.HalfRegister, value);
Log("Temperature register {0} value updated from 0x{1:X3} (fractional): {2}/2", i, ts.HalfRegister, value);
}
if (ts.SourceRegister > 0)
{
source = (SourceNct67Xxd)(ReadByte(ts.SourceRegister) & 0x1F);
System.Diagnostics.Debug.WriteLine("Temperature register {0} source at 0x{1:X3}: {2:G} ({2:D})", i, ts.SourceRegister, source);
Log("Temperature register {0} source at 0x{1:X3}: {2:G} ({2:D})", i, ts.SourceRegister, source);
}
else
{
source = (SourceNct67Xxd)ts.Source;
System.Diagnostics.Debug.WriteLine("Temperature register {0} source register is 0, source set to: {1:G} ({1:D})", i, source);
Log("Temperature register {0} source register is 0, source set to: {1:G} ({1:D})", i, source);
}
// Skip reading when already filled, because later values are without fractional
if ((temperatureSourceMask & (1L << (byte)source)) > 0)
{
System.Diagnostics.Debug.WriteLine("Temperature register {0} discarded, because source seen before.", i);
Log("Temperature register {0} discarded, because source seen before.", i);
continue;
}
temperature = 0.5f * value;
System.Diagnostics.Debug.WriteLine("Temperature register {0} final temperature: {1}.", i, temperature);
Log("Temperature register {0} final temperature: {1}.", i, temperature);
if (temperature is > 125 or < -55)
{
temperature = null;
System.Diagnostics.Debug.WriteLine("Temperature register {0} discarded: Out of range.", i);
Log("Temperature register {0} discarded: Out of range.", i);
}
else
{
temperatureSourceMask |= 1L << (byte)source;
System.Diagnostics.Debug.WriteLine("Temperature register {0} accepted.", i);
Log("Temperature register {0} accepted.", i);
}
for (int j = 0; j < Temperatures.Length; j++)
@@ -700,9 +694,10 @@ internal class Nct677X : ISuperIO
if ((SourceNct67Xxd)_temperaturesSource[j].Source == source)
{
Temperatures[j] = temperature;
System.Diagnostics.Debug.WriteLine("Temperature register {0}, value from source {1:G} ({1:D}), written at position {2}.", i, _temperaturesSource[j].Source, j);
Log("Temperature register {0}, value from source {1:G} ({1:D}), written at position {2}.", i, _temperaturesSource[j].Source, j);
}
}
break;
default:
@@ -724,6 +719,7 @@ internal class Nct677X : ISuperIO
if ((SourceNct67Xxd)_temperaturesSource[j].Source == source)
Temperatures[j] = temperature;
}
break;
}
}
@@ -733,23 +729,23 @@ internal class Nct677X : ISuperIO
TemperatureSourceData ts = _temperaturesSource[i];
if (!ts.AlternateRegister.HasValue)
{
System.Diagnostics.Debug.WriteLine("Alternate temperature register for temperature {0}, {1:G} ({1:D}), skipped, because address is null.", i, ts.Source);
Log("Alternate temperature register for temperature {0}, {1:G} ({1:D}), skipped, because address is null.", i, ts.Source);
continue;
}
if ((temperatureSourceMask & (1L << (byte)(SourceNct67Xxd)ts.Source)) > 0)
{
System.Diagnostics.Debug.WriteLine("Alternate temperature register for temperature {0}, {1:G} ({1:D}), at 0x{2:X3} skipped, because value already set.", i, ts.Source, ts.AlternateRegister.Value);
Log("Alternate temperature register for temperature {0}, {1:G} ({1:D}), at 0x{2:X3} skipped, because value already set.", i, ts.Source, ts.AlternateRegister.Value);
continue;
}
float? temperature = (sbyte)ReadByte(ts.AlternateRegister.Value);
System.Diagnostics.Debug.WriteLine("Alternate temperature register for temperature {0}, {1:G} ({1:D}), at 0x{2:X3} final temperature: {3}.", i, ts.Source, ts.AlternateRegister.Value, temperature);
Log("Alternate temperature register for temperature {0}, {1:G} ({1:D}), at 0x{2:X3} final temperature: {3}.", i, ts.Source, ts.AlternateRegister.Value, temperature);
if (temperature is > 125 or <= 0)
{
temperature = null;
System.Diagnostics.Debug.WriteLine("Alternate Temperature register for temperature {0}, {1:G} ({1:D}), discarded: Out of range.", i, ts.Source);
Log("Alternate Temperature register for temperature {0}, {1:G} ({1:D}), discarded: Out of range.", i, ts.Source);
}
Temperatures[i] = temperature;
@@ -1058,7 +1054,7 @@ internal class Nct677X : ISuperIO
if (access == EC_SPACE_PAGE_SELECT || DateTime.UtcNow > timeout)
break;
System.Threading.Thread.Sleep(1);
Thread.Sleep(1);
}
if (access != EC_SPACE_PAGE_SELECT)
@@ -1078,30 +1074,25 @@ internal class Nct677X : ISuperIO
private bool IsNuvotonVendor()
{
return Chip is Chip.NCT6683D or Chip.NCT6686D or Chip.NCT6687D or Chip.NCT6687DR or Chip.NCT6701D || ((ReadByte(VENDOR_ID_HIGH_REGISTER) << 8) | ReadByte(VENDOR_ID_LOW_REGISTER)) == NUVOTON_VENDOR_ID;
return Chip is Chip.NCT6683D or Chip.NCT6686D or Chip.NCT6687D or Chip.NCT6687DR or Chip.NCT6701D ||
((ReadByte(VENDOR_ID_HIGH_REGISTER) << 8) | ReadByte(VENDOR_ID_LOW_REGISTER)) == NUVOTON_VENDOR_ID;
}
private void Set6687DRControl(int index, byte? value)
{
if (index > 1) // System Fan Control
{
int initFanCurveReg = FAN_PWM_COMMAND_REG[index]; // Initial Register Address for the Fan Curve
int targetFanCurveAddr = initFanCurveReg; // Address of the Current Fan Curve Register we're writing to
ushort targetFanCurveReg; // Integer value of the current fan curve register address, not the value within
byte currentSpeed = ReadByte(FAN_PWM_OUT_REG[index]); // Current Speed of the target fan
int initFanCurveReg = FAN_PWM_COMMAND_REG[index]; // Initial Register Address for the Fan Curve
byte currentSpeed = ReadByte(FAN_PWM_OUT_REG[index]); // Current Speed of the target fan
// If current fan duty cycle matches requested duty cycle, skip re-writing the fan curve
if (currentSpeed == value.Value)
{
return;
}
else
if (currentSpeed != value.Value)
{
// Write 7-point fan curve
for (int count = 0; count < 14; count += 2)
{
targetFanCurveAddr = initFanCurveReg+count;
targetFanCurveReg = Convert.ToUInt16(targetFanCurveAddr);
int targetFanCurveAddr = initFanCurveReg + count; // Address of the Current Fan Curve Register we're writing to
ushort targetFanCurveReg = Convert.ToUInt16(targetFanCurveAddr); // Integer value of the current fan curve register address, not the value within
WriteByte(targetFanCurveReg, value.Value);
}
}
@@ -1150,10 +1141,14 @@ internal class Nct677X : ISuperIO
WriteByte(FAN_PWM_REQUEST_REG[index], 0x80);
Thread.Sleep(50);
if (Chip is Chip.NCT6687DR) { // for MSI AM5/LGA1851 boards using NCT6687D
if (Chip is Chip.NCT6687DR)
{
// for MSI AM5/LGA1851 boards using NCT6687D
Set6687DRControl(index, _initialFanPwmCommand[index]);
}
else { // All other motherboards that use NCT6683/6686/6687
else
{
// All other motherboards that use NCT6683/6686/6687
WriteByte(FAN_PWM_COMMAND_REG[index], _initialFanPwmCommand[index]);
}
@@ -1192,6 +1187,22 @@ internal class Nct677X : ISuperIO
_lpcPort.WinbondNuvotonFintekExit();
}
[Conditional("DEBUG_LOG")]
private static void Log(string format, params object[] args)
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, format, args));
}
private readonly struct TemperatureSourceData(Enum source, ushort register, ushort halfRegister = 0, int halfBit = -1, ushort sourceRegister = 0, ushort? alternateRegister = null)
{
public readonly Enum Source = source;
public readonly ushort Register = register;
public readonly ushort HalfRegister = halfRegister;
public readonly int HalfBit = halfBit;
public readonly ushort SourceRegister = sourceRegister;
public readonly ushort? AlternateRegister = alternateRegister;
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
private enum SourceNct6771F : byte
{