RAMSPDToolkit Update + timings added (#1835)
* Workaround for page changing on DDR5 systems with SPD Write Protection active has been implemented in new version of RAMSPDToolkit. Code for LHM has been adjusted accordingly. Added more sensors (timings). * Move abbreviation of timings to start of string. * Simplify names for timings. * Update version. * Remove extra padding.
This commit is contained in:
@@ -646,6 +646,9 @@ public class SensorGadget : Gadget
|
||||
case SensorType.TimeSpan:
|
||||
format = "{0:g}";
|
||||
break;
|
||||
case SensorType.Timing:
|
||||
format = "{0:F3} ns";
|
||||
break;
|
||||
case SensorType.Energy:
|
||||
format = "{0:F0} mWh";
|
||||
break;
|
||||
|
||||
@@ -76,6 +76,9 @@ public class SensorNode : Node
|
||||
case SensorType.TimeSpan:
|
||||
Format = "{0:g}";
|
||||
break;
|
||||
case SensorType.Timing:
|
||||
Format = "{0:F3} ns";
|
||||
break;
|
||||
case SensorType.Energy:
|
||||
Format = "{0:F0} mWh";
|
||||
break;
|
||||
|
||||
@@ -165,6 +165,8 @@ public class SensorNotifyIcon : IDisposable
|
||||
return _unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit ? $"{UnitManager.CelsiusToFahrenheit(Sensor.Value):F0}" : $"{Sensor.Value:F0}";
|
||||
case SensorType.TimeSpan:
|
||||
return $"{TimeSpan.FromSeconds(Sensor.Value.Value):g}";
|
||||
case SensorType.Timing:
|
||||
return $"{Sensor.Value.Value:F3}";
|
||||
case SensorType.Clock:
|
||||
case SensorType.Fan:
|
||||
case SensorType.Flow:
|
||||
@@ -289,6 +291,7 @@ public class SensorNotifyIcon : IDisposable
|
||||
case SensorType.Noise: format = "\n{0}: {0:F0} dBA"; break;
|
||||
case SensorType.Conductivity: format = "\n{0}: {0:F1} µS/cm"; break;
|
||||
case SensorType.Humidity: format = "\n{0}: {0:F0} %"; break;
|
||||
case SensorType.Timing: format = "\n{0}: {0:F3} ns"; break;
|
||||
}
|
||||
|
||||
string formattedValue = string.Format(format, Sensor.Name, Sensor.Value);
|
||||
|
||||
@@ -91,6 +91,10 @@ public sealed class TypeNode : Node, IExpandPersistNode
|
||||
Image = Utilities.EmbeddedResources.GetImage("time.png");
|
||||
Text = "Times";
|
||||
break;
|
||||
case SensorType.Timing:
|
||||
Image = Utilities.EmbeddedResources.GetImage("time.png");
|
||||
Text = "Timings";
|
||||
break;
|
||||
case SensorType.Noise:
|
||||
Image = Utilities.EmbeddedResources.GetImage("loudspeaker.png");
|
||||
Text = "Noise Levels";
|
||||
|
||||
@@ -29,7 +29,8 @@ public enum SensorType
|
||||
Data, // GB = 2^30 Bytes
|
||||
SmallData, // MB = 2^20 Bytes
|
||||
Throughput, // B/s
|
||||
TimeSpan, // Seconds
|
||||
TimeSpan, // Seconds
|
||||
Timing, // ns
|
||||
Energy, // milliwatt-hour (mWh)
|
||||
Noise, // dBA
|
||||
Conductivity, // µS/cm
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
using LibreHardwareMonitor.Hardware.Memory.Sensors;
|
||||
using RAMSPDToolkit.SPD;
|
||||
using RAMSPDToolkit.SPD.Enums;
|
||||
using RAMSPDToolkit.SPD.Interfaces;
|
||||
using RAMSPDToolkit.SPD.Interop.Shared;
|
||||
|
||||
@@ -19,40 +18,36 @@ internal sealed class DimmMemory : Hardware
|
||||
public DimmMemory(SPDAccessor accessor, string name, Identifier identifier, ISettings settings)
|
||||
: base(name, identifier, settings)
|
||||
{
|
||||
//Check which kind of RAM we have
|
||||
switch (accessor.MemoryType())
|
||||
//Only add thermal sensor if present
|
||||
if (accessor is IThermalSensor ts && ts.HasThermalSensor)
|
||||
{
|
||||
case SPDMemoryType.SPD_DDR4_SDRAM:
|
||||
case SPDMemoryType.SPD_DDR4E_SDRAM:
|
||||
case SPDMemoryType.SPD_LPDDR4_SDRAM:
|
||||
case SPDMemoryType.SPD_LPDDR4X_SDRAM:
|
||||
_thermalSensor = new SpdThermalSensor($"DIMM #{accessor.Index}",
|
||||
accessor.Index,
|
||||
SensorType.Temperature,
|
||||
this,
|
||||
settings,
|
||||
accessor as IThermalSensor);
|
||||
|
||||
break;
|
||||
case SPDMemoryType.SPD_DDR5_SDRAM:
|
||||
case SPDMemoryType.SPD_LPDDR5_SDRAM:
|
||||
//Check if we are on correct page or if write protection is not enabled
|
||||
if (accessor.PageData.HasFlag(PageData.ThermalData) || !accessor.HasSPDWriteProtection)
|
||||
{
|
||||
//Check which kind of RAM we have
|
||||
switch (accessor.MemoryType())
|
||||
{
|
||||
case SPDMemoryType.SPD_DDR4_SDRAM:
|
||||
case SPDMemoryType.SPD_DDR4E_SDRAM:
|
||||
case SPDMemoryType.SPD_LPDDR4_SDRAM:
|
||||
case SPDMemoryType.SPD_LPDDR4X_SDRAM:
|
||||
case SPDMemoryType.SPD_DDR5_SDRAM:
|
||||
case SPDMemoryType.SPD_LPDDR5_SDRAM:
|
||||
_thermalSensor = new SpdThermalSensor($"DIMM #{accessor.Index}",
|
||||
accessor.Index,
|
||||
SensorType.Temperature,
|
||||
this,
|
||||
settings,
|
||||
accessor as IThermalSensor);
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool hasThermalSensor = _thermalSensor != null;
|
||||
|
||||
//Add thermal sensor
|
||||
if (_thermalSensor != null)
|
||||
if (hasThermalSensor)
|
||||
ActivateSensor(_thermalSensor);
|
||||
|
||||
//Add other sensors
|
||||
CreateSensors(accessor, hasThermalSensor);
|
||||
}
|
||||
|
||||
public override HardwareType HardwareType => HardwareType.Memory;
|
||||
@@ -61,4 +56,80 @@ internal sealed class DimmMemory : Hardware
|
||||
{
|
||||
_thermalSensor?.UpdateSensor();
|
||||
}
|
||||
|
||||
private void CreateSensors(SPDAccessor accessor, bool hasThermalSensor)
|
||||
{
|
||||
if (accessor is DDR4Accessor ddr4)
|
||||
{
|
||||
CreateSensorsDDR4(ddr4, hasThermalSensor);
|
||||
}
|
||||
else if (accessor is DDR5Accessor ddr5)
|
||||
{
|
||||
CreateSensorsDDR5(ddr5, hasThermalSensor);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateSensorsDDR4(DDR4Accessor accessor, bool hasThermalSensor)
|
||||
{
|
||||
if (hasThermalSensor)
|
||||
{
|
||||
//Temperature Resolution (fixed value)
|
||||
AddSensor("Temperature Sensor Resolution", 0, false, SensorType.Temperature, accessor.TemperatureResolution);
|
||||
}
|
||||
|
||||
//Timings
|
||||
AddSensor("tCKAVGmin (Minimum Cycle Time)", 1, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumCycleTime);
|
||||
AddSensor("tCKAVGmax (Maximum Cycle Time)", 2, false, SensorType.Timing, (float)accessor.SDRAMTimings.MaximumCycleTime);
|
||||
AddSensor("tAA (CAS Latency Time)", 3, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumCASLatencyTime);
|
||||
AddSensor("tRCD (RAS to CAS Delay Time)", 4, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumRASToCASDelayTime);
|
||||
AddSensor("tRP (Row Precharge Delay Time)", 5, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumRowPrechargeDelayTime);
|
||||
AddSensor("tRAS (Active to Precharge Delay Time)", 6, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumActiveToPrechargeDelayTime);
|
||||
AddSensor("tRC (Active to Active/Refresh Delay Time)", 7, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumActiveToActiveRefreshDelayTime);
|
||||
AddSensor("tRFC1 (Refresh Recovery Delay Time)", 8, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumRefreshRecoveryDelayTime1);
|
||||
AddSensor("tRFC2 (Refresh Recovery Delay Time)", 9, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumRefreshRecoveryDelayTime2);
|
||||
AddSensor("tRFC4 (Refresh Recovery Delay Time)", 10, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumRefreshRecoveryDelayTime4);
|
||||
AddSensor("tFAW (Four Activate Window Time)", 11, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumFourActivateWindowTime);
|
||||
AddSensor("tRRD_S (Activate to Activate Delay Time)", 12, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumActivateToActivateDelay_DiffGroup);
|
||||
AddSensor("tRRD_L (Activate to Activate Delay Time)", 13, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumActivateToActivateDelay_SameGroup);
|
||||
AddSensor("tCCD_L (CAS to CAS Delay Time)", 14, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumCASToCASDelay_SameGroup);
|
||||
AddSensor("tWR (Write Recovery Time)", 15, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumWriteRecoveryTime);
|
||||
AddSensor("tWTR_S (Write to Read Time)", 16, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumWriteToReadTime_DiffGroup);
|
||||
AddSensor("tWTR_L (Write to Read Time)", 17, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumWriteToReadTime_SameGroup);
|
||||
|
||||
}
|
||||
|
||||
private void CreateSensorsDDR5(DDR5Accessor accessor, bool hasThermalSensor)
|
||||
{
|
||||
if (hasThermalSensor)
|
||||
{
|
||||
//Temperature Resolution (fixed value)
|
||||
AddSensor("Temperature Sensor Resolution", 0, false, SensorType.Temperature, accessor.TemperatureResolution);
|
||||
}
|
||||
|
||||
//Timings
|
||||
AddSensor("tCKAVGmin (Minimum Cycle Time)", 1, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumCycleTime);
|
||||
AddSensor("tCKAVGmax (Maximum Cycle Time)", 2, false, SensorType.Timing, (float)accessor.SDRAMTimings.MaximumCycleTime);
|
||||
AddSensor("tAA (CAS Latency Time)", 3, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumCASLatencyTime);
|
||||
AddSensor("tRCD (RAS to CAS Delay Time)", 4, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumRASToCASDelayTime);
|
||||
AddSensor("tRP (Row Precharge Delay Time)", 5, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumRowPrechargeDelayTime);
|
||||
AddSensor("tRAS (Active to Precharge Delay Time)", 6, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumActiveToPrechargeDelayTime);
|
||||
AddSensor("tRC (Active to Active/Refresh Delay Time)", 7, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumActiveToActiveRefreshDelayTime);
|
||||
AddSensor("tWR (Write Recovery Time)", 8, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumWriteRecoveryTime);
|
||||
AddSensor("tRFC1 (Normal Refresh Recovery Time)", 9, false, SensorType.Timing, (float)accessor.SDRAMTimings.NormalRefreshRecoveryTime);
|
||||
AddSensor("tRFC2 (Fine Granularity Refresh Recovery Time)", 10, false, SensorType.Timing, (float)accessor.SDRAMTimings.FineGranularityRefreshRecoveryTime);
|
||||
AddSensor("tRFCsb (Same Bank Refresh Recovery Time)", 11, false, SensorType.Timing, (float)accessor.SDRAMTimings.SameBankRefreshRecoveryTime);
|
||||
AddSensor("tRFC1_dlr (Normal Refresh Recovery Time 3DS)", 12, false, SensorType.Timing, (float)accessor.SDRAMTimings.NormalRefreshRecoveryTime_3DSDifferentLogicalRank);
|
||||
AddSensor("tRFC2_dlr (Fine Granularity Refresh Recovery Time 3DS)", 13, false, SensorType.Timing, (float)accessor.SDRAMTimings.FineGranularityRefreshRecoveryTime_3DSDifferentLogicalRank);
|
||||
AddSensor("tRFCsb_dlr (Same Bank Refresh Recovery Time 3DS)", 14, false, SensorType.Timing, (float)accessor.SDRAMTimings.SameBankRefreshRecoveryTime_3DSDifferentLogicalRank);
|
||||
}
|
||||
|
||||
private void AddSensor(string name, int index, bool defaultHidden, SensorType sensorType, float value)
|
||||
{
|
||||
var sensor = new Sensor(name, index, defaultHidden, sensorType, this, null, _settings)
|
||||
{
|
||||
Value = value,
|
||||
};
|
||||
|
||||
ActivateSensor(sensor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,14 +7,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using RAMSPDToolkit.I2CSMBus;
|
||||
using RAMSPDToolkit.SPD;
|
||||
using RAMSPDToolkit.SPD.Enums;
|
||||
using RAMSPDToolkit.SPD.Interfaces;
|
||||
using RAMSPDToolkit.SPD.Interop.Shared;
|
||||
using RAMSPDToolkit.Windows.Driver;
|
||||
|
||||
@@ -162,9 +160,8 @@ internal class MemoryGroup : IGroup, IHardwareChanged
|
||||
//RAM available and detected
|
||||
if (detector.Accessor != null)
|
||||
{
|
||||
//We are only interested in modules with thermal sensor
|
||||
if (detector.Accessor is IThermalSensor { HasThermalSensor: true })
|
||||
accessors.Add(detector.Accessor);
|
||||
//Add all detected modules
|
||||
accessors.Add(detector.Accessor);
|
||||
|
||||
ramDetected = true;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net472;netstandard2.0;net6.0;net8.0</TargetFrameworks>
|
||||
<AssemblyName>LibreHardwareMonitorLib</AssemblyName>
|
||||
@@ -41,7 +41,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HidSharp" Version="2.1.0" />
|
||||
<PackageReference Include="RAMSPDToolkit-NDD" Version="1.1.4" />
|
||||
<PackageReference Include="RAMSPDToolkit-NDD" Version="1.2.2" />
|
||||
<PackageReference Include="System.Management" Version="9.0.8" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user