Hardware/LPC/F718XX.cs
author sl
Sun, 03 Feb 2013 18:01:50 +0100
changeset 391 ca4c0e7ae75d
parent 344 3145aadca3d2
permissions -rw-r--r--
Converted project to VisualStudio 2012.
Adding SoundGraphDisplay and SensorFrontView classes.
They were respectively based on SystemTray and SensorNotifyIcon.
SoundGraphDisplay is now able to load iMONDisplay.dll providing it lives on your PATH.
Adding option to sensor context menu for adding it into FrontView.
moel@16
     1
/*
moel@16
     2
 
moel@344
     3
  This Source Code Form is subject to the terms of the Mozilla Public
moel@344
     4
  License, v. 2.0. If a copy of the MPL was not distributed with this
moel@344
     5
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
moel@16
     6
 
moel@344
     7
  Copyright (C) 2009-2011 Michael Möller <mmoeller@openhardwaremonitor.org>
moel@344
     8
	
moel@16
     9
*/
moel@16
    10
moel@166
    11
using System.Globalization;
moel@16
    12
using System.Text;
moel@16
    13
moel@16
    14
namespace OpenHardwareMonitor.Hardware.LPC {
moel@165
    15
  internal class F718XX : ISuperIO {
moel@16
    16
moel@195
    17
    private readonly ushort address;
moel@195
    18
    private readonly Chip chip;
moel@16
    19
moel@195
    20
    private readonly float?[] voltages;
moel@195
    21
    private readonly float?[] temperatures;
moel@195
    22
    private readonly float?[] fans;
moel@323
    23
    private readonly float?[] controls;
moel@16
    24
moel@16
    25
    // Hardware Monitor
moel@16
    26
    private const byte ADDRESS_REGISTER_OFFSET = 0x05;
moel@16
    27
    private const byte DATA_REGISTER_OFFSET = 0x06;
moel@16
    28
moel@16
    29
    // Hardware Monitor Registers
moel@16
    30
    private const byte VOLTAGE_BASE_REG = 0x20;
moel@68
    31
    private const byte TEMPERATURE_CONFIG_REG = 0x69;
moel@68
    32
    private const byte TEMPERATURE_BASE_REG = 0x70;
moel@195
    33
    private readonly byte[] FAN_TACHOMETER_REG = 
moel@195
    34
      new byte[] { 0xA0, 0xB0, 0xC0, 0xD0 };
moel@16
    35
    
moel@16
    36
    private byte ReadByte(byte register) {
moel@236
    37
      Ring0.WriteIoPort(
moel@16
    38
        (ushort)(address + ADDRESS_REGISTER_OFFSET), register);
moel@236
    39
      return Ring0.ReadIoPort((ushort)(address + DATA_REGISTER_OFFSET));
moel@132
    40
    }
moel@16
    41
moel@228
    42
    public byte? ReadGPIO(int index) {
moel@228
    43
      return null;
moel@228
    44
    }
moel@228
    45
moel@228
    46
    public void WriteGPIO(int index, byte value) { }
moel@228
    47
moel@323
    48
    public void SetControl(int index, byte? value) { }   
moel@323
    49
moel@130
    50
    public F718XX(Chip chip, ushort address) {
moel@16
    51
      this.address = address;
moel@130
    52
      this.chip = chip;
moel@16
    53
moel@130
    54
      voltages = new float?[chip == Chip.F71858 ? 3 : 9];
moel@352
    55
      temperatures = new float?[chip == Chip.F71808E ? 2 : 3];
moel@352
    56
      fans = new float?[chip == Chip.F71882 || chip == Chip.F71858 ? 4 : 3];
moel@323
    57
      controls = new float?[0];
moel@16
    58
    }
moel@16
    59
moel@130
    60
    public Chip Chip { get { return chip; } }
moel@130
    61
    public float?[] Voltages { get { return voltages; } }
moel@130
    62
    public float?[] Temperatures { get { return temperatures; } }
moel@130
    63
    public float?[] Fans { get { return fans; } }
moel@323
    64
    public float?[] Controls { get { return controls; } }
moel@130
    65
moel@130
    66
    public string GetReport() {
moel@16
    67
      StringBuilder r = new StringBuilder();
moel@16
    68
moel@31
    69
      r.AppendLine("LPC " + this.GetType().Name);
moel@16
    70
      r.AppendLine();
moel@166
    71
      r.Append("Base Adress: 0x"); 
moel@166
    72
      r.AppendLine(address.ToString("X4", CultureInfo.InvariantCulture));
moel@16
    73
      r.AppendLine();
moel@162
    74
moel@236
    75
      if (!Ring0.WaitIsaBusMutex(100))
moel@162
    76
        return r.ToString();
moel@162
    77
moel@16
    78
      r.AppendLine("Hardware Monitor Registers");
moel@16
    79
      r.AppendLine();
moel@16
    80
      r.AppendLine("      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
moel@16
    81
      r.AppendLine();
moel@16
    82
      for (int i = 0; i <= 0xF; i++) {
moel@166
    83
        r.Append(" "); 
moel@166
    84
        r.Append((i << 4).ToString("X2", CultureInfo.InvariantCulture)); 
moel@166
    85
        r.Append("  ");
moel@16
    86
        for (int j = 0; j <= 0xF; j++) {
moel@16
    87
          r.Append(" ");
moel@166
    88
          r.Append(ReadByte((byte)((i << 4) | j)).ToString("X2", 
moel@166
    89
            CultureInfo.InvariantCulture));
moel@16
    90
        }
moel@16
    91
        r.AppendLine();
moel@16
    92
      }
moel@16
    93
      r.AppendLine();
moel@162
    94
moel@236
    95
      Ring0.ReleaseIsaBusMutex();
moel@162
    96
moel@16
    97
      return r.ToString();
moel@16
    98
    }
moel@16
    99
moel@130
   100
    public void Update() {
moel@236
   101
      if (!Ring0.WaitIsaBusMutex(10))
moel@162
   102
        return;
moel@16
   103
moel@130
   104
      for (int i = 0; i < voltages.Length; i++) {
moel@352
   105
        if (chip == Chip.F71808E && i == 6) {
moel@352
   106
          // 0x26 is reserved on F71808E
moel@352
   107
          voltages[i] = 0;
moel@352
   108
        } else {
moel@352
   109
          int value = ReadByte((byte)(VOLTAGE_BASE_REG + i));
moel@352
   110
          voltages[i] = 0.008f * value;
moel@352
   111
        }
moel@16
   112
      }
moel@68
   113
     
moel@130
   114
      for (int i = 0; i < temperatures.Length; i++) {
moel@68
   115
        switch (chip) {
moel@68
   116
          case Chip.F71858: {
moel@195
   117
              int tableMode = 0x3 & ReadByte(TEMPERATURE_CONFIG_REG);
moel@68
   118
              int high = 
moel@130
   119
                ReadByte((byte)(TEMPERATURE_BASE_REG + 2 * i));
moel@68
   120
              int low =
moel@130
   121
                ReadByte((byte)(TEMPERATURE_BASE_REG + 2 * i + 1));              
moel@68
   122
              if (high != 0xbb && high != 0xcc) {
moel@68
   123
                int bits = 0;
moel@68
   124
                switch (tableMode) {
moel@68
   125
                  case 0: bits = 0; break;
moel@68
   126
                  case 1: bits = 0; break;
moel@68
   127
                  case 2: bits = (high & 0x80) << 8; break;
moel@68
   128
                  case 3: bits = (low & 0x01) << 15; break;
moel@68
   129
                }
moel@68
   130
                bits |= high << 7;
moel@68
   131
                bits |= (low & 0xe0) >> 1;
moel@68
   132
                short value = (short)(bits & 0xfff0);
moel@130
   133
                temperatures[i] = value / 128.0f;
moel@68
   134
              } else {
moel@130
   135
                temperatures[i] = null;
moel@68
   136
              }
moel@68
   137
          } break;
moel@68
   138
          default: {
moel@68
   139
            sbyte value = (sbyte)ReadByte((byte)(
moel@130
   140
              TEMPERATURE_BASE_REG + 2 * (i + 1)));            
moel@68
   141
            if (value < sbyte.MaxValue && value > 0)
moel@130
   142
              temperatures[i] = value;
moel@130
   143
            else
moel@130
   144
              temperatures[i] = null;
moel@68
   145
          } break;
moel@68
   146
        }
moel@16
   147
      }
moel@16
   148
moel@130
   149
      for (int i = 0; i < fans.Length; i++) {
moel@130
   150
        int value = ReadByte(FAN_TACHOMETER_REG[i]) << 8;
moel@130
   151
        value |= ReadByte((byte)(FAN_TACHOMETER_REG[i] + 1));
moel@16
   152
moel@130
   153
        if (value > 0) 
moel@130
   154
          fans[i] = (value < 0x0fff) ? 1.5e6f / value : 0;
moel@130
   155
        else 
moel@130
   156
          fans[i] = null;        
moel@162
   157
      }
moel@162
   158
moel@236
   159
      Ring0.ReleaseIsaBusMutex();
moel@16
   160
    }
moel@16
   161
  }
moel@16
   162
}