@@ -39,6 +39,21 @@ internal sealed class NvidiaGpu : GenericGpu
3939 private readonly Sensor _coreVoltage ;
4040 private readonly Sensor [ ] _temperatures ;
4141 private readonly uint _thermalSensorsMask ;
42+ private readonly Sensor [ ] _12VHPwrPinCurrentSensors ;
43+ private readonly Sensor [ ] _12VHPwrPinVoltageSensors ;
44+ private readonly Sensor [ ] _12VHPwrPinPowerSensors ;
45+ private readonly Sensor _12VHPwrConnectorPowerSensor ;
46+ private readonly Sensor _12VHPwrConnectorCurrentSensor ;
47+
48+ // ASUS Astral subsystem IDs for 12VHPwr pin monitoring
49+ private static readonly uint [ ] AstralSubSystemIds =
50+ [
51+ 0x89EA1043 , // Astral 5090D OC
52+ 0x8A611043 , // Astral 5090 Matrix
53+ 0x89EC1043 , // Astral 5090 LC
54+ 0x89E31043 , // Astral 5090 OC
55+ 0x89DE1043 , // Astral 5080 OC
56+ ] ;
4257
4358 public NvidiaGpu ( int adapterIndex , NvApi . NvPhysicalGpuHandle handle , NvApi . NvDisplayHandle ? displayHandle , ISettings settings )
4459 : base ( GetName ( handle ) ,
@@ -428,6 +443,58 @@ public NvidiaGpu(int adapterIndex, NvApi.NvPhysicalGpuHandle handle, NvApi.NvDis
428443 _memoryTotal = new Sensor ( "GPU Memory Total" , 2 , SensorType . SmallData , this , settings ) ;
429444 _memoryLoad = new Sensor ( "GPU Memory" , 3 , SensorType . Load , this , settings ) ;
430445
446+ // Pin power sensors for NVIDIA RTX Astral series from ASUS
447+ if ( NvApi . NvAPI_I2CReadEx != null && NvApi . NvAPI_GPU_GetPCIIdentifiers != null )
448+ {
449+ NvApi . NvStatus pciIdentifierStatus = NvApi . NvAPI_GPU_GetPCIIdentifiers ( _handle , out _ , out uint subSystemId , out _ , out _ ) ;
450+
451+ if ( pciIdentifierStatus == NvApi . NvStatus . OK && AstralSubSystemIds . Contains ( subSystemId ) )
452+ {
453+ _12VHPwrPinVoltageSensors =
454+ [
455+ new Sensor ( "12VHPWR Pin 1" , 0 , SensorType . Voltage , this , settings ) ,
456+ new Sensor ( "12VHPWR Pin 2" , 1 , SensorType . Voltage , this , settings ) ,
457+ new Sensor ( "12VHPWR Pin 3" , 2 , SensorType . Voltage , this , settings ) ,
458+ new Sensor ( "12VHPWR Pin 4" , 3 , SensorType . Voltage , this , settings ) ,
459+ new Sensor ( "12VHPWR Pin 5" , 4 , SensorType . Voltage , this , settings ) ,
460+ new Sensor ( "12VHPWR Pin 6" , 5 , SensorType . Voltage , this , settings ) ,
461+ ] ;
462+ _12VHPwrPinCurrentSensors =
463+ [
464+ new Sensor ( "12VHPWR Pin 1" , 1 , SensorType . Current , this , settings ) ,
465+ new Sensor ( "12VHPWR Pin 2" , 2 , SensorType . Current , this , settings ) ,
466+ new Sensor ( "12VHPWR Pin 3" , 3 , SensorType . Current , this , settings ) ,
467+ new Sensor ( "12VHPWR Pin 4" , 4 , SensorType . Current , this , settings ) ,
468+ new Sensor ( "12VHPWR Pin 5" , 5 , SensorType . Current , this , settings ) ,
469+ new Sensor ( "12VHPWR Pin 6" , 6 , SensorType . Current , this , settings ) ,
470+ ] ;
471+ _12VHPwrPinPowerSensors =
472+ [
473+ new Sensor ( "12VHPWR Pin 1" , 2 , SensorType . Power , this , settings ) ,
474+ new Sensor ( "12VHPWR Pin 2" , 3 , SensorType . Power , this , settings ) ,
475+ new Sensor ( "12VHPWR Pin 3" , 4 , SensorType . Power , this , settings ) ,
476+ new Sensor ( "12VHPWR Pin 4" , 5 , SensorType . Power , this , settings ) ,
477+ new Sensor ( "12VHPWR Pin 5" , 6 , SensorType . Power , this , settings ) ,
478+ new Sensor ( "12VHPWR Pin 6" , 7 , SensorType . Power , this , settings ) ,
479+ ] ;
480+
481+ foreach ( Sensor sensor in _12VHPwrPinVoltageSensors )
482+ ActivateSensor ( sensor ) ;
483+
484+ foreach ( Sensor sensor in _12VHPwrPinCurrentSensors )
485+ ActivateSensor ( sensor ) ;
486+
487+ foreach ( Sensor sensor in _12VHPwrPinPowerSensors )
488+ ActivateSensor ( sensor ) ;
489+
490+ _12VHPwrConnectorPowerSensor = new Sensor ( "12VHPWR Connector" , 1 , SensorType . Power , this , settings ) ;
491+ _12VHPwrConnectorCurrentSensor = new Sensor ( "12VHPWR Connector" , 0 , SensorType . Current , this , settings ) ;
492+
493+ ActivateSensor ( _12VHPwrConnectorPowerSensor ) ;
494+ ActivateSensor ( _12VHPwrConnectorCurrentSensor ) ;
495+ }
496+ }
497+
431498 Update ( ) ;
432499 }
433500
@@ -675,6 +742,75 @@ public override void Update()
675742 ActivateSensor ( _pcieThroughputTx ) ;
676743 }
677744 }
745+
746+ // Astral specific
747+ if ( _12VHPwrPinCurrentSensors is { Length : > 0 } && TryReadAstral12VHPwrPinSensors ( out ushort [ ] pinSensorValues ) )
748+ {
749+ float connectorCurrent = 0 ;
750+ float connectorPower = 0 ;
751+ for ( int i = 0 ; i < 6 ; i ++ )
752+ {
753+ float current = pinSensorValues [ i * 2 ] / 1000f ;
754+ float voltage = pinSensorValues [ i * 2 + 1 ] / 1000f ;
755+ _12VHPwrPinVoltageSensors [ i ] . Value = voltage ;
756+ _12VHPwrPinCurrentSensors [ i ] . Value = current ;
757+ _12VHPwrPinPowerSensors [ i ] . Value = voltage * current ;
758+
759+ connectorCurrent += current ;
760+ connectorPower += voltage * current ;
761+ }
762+
763+ _12VHPwrConnectorCurrentSensor . Value = connectorCurrent ;
764+ _12VHPwrConnectorPowerSensor . Value = connectorPower ;
765+ }
766+ }
767+
768+ private bool TryReadAstral12VHPwrPinSensors ( out ushort [ ] data )
769+ {
770+ data = null ;
771+
772+ if ( NvApi . NvAPI_I2CReadEx == null )
773+ return false ;
774+
775+ byte [ ] dataBuffer = new byte [ 24 ] ;
776+ byte [ ] regAddress = [ 0x80 ] ;
777+
778+ unsafe
779+ {
780+ fixed ( byte * pData = dataBuffer )
781+ fixed ( byte * pRegAddr = regAddress )
782+ {
783+ NvApi . NvI2CInfo i2cInfo = new ( )
784+ {
785+ Version = ( uint ) NvApi . MAKE_NVAPI_VERSION < NvApi . NvI2CInfo > ( 3 ) ,
786+ DisplayMask = 0 ,
787+ IsDDCPort = 0 ,
788+ I2CDevAddress = 0x2B << 1 ,
789+ I2CRegAddress = ( IntPtr ) pRegAddr ,
790+ RegAddrSize = 1 ,
791+ Data = ( IntPtr ) pData ,
792+ Size = 24 ,
793+ I2CSpeed = NvApi . NVAPI_I2C_SPEED_DEPRECATED ,
794+ I2CSpeedKhz = NvApi . NvI2CSpeed . Speed100Khz ,
795+ PortId = 0x1 ,
796+ IsPortIdSet = 1
797+ } ;
798+
799+ uint readData = 0 ;
800+ if ( NvApi . NvAPI_I2CReadEx ( _handle , ref i2cInfo , ref readData ) != NvApi . NvStatus . OK )
801+ return false ;
802+ }
803+ }
804+
805+ // Parse 12 x u16 big-endian (as mV and mA) values in reverse order
806+ data = new ushort [ 12 ] ;
807+ for ( int i = 0 ; i < 12 ; i ++ )
808+ {
809+ int pinIndex = 11 - i ;
810+ data [ i ] = ( ushort ) ( ( dataBuffer [ pinIndex * 2 ] << 8 ) | dataBuffer [ pinIndex * 2 + 1 ] ) ;
811+ }
812+
813+ return true ;
678814 }
679815
680816 public override string GetReport ( )
0 commit comments