Hardware/LPC/F718XX.cs
author moel.mich
Tue, 25 May 2010 18:57:28 +0000
changeset 127 76aaf45a01c7
parent 110 411b72b73d8f
child 130 80065ab20b84
permissions -rw-r--r--
Added a workaround for the "You must keep the stream open for the lifetime of the Image." problem of the Image.FromStream method. This also reduced the overall memory usage (private working set).
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@16
    38
using System;
moel@16
    39
using System.Collections.Generic;
moel@16
    40
using System.Drawing;
moel@16
    41
using System.Text;
moel@16
    42
moel@16
    43
namespace OpenHardwareMonitor.Hardware.LPC {
moel@31
    44
  public class F718XX : LPCHardware, IHardware {
moel@16
    45
moel@16
    46
    private ushort address;
moel@16
    47
moel@16
    48
    private Sensor[] temperatures;
moel@16
    49
    private Sensor[] fans;
moel@16
    50
    private Sensor[] voltages;
moel@16
    51
    private float[] voltageGains;
moel@16
    52
moel@16
    53
    // Hardware Monitor
moel@16
    54
    private const byte ADDRESS_REGISTER_OFFSET = 0x05;
moel@16
    55
    private const byte DATA_REGISTER_OFFSET = 0x06;
moel@16
    56
moel@16
    57
    // Hardware Monitor Registers
moel@16
    58
    private const byte VOLTAGE_BASE_REG = 0x20;
moel@68
    59
    private const byte TEMPERATURE_CONFIG_REG = 0x69;
moel@68
    60
    private const byte TEMPERATURE_BASE_REG = 0x70;
moel@16
    61
    private byte[] FAN_TACHOMETER_REG = new byte[] { 0xA0, 0xB0, 0xC0, 0xD0 };
moel@16
    62
    
moel@16
    63
    private byte ReadByte(byte register) {
moel@16
    64
      WinRing0.WriteIoPortByte(
moel@16
    65
        (ushort)(address + ADDRESS_REGISTER_OFFSET), register);
moel@16
    66
      return WinRing0.ReadIoPortByte((ushort)(address + DATA_REGISTER_OFFSET));
moel@103
    67
    } 
moel@16
    68
moel@31
    69
    public F718XX(Chip chip, ushort address) : base(chip) {
moel@16
    70
      this.address = address;
moel@16
    71
moel@16
    72
      temperatures = new Sensor[3];
moel@16
    73
      for (int i = 0; i < temperatures.Length; i++)
moel@63
    74
        temperatures[i] = new Sensor("Temperature #" + (i + 1), i, null,
moel@63
    75
          SensorType.Temperature, this, new ParameterDescription[] {
moel@122
    76
            new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
moel@63
    77
          });
moel@16
    78
moel@68
    79
      fans = new Sensor[chip == Chip.F71882 ? 4 : 3];
moel@16
    80
      for (int i = 0; i < fans.Length; i++)
moel@16
    81
        fans[i] = new Sensor("Fan #" + (i + 1), i, SensorType.Fan, this);
moel@16
    82
moel@68
    83
      switch (chip) {
moel@68
    84
        case Chip.F71858:
moel@68
    85
          voltageGains = new float[] { 1, 1, 1 };
moel@68
    86
          voltages = new Sensor[3];
moel@68
    87
          voltages[0] = new Sensor("VCC3V", 0, SensorType.Voltage, this);
moel@68
    88
          voltages[1] = new Sensor("VSB3V", 1, SensorType.Voltage, this);
moel@68
    89
          voltages[2] = new Sensor("Battery", 2, SensorType.Voltage, this);
moel@68
    90
          break;
moel@68
    91
        default:
moel@68
    92
          voltageGains = new float[] { 1, 0.5f, 1, 1, 1, 1, 1, 1, 1 };
moel@68
    93
          voltages = new Sensor[4];
moel@68
    94
          voltages[0] = new Sensor("VCC3V", 0, SensorType.Voltage, this);
moel@68
    95
          voltages[1] = new Sensor("CPU VCore", 1, SensorType.Voltage, this);
moel@68
    96
          voltages[2] = new Sensor("VSB3V", 7, SensorType.Voltage, this);
moel@68
    97
          voltages[3] = new Sensor("Battery", 8, SensorType.Voltage, this);
moel@68
    98
          break;
moel@68
    99
      }
moel@16
   100
    }
moel@16
   101
moel@110
   102
    public override string GetReport() {
moel@16
   103
      StringBuilder r = new StringBuilder();
moel@16
   104
moel@31
   105
      r.AppendLine("LPC " + this.GetType().Name);
moel@16
   106
      r.AppendLine();
moel@16
   107
      r.Append("Base Adress: 0x"); r.AppendLine(address.ToString("X4"));
moel@16
   108
      r.AppendLine();
moel@16
   109
      r.AppendLine("Hardware Monitor Registers");
moel@16
   110
      r.AppendLine();
moel@16
   111
moel@16
   112
      r.AppendLine("      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
moel@16
   113
      r.AppendLine();
moel@16
   114
      for (int i = 0; i <= 0xF; i++) {
moel@16
   115
        r.Append(" "); r.Append((i << 4).ToString("X2")); r.Append("  ");
moel@16
   116
        for (int j = 0; j <= 0xF; j++) {
moel@16
   117
          r.Append(" ");
moel@16
   118
          r.Append(ReadByte((byte)((i << 4) | j)).ToString("X2"));
moel@16
   119
        }
moel@16
   120
        r.AppendLine();
moel@16
   121
      }
moel@16
   122
      r.AppendLine();
moel@16
   123
      return r.ToString();
moel@16
   124
    }
moel@16
   125
moel@110
   126
    public override void Update() {
moel@16
   127
moel@16
   128
      foreach (Sensor sensor in voltages) {
moel@16
   129
        int value = ReadByte((byte)(VOLTAGE_BASE_REG + sensor.Index));
moel@16
   130
        sensor.Value = voltageGains[sensor.Index] * 0.001f * (value << 4);
moel@16
   131
        if (sensor.Value > 0)
moel@16
   132
          ActivateSensor(sensor);
moel@16
   133
      }
moel@68
   134
     
moel@16
   135
      foreach (Sensor sensor in temperatures) {
moel@68
   136
        switch (chip) {
moel@68
   137
          case Chip.F71858: {
moel@68
   138
              int tableMode = 0x3 & ReadByte((byte)(TEMPERATURE_CONFIG_REG));
moel@68
   139
              int high = 
moel@68
   140
                ReadByte((byte)(TEMPERATURE_BASE_REG + 2 * sensor.Index));
moel@68
   141
              int low =
moel@68
   142
                ReadByte((byte)(TEMPERATURE_BASE_REG + 2 * sensor.Index + 1));              
moel@68
   143
              if (high != 0xbb && high != 0xcc) {
moel@68
   144
                int bits = 0;
moel@68
   145
                switch (tableMode) {
moel@68
   146
                  case 0: bits = 0; break;
moel@68
   147
                  case 1: bits = 0; break;
moel@68
   148
                  case 2: bits = (high & 0x80) << 8; break;
moel@68
   149
                  case 3: bits = (low & 0x01) << 15; break;
moel@68
   150
                }
moel@68
   151
                bits |= high << 7;
moel@68
   152
                bits |= (low & 0xe0) >> 1;
moel@68
   153
                short value = (short)(bits & 0xfff0);
moel@68
   154
                sensor.Value = value / 128.0f;
moel@68
   155
                ActivateSensor(sensor);
moel@68
   156
              } else {
moel@84
   157
                sensor.Value = null;
moel@68
   158
              }
moel@68
   159
          } break;
moel@68
   160
          default: {
moel@68
   161
            sbyte value = (sbyte)ReadByte((byte)(
moel@68
   162
              TEMPERATURE_BASE_REG + 2 * (sensor.Index + 1)));
moel@68
   163
            sensor.Value = value + sensor.Parameters[0].Value;
moel@68
   164
            if (value < sbyte.MaxValue && value > 0)
moel@68
   165
              ActivateSensor(sensor);
moel@68
   166
          } break;
moel@68
   167
        }
moel@16
   168
      }
moel@16
   169
moel@16
   170
      foreach (Sensor sensor in fans) {
moel@16
   171
        int value = ReadByte(FAN_TACHOMETER_REG[sensor.Index]) << 8;
moel@16
   172
        value |= ReadByte((byte)(FAN_TACHOMETER_REG[sensor.Index] + 1));
moel@16
   173
moel@16
   174
        if (value > 0) {
moel@16
   175
          sensor.Value = (value < 0x0fff) ? 1.5e6f / value : 0;
moel@34
   176
          if (sensor.Value > 0)
moel@34
   177
            ActivateSensor(sensor);
moel@16
   178
        } else {
moel@84
   179
          sensor.Value = null;
moel@16
   180
        }
moel@16
   181
      }      
moel@16
   182
    }
moel@16
   183
  }
moel@16
   184
}