Hardware/TBalancer/FTD2XX.cs
author moel.mich
Sat, 27 Oct 2012 11:40:28 +0000
changeset 384 76f859f4aea1
parent 344 3145aadca3d2
permissions -rw-r--r--
Reduced the amount of dynamic memory allocation when reading from the T-Balancer or creating tray icons.
moel@87
     1
/*
moel@87
     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@87
     6
 
moel@384
     7
  Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
moel@344
     8
	
moel@87
     9
*/
moel@87
    10
moel@87
    11
using System;
moel@87
    12
using System.Runtime.InteropServices;
moel@87
    13
moel@87
    14
namespace OpenHardwareMonitor.Hardware.TBalancer {
moel@87
    15
moel@165
    16
  internal enum FT_DEVICE : uint {
moel@186
    17
    FT_DEVICE_232BM,
moel@186
    18
    FT_DEVICE_232AM,
moel@87
    19
    FT_DEVICE_100AX,
moel@87
    20
    FT_DEVICE_UNKNOWN,
moel@186
    21
    FT_DEVICE_2232C,
moel@87
    22
    FT_DEVICE_232R,
moel@87
    23
    FT_DEVICE_2232H,
moel@87
    24
    FT_DEVICE_4232H
moel@87
    25
  }
moel@87
    26
moel@165
    27
  internal enum FT_STATUS {
moel@87
    28
    FT_OK,
moel@87
    29
    FT_INVALID_HANDLE,
moel@87
    30
    FT_DEVICE_NOT_FOUND,
moel@87
    31
    FT_DEVICE_NOT_OPENED,
moel@87
    32
    FT_IO_ERROR,
moel@87
    33
    FT_INSUFFICIENT_RESOURCES,
moel@87
    34
    FT_INVALID_PARAMETER,
moel@87
    35
    FT_INVALID_BAUD_RATE,
moel@87
    36
    FT_DEVICE_NOT_OPENED_FOR_ERASE,
moel@87
    37
    FT_DEVICE_NOT_OPENED_FOR_WRITE,
moel@87
    38
    FT_FAILED_TO_WRITE_DEVICE,
moel@87
    39
    FT_EEPROM_READ_FAILED,
moel@87
    40
    FT_EEPROM_WRITE_FAILED,
moel@87
    41
    FT_EEPROM_ERASE_FAILED,
moel@87
    42
    FT_EEPROM_NOT_PRESENT,
moel@87
    43
    FT_EEPROM_NOT_PROGRAMMED,
moel@87
    44
    FT_INVALID_ARGS,
moel@87
    45
    FT_OTHER_ERROR
moel@87
    46
  }
moel@87
    47
moel@165
    48
  internal enum FT_FLOW_CONTROL : ushort {
moel@87
    49
    FT_FLOW_DTR_DSR = 512,
moel@87
    50
    FT_FLOW_NONE = 0,
moel@87
    51
    FT_FLOW_RTS_CTS = 256,
moel@87
    52
    FT_FLOW_XON_XOFF = 1024,
moel@87
    53
  }
moel@87
    54
moel@165
    55
  internal enum FT_PURGE : uint {
moel@87
    56
    FT_PURGE_RX = 1,
moel@87
    57
    FT_PURGE_TX = 2,
moel@87
    58
    FT_PURGE_ALL = 3,
moel@87
    59
  }
moel@87
    60
moel@87
    61
  [StructLayout(LayoutKind.Sequential)]
moel@165
    62
  internal struct FT_HANDLE {
moel@195
    63
    private readonly uint handle;
moel@87
    64
  }
moel@87
    65
moel@87
    66
  [StructLayout(LayoutKind.Sequential)]
moel@165
    67
  internal struct FT_DEVICE_INFO_NODE {    
moel@87
    68
    public uint Flags;
moel@87
    69
    public FT_DEVICE Type; 
moel@87
    70
    public uint ID; 
moel@87
    71
    public uint LocId; 
moel@87
    72
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
moel@87
    73
    public string SerialNumber; 
moel@87
    74
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
moel@87
    75
    public string Description;
moel@87
    76
    public FT_HANDLE Handle;
moel@87
    77
  }
moel@87
    78
moel@165
    79
  internal class FTD2XX {
moel@87
    80
moel@87
    81
    public delegate FT_STATUS FT_CreateDeviceInfoListDelegate(
moel@87
    82
      out uint numDevices);
moel@87
    83
    public delegate FT_STATUS FT_GetDeviceInfoListDelegate(
moel@87
    84
      [Out] FT_DEVICE_INFO_NODE[] deviceInfoNodes, ref uint length);
moel@87
    85
    public delegate FT_STATUS FT_OpenDelegate(int device, out FT_HANDLE handle);
moel@87
    86
    public delegate FT_STATUS FT_CloseDelegate(FT_HANDLE handle);
moel@87
    87
    public delegate FT_STATUS FT_SetBaudRateDelegate(FT_HANDLE handle,
moel@87
    88
      uint baudRate);
moel@87
    89
    public delegate FT_STATUS FT_SetDataCharacteristicsDelegate(
moel@87
    90
      FT_HANDLE handle, byte wordLength, byte stopBits, byte parity);
moel@87
    91
    public delegate FT_STATUS FT_SetFlowControlDelegate(FT_HANDLE handle,
moel@87
    92
      FT_FLOW_CONTROL flowControl, byte xon, byte xoff);
moel@87
    93
    public delegate FT_STATUS FT_SetTimeoutsDelegate(FT_HANDLE handle,
moel@87
    94
      uint readTimeout, uint writeTimeout);
moel@87
    95
    public delegate FT_STATUS FT_WriteDelegate(FT_HANDLE handle, byte[] buffer,
moel@87
    96
      uint bytesToWrite, out uint bytesWritten);
moel@87
    97
    public delegate FT_STATUS FT_PurgeDelegate(FT_HANDLE handle, FT_PURGE mask);
moel@87
    98
    public delegate FT_STATUS FT_GetStatusDelegate(FT_HANDLE handle,
moel@87
    99
      out uint amountInRxQueue, out uint amountInTxQueue, out uint eventStatus);
moel@87
   100
    public delegate FT_STATUS FT_ReadDelegate(FT_HANDLE handle, 
moel@87
   101
      [Out] byte[] buffer, uint bytesToRead, out uint bytesReturned);
moel@384
   102
    public delegate FT_STATUS FT_ReadByteDelegate(FT_HANDLE handle,
moel@384
   103
      out byte buffer, uint bytesToRead, out uint bytesReturned);
moel@87
   104
moel@167
   105
    public static readonly FT_CreateDeviceInfoListDelegate 
moel@167
   106
      FT_CreateDeviceInfoList = CreateDelegate<
moel@167
   107
      FT_CreateDeviceInfoListDelegate>("FT_CreateDeviceInfoList");
moel@167
   108
    public static readonly FT_GetDeviceInfoListDelegate 
moel@167
   109
      FT_GetDeviceInfoList = CreateDelegate<
moel@167
   110
      FT_GetDeviceInfoListDelegate>("FT_GetDeviceInfoList");
moel@167
   111
    public static readonly FT_OpenDelegate 
moel@167
   112
      FT_Open = CreateDelegate<
moel@167
   113
      FT_OpenDelegate>("FT_Open");
moel@167
   114
    public static readonly FT_CloseDelegate 
moel@167
   115
      FT_Close = CreateDelegate<
moel@167
   116
      FT_CloseDelegate>("FT_Close");
moel@167
   117
    public static readonly FT_SetBaudRateDelegate 
moel@167
   118
      FT_SetBaudRate = CreateDelegate<
moel@167
   119
      FT_SetBaudRateDelegate>("FT_SetBaudRate");
moel@167
   120
    public static readonly FT_SetDataCharacteristicsDelegate 
moel@167
   121
      FT_SetDataCharacteristics = CreateDelegate<
moel@167
   122
      FT_SetDataCharacteristicsDelegate>("FT_SetDataCharacteristics");
moel@167
   123
    public static readonly FT_SetFlowControlDelegate 
moel@167
   124
      FT_SetFlowControl = CreateDelegate<
moel@167
   125
      FT_SetFlowControlDelegate>("FT_SetFlowControl");
moel@167
   126
    public static readonly FT_SetTimeoutsDelegate 
moel@167
   127
      FT_SetTimeouts = CreateDelegate<
moel@167
   128
      FT_SetTimeoutsDelegate>("FT_SetTimeouts");
moel@167
   129
    public static readonly FT_WriteDelegate 
moel@167
   130
      FT_Write = CreateDelegate<
moel@167
   131
      FT_WriteDelegate>("FT_Write");
moel@167
   132
    public static readonly FT_PurgeDelegate 
moel@167
   133
      FT_Purge = CreateDelegate<
moel@167
   134
      FT_PurgeDelegate>("FT_Purge");
moel@167
   135
    public static readonly FT_GetStatusDelegate 
moel@167
   136
      FT_GetStatus = CreateDelegate<
moel@167
   137
      FT_GetStatusDelegate>("FT_GetStatus");
moel@167
   138
    public static readonly FT_ReadDelegate 
moel@167
   139
      FT_Read = CreateDelegate<
moel@167
   140
      FT_ReadDelegate>("FT_Read");
moel@384
   141
    public static readonly FT_ReadByteDelegate
moel@384
   142
      FT_ReadByte = CreateDelegate<
moel@384
   143
      FT_ReadByteDelegate>("FT_Read");
moel@167
   144
moel@167
   145
    private FTD2XX() { }
moel@87
   146
moel@87
   147
    public static FT_STATUS Write(FT_HANDLE handle, byte[] buffer) {
moel@87
   148
      uint bytesWritten;
moel@87
   149
      FT_STATUS status = FT_Write(handle, buffer, (uint)buffer.Length, 
moel@87
   150
        out bytesWritten);
moel@87
   151
      if (bytesWritten != buffer.Length)
moel@87
   152
        return FT_STATUS.FT_FAILED_TO_WRITE_DEVICE;
moel@87
   153
      else
moel@87
   154
        return status;
moel@87
   155
    }
moel@87
   156
moel@87
   157
    public static int BytesToRead(FT_HANDLE handle) {
moel@87
   158
      uint amountInRxQueue;
moel@87
   159
      uint amountInTxQueue;
moel@87
   160
      uint eventStatus;
moel@87
   161
      if (FT_GetStatus(handle, out amountInRxQueue, out amountInTxQueue,
moel@87
   162
        out eventStatus) == FT_STATUS.FT_OK) {
moel@87
   163
        return (int)amountInRxQueue;
moel@87
   164
      } else {
moel@87
   165
        return 0;
moel@87
   166
      }
moel@87
   167
    }
moel@87
   168
moel@87
   169
    public static byte ReadByte(FT_HANDLE handle) {
moel@384
   170
      byte buffer;
moel@87
   171
      uint bytesReturned;
moel@384
   172
      FT_STATUS status = FT_ReadByte(handle, out buffer, 1, out bytesReturned);
moel@87
   173
      if (status != FT_STATUS.FT_OK || bytesReturned != 1)
moel@167
   174
        throw new InvalidOperationException();
moel@384
   175
      return buffer;
moel@384
   176
    }
moel@384
   177
moel@384
   178
    public static void Read(FT_HANDLE handle, byte[] buffer) {
moel@384
   179
      uint bytesReturned;
moel@384
   180
      FT_STATUS status = 
moel@384
   181
        FT_Read(handle, buffer, (uint)buffer.Length, out bytesReturned);
moel@384
   182
      if (status != FT_STATUS.FT_OK || bytesReturned != buffer.Length)
moel@384
   183
        throw new InvalidOperationException();
moel@87
   184
    }
moel@87
   185
moel@167
   186
    private static string GetDllName() {
moel@195
   187
      int p = (int)Environment.OSVersion.Platform;
moel@167
   188
      if ((p == 4) || (p == 128))
moel@167
   189
        return "libftd2xx.so";
moel@167
   190
      else
moel@167
   191
        return "ftd2xx.dll";
moel@167
   192
    }
moel@87
   193
moel@167
   194
    private static T CreateDelegate<T>(string entryPoint)
moel@87
   195
      where T : class {
moel@167
   196
      DllImportAttribute attribute = new DllImportAttribute(GetDllName());
moel@87
   197
      attribute.CallingConvention = CallingConvention.StdCall;
moel@87
   198
      attribute.PreserveSig = true;
moel@87
   199
      attribute.EntryPoint = entryPoint;
moel@167
   200
      T newDelegate;
moel@87
   201
      PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
moel@167
   202
      return newDelegate;
moel@87
   203
    }
moel@87
   204
  }
moel@87
   205
}