Fixes for ASUS Crosshair VIII Hero (#540)
This commit is contained in:
@@ -12,25 +12,37 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
{
|
||||
public abstract class EmbeddedController : Hardware
|
||||
{
|
||||
private readonly List<EmbeddedControllerSensor> _sensors;
|
||||
private readonly IReadOnlyList<EmbeddedControllerSource> _sources;
|
||||
private readonly List<Sensor> _sensors;
|
||||
private readonly ushort[] _registers;
|
||||
private readonly byte[] _data;
|
||||
|
||||
protected EmbeddedController(List<EmbeddedControllerSource> sources, ISettings settings) : base("Embedded Controller", new Identifier("lpc", "ec"), settings)
|
||||
{
|
||||
_sources = sources;
|
||||
var indices = new Dictionary<SensorType, int>();
|
||||
foreach (SensorType t in Enum.GetValues(typeof(SensorType)))
|
||||
{
|
||||
indices.Add(t, 0);
|
||||
}
|
||||
|
||||
_sensors = new List<EmbeddedControllerSensor>();
|
||||
foreach (EmbeddedControllerSource s in sources)
|
||||
_sensors = new List<Sensor>();
|
||||
List<ushort> registers = new();
|
||||
foreach (EmbeddedControllerSource s in sources)
|
||||
{
|
||||
int index = indices[s.Type];
|
||||
indices[s.Type] = index + 1;
|
||||
_sensors.Add(new EmbeddedControllerSensor(s, index, this, settings));
|
||||
_sensors.Add(new Sensor(s.Name, index, s.Type, this, settings));
|
||||
for (int i = 0; i < s.Size; ++i)
|
||||
{
|
||||
registers.Add((ushort)(s.Register + i));
|
||||
}
|
||||
|
||||
ActivateSensor(_sensors[_sensors.Count - 1]);
|
||||
}
|
||||
|
||||
_registers = registers.ToArray();
|
||||
_data = new byte[_registers.Length];
|
||||
}
|
||||
|
||||
public override HardwareType HardwareType => HardwareType.EmbeddedController;
|
||||
@@ -47,13 +59,13 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
{
|
||||
sources.AddRange(new EmbeddedControllerSource[]
|
||||
{
|
||||
new("Chipset", 0x3A, SensorType.Temperature, ReadByte),
|
||||
new("CPU", 0x3B, SensorType.Temperature, ReadByte),
|
||||
new("Motherboard", 0x3C, SensorType.Temperature, ReadByte),
|
||||
new("T Sensor", 0x3D, SensorType.Temperature, ReadByte),
|
||||
new("VRM", 0x3E, SensorType.Temperature, ReadByte),
|
||||
new("CPU Opt", 0xB0, SensorType.Fan, ReadWordBE),
|
||||
new("CPU", 0xF4, SensorType.Current, ReadByte)
|
||||
new("Chipset", SensorType.Temperature, 0x003A, 1),
|
||||
new("CPU", SensorType.Temperature, 0x003B, 1),
|
||||
new("Motherboard", SensorType.Temperature, 0x003C, 1),
|
||||
new("T Sensor", SensorType.Temperature, 0x003D, 1, blank: 0xD8),
|
||||
new("VRM", SensorType.Temperature, 0x003E, 1),
|
||||
new("CPU Opt", SensorType.Fan, 0x00B0, 2),
|
||||
new("CPU", SensorType.Current, 0x00F4, 1)
|
||||
});
|
||||
|
||||
break;
|
||||
@@ -65,7 +77,7 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
case Model.ROG_STRIX_X570_E_GAMING:
|
||||
case Model.ROG_CROSSHAIR_VIII_HERO:
|
||||
{
|
||||
sources.Add(new EmbeddedControllerSource("Chipset", 0xB4, SensorType.Fan, ReadWordBE));
|
||||
sources.Add(new EmbeddedControllerSource("Chipset", SensorType.Fan, 0x00B4, 2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -76,7 +88,9 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
case Model.ROG_CROSSHAIR_VIII_DARK_HERO:
|
||||
{
|
||||
// TODO: "why 42?" is a silly question, I know, but still, why? On the serious side, it might be 41.6(6)
|
||||
sources.Add(new EmbeddedControllerSource("Flow Rate", 0xBC, SensorType.Flow, (ecIO, port) => ecIO.ReadWordBE(port) / 42f * 60f));
|
||||
sources.Add(new EmbeddedControllerSource("Flow Rate", SensorType.Flow, 0x00BC, 2, 1.0f / 42f * 60f));
|
||||
sources.Add(new EmbeddedControllerSource("Water In", SensorType.Temperature, 0x0100, 1, blank: 0xD8));
|
||||
sources.Add(new EmbeddedControllerSource("Water Out", SensorType.Temperature, 0x0101, 1, blank: 0xD8));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -95,18 +109,22 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
try
|
||||
{
|
||||
using IEmbeddedControllerIO embeddedControllerIO = AcquireIOInterface();
|
||||
|
||||
foreach (EmbeddedControllerSensor sensor in _sensors)
|
||||
{
|
||||
sensor.Update(embeddedControllerIO);
|
||||
}
|
||||
}
|
||||
catch (WindowsEmbeddedControllerIO.BusMutexLockingFailedException)
|
||||
if (!TryUpdateData())
|
||||
{
|
||||
// just skip this update cycle?
|
||||
return;
|
||||
}
|
||||
|
||||
int readRegister = 0;
|
||||
for (int si = 0; si < _sensors.Count; ++si)
|
||||
{
|
||||
int val = 0;
|
||||
for (int i = 0; i < _sources[si].Size; ++i, ++readRegister)
|
||||
{
|
||||
val = (val << 8) + _data[readRegister];
|
||||
}
|
||||
|
||||
_sensors[si].Value = val != _sources[si].Blank ? val * _sources[si].Factor : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +141,13 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
try
|
||||
{
|
||||
using IEmbeddedControllerIO embeddedControllerIO = AcquireIOInterface();
|
||||
|
||||
ushort[] src = new ushort[0x100];
|
||||
byte[] data = new byte[0x100];
|
||||
for (ushort i = 0; i < src.Length; ++i)
|
||||
{
|
||||
src[i] = i;
|
||||
}
|
||||
embeddedControllerIO.Read(src, data);
|
||||
for (int i = 0; i <= 0xF; ++i)
|
||||
{
|
||||
r.Append(" ");
|
||||
@@ -133,7 +157,7 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
{
|
||||
byte address = (byte)(i << 4 | j);
|
||||
r.Append(" ");
|
||||
r.Append(embeddedControllerIO.ReadByte(address).ToString("X2", CultureInfo.InvariantCulture));
|
||||
r.Append(data[address].ToString("X2", CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
r.AppendLine();
|
||||
@@ -147,38 +171,19 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
return r.ToString();
|
||||
}
|
||||
|
||||
public static float ReadByte(IEmbeddedControllerIO ecIO, byte port)
|
||||
{
|
||||
return ecIO.ReadByte(port);
|
||||
}
|
||||
|
||||
public static float ReadWordLE(IEmbeddedControllerIO ecIO, byte port)
|
||||
{
|
||||
return ecIO.ReadWordLE(port);
|
||||
}
|
||||
|
||||
public static float ReadWordBE(IEmbeddedControllerIO ecIO, byte port)
|
||||
{
|
||||
return ecIO.ReadWordBE(port);
|
||||
}
|
||||
|
||||
protected abstract IEmbeddedControllerIO AcquireIOInterface();
|
||||
|
||||
private class EmbeddedControllerSensor : Sensor
|
||||
private bool TryUpdateData()
|
||||
{
|
||||
readonly byte _port;
|
||||
readonly EmbeddedControllerReader _reader;
|
||||
|
||||
public EmbeddedControllerSensor(EmbeddedControllerSource embeddedControllerSource, int index, EmbeddedController hardware, ISettings settings)
|
||||
: base(embeddedControllerSource.Name, index, embeddedControllerSource.Type, hardware, settings)
|
||||
try
|
||||
{
|
||||
_port = embeddedControllerSource.Port;
|
||||
_reader = embeddedControllerSource.Reader;
|
||||
using IEmbeddedControllerIO embeddedControllerIO = AcquireIOInterface();
|
||||
embeddedControllerIO.Read(_registers, _data);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Update(IEmbeddedControllerIO ecIO)
|
||||
catch (WindowsEmbeddedControllerIO.BusMutexLockingFailedException)
|
||||
{
|
||||
Value = _reader(ecIO, _port);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
{
|
||||
public delegate float EmbeddedControllerReader(IEmbeddedControllerIO ecIO, byte port);
|
||||
public delegate float EmbeddedControllerReader(IEmbeddedControllerIO ecIO, ushort register);
|
||||
}
|
||||
|
||||
@@ -7,17 +7,23 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
{
|
||||
public class EmbeddedControllerSource
|
||||
{
|
||||
public EmbeddedControllerSource(string name, byte port, SensorType type, EmbeddedControllerReader reader)
|
||||
public EmbeddedControllerSource(string name, SensorType type, ushort register, byte size, float factor = 1.0f, uint blank = uint.MaxValue)
|
||||
{
|
||||
Name = name;
|
||||
Port = port;
|
||||
|
||||
Register = register;
|
||||
Size = size;
|
||||
Type = type;
|
||||
Reader = reader;
|
||||
Factor = factor;
|
||||
Blank = blank;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public ushort Register { get; }
|
||||
public byte Size { get; }
|
||||
public float Factor { get; }
|
||||
|
||||
public byte Port { get; }
|
||||
public uint Blank { get; }
|
||||
|
||||
public EmbeddedControllerReader Reader { get; }
|
||||
|
||||
|
||||
@@ -9,14 +9,6 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
{
|
||||
public interface IEmbeddedControllerIO : IDisposable
|
||||
{
|
||||
void WriteByte(byte register, byte value);
|
||||
|
||||
void WriteWord(byte register, ushort value);
|
||||
|
||||
byte ReadByte(byte register);
|
||||
|
||||
ushort ReadWordBE(byte register);
|
||||
|
||||
ushort ReadWordLE(byte register);
|
||||
void Read(ushort[] registers, byte[] data);
|
||||
}
|
||||
}
|
||||
|
||||
+28
-59
@@ -4,6 +4,7 @@
|
||||
// All Rights Reserved.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
@@ -35,30 +36,32 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
}
|
||||
}
|
||||
|
||||
public byte ReadByte(byte register)
|
||||
public void Read(ushort[] registers, byte[] data)
|
||||
{
|
||||
Trace.Assert(registers.Length <= data.Length,
|
||||
"data buffer length has to be greater or equal to the registers array length");
|
||||
|
||||
for (int i = 0; i < registers.Length; ++i)
|
||||
{
|
||||
byte bank = (byte)(registers[i] >> 8);
|
||||
byte index = (byte)(registers[i] & 0xFF);
|
||||
|
||||
SwitchBank(bank);
|
||||
data[i] = ReadByte(index);
|
||||
}
|
||||
SwitchBank(0);
|
||||
}
|
||||
|
||||
private byte ReadByte(byte register)
|
||||
{
|
||||
return ReadLoop<byte>(register, ReadByteOp);
|
||||
}
|
||||
|
||||
public ushort ReadWordLE(byte register)
|
||||
{
|
||||
return ReadLoop<ushort>(register, ReadWordLEOp);
|
||||
}
|
||||
|
||||
public ushort ReadWordBE(byte register)
|
||||
{
|
||||
return ReadLoop<ushort>(register, ReadWordBEOp);
|
||||
}
|
||||
|
||||
public void WriteByte(byte register, byte value)
|
||||
private void WriteByte(byte register, byte value)
|
||||
{
|
||||
WriteLoop(register, value, WriteByteOp);
|
||||
}
|
||||
|
||||
public void WriteWord(byte register, ushort value)
|
||||
{
|
||||
WriteLoop(register, value, WriteWordOp);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -69,6 +72,13 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
}
|
||||
}
|
||||
|
||||
private byte SwitchBank(byte bank)
|
||||
{
|
||||
byte previous = ReadByte(0xFF);
|
||||
WriteByte(0xFF, bank);
|
||||
return previous;
|
||||
}
|
||||
|
||||
private TResult ReadLoop<TResult>(byte register, ReadOp<TResult> op) where TResult : new()
|
||||
{
|
||||
TResult result = new();
|
||||
@@ -182,7 +192,7 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
}
|
||||
|
||||
|
||||
#region Read/Write ops
|
||||
#region Read/Write ops
|
||||
|
||||
protected bool ReadByteOp(byte register, out byte value)
|
||||
{
|
||||
@@ -225,47 +235,6 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
||||
return false;
|
||||
}
|
||||
|
||||
protected bool ReadWordLEOp(byte register, out ushort value)
|
||||
{
|
||||
return ReadWordOp(register, (byte)(register + 1), out value);
|
||||
}
|
||||
|
||||
protected bool ReadWordBEOp(byte register, out ushort value)
|
||||
{
|
||||
return ReadWordOp((byte)(register + 1), register, out value);
|
||||
}
|
||||
|
||||
protected bool ReadWordOp(byte registerLsb, byte registerMsb, out ushort value)
|
||||
{
|
||||
value = 0;
|
||||
|
||||
if (!ReadByteOp(registerLsb, out byte result))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = result;
|
||||
|
||||
if (!ReadByteOp(registerMsb, out result))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value |= (ushort)(result << 8);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool WriteWordOp(byte register, ushort value)
|
||||
{
|
||||
//Byte order: little endia
|
||||
|
||||
byte msb = (byte)(value >> 8);
|
||||
byte lsb = (byte)value;
|
||||
|
||||
return WriteByteOp(register, lsb) && WriteByteOp((byte)(register + 1), msb);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,15 +224,6 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc
|
||||
new TemperatureSourceData(SourceNct67Xxd.PECI_1_CAL, 0),
|
||||
new TemperatureSourceData(SourceNct67Xxd.VIRTUAL_TEMP, 0)
|
||||
});
|
||||
|
||||
if (chip == Chip.NCT6798D)
|
||||
{
|
||||
temperaturesSources.AddRange(new TemperatureSourceData[]
|
||||
{
|
||||
new TemperatureSourceData(SourceNct67Xxd.WATER_IN, 0xC33),
|
||||
new TemperatureSourceData(SourceNct67Xxd.WATER_OUT, 0xC39)
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -990,9 +981,7 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc
|
||||
BYTE_TEMP1 = 27,
|
||||
PECI_0_CAL = 28,
|
||||
PECI_1_CAL = 29,
|
||||
VIRTUAL_TEMP = 31,
|
||||
WATER_IN = 32,
|
||||
WATER_OUT = 33
|
||||
VIRTUAL_TEMP = 31
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
|
||||
@@ -2405,14 +2405,20 @@ namespace LibreHardwareMonitor.Hardware.Motherboard
|
||||
t.Add(new Temperature("PECI 0 Calibrated", 21));
|
||||
t.Add(new Temperature("PECI 1 Calibrated", 22));
|
||||
t.Add(new Temperature("Virtual", 23));
|
||||
t.Add(new Temperature("Water In", 24));
|
||||
t.Add(new Temperature("Water Out", 25));
|
||||
|
||||
for (int i = 0; i < superIO.Fans.Length; i++)
|
||||
f.Add(new Fan("Fan #" + (i + 1), i));
|
||||
string[] fanControlNames = {"Chassis Fan 1", "CPU Fan", "Chassis Fan 2",
|
||||
"Chassis Fan 3", "High Amp Fan", "W_PUMP+", "AIO Pump"};
|
||||
System.Diagnostics.Debug.Assert(fanControlNames.Length == superIO.Fans.Length,
|
||||
string.Format("Expected {0} fan register in the SuperIO chip", fanControlNames.Length));
|
||||
System.Diagnostics.Debug.Assert(superIO.Fans.Length == superIO.Controls.Length,
|
||||
"Expected counts of fan controls and fan speed registers to be equal");
|
||||
|
||||
for (int i = 0; i < fanControlNames.Length; i++)
|
||||
f.Add(new Fan(fanControlNames[i], i));
|
||||
|
||||
for (int i = 0; i < fanControlNames.Length; i++)
|
||||
c.Add(new Ctrl(fanControlNames[i], i));
|
||||
|
||||
for (int i = 0; i < superIO.Controls.Length; i++)
|
||||
c.Add(new Ctrl("Fan Control #" + (i + 1), i));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user