Hardware/LPC/IT87XX.cs
author moel.mich
Sat, 02 Oct 2010 18:15:46 +0000
changeset 206 1fa8eddc24a7
parent 182 4801e9eaf979
child 228 458a6c3de579
permissions -rw-r--r--
Replaced HttpUtility.UrlEncode with Uri.EscapeDataString and deleted the reference to the System.Web assembly. The System.Web assembly seems to be missing on some .NET 4.0 installations (and the overhead of using it is a bit large, just for the UrlEncode method).
moel@16
     1
/*
moel@16
     2
  
moel@16
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@16
     4
moel@16
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@16
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@16
     7
  the License. You may obtain a copy of the License at
moel@16
     8
 
moel@16
     9
  http://www.mozilla.org/MPL/
moel@16
    10
moel@16
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@16
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@16
    13
  for the specific language governing rights and limitations under the License.
moel@16
    14
moel@16
    15
  The Original Code is the Open Hardware Monitor code.
moel@16
    16
moel@16
    17
  The Initial Developer of the Original Code is 
moel@16
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@16
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@16
    20
  the Initial Developer. All Rights Reserved.
moel@16
    21
moel@16
    22
  Contributor(s):
moel@16
    23
moel@16
    24
  Alternatively, the contents of this file may be used under the terms of
moel@16
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@16
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@16
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@16
    28
  of those above. If you wish to allow use of your version of this file only
moel@16
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@16
    30
  use your version of this file under the terms of the MPL, indicate your
moel@16
    31
  decision by deleting the provisions above and replace them with the notice
moel@16
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@16
    33
  the provisions above, a recipient may use your version of this file under
moel@16
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@16
    35
 
moel@16
    36
*/
moel@16
    37
moel@166
    38
using System.Globalization;
moel@16
    39
using System.Text;
moel@16
    40
moel@16
    41
namespace OpenHardwareMonitor.Hardware.LPC {
moel@165
    42
  internal class IT87XX : ISuperIO {
moel@130
    43
       
moel@195
    44
    private readonly ushort address;
moel@195
    45
    private readonly Chip chip;
moel@195
    46
    private readonly byte version;
moel@16
    47
moel@78
    48
    private readonly ushort addressReg;
moel@78
    49
    private readonly ushort dataReg;
moel@78
    50
moel@195
    51
    private readonly float?[] voltages = new float?[0];
moel@195
    52
    private readonly float?[] temperatures = new float?[0];
moel@195
    53
    private readonly float?[] fans = new float?[0];
moel@170
    54
moel@170
    55
    private readonly float voltageGain;
moel@16
    56
   
moel@16
    57
    // Consts
moel@16
    58
    private const byte ITE_VENDOR_ID = 0x90;
moel@16
    59
       
moel@16
    60
    // Environment Controller
moel@16
    61
    private const byte ADDRESS_REGISTER_OFFSET = 0x05;
moel@16
    62
    private const byte DATA_REGISTER_OFFSET = 0x06;
moel@16
    63
moel@16
    64
    // Environment Controller Registers    
moel@16
    65
    private const byte CONFIGURATION_REGISTER = 0x00;
moel@16
    66
    private const byte TEMPERATURE_BASE_REG = 0x29;
moel@16
    67
    private const byte VENDOR_ID_REGISTER = 0x58;
moel@16
    68
    private const byte FAN_TACHOMETER_16_BIT_ENABLE_REGISTER = 0x0c;
moel@195
    69
    private readonly byte[] FAN_TACHOMETER_REG = 
moel@16
    70
      new byte[] { 0x0d, 0x0e, 0x0f, 0x80, 0x82 };
moel@195
    71
    private readonly byte[] FAN_TACHOMETER_EXT_REG =
moel@16
    72
      new byte[] { 0x18, 0x19, 0x1a, 0x81, 0x83 };
moel@78
    73
    private const byte VOLTAGE_BASE_REG = 0x20;
moel@78
    74
moel@78
    75
    private byte ReadByte(byte register, out bool valid) {
moel@78
    76
      WinRing0.WriteIoPortByte(addressReg, register);
moel@78
    77
      byte value = WinRing0.ReadIoPortByte(dataReg);
moel@78
    78
      valid = register == WinRing0.ReadIoPortByte(addressReg);
moel@78
    79
      return value;
moel@144
    80
    } 
moel@16
    81
moel@145
    82
    public IT87XX(Chip chip, ushort address, byte version) {
moel@16
    83
      
moel@16
    84
      this.address = address;
moel@130
    85
      this.chip = chip;
moel@145
    86
      this.version = version;
moel@78
    87
      this.addressReg = (ushort)(address + ADDRESS_REGISTER_OFFSET);
moel@78
    88
      this.dataReg = (ushort)(address + DATA_REGISTER_OFFSET);
moel@16
    89
      
moel@16
    90
      // Check vendor id
moel@78
    91
      bool valid;
moel@78
    92
      byte vendorId = ReadByte(VENDOR_ID_REGISTER, out valid);       
moel@78
    93
      if (!valid || vendorId != ITE_VENDOR_ID)
moel@16
    94
        return;
moel@16
    95
moel@16
    96
      // Bit 0x10 of the configuration register should always be 1
moel@78
    97
      if ((ReadByte(CONFIGURATION_REGISTER, out valid) & 0x10) == 0)
moel@78
    98
        return;
moel@78
    99
      if (!valid)
moel@16
   100
        return;
moel@16
   101
moel@130
   102
      voltages = new float?[9];
moel@130
   103
      temperatures = new float?[3];
moel@130
   104
      fans = new float?[5];
moel@170
   105
moel@170
   106
      // The IT8721F uses a 12mV resultion ADC, all others 16mV
moel@170
   107
      if (chip == Chip.IT8721F) {
moel@170
   108
        voltageGain = 0.012f;
moel@170
   109
      } else {
moel@170
   110
        voltageGain = 0.016f;
moel@170
   111
      }
moel@16
   112
    }
moel@16
   113
moel@130
   114
    public Chip Chip { get { return chip; } }
moel@130
   115
    public float?[] Voltages { get { return voltages; } }
moel@130
   116
    public float?[] Temperatures { get { return temperatures; } }
moel@130
   117
    public float?[] Fans { get { return fans; } }
moel@16
   118
moel@130
   119
    public string GetReport() {
moel@16
   120
      StringBuilder r = new StringBuilder();
moel@16
   121
moel@31
   122
      r.AppendLine("LPC " + this.GetType().Name);
moel@16
   123
      r.AppendLine();
moel@16
   124
      r.Append("Chip ID: 0x"); r.AppendLine(chip.ToString("X"));
moel@166
   125
      r.Append("Chip Version: 0x"); r.AppendLine(
moel@166
   126
        version.ToString("X", CultureInfo.InvariantCulture));
moel@166
   127
      r.Append("Base Address: 0x"); r.AppendLine(
moel@166
   128
        address.ToString("X4", CultureInfo.InvariantCulture));
moel@16
   129
      r.AppendLine();
moel@162
   130
moel@163
   131
      if (!WinRing0.WaitIsaBusMutex(100))
moel@162
   132
        return r.ToString();
moel@162
   133
moel@16
   134
      r.AppendLine("Environment Controller Registers");
moel@16
   135
      r.AppendLine();
moel@16
   136
      r.AppendLine("      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
moel@16
   137
      r.AppendLine();
moel@16
   138
      for (int i = 0; i <= 0xA; i++) {
moel@166
   139
        r.Append(" "); 
moel@166
   140
        r.Append((i << 4).ToString("X2", CultureInfo.InvariantCulture)); 
moel@166
   141
        r.Append("  ");
moel@16
   142
        for (int j = 0; j <= 0xF; j++) {
moel@16
   143
          r.Append(" ");
moel@78
   144
          bool valid;
moel@78
   145
          byte value = ReadByte((byte)((i << 4) | j), out valid);
moel@195
   146
          r.Append(
moel@195
   147
            valid ? value.ToString("X2", CultureInfo.InvariantCulture) : "??");
moel@16
   148
        }
moel@16
   149
        r.AppendLine();
moel@16
   150
      }
moel@16
   151
      r.AppendLine();
moel@16
   152
moel@162
   153
      WinRing0.ReleaseIsaBusMutex();
moel@162
   154
moel@16
   155
      return r.ToString();
moel@16
   156
    }
moel@16
   157
moel@130
   158
    public void Update() {
moel@163
   159
      if (!WinRing0.WaitIsaBusMutex(10))
moel@162
   160
        return;
moel@16
   161
moel@130
   162
      for (int i = 0; i < voltages.Length; i++) {
moel@78
   163
        bool valid;
moel@170
   164
        
moel@170
   165
        float value = 
moel@170
   166
          voltageGain * ReadByte((byte)(VOLTAGE_BASE_REG + i), out valid);   
moel@170
   167
moel@130
   168
        if (!valid)
moel@130
   169
          continue;
moel@130
   170
        if (value > 0)
moel@130
   171
          voltages[i] = value;  
moel@130
   172
        else
moel@130
   173
          voltages[i] = null;
moel@130
   174
      }
moel@130
   175
moel@130
   176
      for (int i = 0; i < temperatures.Length; i++) {
moel@130
   177
        bool valid;
moel@130
   178
        sbyte value = (sbyte)ReadByte(
moel@130
   179
          (byte)(TEMPERATURE_BASE_REG + i), out valid);
moel@78
   180
        if (!valid)
moel@78
   181
          continue;
moel@78
   182
moel@130
   183
        if (value < sbyte.MaxValue && value > 0)
moel@130
   184
          temperatures[i] = value;
moel@130
   185
        else
moel@130
   186
          temperatures[i] = null;       
moel@16
   187
      }
moel@16
   188
moel@130
   189
      for (int i = 0; i < fans.Length; i++) {
moel@78
   190
        bool valid;
moel@130
   191
        int value = ReadByte(FAN_TACHOMETER_REG[i], out valid);
moel@78
   192
        if (!valid) 
moel@78
   193
          continue;
moel@130
   194
        value |= ReadByte(FAN_TACHOMETER_EXT_REG[i], out valid) << 8;
moel@78
   195
        if (!valid)
moel@78
   196
          continue;
moel@16
   197
moel@36
   198
        if (value > 0x3f) {
moel@130
   199
          fans[i] = (value < 0xffff) ? 1.35e6f / ((value) * 2) : 0;
moel@16
   200
        } else {
moel@130
   201
          fans[i] = null;
moel@16
   202
        }
moel@162
   203
      }
moel@162
   204
moel@162
   205
      WinRing0.ReleaseIsaBusMutex();
moel@126
   206
    }
moel@130
   207
  } 
moel@16
   208
}