* Extend ASUS EC detection to other Crosshair VIII models
Tested to work on my CROSSHAIR VIII Dark Hero.
*Should* also work on the Impact, Formula and Extreme boards since they use the same sensors and thereby most likely the same EC.
Alternatively, an extra case with name.Equals("ROG CROSSHAIR VIII DARK HERO", StringComparison.OrdinalIgnoreCase) could be used instead.
* Add ROG_CROSSHAIR_VIII_DARK_HERO model
* minor formatting
* Update EmbeddedController.cs
Co-authored-by: PhyxionNL <7643972+PhyxionNL@users.noreply.github.com>
186 lines
6.5 KiB
C#
186 lines
6.5 KiB
C#
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
// Copyright (C) LibreHardwareMonitor and Contributors.
|
|
// All Rights Reserved.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
|
|
namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC
|
|
{
|
|
public abstract class EmbeddedController : Hardware
|
|
{
|
|
private readonly List<EmbeddedControllerSensor> _sensors;
|
|
|
|
protected EmbeddedController(List<EmbeddedControllerSource> sources, ISettings settings) : base("Embedded Controller", new Identifier("lpc", "ec"), settings)
|
|
{
|
|
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)
|
|
{
|
|
int index = indices[s.Type];
|
|
indices[s.Type] = index + 1;
|
|
_sensors.Add(new EmbeddedControllerSensor(s, index, this, settings));
|
|
|
|
ActivateSensor(_sensors[_sensors.Count - 1]);
|
|
}
|
|
}
|
|
|
|
public override HardwareType HardwareType => HardwareType.EmbeddedController;
|
|
|
|
internal static EmbeddedController Create(Model model, ISettings settings)
|
|
{
|
|
var sources = new List<EmbeddedControllerSource>();
|
|
|
|
switch (model)
|
|
{
|
|
case Model.ROG_STRIX_X570_E_GAMING:
|
|
case Model.ROG_CROSSHAIR_VIII_HERO:
|
|
case Model.ROG_CROSSHAIR_VIII_DARK_HERO:
|
|
{
|
|
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)
|
|
});
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (model)
|
|
{
|
|
case Model.ROG_STRIX_X570_E_GAMING:
|
|
case Model.ROG_CROSSHAIR_VIII_HERO:
|
|
{
|
|
sources.Add(new EmbeddedControllerSource("Chipset", 0xB4, SensorType.Fan, ReadWordBE));
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (model)
|
|
{
|
|
case Model.ROG_CROSSHAIR_VIII_HERO:
|
|
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));
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (sources.Count > 0)
|
|
{
|
|
return Environment.OSVersion.Platform switch
|
|
{
|
|
PlatformID.Win32NT => new WindowsEmbeddedController(sources, settings),
|
|
_ => null
|
|
};
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override void Update()
|
|
{
|
|
try
|
|
{
|
|
using IEmbeddedControllerIO embeddedControllerIO = AcquireIOInterface();
|
|
|
|
foreach (EmbeddedControllerSensor sensor in _sensors)
|
|
{
|
|
sensor.Update(embeddedControllerIO);
|
|
}
|
|
}
|
|
catch (WindowsEmbeddedControllerIO.BusMutexLockingFailedException)
|
|
{
|
|
// just skip this update cycle?
|
|
}
|
|
}
|
|
|
|
public override string GetReport()
|
|
{
|
|
StringBuilder r = new();
|
|
|
|
r.AppendLine("EC " + GetType().Name);
|
|
r.AppendLine("Embedded Controller Registers");
|
|
r.AppendLine();
|
|
r.AppendLine(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
|
|
r.AppendLine();
|
|
|
|
try
|
|
{
|
|
using IEmbeddedControllerIO embeddedControllerIO = AcquireIOInterface();
|
|
|
|
for (int i = 0; i <= 0xF; ++i)
|
|
{
|
|
r.Append(" ");
|
|
r.Append((i << 4).ToString("X2", CultureInfo.InvariantCulture));
|
|
r.Append(" ");
|
|
for (int j = 0; j <= 0xF; ++j)
|
|
{
|
|
byte address = (byte)(i << 4 | j);
|
|
r.Append(" ");
|
|
r.Append(embeddedControllerIO.ReadByte(address).ToString("X2", CultureInfo.InvariantCulture));
|
|
}
|
|
|
|
r.AppendLine();
|
|
}
|
|
}
|
|
catch (WindowsEmbeddedControllerIO.BusMutexLockingFailedException e)
|
|
{
|
|
r.AppendLine(e.Message);
|
|
}
|
|
|
|
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
|
|
{
|
|
readonly byte _port;
|
|
readonly EmbeddedControllerReader _reader;
|
|
|
|
public EmbeddedControllerSensor(EmbeddedControllerSource embeddedControllerSource, int index, EmbeddedController hardware, ISettings settings)
|
|
: base(embeddedControllerSource.Name, index, embeddedControllerSource.Type, hardware, settings)
|
|
{
|
|
_port = embeddedControllerSource.Port;
|
|
_reader = embeddedControllerSource.Reader;
|
|
}
|
|
|
|
public void Update(IEmbeddedControllerIO ecIO)
|
|
{
|
|
Value = _reader(ecIO, _port);
|
|
}
|
|
}
|
|
}
|
|
}
|