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