Rewritten the T-Balancer code to use the FTDI D2XX drivers directly instead of the System.IO.Ports.SerialPort class. The SerialPort class has some ugly problems like http://connect.microsoft.com/VisualStudio/feedback/details/140018/serialport-crashes-after-disconnect-of-usb-com-port or http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/8a1825d2-c84b-4620-91e7-3934a4d47330 for which no real solution seems to exist. And Microsoft doesn't feel like it needs to be fixed for years now.
1.1 --- a/GUI/CrashReportForm.cs Fri Apr 02 16:05:07 2010 +0000
1.2 +++ b/GUI/CrashReportForm.cs Mon Apr 05 15:31:19 2010 +0000
1.3 @@ -74,34 +74,37 @@
1.4 }
1.5
1.6 private void sendButton_Click(object sender, EventArgs e) {
1.7 - Version version = typeof(CrashReportForm).Assembly.GetName().Version;
1.8 - WebRequest request = WebRequest.Create(
1.9 - "http://openhardwaremonitor.org/report.php");
1.10 - request.Method = "POST";
1.11 - request.Timeout = 3000;
1.12 - request.ContentType = "application/x-www-form-urlencoded";
1.13 + try {
1.14 + Version version = typeof(CrashReportForm).Assembly.GetName().Version;
1.15 + WebRequest request = WebRequest.Create(
1.16 + "http://openhardwaremonitor.org/report.php");
1.17 + request.Method = "POST";
1.18 + request.Timeout = 3000;
1.19 + request.ContentType = "application/x-www-form-urlencoded";
1.20
1.21 - string report =
1.22 - "version=" + HttpUtility.UrlEncode(version.ToString()) + "&" +
1.23 - "report=" + HttpUtility.UrlEncode(reportTextBox.Text +
1.24 - commentTextBox.Text);
1.25 - byte[] byteArray = Encoding.UTF8.GetBytes(report);
1.26 - request.ContentLength = byteArray.Length;
1.27 -
1.28 - Stream dataStream = request.GetRequestStream();
1.29 - dataStream.Write(byteArray, 0, byteArray.Length);
1.30 - dataStream.Close();
1.31 - try {
1.32 - WebResponse response = request.GetResponse();
1.33 - dataStream = response.GetResponseStream();
1.34 - StreamReader reader = new StreamReader(dataStream);
1.35 - string responseFromServer = reader.ReadToEnd();
1.36 - reader.Close();
1.37 + string report =
1.38 + "version=" + HttpUtility.UrlEncode(version.ToString()) + "&" +
1.39 + "report=" + HttpUtility.UrlEncode(reportTextBox.Text +
1.40 + commentTextBox.Text);
1.41 + byte[] byteArray = Encoding.UTF8.GetBytes(report);
1.42 + request.ContentLength = byteArray.Length;
1.43 +
1.44 + Stream dataStream = request.GetRequestStream();
1.45 + dataStream.Write(byteArray, 0, byteArray.Length);
1.46 dataStream.Close();
1.47 - response.Close();
1.48 - } catch (WebException) {
1.49 + try {
1.50 + WebResponse response = request.GetResponse();
1.51 + dataStream = response.GetResponseStream();
1.52 + StreamReader reader = new StreamReader(dataStream);
1.53 + string responseFromServer = reader.ReadToEnd();
1.54 + reader.Close();
1.55 + dataStream.Close();
1.56 + response.Close();
1.57 + } catch (WebException) {
1.58 + }
1.59 + } finally {
1.60 + Close();
1.61 }
1.62 - Close();
1.63 }
1.64 }
1.65 }
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/Hardware/TBalancer/FTD2XX.cs Mon Apr 05 15:31:19 2010 +0000
2.3 @@ -0,0 +1,207 @@
2.4 +/*
2.5 +
2.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
2.7 +
2.8 + The contents of this file are subject to the Mozilla Public License Version
2.9 + 1.1 (the "License"); you may not use this file except in compliance with
2.10 + the License. You may obtain a copy of the License at
2.11 +
2.12 + http://www.mozilla.org/MPL/
2.13 +
2.14 + Software distributed under the License is distributed on an "AS IS" basis,
2.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
2.16 + for the specific language governing rights and limitations under the License.
2.17 +
2.18 + The Original Code is the Open Hardware Monitor code.
2.19 +
2.20 + The Initial Developer of the Original Code is
2.21 + Michael Möller <m.moeller@gmx.ch>.
2.22 + Portions created by the Initial Developer are Copyright (C) 2009-2010
2.23 + the Initial Developer. All Rights Reserved.
2.24 +
2.25 + Contributor(s):
2.26 +
2.27 + Alternatively, the contents of this file may be used under the terms of
2.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
2.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
2.30 + in which case the provisions of the GPL or the LGPL are applicable instead
2.31 + of those above. If you wish to allow use of your version of this file only
2.32 + under the terms of either the GPL or the LGPL, and not to allow others to
2.33 + use your version of this file under the terms of the MPL, indicate your
2.34 + decision by deleting the provisions above and replace them with the notice
2.35 + and other provisions required by the GPL or the LGPL. If you do not delete
2.36 + the provisions above, a recipient may use your version of this file under
2.37 + the terms of any one of the MPL, the GPL or the LGPL.
2.38 +
2.39 +*/
2.40 +
2.41 +using System;
2.42 +using System.Collections.Generic;
2.43 +using System.Runtime.InteropServices;
2.44 +
2.45 +namespace OpenHardwareMonitor.Hardware.TBalancer {
2.46 +
2.47 + public enum FT_DEVICE : uint {
2.48 + FT_DEVICE_BM,
2.49 + FT_DEVICE_AM,
2.50 + FT_DEVICE_100AX,
2.51 + FT_DEVICE_UNKNOWN,
2.52 + FT_DEVICE_2232,
2.53 + FT_DEVICE_232R,
2.54 + FT_DEVICE_2232H,
2.55 + FT_DEVICE_4232H
2.56 + }
2.57 +
2.58 + public enum FT_STATUS {
2.59 + FT_OK,
2.60 + FT_INVALID_HANDLE,
2.61 + FT_DEVICE_NOT_FOUND,
2.62 + FT_DEVICE_NOT_OPENED,
2.63 + FT_IO_ERROR,
2.64 + FT_INSUFFICIENT_RESOURCES,
2.65 + FT_INVALID_PARAMETER,
2.66 + FT_INVALID_BAUD_RATE,
2.67 + FT_DEVICE_NOT_OPENED_FOR_ERASE,
2.68 + FT_DEVICE_NOT_OPENED_FOR_WRITE,
2.69 + FT_FAILED_TO_WRITE_DEVICE,
2.70 + FT_EEPROM_READ_FAILED,
2.71 + FT_EEPROM_WRITE_FAILED,
2.72 + FT_EEPROM_ERASE_FAILED,
2.73 + FT_EEPROM_NOT_PRESENT,
2.74 + FT_EEPROM_NOT_PROGRAMMED,
2.75 + FT_INVALID_ARGS,
2.76 + FT_OTHER_ERROR
2.77 + }
2.78 +
2.79 + public enum FT_FLOW_CONTROL : ushort {
2.80 + FT_FLOW_DTR_DSR = 512,
2.81 + FT_FLOW_NONE = 0,
2.82 + FT_FLOW_RTS_CTS = 256,
2.83 + FT_FLOW_XON_XOFF = 1024,
2.84 + }
2.85 +
2.86 + public enum FT_PURGE : uint {
2.87 + FT_PURGE_RX = 1,
2.88 + FT_PURGE_TX = 2,
2.89 + FT_PURGE_ALL = 3,
2.90 + }
2.91 +
2.92 + [StructLayout(LayoutKind.Sequential)]
2.93 + public struct FT_HANDLE {
2.94 + private uint handle;
2.95 + }
2.96 +
2.97 + [StructLayout(LayoutKind.Sequential)]
2.98 + public struct FT_DEVICE_INFO_NODE {
2.99 + public uint Flags;
2.100 + public FT_DEVICE Type;
2.101 + public uint ID;
2.102 + public uint LocId;
2.103 + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
2.104 + public string SerialNumber;
2.105 + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
2.106 + public string Description;
2.107 + public FT_HANDLE Handle;
2.108 + }
2.109 +
2.110 + public class FTD2XX {
2.111 +
2.112 + public delegate FT_STATUS FT_CreateDeviceInfoListDelegate(
2.113 + out uint numDevices);
2.114 + public delegate FT_STATUS FT_GetDeviceInfoListDelegate(
2.115 + [Out] FT_DEVICE_INFO_NODE[] deviceInfoNodes, ref uint length);
2.116 + public delegate FT_STATUS FT_OpenDelegate(int device, out FT_HANDLE handle);
2.117 + public delegate FT_STATUS FT_CloseDelegate(FT_HANDLE handle);
2.118 + public delegate FT_STATUS FT_SetBaudRateDelegate(FT_HANDLE handle,
2.119 + uint baudRate);
2.120 + public delegate FT_STATUS FT_SetDataCharacteristicsDelegate(
2.121 + FT_HANDLE handle, byte wordLength, byte stopBits, byte parity);
2.122 + public delegate FT_STATUS FT_SetFlowControlDelegate(FT_HANDLE handle,
2.123 + FT_FLOW_CONTROL flowControl, byte xon, byte xoff);
2.124 + public delegate FT_STATUS FT_SetTimeoutsDelegate(FT_HANDLE handle,
2.125 + uint readTimeout, uint writeTimeout);
2.126 + public delegate FT_STATUS FT_WriteDelegate(FT_HANDLE handle, byte[] buffer,
2.127 + uint bytesToWrite, out uint bytesWritten);
2.128 + public delegate FT_STATUS FT_PurgeDelegate(FT_HANDLE handle, FT_PURGE mask);
2.129 + public delegate FT_STATUS FT_GetStatusDelegate(FT_HANDLE handle,
2.130 + out uint amountInRxQueue, out uint amountInTxQueue, out uint eventStatus);
2.131 + public delegate FT_STATUS FT_ReadDelegate(FT_HANDLE handle,
2.132 + [Out] byte[] buffer, uint bytesToRead, out uint bytesReturned);
2.133 +
2.134 + public static FT_CreateDeviceInfoListDelegate FT_CreateDeviceInfoList;
2.135 + public static FT_GetDeviceInfoListDelegate FT_GetDeviceInfoList;
2.136 + public static FT_OpenDelegate FT_Open;
2.137 + public static FT_CloseDelegate FT_Close;
2.138 + public static FT_SetBaudRateDelegate FT_SetBaudRate;
2.139 + public static FT_SetDataCharacteristicsDelegate FT_SetDataCharacteristics;
2.140 + public static FT_SetFlowControlDelegate FT_SetFlowControl;
2.141 + public static FT_SetTimeoutsDelegate FT_SetTimeouts;
2.142 + public static FT_WriteDelegate FT_Write;
2.143 + public static FT_PurgeDelegate FT_Purge;
2.144 + public static FT_GetStatusDelegate FT_GetStatus;
2.145 + public static FT_ReadDelegate FT_Read;
2.146 +
2.147 + public static FT_STATUS Write(FT_HANDLE handle, byte[] buffer) {
2.148 + uint bytesWritten;
2.149 + FT_STATUS status = FT_Write(handle, buffer, (uint)buffer.Length,
2.150 + out bytesWritten);
2.151 + if (bytesWritten != buffer.Length)
2.152 + return FT_STATUS.FT_FAILED_TO_WRITE_DEVICE;
2.153 + else
2.154 + return status;
2.155 + }
2.156 +
2.157 + public static int BytesToRead(FT_HANDLE handle) {
2.158 + uint amountInRxQueue;
2.159 + uint amountInTxQueue;
2.160 + uint eventStatus;
2.161 + if (FT_GetStatus(handle, out amountInRxQueue, out amountInTxQueue,
2.162 + out eventStatus) == FT_STATUS.FT_OK) {
2.163 + return (int)amountInRxQueue;
2.164 + } else {
2.165 + return 0;
2.166 + }
2.167 + }
2.168 +
2.169 + public static byte ReadByte(FT_HANDLE handle) {
2.170 + byte[] buffer = new byte[1];
2.171 + uint bytesReturned;
2.172 + FT_STATUS status = FT_Read(handle, buffer, 1, out bytesReturned);
2.173 + if (status != FT_STATUS.FT_OK || bytesReturned != 1)
2.174 + throw new Exception();
2.175 + return buffer[0];
2.176 + }
2.177 +
2.178 + private static string dllName;
2.179 +
2.180 + private static void GetDelegate<T>(string entryPoint, out T newDelegate)
2.181 + where T : class {
2.182 + DllImportAttribute attribute = new DllImportAttribute(dllName);
2.183 + attribute.CallingConvention = CallingConvention.StdCall;
2.184 + attribute.PreserveSig = true;
2.185 + attribute.EntryPoint = entryPoint;
2.186 + PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
2.187 + }
2.188 +
2.189 + static FTD2XX() {
2.190 + int p = (int)System.Environment.OSVersion.Platform;
2.191 + if ((p == 4) || (p == 128))
2.192 + dllName = "libftd2xx.so";
2.193 + else
2.194 + dllName = "ftd2xx.dll";
2.195 +
2.196 + GetDelegate("FT_CreateDeviceInfoList", out FT_CreateDeviceInfoList);
2.197 + GetDelegate("FT_GetDeviceInfoList", out FT_GetDeviceInfoList);
2.198 + GetDelegate("FT_Open", out FT_Open);
2.199 + GetDelegate("FT_Close", out FT_Close);
2.200 + GetDelegate("FT_SetBaudRate", out FT_SetBaudRate);
2.201 + GetDelegate("FT_SetDataCharacteristics", out FT_SetDataCharacteristics);
2.202 + GetDelegate("FT_SetFlowControl", out FT_SetFlowControl);
2.203 + GetDelegate("FT_SetTimeouts", out FT_SetTimeouts);
2.204 + GetDelegate("FT_Write", out FT_Write);
2.205 + GetDelegate("FT_Purge", out FT_Purge);
2.206 + GetDelegate("FT_GetStatus", out FT_GetStatus);
2.207 + GetDelegate("FT_Read", out FT_Read);
2.208 + }
2.209 + }
2.210 +}
3.1 --- a/Hardware/TBalancer/TBalancer.cs Fri Apr 02 16:05:07 2010 +0000
3.2 +++ b/Hardware/TBalancer/TBalancer.cs Mon Apr 05 15:31:19 2010 +0000
3.3 @@ -39,16 +39,14 @@
3.4 using System.Collections.Generic;
3.5 using System.Configuration;
3.6 using System.Drawing;
3.7 -using System.IO;
3.8 -using System.IO.Ports;
3.9 using System.Text;
3.10
3.11 namespace OpenHardwareMonitor.Hardware.TBalancer {
3.12 public class TBalancer : IHardware {
3.13
3.14 - private string portName;
3.15 + private int portIndex;
3.16 + private FT_HANDLE handle;
3.17 private Image icon;
3.18 - private SerialPort serialPort;
3.19 private byte protocolVersion;
3.20 private Sensor[] digitalTemperatures = new Sensor[8];
3.21 private Sensor[] analogTemperatures = new Sensor[4];
3.22 @@ -68,8 +66,8 @@
3.23 private delegate void MethodDelegate();
3.24 private MethodDelegate alternativeRequest;
3.25
3.26 - public TBalancer(string portName, byte protocolVersion) {
3.27 - this.portName = portName;
3.28 + public TBalancer(int portIndex, byte protocolVersion) {
3.29 + this.portIndex = portIndex;
3.30 this.icon = Utilities.EmbeddedResources.GetImage("bigng.png");
3.31 this.protocolVersion = protocolVersion;
3.32
3.33 @@ -108,12 +106,8 @@
3.34
3.35 alternativeRequest = new MethodDelegate(DelayedAlternativeRequest);
3.36
3.37 - try {
3.38 - serialPort = new SerialPort(portName, 19200, Parity.None, 8,
3.39 - StopBits.One);
3.40 - serialPort.Open();
3.41 - Update();
3.42 - } catch (IOException) { }
3.43 + Open();
3.44 + Update();
3.45 }
3.46
3.47 private void ActivateSensor(Sensor sensor) {
3.48 @@ -171,10 +165,10 @@
3.49 private void ReadData() {
3.50 int[] data = new int[285];
3.51 for (int i = 0; i < data.Length; i++)
3.52 - data[i] = serialPort.ReadByte();
3.53 + data[i] = FTD2XX.ReadByte(handle);
3.54
3.55 if (data[0] != STARTFLAG) {
3.56 - serialPort.DiscardInBuffer();
3.57 + FTD2XX.FT_Purge(handle, FT_PURGE.FT_PURGE_RX);
3.58 return;
3.59 }
3.60
3.61 @@ -258,8 +252,7 @@
3.62 }
3.63
3.64 public string Identifier {
3.65 - get { return "/bigng/" +
3.66 - this.portName.TrimStart(new char[]{'/'}).ToLower(); }
3.67 + get { return "/bigng/" + this.portIndex; }
3.68 }
3.69
3.70 public IHardware[] SubHardware {
3.71 @@ -275,7 +268,7 @@
3.72
3.73 r.AppendLine("T-Balancer bigNG");
3.74 r.AppendLine();
3.75 - r.Append("Port Name: "); r.AppendLine(serialPort.PortName);
3.76 + r.Append("Port Index: "); r.AppendLine(portIndex.ToString());
3.77 r.AppendLine();
3.78
3.79 r.AppendLine("Primary System Information Answer");
3.80 @@ -318,31 +311,32 @@
3.81 }
3.82
3.83 private void DelayedAlternativeRequest() {
3.84 - System.Threading.Thread.Sleep(500);
3.85 - try {
3.86 - if (serialPort.IsOpen)
3.87 - serialPort.Write(new byte[] { 0x37 }, 0, 1);
3.88 - } catch (Exception) { }
3.89 + System.Threading.Thread.Sleep(500);
3.90 + FTD2XX.Write(handle, new byte[] { 0x37 });
3.91 }
3.92
3.93 - public void Update() {
3.94 - try {
3.95 - while (serialPort.IsOpen && serialPort.BytesToRead >= 285)
3.96 - ReadData();
3.97 - if (serialPort.BytesToRead == 1)
3.98 - serialPort.ReadByte();
3.99 + public void Open() {
3.100 + FTD2XX.FT_Open(portIndex, out handle);
3.101 + FTD2XX.FT_SetBaudRate(handle, 19200);
3.102 + FTD2XX.FT_SetDataCharacteristics(handle, 8, 1, 0);
3.103 + FTD2XX.FT_SetFlowControl(handle, FT_FLOW_CONTROL.FT_FLOW_RTS_CTS, 0x11,
3.104 + 0x13);
3.105 + FTD2XX.FT_SetTimeouts(handle, 1000, 1000);
3.106 + FTD2XX.FT_Purge(handle, FT_PURGE.FT_PURGE_ALL);
3.107 + }
3.108
3.109 - serialPort.Write(new byte[] { 0x38 }, 0, 1);
3.110 - alternativeRequest.BeginInvoke(null, null);
3.111 - } catch (InvalidOperationException) {
3.112 - foreach (Sensor sensor in active)
3.113 - sensor.Value = null;
3.114 - }
3.115 + public void Update() {
3.116 + while (FTD2XX.BytesToRead(handle) >= 285)
3.117 + ReadData();
3.118 + if (FTD2XX.BytesToRead(handle) == 1)
3.119 + FTD2XX.ReadByte(handle);
3.120 +
3.121 + FTD2XX.Write(handle, new byte[] { 0x38 });
3.122 + alternativeRequest.BeginInvoke(null, null);
3.123 }
3.124
3.125 public void Close() {
3.126 - if (serialPort.IsOpen)
3.127 - serialPort.Close();
3.128 + FTD2XX.FT_Close(handle);
3.129 }
3.130
3.131 public event SensorEventHandler SensorAdded;
4.1 --- a/Hardware/TBalancer/TBalancerGroup.cs Fri Apr 02 16:05:07 2010 +0000
4.2 +++ b/Hardware/TBalancer/TBalancerGroup.cs Mon Apr 05 15:31:19 2010 +0000
4.3 @@ -49,79 +49,87 @@
4.4 private StringBuilder report = new StringBuilder();
4.5
4.6 public TBalancerGroup() {
4.7 -
4.8 - string[] portNames = SerialPort.GetPortNames();
4.9 - for (int i = portNames.Length - 1; i >= 0; i--) {
4.10 - try {
4.11
4.12 - SerialPort serialPort =
4.13 - new SerialPort(portNames[i], 19200, Parity.None, 8, StopBits.One);
4.14 -
4.15 - bool isValid = false;
4.16 - byte protocolVersion = 0;
4.17 - report.Append("Port Name: "); report.AppendLine(portNames[i]);
4.18 + uint numDevices;
4.19 + try {
4.20 + FTD2XX.FT_CreateDeviceInfoList(out numDevices);
4.21 + } catch (DllNotFoundException) { return; }
4.22 + catch (ArgumentNullException) { return; }
4.23 +
4.24 + FT_DEVICE_INFO_NODE[] info = new FT_DEVICE_INFO_NODE[numDevices];
4.25 + FTD2XX.FT_GetDeviceInfoList(info, ref numDevices);
4.26
4.27 - try {
4.28 - serialPort.Open();
4.29 - } catch (UnauthorizedAccessException) {
4.30 - report.AppendLine("Exception: Access Denied");
4.31 - }
4.32 -
4.33 - if (serialPort.IsOpen) {
4.34 - if (serialPort.CtsHolding) {
4.35 - serialPort.DiscardInBuffer();
4.36 - serialPort.DiscardOutBuffer();
4.37 - serialPort.Write(new byte[] { 0x38 }, 0, 1);
4.38 - int j = 0;
4.39 - while (serialPort.BytesToRead == 0 && j < 2) {
4.40 - Thread.Sleep(100);
4.41 - j++;
4.42 - }
4.43 - if (serialPort.BytesToRead > 0) {
4.44 - if (serialPort.ReadByte() == TBalancer.STARTFLAG) {
4.45 - while (serialPort.BytesToRead < 284 && j < 5) {
4.46 - Thread.Sleep(100);
4.47 - j++;
4.48 - }
4.49 - int length = serialPort.BytesToRead;
4.50 - if (length >= 284) {
4.51 - byte[] data = new byte[285];
4.52 - data[0] = TBalancer.STARTFLAG;
4.53 - for (int k = 1; k < data.Length; k++)
4.54 - data[k] = (byte)serialPort.ReadByte();
4.55 + for (int i = 0; i < numDevices; i++) {
4.56 + report.Append("Device Index: "); report.AppendLine(i.ToString());
4.57 +
4.58 + FT_HANDLE handle;
4.59 + FT_STATUS status;
4.60 + status = FTD2XX.FT_Open(i, out handle);
4.61 + if (status != FT_STATUS.FT_OK) {
4.62 + report.AppendLine("Open Status: " + status);
4.63 + continue;
4.64 + }
4.65
4.66 - // check protocol version 2X (protocols seen: 2C, 2A, 28)
4.67 - isValid = (data[274] & 0xF0) == 0x20;
4.68 - protocolVersion = data[274];
4.69 - if (!isValid) {
4.70 - report.Append("Status: Wrong Protocol Version: 0x");
4.71 - report.AppendLine(protocolVersion.ToString("X"));
4.72 - }
4.73 - } else {
4.74 - report.AppendLine("Status: Wrong Message Length: " +length);
4.75 - }
4.76 - } else {
4.77 - report.AppendLine("Status: Wrong Startflag");
4.78 - }
4.79 - } else {
4.80 - report.AppendLine("Status: No Response");
4.81 + FTD2XX.FT_SetBaudRate(handle, 19200);
4.82 + FTD2XX.FT_SetDataCharacteristics(handle, 8, 1, 0);
4.83 + FTD2XX.FT_SetFlowControl(handle, FT_FLOW_CONTROL.FT_FLOW_RTS_CTS, 0x11,
4.84 + 0x13);
4.85 + FTD2XX.FT_SetTimeouts(handle, 1000, 1000);
4.86 + FTD2XX.FT_Purge(handle, FT_PURGE.FT_PURGE_ALL);
4.87 +
4.88 + status = FTD2XX.Write(handle, new byte[] { 0x38 });
4.89 + if (status != FT_STATUS.FT_OK) {
4.90 + report.AppendLine("Write Status: " + status);
4.91 + FTD2XX.FT_Close(handle);
4.92 + continue;
4.93 + }
4.94 +
4.95 + bool isValid = false;
4.96 + byte protocolVersion = 0;
4.97 +
4.98 + int j = 0;
4.99 + while (FTD2XX.BytesToRead(handle) == 0 && j < 2) {
4.100 + Thread.Sleep(100);
4.101 + j++;
4.102 + }
4.103 + if (FTD2XX.BytesToRead(handle) > 0) {
4.104 + if (FTD2XX.ReadByte(handle) == TBalancer.STARTFLAG) {
4.105 + while (FTD2XX.BytesToRead(handle) < 284 && j < 5) {
4.106 + Thread.Sleep(100);
4.107 + j++;
4.108 + }
4.109 + int length = FTD2XX.BytesToRead(handle);
4.110 + if (length >= 284) {
4.111 + byte[] data = new byte[285];
4.112 + data[0] = TBalancer.STARTFLAG;
4.113 + for (int k = 1; k < data.Length; k++)
4.114 + data[k] = FTD2XX.ReadByte(handle);
4.115 +
4.116 + // check protocol version 2X (protocols seen: 2C, 2A, 28)
4.117 + isValid = (data[274] & 0xF0) == 0x20;
4.118 + protocolVersion = data[274];
4.119 + if (!isValid) {
4.120 + report.Append("Status: Wrong Protocol Version: 0x");
4.121 + report.AppendLine(protocolVersion.ToString("X"));
4.122 }
4.123 } else {
4.124 - report.AppendLine("Status: Not Clear to Send");
4.125 + report.AppendLine("Status: Wrong Message Length: " + length);
4.126 }
4.127 - serialPort.DiscardInBuffer();
4.128 - serialPort.Close();
4.129 - } else {
4.130 - report.AppendLine("Status: Port not Open");
4.131 - }
4.132 - if (isValid) {
4.133 - report.AppendLine("Status: OK");
4.134 - hardware.Add(new TBalancer(portNames[i], protocolVersion));
4.135 - return;
4.136 + } else {
4.137 + report.AppendLine("Status: Wrong Startflag");
4.138 }
4.139 - } catch (Exception e) {
4.140 - report.AppendLine(e.ToString());
4.141 - }
4.142 + } else {
4.143 + report.AppendLine("Status: No Response");
4.144 + }
4.145 +
4.146 + FTD2XX.FT_Purge(handle, FT_PURGE.FT_PURGE_ALL);
4.147 + FTD2XX.FT_Close(handle);
4.148 +
4.149 + if (isValid) {
4.150 + report.AppendLine("Status: OK");
4.151 + hardware.Add(new TBalancer(i, protocolVersion));
4.152 + return;
4.153 + }
4.154 report.AppendLine();
4.155 }
4.156 }
4.157 @@ -134,7 +142,7 @@
4.158
4.159 public string GetReport() {
4.160 if (report.Length > 0) {
4.161 - report.Insert(0, "Serial Port T-Balancer" + Environment.NewLine +
4.162 + report.Insert(0, "FTD2XX" + Environment.NewLine +
4.163 Environment.NewLine);
4.164 report.AppendLine();
4.165 return report.ToString();
5.1 --- a/OpenHardwareMonitor.csproj Fri Apr 02 16:05:07 2010 +0000
5.2 +++ b/OpenHardwareMonitor.csproj Mon Apr 05 15:31:19 2010 +0000
5.3 @@ -95,6 +95,7 @@
5.4 <Compile Include="Hardware\Mainboard\SMBIOS.cs" />
5.5 <Compile Include="Hardware\LPC\W836XX.cs" />
5.6 <Compile Include="Hardware\Computer.cs" />
5.7 + <Compile Include="Hardware\TBalancer\FTD2XX.cs" />
5.8 <Compile Include="Properties\AssemblyInfo.cs" />
5.9 <Compile Include="GUI\AboutBox.cs">
5.10 <SubType>Form</SubType>
6.1 --- a/Program.cs Fri Apr 02 16:05:07 2010 +0000
6.2 +++ b/Program.cs Mon Apr 05 15:31:19 2010 +0000
6.3 @@ -48,6 +48,11 @@
6.4 [STAThread]
6.5 public static void Main() {
6.6 #if !DEBUG
6.7 + Application.ThreadException +=
6.8 + new ThreadExceptionEventHandler(Application_ThreadException);
6.9 + Application.SetUnhandledExceptionMode(
6.10 + UnhandledExceptionMode.CatchException);
6.11 +
6.12 AppDomain.CurrentDomain.UnhandledException +=
6.13 new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
6.14 #endif
6.15 @@ -62,13 +67,31 @@
6.16 }
6.17 }
6.18
6.19 + private static void ReportException(Exception e) {
6.20 + CrashReportForm form = new CrashReportForm();
6.21 + form.Exception = e;
6.22 + form.ShowDialog();
6.23 + }
6.24 +
6.25 + public static void Application_ThreadException(object sender,
6.26 + ThreadExceptionEventArgs e)
6.27 + {
6.28 + try {
6.29 + ReportException(e.Exception);
6.30 + } catch {
6.31 + } finally {
6.32 + Application.Exit();
6.33 + }
6.34 + }
6.35 +
6.36 public static void CurrentDomain_UnhandledException(object sender,
6.37 UnhandledExceptionEventArgs args)
6.38 {
6.39 - CrashReportForm form = new CrashReportForm();
6.40 - form.Exception = (Exception)args.ExceptionObject;
6.41 - form.ShowDialog();
6.42 - Environment.Exit(0);
6.43 + try {
6.44 + Exception e = args.ExceptionObject as Exception;
6.45 + if (e != null)
6.46 + ReportException(e);
6.47 + } catch { }
6.48 }
6.49 }
6.50 }