Hardware/TBalancer/TBalancerGroup.cs
author moel.mich
Sun, 08 May 2011 22:10:13 +0000
changeset 279 6bce967ba1b5
parent 216 b5b076457b68
child 344 3145aadca3d2
permissions -rw-r--r--
Fixed the bus and core clock reading on AMD family 10h model Ah CPUs. The new "Core Performance Boost" feature of these CPUs resulted in very low accuracy of the bus speed (and as a consequence also an inaccurate TSC multiplier). This fixed Issue 205.
moel@1
     1
/*
moel@1
     2
  
moel@1
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@1
     4
moel@1
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@1
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@1
     7
  the License. You may obtain a copy of the License at
moel@1
     8
 
moel@1
     9
  http://www.mozilla.org/MPL/
moel@1
    10
moel@1
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@1
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@1
    13
  for the specific language governing rights and limitations under the License.
moel@1
    14
moel@1
    15
  The Original Code is the Open Hardware Monitor code.
moel@1
    16
moel@1
    17
  The Initial Developer of the Original Code is 
moel@1
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@1
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@1
    20
  the Initial Developer. All Rights Reserved.
moel@1
    21
moel@1
    22
  Contributor(s):
moel@1
    23
moel@1
    24
  Alternatively, the contents of this file may be used under the terms of
moel@1
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@1
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@1
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@1
    28
  of those above. If you wish to allow use of your version of this file only
moel@1
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@1
    30
  use your version of this file under the terms of the MPL, indicate your
moel@1
    31
  decision by deleting the provisions above and replace them with the notice
moel@1
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@1
    33
  the provisions above, a recipient may use your version of this file under
moel@1
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@1
    35
 
moel@1
    36
*/
moel@1
    37
moel@1
    38
using System;
moel@1
    39
using System.Collections.Generic;
moel@166
    40
using System.Globalization;
moel@32
    41
using System.Text;
moel@1
    42
using System.Threading;
moel@1
    43
moel@1
    44
namespace OpenHardwareMonitor.Hardware.TBalancer {
moel@165
    45
  internal class TBalancerGroup : IGroup {
moel@1
    46
moel@195
    47
    private readonly List<TBalancer> hardware = new List<TBalancer>();
moel@195
    48
    private readonly StringBuilder report = new StringBuilder();
moel@1
    49
moel@165
    50
    public TBalancerGroup(ISettings settings) {
moel@32
    51
moel@87
    52
      uint numDevices;
moel@87
    53
      try {
moel@216
    54
        if (FTD2XX.FT_CreateDeviceInfoList(out numDevices) != FT_STATUS.FT_OK) {
moel@216
    55
          report.AppendLine("Status: FT_CreateDeviceInfoList failed");
moel@216
    56
          return;
moel@216
    57
        }
moel@87
    58
      } catch (DllNotFoundException) { return; } 
moel@87
    59
        catch (ArgumentNullException) { return; }
moel@131
    60
        catch (EntryPointNotFoundException) { return; }
moel@160
    61
        catch (BadImageFormatException) { return; }
moel@87
    62
     
moel@87
    63
      FT_DEVICE_INFO_NODE[] info = new FT_DEVICE_INFO_NODE[numDevices];
moel@216
    64
      if (FTD2XX.FT_GetDeviceInfoList(info, ref numDevices) != FT_STATUS.FT_OK) 
moel@216
    65
      {
moel@216
    66
        report.AppendLine("Status: FT_GetDeviceInfoList failed");        
moel@216
    67
        return;
moel@216
    68
      }
moel@216
    69
moel@216
    70
      // make sure numDevices is not larger than the info array
moel@216
    71
      if (numDevices > info.Length)
moel@216
    72
        numDevices = (uint)info.Length;
moel@32
    73
moel@87
    74
      for (int i = 0; i < numDevices; i++) {
moel@166
    75
        report.Append("Device Index: ");
moel@166
    76
        report.AppendLine(i.ToString(CultureInfo.InvariantCulture));
moel@186
    77
        report.Append("Device Type: ");
moel@186
    78
        report.AppendLine(info[i].Type.ToString());
moel@186
    79
moel@186
    80
        // the T-Balancer always uses an FT232BM
moel@186
    81
        if (info[i].Type != FT_DEVICE.FT_DEVICE_232BM) {
moel@186
    82
          report.AppendLine("Status: Wrong device type");
moel@186
    83
          continue;
moel@186
    84
        }
moel@186
    85
moel@87
    86
        FT_HANDLE handle;
moel@195
    87
        FT_STATUS status = FTD2XX.FT_Open(i, out handle);
moel@87
    88
        if (status != FT_STATUS.FT_OK) {
moel@87
    89
          report.AppendLine("Open Status: " + status);
moel@87
    90
          continue;
moel@87
    91
        }
moel@32
    92
moel@87
    93
        FTD2XX.FT_SetBaudRate(handle, 19200);
moel@87
    94
        FTD2XX.FT_SetDataCharacteristics(handle, 8, 1, 0);
moel@87
    95
        FTD2XX.FT_SetFlowControl(handle, FT_FLOW_CONTROL.FT_FLOW_RTS_CTS, 0x11, 
moel@87
    96
          0x13);
moel@87
    97
        FTD2XX.FT_SetTimeouts(handle, 1000, 1000);
moel@87
    98
        FTD2XX.FT_Purge(handle, FT_PURGE.FT_PURGE_ALL);
moel@87
    99
        
moel@87
   100
        status = FTD2XX.Write(handle, new byte[] { 0x38 });
moel@87
   101
        if (status != FT_STATUS.FT_OK) {
moel@87
   102
          report.AppendLine("Write Status: " + status);
moel@87
   103
          FTD2XX.FT_Close(handle);
moel@87
   104
          continue;
moel@87
   105
        }
moel@87
   106
moel@87
   107
        bool isValid = false;
moel@87
   108
        byte protocolVersion = 0;
moel@87
   109
moel@87
   110
        int j = 0;
moel@87
   111
        while (FTD2XX.BytesToRead(handle) == 0 && j < 2) {
moel@87
   112
          Thread.Sleep(100);
moel@87
   113
          j++;
moel@87
   114
        }
moel@87
   115
        if (FTD2XX.BytesToRead(handle) > 0) {
moel@87
   116
          if (FTD2XX.ReadByte(handle) == TBalancer.STARTFLAG) {
moel@87
   117
            while (FTD2XX.BytesToRead(handle) < 284 && j < 5) {
moel@87
   118
              Thread.Sleep(100);
moel@87
   119
              j++;
moel@87
   120
            }
moel@87
   121
            int length = FTD2XX.BytesToRead(handle);
moel@87
   122
            if (length >= 284) {
moel@87
   123
              byte[] data = new byte[285];
moel@87
   124
              data[0] = TBalancer.STARTFLAG;
moel@87
   125
              for (int k = 1; k < data.Length; k++)
moel@87
   126
                data[k] = FTD2XX.ReadByte(handle);
moel@87
   127
moel@87
   128
              // check protocol version 2X (protocols seen: 2C, 2A, 28)
moel@87
   129
              isValid = (data[274] & 0xF0) == 0x20;
moel@87
   130
              protocolVersion = data[274];
moel@87
   131
              if (!isValid) {
moel@87
   132
                report.Append("Status: Wrong Protocol Version: 0x");
moel@166
   133
                report.AppendLine(
moel@166
   134
                  protocolVersion.ToString("X", CultureInfo.InvariantCulture));
moel@1
   135
              }
moel@32
   136
            } else {
moel@87
   137
              report.AppendLine("Status: Wrong Message Length: " + length);
moel@1
   138
            }
moel@87
   139
          } else {
moel@87
   140
            report.AppendLine("Status: Wrong Startflag");
moel@1
   141
          }
moel@87
   142
        } else {
moel@87
   143
          report.AppendLine("Status: No Response");
moel@87
   144
        }
moel@87
   145
moel@87
   146
        FTD2XX.FT_Purge(handle, FT_PURGE.FT_PURGE_ALL);
moel@87
   147
        FTD2XX.FT_Close(handle);
moel@87
   148
moel@87
   149
        if (isValid) {
moel@87
   150
          report.AppendLine("Status: OK");
moel@165
   151
          hardware.Add(new TBalancer(i, protocolVersion, settings));
moel@87
   152
          return;
moel@87
   153
        }
moel@41
   154
        report.AppendLine();
moel@1
   155
      }
moel@1
   156
    }
moel@1
   157
moel@1
   158
    public IHardware[] Hardware {
moel@1
   159
      get {
moel@1
   160
        return hardware.ToArray();
moel@1
   161
      }
moel@1
   162
    }
moel@1
   163
moel@1
   164
    public string GetReport() {
moel@32
   165
      if (report.Length > 0) {
moel@256
   166
        StringBuilder r = new StringBuilder();
moel@256
   167
        r.AppendLine("FTD2XX");
moel@256
   168
        r.AppendLine();
moel@256
   169
        r.Append(report);
moel@256
   170
        r.AppendLine();
moel@256
   171
        return r.ToString();
moel@32
   172
      } else
moel@32
   173
        return null;
moel@1
   174
    }
moel@1
   175
moel@1
   176
    public void Close() {
moel@1
   177
      foreach (TBalancer tbalancer in hardware)
moel@1
   178
        tbalancer.Close();
moel@1
   179
    }
moel@1
   180
  }
moel@1
   181
}