Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
3 This Source Code Form is subject to the terms of the Mozilla Public
4 License, v. 2.0. If a copy of the MPL was not distributed with this
5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 Copyright (C) 2009-2011 Michael Möller <mmoeller@openhardwaremonitor.org>
12 using System.Collections.Generic;
13 using System.Globalization;
16 namespace OpenHardwareMonitor.Hardware.TBalancer {
17 internal class TBalancer : Hardware {
19 private readonly int portIndex;
20 private readonly byte protocolVersion;
21 private readonly Sensor[] digitalTemperatures = new Sensor[8];
22 private readonly Sensor[] analogTemperatures = new Sensor[4];
23 private readonly Sensor[] sensorhubTemperatures = new Sensor[6];
24 private readonly Sensor[] sensorhubFlows = new Sensor[2];
25 private readonly Sensor[] fans = new Sensor[4];
26 private readonly Sensor[] controls = new Sensor[4];
27 private readonly Sensor[] miniNGTemperatures = new Sensor[4];
28 private readonly Sensor[] miniNGFans = new Sensor[4];
29 private readonly Sensor[] miniNGControls = new Sensor[4];
30 private readonly List<ISensor> deactivating = new List<ISensor>();
32 private FT_HANDLE handle;
33 private int[] primaryData = new int[0];
34 private int[] alternativeData = new int[0];
36 public const byte STARTFLAG = 100;
37 public const byte ENDFLAG = 254;
39 private delegate void MethodDelegate();
40 private readonly MethodDelegate alternativeRequest;
42 public TBalancer(int portIndex, byte protocolVersion, ISettings settings)
43 : base("T-Balancer bigNG", new Identifier("bigng",
44 portIndex.ToString(CultureInfo.InvariantCulture)), settings)
47 this.portIndex = portIndex;
48 this.protocolVersion = protocolVersion;
50 ParameterDescription[] parameter = new [] {
51 new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
54 for (int i = 0; i < digitalTemperatures.Length; i++)
55 digitalTemperatures[i] = new Sensor("Digital Sensor " + i,
56 offset + i, SensorType.Temperature, this, parameter, settings);
57 offset += digitalTemperatures.Length;
59 for (int i = 0; i < analogTemperatures.Length; i++)
60 analogTemperatures[i] = new Sensor("Analog Sensor " + (i + 1),
61 offset + i, SensorType.Temperature, this, parameter, settings);
62 offset += analogTemperatures.Length;
64 for (int i = 0; i < sensorhubTemperatures.Length; i++)
65 sensorhubTemperatures[i] = new Sensor("Sensorhub Sensor " + i,
66 offset + i, SensorType.Temperature, this, parameter, settings);
67 offset += sensorhubTemperatures.Length;
69 for (int i = 0; i < miniNGTemperatures.Length; i++)
70 miniNGTemperatures[i] = new Sensor("miniNG #" + (i / 2 + 1) +
71 " Sensor " + (i % 2 + 1), offset + i, SensorType.Temperature,
72 this, parameter, settings);
73 offset += miniNGTemperatures.Length;
75 for (int i = 0; i < sensorhubFlows.Length; i++)
76 sensorhubFlows[i] = new Sensor("Flowmeter " + (i + 1),
77 i, SensorType.Flow, this, new [] {
78 new ParameterDescription("Impulse Rate",
79 "The impulse rate of the flowmeter in pulses/L", 509)
82 for (int i = 0; i < controls.Length; i++) {
83 controls[i] = new Sensor("Fan Channel " + i, i, SensorType.Control,
87 for (int i = 0; i < miniNGControls.Length; i++) {
88 miniNGControls[i] = new Sensor("miniNG #" + (i / 2 + 1) +
89 " Fan Channel " + (i % 2 + 1), 4 + i, SensorType.Control, this,
93 alternativeRequest = new MethodDelegate(DelayedAlternativeRequest);
99 protected override void ActivateSensor(ISensor sensor) {
100 deactivating.Remove(sensor);
101 base.ActivateSensor(sensor);
104 protected override void DeactivateSensor(ISensor sensor) {
105 if (deactivating.Contains(sensor)) {
106 deactivating.Remove(sensor);
107 base.DeactivateSensor(sensor);
108 } else if (active.Contains(sensor)) {
109 deactivating.Add(sensor);
113 private void ReadminiNG(int[] data, int number) {
114 int offset = 1 + number * 65;
116 if (data[offset + 61] != ENDFLAG)
119 for (int i = 0; i < 2; i++) {
120 Sensor sensor = miniNGTemperatures[number * 2 + i];
121 if (data[offset + 7 + i] > 0) {
122 sensor.Value = 0.5f * data[offset + 7 + i] +
123 sensor.Parameters[0].Value;
124 ActivateSensor(sensor);
126 DeactivateSensor(sensor);
130 for (int i = 0; i < 2; i++) {
131 if (miniNGFans[number * 2 + i] == null)
132 miniNGFans[number * 2 + i] =
133 new Sensor("miniNG #" + (number + 1) + " Fan Channel " + (i + 1),
134 4 + number * 2 + i, SensorType.Fan, this, settings);
136 Sensor sensor = miniNGFans[number * 2 + i];
138 sensor.Value = 20.0f * data[offset + 43 + 2 * i];
139 ActivateSensor(sensor);
142 for (int i = 0; i < 2; i++) {
143 Sensor sensor = miniNGControls[number * 2 + i];
144 sensor.Value = data[offset + 15 + i];
145 ActivateSensor(sensor);
149 private void ReadData() {
150 int[] data = new int[285];
151 for (int i = 0; i < data.Length; i++)
152 data[i] = FTD2XX.ReadByte(handle);
154 if (data[0] != STARTFLAG) {
155 FTD2XX.FT_Purge(handle, FT_PURGE.FT_PURGE_RX);
159 if (data[1] == 255 || data[1] == 88) { // bigNG
161 if (data[274] != protocolVersion)
164 this.primaryData = data;
166 for (int i = 0; i < digitalTemperatures.Length; i++)
167 if (data[238 + i] > 0) {
168 digitalTemperatures[i].Value = 0.5f * data[238 + i] +
169 digitalTemperatures[i].Parameters[0].Value;
170 ActivateSensor(digitalTemperatures[i]);
172 DeactivateSensor(digitalTemperatures[i]);
175 for (int i = 0; i < analogTemperatures.Length; i++)
176 if (data[260 + i] > 0) {
177 analogTemperatures[i].Value = 0.5f * data[260 + i] +
178 analogTemperatures[i].Parameters[0].Value;
179 ActivateSensor(analogTemperatures[i]);
181 DeactivateSensor(analogTemperatures[i]);
184 for (int i = 0; i < sensorhubTemperatures.Length; i++)
185 if (data[246 + i] > 0) {
186 sensorhubTemperatures[i].Value = 0.5f * data[246 + i] +
187 sensorhubTemperatures[i].Parameters[0].Value;
188 ActivateSensor(sensorhubTemperatures[i]);
190 DeactivateSensor(sensorhubTemperatures[i]);
193 for (int i = 0; i < sensorhubFlows.Length; i++)
194 if (data[231 + i] > 0 && data[234] > 0) {
195 float pulsesPerSecond = (data[231 + i] * 4.0f) / data[234];
196 float pulsesPerLiter = sensorhubFlows[i].Parameters[0].Value;
197 sensorhubFlows[i].Value = pulsesPerSecond * 3600 / pulsesPerLiter;
198 ActivateSensor(sensorhubFlows[i]);
200 DeactivateSensor(sensorhubFlows[i]);
203 for (int i = 0; i < fans.Length; i++) {
204 float maxRPM = 11.5f * ((data[149 + 2 * i] << 8) | data[148 + 2 * i]);
207 fans[i] = new Sensor("Fan Channel " + i, i, SensorType.Fan,
208 this, new [] { new ParameterDescription("MaxRPM",
209 "Maximum revolutions per minute (RPM) of the fan.", maxRPM)
213 if ((data[136] & (1 << i)) == 0) // pwm mode
214 value = 0.02f * data[137 + i];
216 value = 0.01f * data[141 + i];
218 fans[i].Value = fans[i].Parameters[0].Value * value;
219 ActivateSensor(fans[i]);
221 controls[i].Value = 100 * value;
222 ActivateSensor(controls[i]);
225 } else if (data[1] == 253) { // miniNG #1
226 this.alternativeData = data;
230 if (data[66] == 253) // miniNG #2
235 public override HardwareType HardwareType {
236 get { return HardwareType.TBalancer; }
239 public override string GetReport() {
240 StringBuilder r = new StringBuilder();
242 r.AppendLine("T-Balancer bigNG");
244 r.Append("Port Index: ");
245 r.AppendLine(portIndex.ToString(CultureInfo.InvariantCulture));
248 r.AppendLine("Primary System Information Answer");
250 r.AppendLine(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
252 for (int i = 0; i <= 0x11; i++) {
254 r.Append((i << 4).ToString("X3", CultureInfo.InvariantCulture));
256 for (int j = 0; j <= 0xF; j++) {
257 int index = ((i << 4) | j);
258 if (index < primaryData.Length) {
260 r.Append(primaryData[index].ToString("X2", CultureInfo.InvariantCulture));
267 if (alternativeData.Length > 0) {
268 r.AppendLine("Alternative System Information Answer");
270 r.AppendLine(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
272 for (int i = 0; i <= 0x11; i++) {
274 r.Append((i << 4).ToString("X3", CultureInfo.InvariantCulture));
276 for (int j = 0; j <= 0xF; j++) {
277 int index = ((i << 4) | j);
278 if (index < alternativeData.Length) {
280 r.Append(alternativeData[index].ToString("X2", CultureInfo.InvariantCulture));
291 private void DelayedAlternativeRequest() {
292 System.Threading.Thread.Sleep(500);
293 FTD2XX.Write(handle, new byte[] { 0x37 });
297 FTD2XX.FT_Open(portIndex, out handle);
298 FTD2XX.FT_SetBaudRate(handle, 19200);
299 FTD2XX.FT_SetDataCharacteristics(handle, 8, 1, 0);
300 FTD2XX.FT_SetFlowControl(handle, FT_FLOW_CONTROL.FT_FLOW_RTS_CTS, 0x11,
302 FTD2XX.FT_SetTimeouts(handle, 1000, 1000);
303 FTD2XX.FT_Purge(handle, FT_PURGE.FT_PURGE_ALL);
306 public override void Update() {
307 while (FTD2XX.BytesToRead(handle) >= 285)
309 if (FTD2XX.BytesToRead(handle) == 1)
310 FTD2XX.ReadByte(handle);
312 FTD2XX.Write(handle, new byte[] { 0x38 });
313 alternativeRequest.BeginInvoke(null, null);
316 public override void Close() {
317 FTD2XX.FT_Close(handle);