Hardware/TBalancer/FTD2XX.cs
author moel.mich
Tue, 25 May 2010 18:57:28 +0000
changeset 127 76aaf45a01c7
child 165 813d8bc3192f
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@87
     1
/*
moel@87
     2
  
moel@87
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@87
     4
moel@87
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@87
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@87
     7
  the License. You may obtain a copy of the License at
moel@87
     8
 
moel@87
     9
  http://www.mozilla.org/MPL/
moel@87
    10
moel@87
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@87
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@87
    13
  for the specific language governing rights and limitations under the License.
moel@87
    14
moel@87
    15
  The Original Code is the Open Hardware Monitor code.
moel@87
    16
moel@87
    17
  The Initial Developer of the Original Code is 
moel@87
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@87
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@87
    20
  the Initial Developer. All Rights Reserved.
moel@87
    21
moel@87
    22
  Contributor(s):
moel@87
    23
moel@87
    24
  Alternatively, the contents of this file may be used under the terms of
moel@87
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@87
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@87
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@87
    28
  of those above. If you wish to allow use of your version of this file only
moel@87
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@87
    30
  use your version of this file under the terms of the MPL, indicate your
moel@87
    31
  decision by deleting the provisions above and replace them with the notice
moel@87
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@87
    33
  the provisions above, a recipient may use your version of this file under
moel@87
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@87
    35
 
moel@87
    36
*/
moel@87
    37
moel@87
    38
using System;
moel@87
    39
using System.Collections.Generic;
moel@87
    40
using System.Runtime.InteropServices;
moel@87
    41
moel@87
    42
namespace OpenHardwareMonitor.Hardware.TBalancer {
moel@87
    43
moel@87
    44
  public enum FT_DEVICE : uint {
moel@87
    45
    FT_DEVICE_BM,
moel@87
    46
    FT_DEVICE_AM,
moel@87
    47
    FT_DEVICE_100AX,
moel@87
    48
    FT_DEVICE_UNKNOWN,
moel@87
    49
    FT_DEVICE_2232,
moel@87
    50
    FT_DEVICE_232R,
moel@87
    51
    FT_DEVICE_2232H,
moel@87
    52
    FT_DEVICE_4232H
moel@87
    53
  }
moel@87
    54
moel@87
    55
  public enum FT_STATUS {
moel@87
    56
    FT_OK,
moel@87
    57
    FT_INVALID_HANDLE,
moel@87
    58
    FT_DEVICE_NOT_FOUND,
moel@87
    59
    FT_DEVICE_NOT_OPENED,
moel@87
    60
    FT_IO_ERROR,
moel@87
    61
    FT_INSUFFICIENT_RESOURCES,
moel@87
    62
    FT_INVALID_PARAMETER,
moel@87
    63
    FT_INVALID_BAUD_RATE,
moel@87
    64
    FT_DEVICE_NOT_OPENED_FOR_ERASE,
moel@87
    65
    FT_DEVICE_NOT_OPENED_FOR_WRITE,
moel@87
    66
    FT_FAILED_TO_WRITE_DEVICE,
moel@87
    67
    FT_EEPROM_READ_FAILED,
moel@87
    68
    FT_EEPROM_WRITE_FAILED,
moel@87
    69
    FT_EEPROM_ERASE_FAILED,
moel@87
    70
    FT_EEPROM_NOT_PRESENT,
moel@87
    71
    FT_EEPROM_NOT_PROGRAMMED,
moel@87
    72
    FT_INVALID_ARGS,
moel@87
    73
    FT_OTHER_ERROR
moel@87
    74
  }
moel@87
    75
moel@87
    76
  public enum FT_FLOW_CONTROL : ushort {
moel@87
    77
    FT_FLOW_DTR_DSR = 512,
moel@87
    78
    FT_FLOW_NONE = 0,
moel@87
    79
    FT_FLOW_RTS_CTS = 256,
moel@87
    80
    FT_FLOW_XON_XOFF = 1024,
moel@87
    81
  }
moel@87
    82
moel@87
    83
  public enum FT_PURGE : uint {
moel@87
    84
    FT_PURGE_RX = 1,
moel@87
    85
    FT_PURGE_TX = 2,
moel@87
    86
    FT_PURGE_ALL = 3,
moel@87
    87
  }
moel@87
    88
moel@87
    89
  [StructLayout(LayoutKind.Sequential)]
moel@87
    90
  public struct FT_HANDLE {
moel@87
    91
    private uint handle;
moel@87
    92
  }
moel@87
    93
moel@87
    94
  [StructLayout(LayoutKind.Sequential)]
moel@87
    95
  public struct FT_DEVICE_INFO_NODE {    
moel@87
    96
    public uint Flags;
moel@87
    97
    public FT_DEVICE Type; 
moel@87
    98
    public uint ID; 
moel@87
    99
    public uint LocId; 
moel@87
   100
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
moel@87
   101
    public string SerialNumber; 
moel@87
   102
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
moel@87
   103
    public string Description;
moel@87
   104
    public FT_HANDLE Handle;
moel@87
   105
  }
moel@87
   106
moel@87
   107
  public class FTD2XX {
moel@87
   108
moel@87
   109
    public delegate FT_STATUS FT_CreateDeviceInfoListDelegate(
moel@87
   110
      out uint numDevices);
moel@87
   111
    public delegate FT_STATUS FT_GetDeviceInfoListDelegate(
moel@87
   112
      [Out] FT_DEVICE_INFO_NODE[] deviceInfoNodes, ref uint length);
moel@87
   113
    public delegate FT_STATUS FT_OpenDelegate(int device, out FT_HANDLE handle);
moel@87
   114
    public delegate FT_STATUS FT_CloseDelegate(FT_HANDLE handle);
moel@87
   115
    public delegate FT_STATUS FT_SetBaudRateDelegate(FT_HANDLE handle,
moel@87
   116
      uint baudRate);
moel@87
   117
    public delegate FT_STATUS FT_SetDataCharacteristicsDelegate(
moel@87
   118
      FT_HANDLE handle, byte wordLength, byte stopBits, byte parity);
moel@87
   119
    public delegate FT_STATUS FT_SetFlowControlDelegate(FT_HANDLE handle,
moel@87
   120
      FT_FLOW_CONTROL flowControl, byte xon, byte xoff);
moel@87
   121
    public delegate FT_STATUS FT_SetTimeoutsDelegate(FT_HANDLE handle,
moel@87
   122
      uint readTimeout, uint writeTimeout);
moel@87
   123
    public delegate FT_STATUS FT_WriteDelegate(FT_HANDLE handle, byte[] buffer,
moel@87
   124
      uint bytesToWrite, out uint bytesWritten);
moel@87
   125
    public delegate FT_STATUS FT_PurgeDelegate(FT_HANDLE handle, FT_PURGE mask);
moel@87
   126
    public delegate FT_STATUS FT_GetStatusDelegate(FT_HANDLE handle,
moel@87
   127
      out uint amountInRxQueue, out uint amountInTxQueue, out uint eventStatus);
moel@87
   128
    public delegate FT_STATUS FT_ReadDelegate(FT_HANDLE handle, 
moel@87
   129
      [Out] byte[] buffer, uint bytesToRead, out uint bytesReturned);
moel@87
   130
moel@87
   131
    public static FT_CreateDeviceInfoListDelegate FT_CreateDeviceInfoList;
moel@87
   132
    public static FT_GetDeviceInfoListDelegate FT_GetDeviceInfoList;
moel@87
   133
    public static FT_OpenDelegate FT_Open;
moel@87
   134
    public static FT_CloseDelegate FT_Close;
moel@87
   135
    public static FT_SetBaudRateDelegate FT_SetBaudRate;
moel@87
   136
    public static FT_SetDataCharacteristicsDelegate FT_SetDataCharacteristics;
moel@87
   137
    public static FT_SetFlowControlDelegate FT_SetFlowControl;
moel@87
   138
    public static FT_SetTimeoutsDelegate FT_SetTimeouts;
moel@87
   139
    public static FT_WriteDelegate FT_Write;
moel@87
   140
    public static FT_PurgeDelegate FT_Purge;
moel@87
   141
    public static FT_GetStatusDelegate FT_GetStatus;
moel@87
   142
    public static FT_ReadDelegate FT_Read;
moel@87
   143
moel@87
   144
    public static FT_STATUS Write(FT_HANDLE handle, byte[] buffer) {
moel@87
   145
      uint bytesWritten;
moel@87
   146
      FT_STATUS status = FT_Write(handle, buffer, (uint)buffer.Length, 
moel@87
   147
        out bytesWritten);
moel@87
   148
      if (bytesWritten != buffer.Length)
moel@87
   149
        return FT_STATUS.FT_FAILED_TO_WRITE_DEVICE;
moel@87
   150
      else
moel@87
   151
        return status;
moel@87
   152
    }
moel@87
   153
moel@87
   154
    public static int BytesToRead(FT_HANDLE handle) {
moel@87
   155
      uint amountInRxQueue;
moel@87
   156
      uint amountInTxQueue;
moel@87
   157
      uint eventStatus;
moel@87
   158
      if (FT_GetStatus(handle, out amountInRxQueue, out amountInTxQueue,
moel@87
   159
        out eventStatus) == FT_STATUS.FT_OK) {
moel@87
   160
        return (int)amountInRxQueue;
moel@87
   161
      } else {
moel@87
   162
        return 0;
moel@87
   163
      }
moel@87
   164
    }
moel@87
   165
moel@87
   166
    public static byte ReadByte(FT_HANDLE handle) {
moel@87
   167
      byte[] buffer = new byte[1];
moel@87
   168
      uint bytesReturned;
moel@87
   169
      FT_STATUS status = FT_Read(handle, buffer, 1, out bytesReturned);
moel@87
   170
      if (status != FT_STATUS.FT_OK || bytesReturned != 1)
moel@87
   171
        throw new Exception();
moel@87
   172
      return buffer[0];
moel@87
   173
    }
moel@87
   174
moel@87
   175
    private static string dllName;
moel@87
   176
moel@87
   177
    private static void GetDelegate<T>(string entryPoint, out T newDelegate)
moel@87
   178
      where T : class {
moel@87
   179
      DllImportAttribute attribute = new DllImportAttribute(dllName);
moel@87
   180
      attribute.CallingConvention = CallingConvention.StdCall;
moel@87
   181
      attribute.PreserveSig = true;
moel@87
   182
      attribute.EntryPoint = entryPoint;
moel@87
   183
      PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
moel@87
   184
    }
moel@87
   185
moel@87
   186
    static FTD2XX() {
moel@87
   187
      int p = (int)System.Environment.OSVersion.Platform;
moel@87
   188
      if ((p == 4) || (p == 128))
moel@87
   189
        dllName = "libftd2xx.so";
moel@87
   190
      else
moel@87
   191
        dllName = "ftd2xx.dll";
moel@87
   192
moel@87
   193
      GetDelegate("FT_CreateDeviceInfoList", out FT_CreateDeviceInfoList);
moel@87
   194
      GetDelegate("FT_GetDeviceInfoList", out FT_GetDeviceInfoList);
moel@87
   195
      GetDelegate("FT_Open", out FT_Open);
moel@87
   196
      GetDelegate("FT_Close", out FT_Close);
moel@87
   197
      GetDelegate("FT_SetBaudRate", out FT_SetBaudRate);
moel@87
   198
      GetDelegate("FT_SetDataCharacteristics", out FT_SetDataCharacteristics);
moel@87
   199
      GetDelegate("FT_SetFlowControl", out FT_SetFlowControl);
moel@87
   200
      GetDelegate("FT_SetTimeouts", out FT_SetTimeouts);
moel@87
   201
      GetDelegate("FT_Write", out FT_Write);
moel@87
   202
      GetDelegate("FT_Purge", out FT_Purge);
moel@87
   203
      GetDelegate("FT_GetStatus", out FT_GetStatus);
moel@87
   204
      GetDelegate("FT_Read", out FT_Read);
moel@87
   205
    }
moel@87
   206
  }
moel@87
   207
}