Skip to content

Commit b6ffa29

Browse files
committed
Re-Structure Fan and Control Register Layout for NCT6687DR, Support 10 new MSI Motherboards
* Support for 10 new MSI motherboards with NCT6687D-R SIO controller * Support for newly established fan and control register structure WILL ABSOLUTELY BREAK FAN CONTROL CONFIGS FOR NCT6687DR USERS. This introduces Support for 16 System Fans and Controls, including EZ-Connect, Pump Fan 2, and System Fan 7. Also improved the logic for nct6687dr control.
1 parent 8b28b06 commit b6ffa29

5 files changed

Lines changed: 104 additions & 35 deletions

File tree

OpenHardwareMonitorLib/Hardware/Motherboard/Identification.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,12 +659,20 @@ public static Model GetModel(string name)
659659
return Model.X11SWN_E;
660660
case var _ when name.Equals("PRO B840-P WIFI (MS-7E57)", StringComparison.OrdinalIgnoreCase):
661661
return Model.B840P_PRO_WIFI;
662+
case var _ when name.Equals("B840M GAMING PLUS WIFI6E (MS-7E77)", StringComparison.OrdinalIgnoreCase):
663+
return Model.B840M_GAMING_PLUS_WIFI6E;
662664
case var _ when name.Equals("PRO B850-P WIFI (MS-7E56)", StringComparison.OrdinalIgnoreCase):
663665
return Model.B850P_PRO_WIFI;
664666
case var _ when name.Equals("PRO B850-S WIFI6E (MS-7E80)", StringComparison.OrdinalIgnoreCase):
665667
return Model.B850S_PRO_WIFI6E;
668+
case var _ when name.Equals("PRO B850M-A WIFI (MS-7E66)", StringComparison.OrdinalIgnoreCase):
669+
return Model.B850MA_PRO_WIFI;
670+
case var _ when name.Equals("PRO B850M-P WIFI (MS-7E71)", StringComparison.OrdinalIgnoreCase):
671+
return Model.B850MP_PRO_WIFI;
666672
case var _ when name.Equals("B850 GAMING PLUS WIFI (MS-7E56)", StringComparison.OrdinalIgnoreCase):
667673
return Model.B850_GAMING_PLUS_WIFI;
674+
case var _ when name.Equals("B850 GAMING PLUS WIFI6E (MS-7E80)", StringComparison.OrdinalIgnoreCase):
675+
return Model.B850_GAMING_PLUS_WIFI6E;
668676
case var _ when name.Equals("B850M GAMING PLUS WIFI6E (MS-7E81)", StringComparison.OrdinalIgnoreCase):
669677
return Model.B850M_GAMING_PLUS_WIFI6E;
670678
case var _ when name.Equals("MAG B850M MORTAR WIFI (MS-7E61)", StringComparison.OrdinalIgnoreCase):
@@ -673,8 +681,14 @@ public static Model GetModel(string name)
673681
return Model.B850_TOMAHAWK_MAX_WIFI;
674682
case var _ when name.Equals("MPG B850 EDGE TI WIFI (MS-7E62)", StringComparison.OrdinalIgnoreCase):
675683
return Model.B850_EDGE_TI_WIFI;
684+
case var _ when name.Equals("MPG B850I EDGE TI WIFI (MS-7E79)", StringComparison.OrdinalIgnoreCase):
685+
return Model.B850I_EDGE_TI_WIFI;
686+
case var _ when name.Equals("B850MPOWER (MS-7E83)", StringComparison.OrdinalIgnoreCase):
687+
return Model.B850MPOWER;
676688
case var _ when name.Equals("X870 GAMING PLUS WIFI (MS-7E47)", StringComparison.OrdinalIgnoreCase):
677689
return Model.X870_GAMING_PLUS_WIFI;
690+
case var _ when name.Equals("X870E GAMING PLUS WIFI (MS-7E70)", StringComparison.OrdinalIgnoreCase):
691+
return Model.X870E_GAMING_PLUS_WIFI;
678692
case var _ when name.Equals("MAG X870 TOMAHAWK WIFI (MS-7E51)", StringComparison.OrdinalIgnoreCase):
679693
return Model.X870_TOMAHAWK_WIFI;
680694
case var _ when name.Equals("MAG X870E TOMAHAWK WIFI (MS-7E59)", StringComparison.OrdinalIgnoreCase):
@@ -683,6 +697,8 @@ public static Model GetModel(string name)
683697
return Model.X870E_GODLIKE;
684698
case var _ when name.Equals("PRO X870-P WIFI (MS-7E47)", StringComparison.OrdinalIgnoreCase):
685699
return Model.X870P_PRO_WIFI;
700+
case var _ when name.Equals("PRO X870E-P WIFI (MS-7E70)", StringComparison.OrdinalIgnoreCase):
701+
return Model.X870EP_PRO_WIFI;
686702
case var _ when name.Equals("MPG X870E CARBON WIFI (MS-7E49)", StringComparison.OrdinalIgnoreCase):
687703
return Model.X870E_CARBON_WIFI;
688704
case var _ when name.Equals("MPG X870E EDGE TI WIFI (MS-7E59)", StringComparison.OrdinalIgnoreCase):
@@ -697,6 +713,8 @@ public static Model GetModel(string name)
697713
return Model.Z890_CARBON_WIFI;
698714
case var _ when name.Equals("MPG Z890 EDGE TI WIFI (MS-7E19)", StringComparison.OrdinalIgnoreCase):
699715
return Model.Z890_EDGE_TI_WIFI;
716+
case var _ when name.Equals("MPG Z890I EDGE TI WIFI (MS-7E33)", StringComparison.OrdinalIgnoreCase):
717+
return Model.Z890I_EDGE_TI_WIFI;
700718
case var _ when name.Equals("PRO Z890-P WIFI (MS-7E34)", StringComparison.OrdinalIgnoreCase):
701719
return Model.Z890P_PRO_WIFI;
702720
case var _ when name.Equals("PRO Z890-A WIFI (MS-7E32)", StringComparison.OrdinalIgnoreCase):

OpenHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,27 +395,37 @@ private bool DetectWinbondFintek(LpcPort port, Motherboard motherboard)
395395
switch (motherboard.Model)
396396
{
397397
case Model.B840P_PRO_WIFI:
398+
case Model.B840M_GAMING_PLUS_WIFI6E:
398399
case Model.B850_GAMING_PLUS_WIFI:
400+
case Model.B850_GAMING_PLUS_WIFI6E:
401+
case Model.B850M_GAMING_PLUS_WIFI6E:
399402
case Model.B850P_PRO_WIFI:
403+
case Model.B850MA_PRO_WIFI:
404+
case Model.B850MP_PRO_WIFI:
400405
case Model.B850M_MORTAR_WIFI:
401406
case Model.B850_TOMAHAWK_MAX_WIFI:
402407
case Model.B850_EDGE_TI_WIFI:
408+
case Model.B850I_EDGE_TI_WIFI:
409+
case Model.B850MPOWER:
410+
case Model.B850S_PRO_WIFI6E:
403411
case Model.X870_GAMING_PLUS_WIFI:
412+
case Model.X870E_GAMING_PLUS_WIFI:
404413
case Model.X870_TOMAHAWK_WIFI:
405414
case Model.X870P_PRO_WIFI:
415+
case Model.X870EP_PRO_WIFI:
406416
case Model.X870E_TOMAHAWK_WIFI:
407417
case Model.X870E_CARBON_WIFI:
408418
case Model.X870E_EDGE_TI_WIFI:
409419
case Model.X870E_GODLIKE:
410420
case Model.Z890_ACE:
411421
case Model.Z890_CARBON_WIFI:
422+
case Model.Z890_GAMING_PLUS_WIFI:
412423
case Model.Z890_TOMAHAWK_WIFI:
413424
case Model.Z890_EDGE_TI_WIFI:
425+
case Model.Z890I_EDGE_TI_WIFI:
414426
case Model.Z890P_PRO_WIFI:
415427
case Model.Z890A_PRO_WIFI:
416428
case Model.Z890S_PRO_WIFI:
417-
case Model.B850S_PRO_WIFI6E:
418-
case Model.B850M_GAMING_PLUS_WIFI6E:
419429
chip = Chip.NCT6687DR; // MSI AM5/LGA1851 Compatibility
420430
break;
421431
default:

OpenHardwareMonitorLib/Hardware/Motherboard/Lpc/Nct677X.cs

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,12 @@ public Nct677X(LpcPort lpcPort, Chip chip, byte revision, ushort port)
5757
}
5858
else if (chip is Chip.NCT6687DR) // MSI AM5/LGA1851 Motherboards
5959
{
60-
FAN_PWM_OUT_REG = [0x160, 0x161, 0xE05, 0xE04, 0xE03, 0xE02, 0xE01, 0xE00]; // Duty Cycle Sensors
61-
FAN_PWM_COMMAND_REG = [0xA28, 0xA29, 0xC70, 0xC58, 0xC40, 0xC28, 0xC10, 0xBF8]; // Control Registers for CPU/Pump, Initial Fan Curve Registers for System Fans
62-
FAN_CONTROL_MODE_REG = [0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00];
63-
FAN_PWM_REQUEST_REG = [0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01];
60+
// Each index in the below arrays represents a fan header
61+
// ARRAY_KEY = new ushort[] { CPU FAN, PUMP, CHIPSET, EZ-CONNECT FAN, null, null, null, null, null, SYSFAN7, SYSFAN1, SYSFAN2, SYSFAN3, SYSFAN4, SYSFAN5, SYSFAN6 };
62+
FAN_PWM_OUT_REG = [0x160, 0x161, 0x162, 0x163, 0x164, 0x165, 0x166, 0x167, 0xFFF, 0xC93, 0xE05, 0xE04, 0xE03, 0xE02, 0xE01, 0xE00]; // Duty Cycle Sensors
63+
FAN_PWM_COMMAND_REG = [0xA28, 0xA29, 0xA2A, 0xA2B, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xBE0, 0xC70, 0xC58, 0xC40, 0xC28, 0xC10, 0xBF8]; // Control Registers for CPU/Pump/EZ-Connect Fan, Initial Fan Curve Registers for System Fans
64+
FAN_CONTROL_MODE_REG = [0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00];
65+
FAN_PWM_REQUEST_REG = [0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01];
6466
}
6567
else
6668
{
@@ -477,8 +479,8 @@ public Nct677X(LpcPort lpcPort, Chip chip, byte revision, ushort port)
477479
break;
478480

479481
case Chip.NCT6687DR:
480-
Fans = new float?[8];
481-
Controls = new float?[8];
482+
Fans = new float?[16];
483+
Controls = new float?[16];
482484
Voltages = new float?[14];
483485
Temperatures = new float?[7];
484486

@@ -490,7 +492,7 @@ public Nct677X(LpcPort lpcPort, Chip chip, byte revision, ushort port)
490492
new TemperatureSourceData(null, 0x106), // PCH
491493
new TemperatureSourceData(null, 0x108), // CPU Socket
492494
new TemperatureSourceData(null, 0x10A), // PCIE_1
493-
new TemperatureSourceData(null, 0x10C) // M2_1
495+
new TemperatureSourceData(null, 0x10C) // M2_1
494496
];
495497

496498
// VIN0 +12V
@@ -511,13 +513,21 @@ public Nct677X(LpcPort lpcPort, Chip chip, byte revision, ushort port)
511513

512514
// CPU Fan 0x140
513515
// PUMP Fan 0x142
516+
// Chipset Fan 0x144
517+
// EZ-Conn 0x146
518+
// NOTHING
519+
// NOTHING
520+
// NOTHING
521+
// NOTHING
522+
// NOTHING
523+
// NOTHING
514524
// SYS Fan 1 0x15E
515525
// SYS Fan 2 0x15C
516526
// SYS Fan 3 0x15A
517527
// SYS Fan 4 0x158
518528
// SYS Fan 5 0x156
519529
// SYS Fan 6 0x154
520-
_fanRpmRegister = [0x140, 0x142, 0x15E, 0x15C, 0x15A, 0x158, 0x156, 0x154];
530+
_fanRpmRegister = [0x140, 0x142, 0x144, 0x146, 0x148, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x15E, 0x15C, 0x15A, 0x158, 0x156, 0x154];
521531

522532
_restoreDefaultFanControlRequired = new bool[_fanRpmRegister.Length];
523533
_initialFanControlMode = new byte[_fanRpmRegister.Length];
@@ -594,20 +604,28 @@ public void SetControl(int index, byte? value)
594604
// bit 6 : SYS Fan 5
595605
// bit 7 : SYS Fan 6
596606

597-
byte mode = ReadByte(FAN_CONTROL_MODE_REG[index]);
598-
byte bitMask = (byte)(0x01 << index);
599-
mode = (byte)(mode | bitMask);
600-
WriteByte(FAN_CONTROL_MODE_REG[index], mode);
601-
602607
WriteByte(FAN_PWM_REQUEST_REG[index], 0x80);
603608
Thread.Sleep(50);
604609

605610
if (Chip is Chip.NCT6687DR) // For MSI AM5/LGA1851 NCT6687D functionality
606-
{
611+
{
612+
if (index < 8) // Control fans traditionally if part of the old control scheme. Applies to CPU/Pump/EZ-Conn
613+
{
614+
byte mode = ReadByte(FAN_CONTROL_MODE_REG[index]);
615+
byte bitMask = (byte)(0x01 << index);
616+
mode = (byte)(mode | bitMask);
617+
WriteByte(FAN_CONTROL_MODE_REG[index], mode);
618+
}
619+
607620
Set6687DRControl(index, value.Value);
608621
}
609622
else // All other Nuvoton SIO controllers and motherboards that use NCT6683/6686/6687
610623
{
624+
byte mode = ReadByte(FAN_CONTROL_MODE_REG[index]);
625+
byte bitMask = (byte)(0x01 << index);
626+
mode = (byte)(mode | bitMask);
627+
WriteByte(FAN_CONTROL_MODE_REG[index], mode);
628+
611629
WriteByte(FAN_PWM_COMMAND_REG[index], value.Value);
612630
}
613631

@@ -1127,24 +1145,30 @@ private bool IsNuvotonVendor()
11271145

11281146
private void Set6687DRControl(int index, byte? value)
11291147
{
1130-
if (index > 1) // System Fan Control
1148+
if (index > 8) // Brute Force System Fan Control
11311149
{
1132-
int initFanCurveReg = FAN_PWM_COMMAND_REG[index]; // Initial Register Address for the Fan Curve
1133-
byte currentSpeed = ReadByte(FAN_PWM_OUT_REG[index]); // Current Speed of the target fan
1150+
int initFanCurveReg = FAN_PWM_COMMAND_REG[index]; // Initial Register Address for the Fan Curve
1151+
int targetFanCurveAddr = initFanCurveReg; // Address of the Current Fan Curve Register we're writing to
1152+
ushort targetFanCurveReg; // Integer value of the current fan curve register address, not the value within
1153+
byte currentSpeed = ReadByte(FAN_PWM_OUT_REG[index]); // Current Speed of the target fan
11341154

11351155
// If current fan duty cycle matches requested duty cycle, skip re-writing the fan curve
1136-
if (currentSpeed != value.Value)
1156+
if (currentSpeed == value.Value)
1157+
{
1158+
return;
1159+
}
1160+
else
11371161
{
11381162
// Write 7-point fan curve
11391163
for (int count = 0; count < 14; count += 2)
11401164
{
1141-
int targetFanCurveAddr = initFanCurveReg + count; // Address of the Current Fan Curve Register we're writing to
1142-
ushort targetFanCurveReg = Convert.ToUInt16(targetFanCurveAddr); // Integer value of the current fan curve register address, not the value within
1165+
targetFanCurveAddr = initFanCurveReg+count;
1166+
targetFanCurveReg = Convert.ToUInt16(targetFanCurveAddr);
11431167
WriteByte(targetFanCurveReg, value.Value);
11441168
}
11451169
}
11461170
}
1147-
else // Control CPU and Pump Fan normally
1171+
else // Control CPU, Pump, Chipset, or EZ-Connect Fan normally
11481172
{
11491173
WriteByte(FAN_PWM_COMMAND_REG[index], value.Value);
11501174
}

OpenHardwareMonitorLib/Hardware/Motherboard/Model.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,24 +142,33 @@ public enum Model
142142
X570_MS7C35,
143143
B850M_MORTAR_WIFI,
144144
B850_GAMING_PLUS_WIFI,
145+
B850_GAMING_PLUS_WIFI6E,
145146
B850M_GAMING_PLUS_WIFI6E,
146147
B840P_PRO_WIFI,
148+
B840M_GAMING_PLUS_WIFI6E,
147149
B850_TOMAHAWK_MAX_WIFI,
148150
B650M_PROJECT_ZERO,
149151
B850P_PRO_WIFI,
152+
B850MA_PRO_WIFI,
153+
B850MP_PRO_WIFI,
150154
B850_EDGE_TI_WIFI,
155+
B850I_EDGE_TI_WIFI,
156+
B850MPOWER,
151157
X870_GAMING_PLUS_WIFI,
158+
X870E_GAMING_PLUS_WIFI,
152159
X870_TOMAHAWK_WIFI,
153160
X870E_TOMAHAWK_WIFI,
154161
X870E_GODLIKE,
155162
X870P_PRO_WIFI,
163+
X870EP_PRO_WIFI,
156164
X870E_CARBON_WIFI,
157165
X870E_EDGE_TI_WIFI,
158166
Z790_GODLIKE_MAX,
159167
Z890_ACE,
160168
Z890_TOMAHAWK_WIFI,
161169
Z890_CARBON_WIFI,
162170
Z890_EDGE_TI_WIFI,
171+
Z890I_EDGE_TI_WIFI,
163172
Z890P_PRO_WIFI,
164173
Z890A_PRO_WIFI,
165174
Z890S_PRO_WIFI,

OpenHardwareMonitorLib/Hardware/Motherboard/SuperIOHardware.cs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -631,21 +631,25 @@ private static void GetBoardSpecificConfiguration
631631

632632
f.Add(new Fan("CPU Fan", 0));
633633
f.Add(new Fan("Pump Fan #1", 1));
634-
f.Add(new Fan("System Fan #1", 2));
635-
f.Add(new Fan("System Fan #2", 3));
636-
f.Add(new Fan("System Fan #3", 4));
637-
f.Add(new Fan("System Fan #4", 5));
638-
f.Add(new Fan("System Fan #5", 6));
639-
f.Add(new Fan("System Fan #6", 7));
634+
f.Add(new Fan("Chipset Fan", 2));
635+
f.Add(new Fan("System Fan #1", 10));
636+
f.Add(new Fan("System Fan #2", 11));
637+
f.Add(new Fan("System Fan #3", 12));
638+
f.Add(new Fan("System Fan #4", 13));
639+
f.Add(new Fan("System Fan #5", 14));
640+
f.Add(new Fan("System Fan #6", 15));
641+
f.Add(new Fan("EZ-Connect Fan", 3));
640642

641643
c.Add(new Control("CPU Fan", 0));
642644
c.Add(new Control("Pump Fan", 1));
643-
c.Add(new Control("System Fan #1", 2));
644-
c.Add(new Control("System Fan #2", 3));
645-
c.Add(new Control("System Fan #3", 4));
646-
c.Add(new Control("System Fan #4", 5));
647-
c.Add(new Control("System Fan #5", 6));
648-
c.Add(new Control("System Fan #6", 7));
645+
c.Add(new Control("Chipset Fan", 2));
646+
c.Add(new Control("System Fan #1", 10));
647+
c.Add(new Control("System Fan #2", 11));
648+
c.Add(new Control("System Fan #3", 12));
649+
c.Add(new Control("System Fan #4", 13));
650+
c.Add(new Control("System Fan #5", 14));
651+
c.Add(new Control("System Fan #6", 15));
652+
c.Add(new Control("EZ-Connect Fan", 3));
649653

650654
switch (model)
651655
{
@@ -672,6 +676,9 @@ private static void GetBoardSpecificConfiguration
672676

673677
case Model.X870E_CARBON_WIFI:
674678
case Model.X870E_GODLIKE:
679+
f.Add(new Fan("System Fan #7", 9));
680+
c.Add(new Control("System Fan #7", 9));
681+
675682
v.Add(new Voltage("+12V", 0));
676683
v.Add(new Voltage("+5V", 1));
677684
v.Add(new Voltage("CPU Northbridge/SoC", 2));
@@ -717,6 +724,7 @@ private static void GetBoardSpecificConfiguration
717724
break;
718725

719726
case Model.Z890_EDGE_TI_WIFI:
727+
case Model.Z890I_EDGE_TI_WIFI:
720728
case Model.Z890P_PRO_WIFI:
721729
case Model.Z890A_PRO_WIFI:
722730
case Model.Z890S_PRO_WIFI:

0 commit comments

Comments
 (0)