//----------------------------------------------------------------------- // // Copyright © 2012 Nils Hammar and Future Technology Devices International Limited. All rights reserved. // //----------------------------------------------------------------------- /* * Code is based on FTDI code, rewritten by Nils Hammar. */ namespace FtdiApi { using System; using System.Runtime.InteropServices; using System.Text; using System.Threading; using global::FtdiApi.Constants; using global::FtdiApi.Enums; using global::FtdiApi.Structs; /// /// API for FTDI USB devices like USB to Serial devices. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Reviewed.")] [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1516:ElementsMustBeSeparatedByBlankLine", Justification = "Reviewed.")] [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:ElementsMustAppearInTheCorrectOrder", Justification = "Reviewed.")] [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1121:UseBuiltInTypeAlias", Justification = "Reviewed.")] [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "Reviewed.")] [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed.")] [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:FieldNamesMustBeginWithLowerCaseLetter", Justification = "Reviewed.")] [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:CurlyBracketsMustNotBeOmitted", Justification = "Reviewed.")] public class FtdiPort { #region VARIABLES //// Create private variables for the device within the class /// /// Handle to the opened port. /// private IntPtr ftHandle = IntPtr.Zero; /// /// Instance of master class for DLL access. /// private FTDI ftdi; #endregion #region PROPERTY_DEFINITIONS /// /// Gets a value indicating whether the device is open. /// public bool IsOpen { get { return this.ftHandle != IntPtr.Zero; } } /// /// Gets the interface identifier. /// internal string InterfaceIdentifier { get { string Identifier; Identifier = String.Empty; if (this.IsOpen) { FT_DEVICE deviceType = FT_DEVICE.FT_DEVICE_BM; this.GetDeviceType(ref deviceType); if ((deviceType == FT_DEVICE.FT_DEVICE_2232) | (deviceType == FT_DEVICE.FT_DEVICE_2232H) | (deviceType == FT_DEVICE.FT_DEVICE_4232H)) { string Description; this.GetDescription(out Description); Identifier = Description.Substring(Description.Length - 1); return Identifier; } } return Identifier; } } #endregion #region CONSTRUCTOR_DESTRUCTOR /// /// Initializes a new instance of the class. /// /// Main class instance. public FtdiPort(FTDI ftdi) { this.ftdi = ftdi; } #endregion #region METHOD_DEFINITIONS /// /// Opens the FTDI device with the specified index. /// /// Index of the device to open. /// Note that this cannot be guaranteed to open a specific device. /// Initializes the device to 8 data bits, 1 stop bit, no parity, no flow control and 9600 Baud. public void OpenByIndex(uint index) { FTDI.FunctionValidator("FT_Open", this.ftdi.NativeMethodsInstance.FT_Open); FTDI.FunctionValidator("FT_SetDataCharacteristics", this.ftdi.NativeMethodsInstance.FT_SetDataCharacteristics); FTDI.FunctionValidator("FT_SetFlowControl", this.ftdi.NativeMethodsInstance.FT_SetFlowControl); FTDI.FunctionValidator("FT_SetBaudRate", this.ftdi.NativeMethodsInstance.FT_SetBaudRate); // Call FT_Open FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_Open(index, ref this.ftHandle); FTDI.ErrorHandler("OpenByIndex:Open", ftStatus, FT_ERROR.FT_NO_ERROR); // Initialise port data characteristics byte WordLength = FT_DATA_BITS.FT_BITS_8; byte StopBits = FT_STOP_BITS.FT_STOP_BITS_1; byte Parity = FT_PARITY.FT_PARITY_NONE; ftStatus = this.ftdi.NativeMethodsInstance.FT_SetDataCharacteristics(this.ftHandle, WordLength, StopBits, Parity); FTDI.ErrorHandler("OpenByIndex:SetDataCharacteristics", ftStatus, FT_ERROR.FT_NO_ERROR); // Initialise to no flow control ushort FlowControl = FT_FLOW_CONTROL.FT_FLOW_NONE; byte Xon = 0x11; byte Xoff = 0x13; ftStatus = this.ftdi.NativeMethodsInstance.FT_SetFlowControl(this.ftHandle, FlowControl, Xon, Xoff); FTDI.ErrorHandler("OpenByIndex:SetFlowControl", ftStatus, FT_ERROR.FT_NO_ERROR); // Initialise Baud rate uint BaudRate = 9600; ftStatus = this.ftdi.NativeMethodsInstance.FT_SetBaudRate(this.ftHandle, BaudRate); FTDI.ErrorHandler("OpenByIndex:SetBaudRate", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Opens the FTDI device with the specified serial number. /// /// Serial number of the device to open. /// Initializes the device to 8 data bits, 1 stop bit, no parity, no flow control and 9600 Baud. public void OpenBySerialNumber(string serialnumber) { FTDI.FunctionValidator("FT_OpenEx", this.ftdi.NativeMethodsInstance.FT_OpenEx); FTDI.FunctionValidator("FT_SetDataCharacteristics", this.ftdi.NativeMethodsInstance.FT_SetDataCharacteristics); FTDI.FunctionValidator("FT_SetFlowControl", this.ftdi.NativeMethodsInstance.FT_SetFlowControl); FTDI.FunctionValidator("FT_SetBaudRate", this.ftdi.NativeMethodsInstance.FT_SetBaudRate); // Call FT_OpenEx FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_OpenEx(serialnumber, FT_OPENEX_MODES.FT_OPEN_BY_SERIAL_NUMBER, ref this.ftHandle); FTDI.ErrorHandler("OpenBySerialNumber:OpenEx", ftStatus, FT_ERROR.FT_NO_ERROR); // Initialise port data characteristics byte WordLength = FT_DATA_BITS.FT_BITS_8; byte StopBits = FT_STOP_BITS.FT_STOP_BITS_1; byte Parity = FT_PARITY.FT_PARITY_NONE; ftStatus = this.ftdi.NativeMethodsInstance.FT_SetDataCharacteristics(this.ftHandle, WordLength, StopBits, Parity); FTDI.ErrorHandler("OpenBySerialNumber:SetDataCharacteristics", ftStatus, FT_ERROR.FT_NO_ERROR); // Initialise to no flow control ushort FlowControl = FT_FLOW_CONTROL.FT_FLOW_NONE; byte Xon = 0x11; byte Xoff = 0x13; ftStatus = this.ftdi.NativeMethodsInstance.FT_SetFlowControl(this.ftHandle, FlowControl, Xon, Xoff); FTDI.ErrorHandler("OpenBySerialNumber:SetFlowControl", ftStatus, FT_ERROR.FT_NO_ERROR); // Initialise Baud rate uint BaudRate = 9600; ftStatus = this.ftdi.NativeMethodsInstance.FT_SetBaudRate(this.ftHandle, BaudRate); FTDI.ErrorHandler("OpenBySerialNumber:SetBaudRate", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Opens the FTDI device with the specified description. /// /// Description of the device to open. /// Initializes the device to 8 data bits, 1 stop bit, no parity, no flow control and 9600 Baud. public void OpenByDescription(string description) { FTDI.FunctionValidator("FT_OpenEx", this.ftdi.NativeMethodsInstance.FT_OpenEx); FTDI.FunctionValidator("FT_SetDataCharacteristics", this.ftdi.NativeMethodsInstance.FT_SetDataCharacteristics); FTDI.FunctionValidator("FT_SetFlowControl", this.ftdi.NativeMethodsInstance.FT_SetFlowControl); FTDI.FunctionValidator("FT_SetBaudRate", this.ftdi.NativeMethodsInstance.FT_SetBaudRate); // Call FT_OpenEx FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_OpenEx(description, FT_OPENEX_MODES.FT_OPEN_BY_DESCRIPTION, ref this.ftHandle); FTDI.ErrorHandler("OpenByDescription:OpenEx", ftStatus, FT_ERROR.FT_NO_ERROR); // Initialise port data characteristics byte WordLength = FT_DATA_BITS.FT_BITS_8; byte StopBits = FT_STOP_BITS.FT_STOP_BITS_1; byte Parity = FT_PARITY.FT_PARITY_NONE; ftStatus = this.ftdi.NativeMethodsInstance.FT_SetDataCharacteristics(this.ftHandle, WordLength, StopBits, Parity); FTDI.ErrorHandler("OpenByDescription:SetDataCharacteristics", ftStatus, FT_ERROR.FT_NO_ERROR); // Initialise to no flow control ushort FlowControl = FT_FLOW_CONTROL.FT_FLOW_NONE; byte Xon = 0x11; byte Xoff = 0x13; ftStatus = this.ftdi.NativeMethodsInstance.FT_SetFlowControl(this.ftHandle, FlowControl, Xon, Xoff); FTDI.ErrorHandler("OpenByDescription:SetFlowControl", ftStatus, FT_ERROR.FT_NO_ERROR); // Initialise Baud rate uint BaudRate = 9600; ftStatus = this.ftdi.NativeMethodsInstance.FT_SetBaudRate(this.ftHandle, BaudRate); FTDI.ErrorHandler("OpenByDescription:SetBaudRate", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Opens the FTDI device at the specified physical location. /// /// Location of the device to open. /// Initializes the device to 8 data bits, 1 stop bit, no parity, no flow control and 9600 Baud. public void OpenByLocation(uint location) { FTDI.FunctionValidator("FT_OpenExLoc", this.ftdi.NativeMethodsInstance.FT_OpenExLoc); FTDI.FunctionValidator("FT_SetDataCharacteristics", this.ftdi.NativeMethodsInstance.FT_SetDataCharacteristics); FTDI.FunctionValidator("FT_SetFlowControl", this.ftdi.NativeMethodsInstance.FT_SetFlowControl); FTDI.FunctionValidator("FT_SetBaudRate", this.ftdi.NativeMethodsInstance.FT_SetBaudRate); // Call FT_OpenEx FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_OpenExLoc(location, FT_OPENEX_MODES.FT_OPEN_BY_LOCATION, ref this.ftHandle); FTDI.ErrorHandler("OpenByLocation:OpenEx", ftStatus, FT_ERROR.FT_NO_ERROR); // Initialise port data characteristics byte WordLength = FT_DATA_BITS.FT_BITS_8; byte StopBits = FT_STOP_BITS.FT_STOP_BITS_1; byte Parity = FT_PARITY.FT_PARITY_NONE; ftStatus = this.ftdi.NativeMethodsInstance.FT_SetDataCharacteristics(this.ftHandle, WordLength, StopBits, Parity); FTDI.ErrorHandler("OpenByLocation:SetDataCharacteristics", ftStatus, FT_ERROR.FT_NO_ERROR); // Initialise to no flow control ushort FlowControl = FT_FLOW_CONTROL.FT_FLOW_NONE; byte Xon = 0x11; byte Xoff = 0x13; ftStatus = this.ftdi.NativeMethodsInstance.FT_SetFlowControl(this.ftHandle, FlowControl, Xon, Xoff); FTDI.ErrorHandler("OpenByLocation:SetFlowControl", ftStatus, FT_ERROR.FT_NO_ERROR); // Initialise Baud rate uint BaudRate = 9600; ftStatus = this.ftdi.NativeMethodsInstance.FT_SetBaudRate(this.ftHandle, BaudRate); FTDI.ErrorHandler("OpenByLocation:SetBaudRate", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Closes the handle to an open FTDI device. /// public void Close() { FTDI.FunctionValidator("FT_Close", this.ftdi.NativeMethodsInstance.FT_Close); // Silently ignore if we are trying to close without having opened before. if (this.ftHandle != IntPtr.Zero) { // Call FT_Close FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_Close(this.ftHandle); FTDI.ErrorHandler("Close", ftStatus, FT_ERROR.FT_NO_ERROR); } } /// /// Read data from an open FTDI device. /// /// An array of bytes which will be populated with the data read from the device. /// The number of bytes requested from the device. /// The number of bytes actually read. public void Read(byte[] dataBuffer, uint numBytesToRead, ref uint numBytesRead) { // If the buffer is not big enough to receive the amount of data requested, adjust the number of bytes to read if (dataBuffer.Length < numBytesToRead) { numBytesToRead = (uint)dataBuffer.Length; } this.PortFunctionValidator("FT_Read", this.ftdi.NativeMethodsInstance.FT_Read); // Call FT_Read FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_Read(this.ftHandle, dataBuffer, numBytesToRead, ref numBytesRead); FTDI.ErrorHandler("Read", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Read data from an open FTDI device. /// /// A string containing the data read /// The number of bytes requested from the device. /// The number of bytes actually read. public void Read(out string dataBuffer, uint numBytesToRead, ref uint numBytesRead) { this.PortFunctionValidator("FT_Read", this.ftdi.NativeMethodsInstance.FT_Read); // Call FT_Read byte[] byteDataBuffer = new byte[numBytesToRead]; FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_Read(this.ftHandle, byteDataBuffer, numBytesToRead, ref numBytesRead); FTDI.ErrorHandler("Read", ftStatus, FT_ERROR.FT_NO_ERROR); // Convert ASCII byte array back to Unicode string for passing back dataBuffer = Encoding.ASCII.GetString(byteDataBuffer); // Trim buffer to actual bytes read dataBuffer = dataBuffer.Substring(0, (int)numBytesRead); } /// /// Write data to an open FTDI device. /// /// An array of bytes which contains the data to be written to the device. /// The number of bytes to be written to the device. /// The number of bytes actually written to the device. public void Write(byte[] dataBuffer, Int32 numBytesToWrite, ref uint numBytesWritten) { this.PortFunctionValidator("FT_Write", this.ftdi.NativeMethodsInstance.FT_Write); // Call FT_Write FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_Write(this.ftHandle, dataBuffer, (uint)numBytesToWrite, ref numBytesWritten); FTDI.ErrorHandler("Write", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Write data to an open FTDI device. /// /// An array of bytes which contains the data to be written to the device. /// The number of bytes to be written to the device. /// The number of bytes actually written to the device. public void Write(byte[] dataBuffer, uint numBytesToWrite, ref uint numBytesWritten) { this.PortFunctionValidator("FT_Write", this.ftdi.NativeMethodsInstance.FT_Write); // Call FT_Write FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_Write(this.ftHandle, dataBuffer, numBytesToWrite, ref numBytesWritten); FTDI.ErrorHandler("Write", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Write data to an open FTDI device. /// /// A string which contains the data to be written to the device. /// The number of bytes to be written to the device. /// The number of bytes actually written to the device. public void Write(string dataBuffer, Int32 numBytesToWrite, ref uint numBytesWritten) { this.PortFunctionValidator("FT_Write", this.ftdi.NativeMethodsInstance.FT_Write); // Convert Unicode string to ASCII byte array byte[] byteDataBuffer = Encoding.ASCII.GetBytes(dataBuffer); // Call FT_Write FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_Write(this.ftHandle, byteDataBuffer, (uint)numBytesToWrite, ref numBytesWritten); FTDI.ErrorHandler("Write", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Write data to an open FTDI device. /// /// A string which contains the data to be written to the device. /// The number of bytes to be written to the device. /// The number of bytes actually written to the device. public void Write(string dataBuffer, uint numBytesToWrite, ref uint numBytesWritten) { this.PortFunctionValidator("FT_Write", this.ftdi.NativeMethodsInstance.FT_Write); // Convert Unicode string to ASCII byte array byte[] byteDataBuffer = Encoding.ASCII.GetBytes(dataBuffer); // Call FT_Write FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_Write(this.ftHandle, byteDataBuffer, numBytesToWrite, ref numBytesWritten); FTDI.ErrorHandler("Write", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Reset an open FTDI device. /// public void ResetDevice() { this.PortFunctionValidator("FT_ResetDevice", this.ftdi.NativeMethodsInstance.FT_ResetDevice); // Call FT_ResetDevice FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_ResetDevice(this.ftHandle); FTDI.ErrorHandler("ResetDevice", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Purge data from the devices transmit and/or receive buffers. /// /// Specifies which buffer(s) to be purged. Valid values are any combination of the following flags: FT_PURGE_RX, FT_PURGE_TX public void Purge(uint purgemask) { this.PortFunctionValidator("FT_Purge", this.ftdi.NativeMethodsInstance.FT_Purge); // Call FT_Purge FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_Purge(this.ftHandle, purgemask); FTDI.ErrorHandler("Purge", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Register for event notification. /// /// After setting event notification, the event can be caught by executing the WaitOne() method of the EventWaitHandle. If multiple event types are being monitored, the event that fired can be determined from the GetEventType method. /// The type of events to signal. Can be any combination of the following: FT_EVENT_RXCHAR, FT_EVENT_MODEM_STATUS, FT_EVENT_LINE_STATUS /// Handle to the event that will receive the notification public void SetEventNotification(uint eventmask, WaitHandle eventhandle) { this.PortFunctionValidator("FT_SetEventNotification", this.ftdi.NativeMethodsInstance.FT_SetEventNotification); // Call FT_SetSetEventNotification FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetEventNotification(this.ftHandle, eventmask, eventhandle.SafeWaitHandle); FTDI.ErrorHandler("SetEventNotification", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Stops the driver issuing USB in requests. /// public void StopInTask() { this.PortFunctionValidator("FT_StopInTask", this.ftdi.NativeMethodsInstance.FT_StopInTask); // Call FT_StopInTask FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_StopInTask(this.ftHandle); FTDI.ErrorHandler("StopInTask", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Resumes the driver issuing USB in requests. /// public void RestartInTask() { this.PortFunctionValidator("FT_RestartInTask", this.ftdi.NativeMethodsInstance.FT_RestartInTask); // Call FT_RestartInTask FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_RestartInTask(this.ftHandle); FTDI.ErrorHandler("RestartInTask", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Resets the device port. /// public void ResetPort() { this.PortFunctionValidator("FT_ResetPort", this.ftdi.NativeMethodsInstance.FT_ResetPort); // Call FT_ResetPort FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_ResetPort(this.ftHandle); FTDI.ErrorHandler("ResetPort", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Causes the device to be re-enumerated on the USB bus. This is equivalent to unplugging and re-plugging the device. /// Also calls FT_Close if FT_CyclePort is successful, so no need to call this separately in the application. /// public void CyclePort() { this.PortFunctionValidator("FT_CyclePort", this.ftdi.NativeMethodsInstance.FT_CyclePort); this.PortFunctionValidator("FT_Close", this.ftdi.NativeMethodsInstance.FT_Close); // Call FT_CyclePort FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_CyclePort(this.ftHandle); FTDI.ErrorHandler("CyclePort:CyclePort", ftStatus, FT_ERROR.FT_NO_ERROR); // If successful, call FT_Close ftStatus = this.ftdi.NativeMethodsInstance.FT_Close(this.ftHandle); FTDI.ErrorHandler("CyclePort:Close", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Puts the device in a mode other than the default UART or FIFO mode. /// /// Sets up which bits are inputs and which are outputs. A bit value of 0 sets the corresponding pin to an input, a bit value of 1 sets the corresponding pin to an output. /// In the case of CBUS Bit Bang, the upper nibble of this value controls which pins are inputs and outputs, while the lower nibble controls which of the outputs are high and low. /// For FT232H devices, valid values are FT_BIT_MODE_RESET, FT_BIT_MODE_ASYNC_BITBANG, FT_BIT_MODE_MPSSE, FT_BIT_MODE_SYNC_BITBANG, FT_BIT_MODE_CBUS_BITBANG, FT_BIT_MODE_MCU_HOST, FT_BIT_MODE_FAST_SERIAL, FT_BIT_MODE_SYNC_FIFO. /// For FT2232H devices, valid values are FT_BIT_MODE_RESET, FT_BIT_MODE_ASYNC_BITBANG, FT_BIT_MODE_MPSSE, FT_BIT_MODE_SYNC_BITBANG, FT_BIT_MODE_MCU_HOST, FT_BIT_MODE_FAST_SERIAL, FT_BIT_MODE_SYNC_FIFO. /// For FT4232H devices, valid values are FT_BIT_MODE_RESET, FT_BIT_MODE_ASYNC_BITBANG, FT_BIT_MODE_MPSSE, FT_BIT_MODE_SYNC_BITBANG. /// For FT232R devices, valid values are FT_BIT_MODE_RESET, FT_BIT_MODE_ASYNC_BITBANG, FT_BIT_MODE_SYNC_BITBANG, FT_BIT_MODE_CBUS_BITBANG. /// For FT245R devices, valid values are FT_BIT_MODE_RESET, FT_BIT_MODE_ASYNC_BITBANG, FT_BIT_MODE_SYNC_BITBANG. /// For FT2232 devices, valid values are FT_BIT_MODE_RESET, FT_BIT_MODE_ASYNC_BITBANG, FT_BIT_MODE_MPSSE, FT_BIT_MODE_SYNC_BITBANG, FT_BIT_MODE_MCU_HOST, FT_BIT_MODE_FAST_SERIAL. /// For FT232B and FT245B devices, valid values are FT_BIT_MODE_RESET, FT_BIT_MODE_ASYNC_BITBANG. /// Thrown when the current device does not support the requested bit mode. public void SetBitMode(byte Mask, byte BitMode) { this.PortFunctionValidator("FT_SetBitMode", this.ftdi.NativeMethodsInstance.FT_SetBitMode); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Set Bit Mode does not apply to FT8U232AM, FT8U245AM or FT8U100AX devices this.GetDeviceType(ref DeviceType); if (DeviceType == FT_DEVICE.FT_DEVICE_AM) { // Throw an exception ftErrorCondition = FT_ERROR.FT_INVALID_BITMODE; FTDI.ErrorHandler("SetBitMode:FT_DEVICE_AM", ftStatus, ftErrorCondition); } else if (DeviceType == FT_DEVICE.FT_DEVICE_100AX) { // Throw an exception ftErrorCondition = FT_ERROR.FT_INVALID_BITMODE; FTDI.ErrorHandler("SetBitMode:FT_DEVICE_AM", ftStatus, ftErrorCondition); } else if ((DeviceType == FT_DEVICE.FT_DEVICE_BM) && (BitMode != FT_BIT_MODES.FT_BIT_MODE_RESET)) { if ((BitMode & FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG) == 0) { // Throw an exception ftErrorCondition = FT_ERROR.FT_INVALID_BITMODE; FTDI.ErrorHandler("SetBitMode:FT_DEVICE_BM", ftStatus, ftErrorCondition); } } else if ((DeviceType == FT_DEVICE.FT_DEVICE_2232) && (BitMode != FT_BIT_MODES.FT_BIT_MODE_RESET)) { if ((BitMode & (FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG | FT_BIT_MODES.FT_BIT_MODE_MPSSE | FT_BIT_MODES.FT_BIT_MODE_SYNC_BITBANG | FT_BIT_MODES.FT_BIT_MODE_MCU_HOST | FT_BIT_MODES.FT_BIT_MODE_FAST_SERIAL)) == 0) { // Throw an exception ftErrorCondition = FT_ERROR.FT_INVALID_BITMODE; FTDI.ErrorHandler("SetBitMode:FT_DEVICE_2232", ftStatus, ftErrorCondition); } if ((BitMode == FT_BIT_MODES.FT_BIT_MODE_MPSSE) & (this.InterfaceIdentifier != "A")) { // MPSSE mode is only available on channel A // Throw an exception ftErrorCondition = FT_ERROR.FT_INVALID_BITMODE; FTDI.ErrorHandler("SetBitMode:FT_DEVICE_2232", ftStatus, ftErrorCondition); } } else if ((DeviceType == FT_DEVICE.FT_DEVICE_232R) && (BitMode != FT_BIT_MODES.FT_BIT_MODE_RESET)) { if ((BitMode & (FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG | FT_BIT_MODES.FT_BIT_MODE_SYNC_BITBANG | FT_BIT_MODES.FT_BIT_MODE_CBUS_BITBANG)) == 0) { // Throw an exception ftErrorCondition = FT_ERROR.FT_INVALID_BITMODE; FTDI.ErrorHandler("SetBitMode:FT_DEVICE_232R", ftStatus, ftErrorCondition); } } else if ((DeviceType == FT_DEVICE.FT_DEVICE_2232H) && (BitMode != FT_BIT_MODES.FT_BIT_MODE_RESET)) { if ((BitMode & (FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG | FT_BIT_MODES.FT_BIT_MODE_MPSSE | FT_BIT_MODES.FT_BIT_MODE_SYNC_BITBANG | FT_BIT_MODES.FT_BIT_MODE_MCU_HOST | FT_BIT_MODES.FT_BIT_MODE_FAST_SERIAL | FT_BIT_MODES.FT_BIT_MODE_SYNC_FIFO)) == 0) { // Throw an exception ftErrorCondition = FT_ERROR.FT_INVALID_BITMODE; FTDI.ErrorHandler("SetBitMode:FT_DEVICE_2232H", ftStatus, ftErrorCondition); } if (((BitMode == FT_BIT_MODES.FT_BIT_MODE_MCU_HOST) | (BitMode == FT_BIT_MODES.FT_BIT_MODE_SYNC_FIFO)) & (this.InterfaceIdentifier != "A")) { // MCU Host Emulation and Single channel synchronous 245 FIFO mode is only available on channel A // Throw an exception ftErrorCondition = FT_ERROR.FT_INVALID_BITMODE; FTDI.ErrorHandler("SetBitMode:FT_DEVICE_2232H", ftStatus, ftErrorCondition); } } else if ((DeviceType == FT_DEVICE.FT_DEVICE_4232H) && (BitMode != FT_BIT_MODES.FT_BIT_MODE_RESET)) { if ((BitMode & (FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG | FT_BIT_MODES.FT_BIT_MODE_MPSSE | FT_BIT_MODES.FT_BIT_MODE_SYNC_BITBANG)) == 0) { // Throw an exception ftErrorCondition = FT_ERROR.FT_INVALID_BITMODE; FTDI.ErrorHandler("SetBitMode:FT_DEVICE_4232H", ftStatus, ftErrorCondition); } if ((BitMode == FT_BIT_MODES.FT_BIT_MODE_MPSSE) & ((this.InterfaceIdentifier != "A") & (this.InterfaceIdentifier != "B"))) { // MPSSE mode is only available on channel A and B // Throw an exception ftErrorCondition = FT_ERROR.FT_INVALID_BITMODE; FTDI.ErrorHandler("SetBitMode:FT_DEVICE_4232H", ftStatus, ftErrorCondition); } } else if ((DeviceType == FT_DEVICE.FT_DEVICE_232H) && (BitMode != FT_BIT_MODES.FT_BIT_MODE_RESET)) { // FT232H supports all current bit modes! if (BitMode > FT_BIT_MODES.FT_BIT_MODE_SYNC_FIFO) { // Throw an exception ftErrorCondition = FT_ERROR.FT_INVALID_BITMODE; FTDI.ErrorHandler("SetBitMode:FT_DEVICE_232H", ftStatus, ftErrorCondition); } } // Requested bit mode is supported // Note FT_BIT_MODES.FT_BIT_MODE_RESET falls through to here - no bits set so cannot check for AND // Call FT_SetBitMode ftStatus = this.ftdi.NativeMethodsInstance.FT_SetBitMode(this.ftHandle, Mask, BitMode); FTDI.ErrorHandler("SetBitMode:SetBitMode", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Gets the instantaneous state of the device IO pins. /// /// A bitmap value containing the instantaneous state of the device IO pins public void GetPinStates(ref byte BitMode) { this.PortFunctionValidator("GetPinStates: FT_GetBitMode", this.ftdi.NativeMethodsInstance.FT_GetBitMode); // Call FT_GetBitMode FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetBitMode(this.ftHandle, ref BitMode); FTDI.ErrorHandler("GetPinStates", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Reads an individual word value from a specified location in the device's EEPROM. /// /// The EEPROM location to read data from /// The WORD value read from the EEPROM location specified in the Address parameter public void ReadEEPROMLocation(uint Address, ref ushort EEValue) { this.PortFunctionValidator("FT_ReadEE", this.ftdi.NativeMethodsInstance.FT_ReadEE); // Call FT_ReadEE FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_ReadEE(this.ftHandle, Address, ref EEValue); FTDI.ErrorHandler("ReadEEPROMLocation", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Writes an individual word value to a specified location in the device's EEPROM. /// /// The EEPROM location to read data from /// The WORD value to write to the EEPROM location specified by the Address parameter public void WriteEEPROMLocation(uint Address, ushort EEValue) { this.PortFunctionValidator("FT_WriteEE", this.ftdi.NativeMethodsInstance.FT_WriteEE); // Call FT_WriteEE FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_WriteEE(this.ftHandle, Address, EEValue); FTDI.ErrorHandler("WriteEEPROMLocation", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Erases the device EEPROM. /// /// Thrown when attempting to erase the EEPROM of a device with an internal EEPROM such as an FT232R or FT245R. public void EraseEEPROM() { this.PortFunctionValidator("FT_EraseEE", this.ftdi.NativeMethodsInstance.FT_EraseEE); FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is not an FT232R or FT245R that we are trying to erase this.GetDeviceType(ref DeviceType); if (DeviceType == FT_DEVICE.FT_DEVICE_232R) { // If it is a device with an internal EEPROM, throw an exception FTDI.ErrorHandler("EraseEEPROM", FT_STATUS.FT_OTHER_ERROR, FT_ERROR.FT_INCORRECT_DEVICE); } // Call FT_EraseEE FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_EraseEE(this.ftHandle); FTDI.ErrorHandler("EraseEEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Reads the EEPROM contents of an FT232B or FT245B device. /// /// An FTDI.FT232B_EEPROM_STRUCTURE which contains only the relevant information for an FT232B and FT245B device. /// Thrown when the current device does not match the type required by this method. public void ReadFT232BEEPROM(FT232B_EEPROM_STRUCTURE ee232b) { this.PortFunctionValidator("ReadFT232BEEPROM: FT_EE_Read", this.ftdi.NativeMethodsInstance.FT_EE_Read); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT232B or FT245B that we are trying to read this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_BM) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("ReadFT232BEEPROM", ftStatus, ftErrorCondition); } FT_PROGRAM_DATA eedata = new FT_PROGRAM_DATA(); // Set up structure headers eedata.Signature1 = 0x00000000; eedata.Signature2 = 0xFFFFFFFF; eedata.Version = 2; // Allocate space from unmanaged heap eedata.Manufacturer = Marshal.AllocHGlobal(32); eedata.ManufacturerID = Marshal.AllocHGlobal(16); eedata.Description = Marshal.AllocHGlobal(64); eedata.SerialNumber = Marshal.AllocHGlobal(16); // Call FT_EE_Read ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_Read(this.ftHandle, eedata); FTDI.ErrorHandler("ReadFT232BEEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Retrieve string values ee232b.Manufacturer = Marshal.PtrToStringAnsi(eedata.Manufacturer); ee232b.ManufacturerID = Marshal.PtrToStringAnsi(eedata.ManufacturerID); ee232b.Description = Marshal.PtrToStringAnsi(eedata.Description); ee232b.SerialNumber = Marshal.PtrToStringAnsi(eedata.SerialNumber); // Free unmanaged buffers Marshal.FreeHGlobal(eedata.Manufacturer); Marshal.FreeHGlobal(eedata.ManufacturerID); Marshal.FreeHGlobal(eedata.Description); Marshal.FreeHGlobal(eedata.SerialNumber); // Map non-string elements to structure to be returned // Standard elements ee232b.VendorID = eedata.VendorID; ee232b.ProductID = eedata.ProductID; ee232b.MaxPower = eedata.MaxPower; ee232b.SelfPowered = Convert.ToBoolean(eedata.SelfPowered); ee232b.RemoteWakeup = Convert.ToBoolean(eedata.RemoteWakeup); // B specific fields ee232b.PullDownEnable = Convert.ToBoolean(eedata.PullDownEnable); ee232b.SerNumEnable = Convert.ToBoolean(eedata.SerNumEnable); ee232b.USBVersionEnable = Convert.ToBoolean(eedata.USBVersionEnable); ee232b.USBVersion = eedata.USBVersion; } /// /// Reads the EEPROM contents of an FT2232 device. /// /// An FTDI.FT2232_EEPROM_STRUCTURE which contains only the relevant information for an FT2232 device. /// Thrown when the current device does not match the type required by this method. public void ReadFT2232EEPROM(FT2232_EEPROM_STRUCTURE ee2232) { this.PortFunctionValidator("ReadFT2232EEPROM: FT_EE_Read", this.ftdi.NativeMethodsInstance.FT_EE_Read); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT2232 that we are trying to read this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_2232) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("ReadFT2232EEPROM", ftStatus, ftErrorCondition); } FT_PROGRAM_DATA eedata = new FT_PROGRAM_DATA(); // Set up structure headers eedata.Signature1 = 0x00000000; eedata.Signature2 = 0xFFFFFFFF; eedata.Version = 2; // Allocate space from unmanaged heap eedata.Manufacturer = Marshal.AllocHGlobal(32); eedata.ManufacturerID = Marshal.AllocHGlobal(16); eedata.Description = Marshal.AllocHGlobal(64); eedata.SerialNumber = Marshal.AllocHGlobal(16); // Call FT_EE_Read ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_Read(this.ftHandle, eedata); FTDI.ErrorHandler("ReadFT2232EEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Retrieve string values ee2232.Manufacturer = Marshal.PtrToStringAnsi(eedata.Manufacturer); ee2232.ManufacturerID = Marshal.PtrToStringAnsi(eedata.ManufacturerID); ee2232.Description = Marshal.PtrToStringAnsi(eedata.Description); ee2232.SerialNumber = Marshal.PtrToStringAnsi(eedata.SerialNumber); // Free unmanaged buffers Marshal.FreeHGlobal(eedata.Manufacturer); Marshal.FreeHGlobal(eedata.ManufacturerID); Marshal.FreeHGlobal(eedata.Description); Marshal.FreeHGlobal(eedata.SerialNumber); // Map non-string elements to structure to be returned // Standard elements ee2232.VendorID = eedata.VendorID; ee2232.ProductID = eedata.ProductID; ee2232.MaxPower = eedata.MaxPower; ee2232.SelfPowered = Convert.ToBoolean(eedata.SelfPowered); ee2232.RemoteWakeup = Convert.ToBoolean(eedata.RemoteWakeup); // 2232 specific fields ee2232.PullDownEnable = Convert.ToBoolean(eedata.PullDownEnable5); ee2232.SerNumEnable = Convert.ToBoolean(eedata.SerNumEnable5); ee2232.USBVersionEnable = Convert.ToBoolean(eedata.USBVersionEnable5); ee2232.USBVersion = eedata.USBVersion5; ee2232.AIsHighCurrent = Convert.ToBoolean(eedata.AIsHighCurrent); ee2232.BIsHighCurrent = Convert.ToBoolean(eedata.BIsHighCurrent); ee2232.IFAIsFifo = Convert.ToBoolean(eedata.IFAIsFifo); ee2232.IFAIsFifoTar = Convert.ToBoolean(eedata.IFAIsFifoTar); ee2232.IFAIsFastSer = Convert.ToBoolean(eedata.IFAIsFastSer); ee2232.AIsVCP = Convert.ToBoolean(eedata.AIsVCP); ee2232.IFBIsFifo = Convert.ToBoolean(eedata.IFBIsFifo); ee2232.IFBIsFifoTar = Convert.ToBoolean(eedata.IFBIsFifoTar); ee2232.IFBIsFastSer = Convert.ToBoolean(eedata.IFBIsFastSer); ee2232.BIsVCP = Convert.ToBoolean(eedata.BIsVCP); } /// /// Reads the EEPROM contents of an FT232R or FT245R device. /// Calls FT_EE_Read in FTD2XX DLL /// /// An FTDI.FT232R_EEPROM_STRUCTURE which contains only the relevant information for an FT232R and FT245R device. /// The structure is populated by the call to this method. /// Thrown when the current device does not match the type required by this method. public void ReadFT232REEPROM(FT232R_EEPROM_STRUCTURE ee232r) { this.PortFunctionValidator("ReadFT232REEPROM: FT_EE_Read", this.ftdi.NativeMethodsInstance.FT_EE_Read); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT232R or FT245R that we are trying to read this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_232R) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("ReadFT232REEPROM", ftStatus, ftErrorCondition); } FT_PROGRAM_DATA eedata = new FT_PROGRAM_DATA(); // Set up structure headers eedata.Signature1 = 0x00000000; eedata.Signature2 = 0xFFFFFFFF; eedata.Version = 2; // Allocate space from unmanaged heap eedata.Manufacturer = Marshal.AllocHGlobal(32); eedata.ManufacturerID = Marshal.AllocHGlobal(16); eedata.Description = Marshal.AllocHGlobal(64); eedata.SerialNumber = Marshal.AllocHGlobal(16); // Call FT_EE_Read ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_Read(this.ftHandle, eedata); FTDI.ErrorHandler("ReadFT232REEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Retrieve string values ee232r.Manufacturer = Marshal.PtrToStringAnsi(eedata.Manufacturer); ee232r.ManufacturerID = Marshal.PtrToStringAnsi(eedata.ManufacturerID); ee232r.Description = Marshal.PtrToStringAnsi(eedata.Description); ee232r.SerialNumber = Marshal.PtrToStringAnsi(eedata.SerialNumber); // Free unmanaged buffers Marshal.FreeHGlobal(eedata.Manufacturer); Marshal.FreeHGlobal(eedata.ManufacturerID); Marshal.FreeHGlobal(eedata.Description); Marshal.FreeHGlobal(eedata.SerialNumber); // Map non-string elements to structure to be returned // Standard elements ee232r.VendorID = eedata.VendorID; ee232r.ProductID = eedata.ProductID; ee232r.MaxPower = eedata.MaxPower; ee232r.SelfPowered = Convert.ToBoolean(eedata.SelfPowered); ee232r.RemoteWakeup = Convert.ToBoolean(eedata.RemoteWakeup); // 232R specific fields ee232r.UseExtOsc = Convert.ToBoolean(eedata.UseExtOsc); ee232r.HighDriveIOs = Convert.ToBoolean(eedata.HighDriveIOs); ee232r.EndpointSize = eedata.EndpointSize; ee232r.PullDownEnable = Convert.ToBoolean(eedata.PullDownEnableR); ee232r.SerNumEnable = Convert.ToBoolean(eedata.SerNumEnableR); ee232r.InvertTXD = Convert.ToBoolean(eedata.InvertTXD); ee232r.InvertRXD = Convert.ToBoolean(eedata.InvertRXD); ee232r.InvertRTS = Convert.ToBoolean(eedata.InvertRTS); ee232r.InvertCTS = Convert.ToBoolean(eedata.InvertCTS); ee232r.InvertDTR = Convert.ToBoolean(eedata.InvertDTR); ee232r.InvertDSR = Convert.ToBoolean(eedata.InvertDSR); ee232r.InvertDCD = Convert.ToBoolean(eedata.InvertDCD); ee232r.InvertRI = Convert.ToBoolean(eedata.InvertRI); ee232r.Cbus0 = eedata.Cbus0; ee232r.Cbus1 = eedata.Cbus1; ee232r.Cbus2 = eedata.Cbus2; ee232r.Cbus3 = eedata.Cbus3; ee232r.Cbus4 = eedata.Cbus4; ee232r.RIsD2XX = Convert.ToBoolean(eedata.RIsD2XX); } /// /// Reads the EEPROM contents of an FT2232H device. /// /// An FTDI.FT2232H_EEPROM_STRUCTURE which contains only the relevant information for an FT2232H device. /// Thrown when the current device does not match the type required by this method. public void ReadFT2232HEEPROM(FT2232H_EEPROM_STRUCTURE ee2232h) { this.PortFunctionValidator("ReadFT2232HEEPROM: FT_EE_Read", this.ftdi.NativeMethodsInstance.FT_EE_Read); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT2232H that we are trying to read this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_2232H) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("ReadFT2232HEEPROM", ftStatus, ftErrorCondition); } FT_PROGRAM_DATA eedata = new FT_PROGRAM_DATA(); // Set up structure headers eedata.Signature1 = 0x00000000; eedata.Signature2 = 0xFFFFFFFF; eedata.Version = 3; // Allocate space from unmanaged heap eedata.Manufacturer = Marshal.AllocHGlobal(32); eedata.ManufacturerID = Marshal.AllocHGlobal(16); eedata.Description = Marshal.AllocHGlobal(64); eedata.SerialNumber = Marshal.AllocHGlobal(16); // Call FT_EE_Read ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_Read(this.ftHandle, eedata); FTDI.ErrorHandler("ReadFT2232HEEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Retrieve string values ee2232h.Manufacturer = Marshal.PtrToStringAnsi(eedata.Manufacturer); ee2232h.ManufacturerID = Marshal.PtrToStringAnsi(eedata.ManufacturerID); ee2232h.Description = Marshal.PtrToStringAnsi(eedata.Description); ee2232h.SerialNumber = Marshal.PtrToStringAnsi(eedata.SerialNumber); // Free unmanaged buffers Marshal.FreeHGlobal(eedata.Manufacturer); Marshal.FreeHGlobal(eedata.ManufacturerID); Marshal.FreeHGlobal(eedata.Description); Marshal.FreeHGlobal(eedata.SerialNumber); // Map non-string elements to structure to be returned // Standard elements ee2232h.VendorID = eedata.VendorID; ee2232h.ProductID = eedata.ProductID; ee2232h.MaxPower = eedata.MaxPower; ee2232h.SelfPowered = Convert.ToBoolean(eedata.SelfPowered); ee2232h.RemoteWakeup = Convert.ToBoolean(eedata.RemoteWakeup); // 2232H specific fields ee2232h.PullDownEnable = Convert.ToBoolean(eedata.PullDownEnable7); ee2232h.SerNumEnable = Convert.ToBoolean(eedata.SerNumEnable7); ee2232h.ALSlowSlew = Convert.ToBoolean(eedata.ALSlowSlew); ee2232h.ALSchmittInput = Convert.ToBoolean(eedata.ALSchmittInput); ee2232h.ALDriveCurrent = eedata.ALDriveCurrent; ee2232h.AHSlowSlew = Convert.ToBoolean(eedata.AHSlowSlew); ee2232h.AHSchmittInput = Convert.ToBoolean(eedata.AHSchmittInput); ee2232h.AHDriveCurrent = eedata.AHDriveCurrent; ee2232h.BLSlowSlew = Convert.ToBoolean(eedata.BLSlowSlew); ee2232h.BLSchmittInput = Convert.ToBoolean(eedata.BLSchmittInput); ee2232h.BLDriveCurrent = eedata.BLDriveCurrent; ee2232h.BHSlowSlew = Convert.ToBoolean(eedata.BHSlowSlew); ee2232h.BHSchmittInput = Convert.ToBoolean(eedata.BHSchmittInput); ee2232h.BHDriveCurrent = eedata.BHDriveCurrent; ee2232h.IFAIsFifo = Convert.ToBoolean(eedata.IFAIsFifo7); ee2232h.IFAIsFifoTar = Convert.ToBoolean(eedata.IFAIsFifoTar7); ee2232h.IFAIsFastSer = Convert.ToBoolean(eedata.IFAIsFastSer7); ee2232h.AIsVCP = Convert.ToBoolean(eedata.AIsVCP7); ee2232h.IFBIsFifo = Convert.ToBoolean(eedata.IFBIsFifo7); ee2232h.IFBIsFifoTar = Convert.ToBoolean(eedata.IFBIsFifoTar7); ee2232h.IFBIsFastSer = Convert.ToBoolean(eedata.IFBIsFastSer7); ee2232h.BIsVCP = Convert.ToBoolean(eedata.BIsVCP7); ee2232h.PowerSaveEnable = Convert.ToBoolean(eedata.PowerSaveEnable); } /// /// Reads the EEPROM contents of an FT4232H device. /// /// An FTDI.FT4232H_EEPROM_STRUCTURE which contains only the relevant information for an FT4232H device. /// Thrown when the current device does not match the type required by this method. public void ReadFT4232HEEPROM(FT4232H_EEPROM_STRUCTURE ee4232h) { this.PortFunctionValidator("ReadFT4232HEEPROM: FT_EE_Read", this.ftdi.NativeMethodsInstance.FT_EE_Read); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT4232H that we are trying to read this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_4232H) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("ReadFT4232HEEPROM", ftStatus, ftErrorCondition); } FT_PROGRAM_DATA eedata = new FT_PROGRAM_DATA(); // Set up structure headers eedata.Signature1 = 0x00000000; eedata.Signature2 = 0xFFFFFFFF; eedata.Version = 4; // Allocate space from unmanaged heap eedata.Manufacturer = Marshal.AllocHGlobal(32); eedata.ManufacturerID = Marshal.AllocHGlobal(16); eedata.Description = Marshal.AllocHGlobal(64); eedata.SerialNumber = Marshal.AllocHGlobal(16); // Call FT_EE_Read ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_Read(this.ftHandle, eedata); FTDI.ErrorHandler("ReadFT4232HEEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Retrieve string values ee4232h.Manufacturer = Marshal.PtrToStringAnsi(eedata.Manufacturer); ee4232h.ManufacturerID = Marshal.PtrToStringAnsi(eedata.ManufacturerID); ee4232h.Description = Marshal.PtrToStringAnsi(eedata.Description); ee4232h.SerialNumber = Marshal.PtrToStringAnsi(eedata.SerialNumber); // Free unmanaged buffers Marshal.FreeHGlobal(eedata.Manufacturer); Marshal.FreeHGlobal(eedata.ManufacturerID); Marshal.FreeHGlobal(eedata.Description); Marshal.FreeHGlobal(eedata.SerialNumber); // Map non-string elements to structure to be returned // Standard elements ee4232h.VendorID = eedata.VendorID; ee4232h.ProductID = eedata.ProductID; ee4232h.MaxPower = eedata.MaxPower; ee4232h.SelfPowered = Convert.ToBoolean(eedata.SelfPowered); ee4232h.RemoteWakeup = Convert.ToBoolean(eedata.RemoteWakeup); // 4232H specific fields ee4232h.PullDownEnable = Convert.ToBoolean(eedata.PullDownEnable8); ee4232h.SerNumEnable = Convert.ToBoolean(eedata.SerNumEnable8); ee4232h.ASlowSlew = Convert.ToBoolean(eedata.ASlowSlew); ee4232h.ASchmittInput = Convert.ToBoolean(eedata.ASchmittInput); ee4232h.ADriveCurrent = eedata.ADriveCurrent; ee4232h.BSlowSlew = Convert.ToBoolean(eedata.BSlowSlew); ee4232h.BSchmittInput = Convert.ToBoolean(eedata.BSchmittInput); ee4232h.BDriveCurrent = eedata.BDriveCurrent; ee4232h.CSlowSlew = Convert.ToBoolean(eedata.CSlowSlew); ee4232h.CSchmittInput = Convert.ToBoolean(eedata.CSchmittInput); ee4232h.CDriveCurrent = eedata.CDriveCurrent; ee4232h.DSlowSlew = Convert.ToBoolean(eedata.DSlowSlew); ee4232h.DSchmittInput = Convert.ToBoolean(eedata.DSchmittInput); ee4232h.DDriveCurrent = eedata.DDriveCurrent; ee4232h.ARIIsTXDEN = Convert.ToBoolean(eedata.ARIIsTXDEN); ee4232h.BRIIsTXDEN = Convert.ToBoolean(eedata.BRIIsTXDEN); ee4232h.CRIIsTXDEN = Convert.ToBoolean(eedata.CRIIsTXDEN); ee4232h.DRIIsTXDEN = Convert.ToBoolean(eedata.DRIIsTXDEN); ee4232h.AIsVCP = Convert.ToBoolean(eedata.AIsVCP8); ee4232h.BIsVCP = Convert.ToBoolean(eedata.BIsVCP8); ee4232h.CIsVCP = Convert.ToBoolean(eedata.CIsVCP8); ee4232h.DIsVCP = Convert.ToBoolean(eedata.DIsVCP8); } /// /// Reads the EEPROM contents of an FT232H device. /// /// An FTDI.FT232H_EEPROM_STRUCTURE which contains only the relevant information for an FT232H device. /// Thrown when the current device does not match the type required by this method. public void ReadFT232HEEPROM(FT232H_EEPROM_STRUCTURE ee232h) { this.PortFunctionValidator("ReadFT232HEEPROM: FT_EE_Read", this.ftdi.NativeMethodsInstance.FT_EE_Read); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT232H that we are trying to read this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_232H) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("ReadFT232HEEPROM", ftStatus, ftErrorCondition); } FT_PROGRAM_DATA eedata = new FT_PROGRAM_DATA(); // Set up structure headers eedata.Signature1 = 0x00000000; eedata.Signature2 = 0xFFFFFFFF; eedata.Version = 5; // Allocate space from unmanaged heap eedata.Manufacturer = Marshal.AllocHGlobal(32); eedata.ManufacturerID = Marshal.AllocHGlobal(16); eedata.Description = Marshal.AllocHGlobal(64); eedata.SerialNumber = Marshal.AllocHGlobal(16); // Call FT_EE_Read ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_Read(this.ftHandle, eedata); FTDI.ErrorHandler("ReadFT232HEEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Retrieve string values ee232h.Manufacturer = Marshal.PtrToStringAnsi(eedata.Manufacturer); ee232h.ManufacturerID = Marshal.PtrToStringAnsi(eedata.ManufacturerID); ee232h.Description = Marshal.PtrToStringAnsi(eedata.Description); ee232h.SerialNumber = Marshal.PtrToStringAnsi(eedata.SerialNumber); // Free unmanaged buffers Marshal.FreeHGlobal(eedata.Manufacturer); Marshal.FreeHGlobal(eedata.ManufacturerID); Marshal.FreeHGlobal(eedata.Description); Marshal.FreeHGlobal(eedata.SerialNumber); // Map non-string elements to structure to be returned // Standard elements ee232h.VendorID = eedata.VendorID; ee232h.ProductID = eedata.ProductID; ee232h.MaxPower = eedata.MaxPower; ee232h.SelfPowered = Convert.ToBoolean(eedata.SelfPowered); ee232h.RemoteWakeup = Convert.ToBoolean(eedata.RemoteWakeup); // 232H specific fields ee232h.PullDownEnable = Convert.ToBoolean(eedata.PullDownEnableH); ee232h.SerNumEnable = Convert.ToBoolean(eedata.SerNumEnableH); ee232h.ACSlowSlew = Convert.ToBoolean(eedata.ACSlowSlewH); ee232h.ACSchmittInput = Convert.ToBoolean(eedata.ACSchmittInputH); ee232h.ACDriveCurrent = eedata.ACDriveCurrentH; ee232h.ADSlowSlew = Convert.ToBoolean(eedata.ADSlowSlewH); ee232h.ADSchmittInput = Convert.ToBoolean(eedata.ADSchmittInputH); ee232h.ADDriveCurrent = eedata.ADDriveCurrentH; ee232h.Cbus0 = eedata.Cbus0H; ee232h.Cbus1 = eedata.Cbus1H; ee232h.Cbus2 = eedata.Cbus2H; ee232h.Cbus3 = eedata.Cbus3H; ee232h.Cbus4 = eedata.Cbus4H; ee232h.Cbus5 = eedata.Cbus5H; ee232h.Cbus6 = eedata.Cbus6H; ee232h.Cbus7 = eedata.Cbus7H; ee232h.Cbus8 = eedata.Cbus8H; ee232h.Cbus9 = eedata.Cbus9H; ee232h.IsFifo = Convert.ToBoolean(eedata.IsFifoH); ee232h.IsFifoTar = Convert.ToBoolean(eedata.IsFifoTarH); ee232h.IsFastSer = Convert.ToBoolean(eedata.IsFastSerH); ee232h.IsFT1248 = Convert.ToBoolean(eedata.IsFT1248H); ee232h.FT1248Cpol = Convert.ToBoolean(eedata.FT1248CpolH); ee232h.FT1248Lsb = Convert.ToBoolean(eedata.FT1248LsbH); ee232h.FT1248FlowControl = Convert.ToBoolean(eedata.FT1248FlowControlH); ee232h.IsVCP = Convert.ToBoolean(eedata.IsVCPH); ee232h.PowerSaveEnable = Convert.ToBoolean(eedata.PowerSaveEnableH); } /// /// Reads the EEPROM contents of an X-Series device. /// /// An FTDI.FT_XSERIES_EEPROM_STRUCTURE which contains only the relevant information for an X-Series device. /// Thrown when the current device does not match the type required by this method. public void ReadXSeriesEEPROM(FT_XSERIES_EEPROM_STRUCTURE eeX) { this.PortFunctionValidator("ReadXSeriesEEPROM: FT_EEPROM_Read", this.ftdi.NativeMethodsInstance.FT_EEPROM_Read); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT232H that we are trying to read this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_X_SERIES) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("ReadXSeriesEEPROM", ftStatus, ftErrorCondition); } FT_XSERIES_DATA eeData = new FT_XSERIES_DATA(); FT_EEPROM_HEADER eeHeader = new FT_EEPROM_HEADER(); byte[] manufacturer = new byte[32]; byte[] manufacturerID = new byte[16]; byte[] description = new byte[64]; byte[] serialNumber = new byte[16]; eeHeader.deviceType = (uint)FT_DEVICE.FT_DEVICE_X_SERIES; eeData.common = eeHeader; // Calculate the size of our data structure... int size = Marshal.SizeOf(eeData); // Allocate space for our pointer... IntPtr eeDataMarshal = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(eeData, eeDataMarshal, false); // Call FT_EEPROM_Read ftStatus = this.ftdi.NativeMethodsInstance.FT_EEPROM_Read(this.ftHandle, eeDataMarshal, (uint)size, manufacturer, manufacturerID, description, serialNumber); FTDI.ErrorHandler("ReadXSeriesEEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Get the data back from the pointer... eeData = (FT_XSERIES_DATA)Marshal.PtrToStructure(eeDataMarshal, typeof(FT_XSERIES_DATA)); // Retrieve string values System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); eeX.Manufacturer = enc.GetString(manufacturer); eeX.ManufacturerID = enc.GetString(manufacturerID); eeX.Description = enc.GetString(description); eeX.SerialNumber = enc.GetString(serialNumber); // Map non-string elements to structure to be returned // Standard elements eeX.VendorID = eeData.common.VendorId; eeX.ProductID = eeData.common.ProductId; eeX.MaxPower = eeData.common.MaxPower; eeX.SelfPowered = Convert.ToBoolean(eeData.common.SelfPowered); eeX.RemoteWakeup = Convert.ToBoolean(eeData.common.RemoteWakeup); eeX.SerNumEnable = Convert.ToBoolean(eeData.common.SerNumEnable); eeX.PullDownEnable = Convert.ToBoolean(eeData.common.PullDownEnable); // X-Series specific fields // CBUS eeX.Cbus0 = eeData.Cbus0; eeX.Cbus1 = eeData.Cbus1; eeX.Cbus2 = eeData.Cbus2; eeX.Cbus3 = eeData.Cbus3; eeX.Cbus4 = eeData.Cbus4; eeX.Cbus5 = eeData.Cbus5; eeX.Cbus6 = eeData.Cbus6; // Drive Options eeX.ACDriveCurrent = eeData.ACDriveCurrent; eeX.ACSchmittInput = eeData.ACSchmittInput; eeX.ACSlowSlew = eeData.ACSlowSlew; eeX.ADDriveCurrent = eeData.ADDriveCurrent; eeX.ADSchmittInput = eeData.ADSchmittInput; eeX.ADSlowSlew = eeData.ADSlowSlew; // BCD eeX.BCDDisableSleep = eeData.BCDDisableSleep; eeX.BCDEnable = eeData.BCDEnable; eeX.BCDForceCbusPWREN = eeData.BCDForceCbusPWREN; // FT1248 eeX.FT1248Cpol = eeData.FT1248Cpol; eeX.FT1248FlowControl = eeData.FT1248FlowControl; eeX.FT1248Lsb = eeData.FT1248Lsb; // I2C eeX.I2CDeviceId = eeData.I2CDeviceId; eeX.I2CDisableSchmitt = eeData.I2CDisableSchmitt; eeX.I2CSlaveAddress = eeData.I2CSlaveAddress; // RS232 Signals eeX.InvertCTS = eeData.InvertCTS; eeX.InvertDCD = eeData.InvertDCD; eeX.InvertDSR = eeData.InvertDSR; eeX.InvertDTR = eeData.InvertDTR; eeX.InvertRI = eeData.InvertRI; eeX.InvertRTS = eeData.InvertRTS; eeX.InvertRXD = eeData.InvertRXD; eeX.InvertTXD = eeData.InvertTXD; // Hardware Options eeX.PowerSaveEnable = eeData.PowerSaveEnable; eeX.RS485EchoSuppress = eeData.RS485EchoSuppress; // Driver Option eeX.IsVCP = eeData.DriverType; } /// /// Writes the specified values to the EEPROM of an FT232B or FT245B device. /// /// The EEPROM settings to be written to the device /// If the strings are too long, they will be truncated to their maximum permitted lengths /// Thrown when the current device does not match the type required by this method. public void WriteFT232BEEPROM(FT232B_EEPROM_STRUCTURE ee232b) { this.PortFunctionValidator("WriteFT232BEEPROM: FT_EE_Program", this.ftdi.NativeMethodsInstance.FT_EE_Program); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT232B or FT245B that we are trying to write this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_BM) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("WriteFT232BEEPROM", ftStatus, ftErrorCondition); } // Check for VID and PID of 0x0000 if ((ee232b.VendorID == 0x0000) | (ee232b.ProductID == 0x0000)) { // Do not allow users to program the device with VID or PID of 0x0000 FTDI.ErrorHandler("WriteFT232BEEPROM", FT_STATUS.FT_INVALID_PARAMETER, FT_ERROR.FT_NO_ERROR); } FT_PROGRAM_DATA eedata = new FT_PROGRAM_DATA(); // Set up structure headers eedata.Signature1 = 0x00000000; eedata.Signature2 = 0xFFFFFFFF; eedata.Version = 2; // Allocate space from unmanaged heap eedata.Manufacturer = Marshal.AllocHGlobal(32); eedata.ManufacturerID = Marshal.AllocHGlobal(16); eedata.Description = Marshal.AllocHGlobal(64); eedata.SerialNumber = Marshal.AllocHGlobal(16); // Check lengths of strings to make sure that they are within our limits // If not, trim them to make them our maximum length if (ee232b.Manufacturer.Length > 32) ee232b.Manufacturer = ee232b.Manufacturer.Substring(0, 32); if (ee232b.ManufacturerID.Length > 16) ee232b.ManufacturerID = ee232b.ManufacturerID.Substring(0, 16); if (ee232b.Description.Length > 64) ee232b.Description = ee232b.Description.Substring(0, 64); if (ee232b.SerialNumber.Length > 16) ee232b.SerialNumber = ee232b.SerialNumber.Substring(0, 16); // Set string values eedata.Manufacturer = Marshal.StringToHGlobalAnsi(ee232b.Manufacturer); eedata.ManufacturerID = Marshal.StringToHGlobalAnsi(ee232b.ManufacturerID); eedata.Description = Marshal.StringToHGlobalAnsi(ee232b.Description); eedata.SerialNumber = Marshal.StringToHGlobalAnsi(ee232b.SerialNumber); // Map non-string elements to structure // Standard elements eedata.VendorID = ee232b.VendorID; eedata.ProductID = ee232b.ProductID; eedata.MaxPower = ee232b.MaxPower; eedata.SelfPowered = Convert.ToUInt16(ee232b.SelfPowered); eedata.RemoteWakeup = Convert.ToUInt16(ee232b.RemoteWakeup); // B specific fields eedata.Rev4 = Convert.ToByte(true); eedata.PullDownEnable = Convert.ToByte(ee232b.PullDownEnable); eedata.SerNumEnable = Convert.ToByte(ee232b.SerNumEnable); eedata.USBVersionEnable = Convert.ToByte(ee232b.USBVersionEnable); eedata.USBVersion = ee232b.USBVersion; // Call FT_EE_Program ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_Program(this.ftHandle, eedata); FTDI.ErrorHandler("WriteFT232BEEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Free unmanaged buffers Marshal.FreeHGlobal(eedata.Manufacturer); Marshal.FreeHGlobal(eedata.ManufacturerID); Marshal.FreeHGlobal(eedata.Description); Marshal.FreeHGlobal(eedata.SerialNumber); } /// /// Writes the specified values to the EEPROM of an FT2232 device. /// Calls FT_EE_Program in FTD2XX DLL /// /// The EEPROM settings to be written to the device /// If the strings are too long, they will be truncated to their maximum permitted lengths /// Thrown when the current device does not match the type required by this method. public void WriteFT2232EEPROM(FT2232_EEPROM_STRUCTURE ee2232) { this.PortFunctionValidator("WriteFT2232EEPROM: FT_EE_Program", this.ftdi.NativeMethodsInstance.FT_EE_Program); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT2232 that we are trying to write this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_2232) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("WriteFT2232EEPROM", ftStatus, ftErrorCondition); } // Check for VID and PID of 0x0000 if ((ee2232.VendorID == 0x0000) | (ee2232.ProductID == 0x0000)) { // Do not allow users to program the device with VID or PID of 0x0000 FTDI.ErrorHandler("WriteFT2232EEPROM", FT_STATUS.FT_INVALID_PARAMETER, FT_ERROR.FT_NO_ERROR); } FT_PROGRAM_DATA eedata = new FT_PROGRAM_DATA(); // Set up structure headers eedata.Signature1 = 0x00000000; eedata.Signature2 = 0xFFFFFFFF; eedata.Version = 2; // Allocate space from unmanaged heap eedata.Manufacturer = Marshal.AllocHGlobal(32); eedata.ManufacturerID = Marshal.AllocHGlobal(16); eedata.Description = Marshal.AllocHGlobal(64); eedata.SerialNumber = Marshal.AllocHGlobal(16); // Check lengths of strings to make sure that they are within our limits // If not, trim them to make them our maximum length if (ee2232.Manufacturer.Length > 32) ee2232.Manufacturer = ee2232.Manufacturer.Substring(0, 32); if (ee2232.ManufacturerID.Length > 16) ee2232.ManufacturerID = ee2232.ManufacturerID.Substring(0, 16); if (ee2232.Description.Length > 64) ee2232.Description = ee2232.Description.Substring(0, 64); if (ee2232.SerialNumber.Length > 16) ee2232.SerialNumber = ee2232.SerialNumber.Substring(0, 16); // Set string values eedata.Manufacturer = Marshal.StringToHGlobalAnsi(ee2232.Manufacturer); eedata.ManufacturerID = Marshal.StringToHGlobalAnsi(ee2232.ManufacturerID); eedata.Description = Marshal.StringToHGlobalAnsi(ee2232.Description); eedata.SerialNumber = Marshal.StringToHGlobalAnsi(ee2232.SerialNumber); // Map non-string elements to structure // Standard elements eedata.VendorID = ee2232.VendorID; eedata.ProductID = ee2232.ProductID; eedata.MaxPower = ee2232.MaxPower; eedata.SelfPowered = Convert.ToUInt16(ee2232.SelfPowered); eedata.RemoteWakeup = Convert.ToUInt16(ee2232.RemoteWakeup); // 2232 specific fields eedata.Rev5 = Convert.ToByte(true); eedata.PullDownEnable5 = Convert.ToByte(ee2232.PullDownEnable); eedata.SerNumEnable5 = Convert.ToByte(ee2232.SerNumEnable); eedata.USBVersionEnable5 = Convert.ToByte(ee2232.USBVersionEnable); eedata.USBVersion5 = ee2232.USBVersion; eedata.AIsHighCurrent = Convert.ToByte(ee2232.AIsHighCurrent); eedata.BIsHighCurrent = Convert.ToByte(ee2232.BIsHighCurrent); eedata.IFAIsFifo = Convert.ToByte(ee2232.IFAIsFifo); eedata.IFAIsFifoTar = Convert.ToByte(ee2232.IFAIsFifoTar); eedata.IFAIsFastSer = Convert.ToByte(ee2232.IFAIsFastSer); eedata.AIsVCP = Convert.ToByte(ee2232.AIsVCP); eedata.IFBIsFifo = Convert.ToByte(ee2232.IFBIsFifo); eedata.IFBIsFifoTar = Convert.ToByte(ee2232.IFBIsFifoTar); eedata.IFBIsFastSer = Convert.ToByte(ee2232.IFBIsFastSer); eedata.BIsVCP = Convert.ToByte(ee2232.BIsVCP); // Call FT_EE_Program ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_Program(this.ftHandle, eedata); FTDI.ErrorHandler("WriteFT2232EEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Free unmanaged buffers Marshal.FreeHGlobal(eedata.Manufacturer); Marshal.FreeHGlobal(eedata.ManufacturerID); Marshal.FreeHGlobal(eedata.Description); Marshal.FreeHGlobal(eedata.SerialNumber); } /// /// Writes the specified values to the EEPROM of an FT232R or FT245R device. /// Calls FT_EE_Program in FTD2XX DLL /// /// The EEPROM settings to be written to the device /// If the strings are too long, they will be truncated to their maximum permitted lengths /// Thrown when the current device does not match the type required by this method. public void WriteFT232REEPROM(FT232R_EEPROM_STRUCTURE ee232r) { this.PortFunctionValidator("WriteFT232REEPROM: FT_EE_Program", this.ftdi.NativeMethodsInstance.FT_EE_Program); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT232R or FT245R that we are trying to write this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_232R) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("WriteFT232REEPROM", ftStatus, ftErrorCondition); } // Check for VID and PID of 0x0000 if ((ee232r.VendorID == 0x0000) | (ee232r.ProductID == 0x0000)) { // Do not allow users to program the device with VID or PID of 0x0000 FTDI.ErrorHandler("WriteFT232REEPROM", FT_STATUS.FT_INVALID_PARAMETER, FT_ERROR.FT_NO_ERROR); } FT_PROGRAM_DATA eedata = new FT_PROGRAM_DATA(); // Set up structure headers eedata.Signature1 = 0x00000000; eedata.Signature2 = 0xFFFFFFFF; eedata.Version = 2; // Allocate space from unmanaged heap eedata.Manufacturer = Marshal.AllocHGlobal(32); eedata.ManufacturerID = Marshal.AllocHGlobal(16); eedata.Description = Marshal.AllocHGlobal(64); eedata.SerialNumber = Marshal.AllocHGlobal(16); // Check lengths of strings to make sure that they are within our limits // If not, trim them to make them our maximum length if (ee232r.Manufacturer.Length > 32) ee232r.Manufacturer = ee232r.Manufacturer.Substring(0, 32); if (ee232r.ManufacturerID.Length > 16) ee232r.ManufacturerID = ee232r.ManufacturerID.Substring(0, 16); if (ee232r.Description.Length > 64) ee232r.Description = ee232r.Description.Substring(0, 64); if (ee232r.SerialNumber.Length > 16) ee232r.SerialNumber = ee232r.SerialNumber.Substring(0, 16); // Set string values eedata.Manufacturer = Marshal.StringToHGlobalAnsi(ee232r.Manufacturer); eedata.ManufacturerID = Marshal.StringToHGlobalAnsi(ee232r.ManufacturerID); eedata.Description = Marshal.StringToHGlobalAnsi(ee232r.Description); eedata.SerialNumber = Marshal.StringToHGlobalAnsi(ee232r.SerialNumber); // Map non-string elements to structure // Standard elements eedata.VendorID = ee232r.VendorID; eedata.ProductID = ee232r.ProductID; eedata.MaxPower = ee232r.MaxPower; eedata.SelfPowered = Convert.ToUInt16(ee232r.SelfPowered); eedata.RemoteWakeup = Convert.ToUInt16(ee232r.RemoteWakeup); // 232R specific fields eedata.PullDownEnableR = Convert.ToByte(ee232r.PullDownEnable); eedata.SerNumEnableR = Convert.ToByte(ee232r.SerNumEnable); eedata.UseExtOsc = Convert.ToByte(ee232r.UseExtOsc); eedata.HighDriveIOs = Convert.ToByte(ee232r.HighDriveIOs); // Override any endpoint size the user has selected and force 64 bytes // Some users have been known to wreck devices by setting 0 here... eedata.EndpointSize = 64; eedata.PullDownEnableR = Convert.ToByte(ee232r.PullDownEnable); eedata.SerNumEnableR = Convert.ToByte(ee232r.SerNumEnable); eedata.InvertTXD = Convert.ToByte(ee232r.InvertTXD); eedata.InvertRXD = Convert.ToByte(ee232r.InvertRXD); eedata.InvertRTS = Convert.ToByte(ee232r.InvertRTS); eedata.InvertCTS = Convert.ToByte(ee232r.InvertCTS); eedata.InvertDTR = Convert.ToByte(ee232r.InvertDTR); eedata.InvertDSR = Convert.ToByte(ee232r.InvertDSR); eedata.InvertDCD = Convert.ToByte(ee232r.InvertDCD); eedata.InvertRI = Convert.ToByte(ee232r.InvertRI); eedata.Cbus0 = ee232r.Cbus0; eedata.Cbus1 = ee232r.Cbus1; eedata.Cbus2 = ee232r.Cbus2; eedata.Cbus3 = ee232r.Cbus3; eedata.Cbus4 = ee232r.Cbus4; eedata.RIsD2XX = Convert.ToByte(ee232r.RIsD2XX); // Call FT_EE_Program ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_Program(this.ftHandle, eedata); FTDI.ErrorHandler("WriteFT232REEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Free unmanaged buffers Marshal.FreeHGlobal(eedata.Manufacturer); Marshal.FreeHGlobal(eedata.ManufacturerID); Marshal.FreeHGlobal(eedata.Description); Marshal.FreeHGlobal(eedata.SerialNumber); } /// /// Writes the specified values to the EEPROM of an FT2232H device. /// Calls FT_EE_Program in FTD2XX DLL /// /// The EEPROM settings to be written to the device /// If the strings are too long, they will be truncated to their maximum permitted lengths /// Thrown when the current device does not match the type required by this method. public void WriteFT2232HEEPROM(FT2232H_EEPROM_STRUCTURE ee2232h) { this.PortFunctionValidator("WriteFT2232HEEPROM: FT_EE_Program", this.ftdi.NativeMethodsInstance.FT_EE_Program); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT2232H that we are trying to write this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_2232H) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("WriteFT2232HEEPROM", ftStatus, ftErrorCondition); } // Check for VID and PID of 0x0000 if ((ee2232h.VendorID == 0x0000) | (ee2232h.ProductID == 0x0000)) { // Do not allow users to program the device with VID or PID of 0x0000 FTDI.ErrorHandler("WriteFT2232HEEPROM", FT_STATUS.FT_INVALID_PARAMETER, FT_ERROR.FT_NO_ERROR); } FT_PROGRAM_DATA eedata = new FT_PROGRAM_DATA(); // Set up structure headers eedata.Signature1 = 0x00000000; eedata.Signature2 = 0xFFFFFFFF; eedata.Version = 3; // Allocate space from unmanaged heap eedata.Manufacturer = Marshal.AllocHGlobal(32); eedata.ManufacturerID = Marshal.AllocHGlobal(16); eedata.Description = Marshal.AllocHGlobal(64); eedata.SerialNumber = Marshal.AllocHGlobal(16); // Check lengths of strings to make sure that they are within our limits // If not, trim them to make them our maximum length if (ee2232h.Manufacturer.Length > 32) ee2232h.Manufacturer = ee2232h.Manufacturer.Substring(0, 32); if (ee2232h.ManufacturerID.Length > 16) ee2232h.ManufacturerID = ee2232h.ManufacturerID.Substring(0, 16); if (ee2232h.Description.Length > 64) ee2232h.Description = ee2232h.Description.Substring(0, 64); if (ee2232h.SerialNumber.Length > 16) ee2232h.SerialNumber = ee2232h.SerialNumber.Substring(0, 16); // Set string values eedata.Manufacturer = Marshal.StringToHGlobalAnsi(ee2232h.Manufacturer); eedata.ManufacturerID = Marshal.StringToHGlobalAnsi(ee2232h.ManufacturerID); eedata.Description = Marshal.StringToHGlobalAnsi(ee2232h.Description); eedata.SerialNumber = Marshal.StringToHGlobalAnsi(ee2232h.SerialNumber); // Map non-string elements to structure // Standard elements eedata.VendorID = ee2232h.VendorID; eedata.ProductID = ee2232h.ProductID; eedata.MaxPower = ee2232h.MaxPower; eedata.SelfPowered = Convert.ToUInt16(ee2232h.SelfPowered); eedata.RemoteWakeup = Convert.ToUInt16(ee2232h.RemoteWakeup); // 2232H specific fields eedata.PullDownEnable7 = Convert.ToByte(ee2232h.PullDownEnable); eedata.SerNumEnable7 = Convert.ToByte(ee2232h.SerNumEnable); eedata.ALSlowSlew = Convert.ToByte(ee2232h.ALSlowSlew); eedata.ALSchmittInput = Convert.ToByte(ee2232h.ALSchmittInput); eedata.ALDriveCurrent = ee2232h.ALDriveCurrent; eedata.AHSlowSlew = Convert.ToByte(ee2232h.AHSlowSlew); eedata.AHSchmittInput = Convert.ToByte(ee2232h.AHSchmittInput); eedata.AHDriveCurrent = ee2232h.AHDriveCurrent; eedata.BLSlowSlew = Convert.ToByte(ee2232h.BLSlowSlew); eedata.BLSchmittInput = Convert.ToByte(ee2232h.BLSchmittInput); eedata.BLDriveCurrent = ee2232h.BLDriveCurrent; eedata.BHSlowSlew = Convert.ToByte(ee2232h.BHSlowSlew); eedata.BHSchmittInput = Convert.ToByte(ee2232h.BHSchmittInput); eedata.BHDriveCurrent = ee2232h.BHDriveCurrent; eedata.IFAIsFifo7 = Convert.ToByte(ee2232h.IFAIsFifo); eedata.IFAIsFifoTar7 = Convert.ToByte(ee2232h.IFAIsFifoTar); eedata.IFAIsFastSer7 = Convert.ToByte(ee2232h.IFAIsFastSer); eedata.AIsVCP7 = Convert.ToByte(ee2232h.AIsVCP); eedata.IFBIsFifo7 = Convert.ToByte(ee2232h.IFBIsFifo); eedata.IFBIsFifoTar7 = Convert.ToByte(ee2232h.IFBIsFifoTar); eedata.IFBIsFastSer7 = Convert.ToByte(ee2232h.IFBIsFastSer); eedata.BIsVCP7 = Convert.ToByte(ee2232h.BIsVCP); eedata.PowerSaveEnable = Convert.ToByte(ee2232h.PowerSaveEnable); // Call FT_EE_Program ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_Program(this.ftHandle, eedata); FTDI.ErrorHandler("WriteFT2232HEEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Free unmanaged buffers Marshal.FreeHGlobal(eedata.Manufacturer); Marshal.FreeHGlobal(eedata.ManufacturerID); Marshal.FreeHGlobal(eedata.Description); Marshal.FreeHGlobal(eedata.SerialNumber); } /// /// Writes the specified values to the EEPROM of an FT4232H device. /// Calls FT_EE_Program in FTD2XX DLL /// /// The EEPROM settings to be written to the device /// If the strings are too long, they will be truncated to their maximum permitted lengths /// Thrown when the current device does not match the type required by this method. public void WriteFT4232HEEPROM(FT4232H_EEPROM_STRUCTURE ee4232h) { this.PortFunctionValidator("WriteFT4232HEEPROM: FT_EE_Program", this.ftdi.NativeMethodsInstance.FT_EE_Program); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT4232H that we are trying to write this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_4232H) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("WriteFT4232HEEPROM", ftStatus, ftErrorCondition); } // Check for VID and PID of 0x0000 if ((ee4232h.VendorID == 0x0000) | (ee4232h.ProductID == 0x0000)) { // Do not allow users to program the device with VID or PID of 0x0000 FTDI.ErrorHandler("WriteFT4232HEEPROM", FT_STATUS.FT_INVALID_PARAMETER, FT_ERROR.FT_NO_ERROR); } FT_PROGRAM_DATA eedata = new FT_PROGRAM_DATA(); // Set up structure headers eedata.Signature1 = 0x00000000; eedata.Signature2 = 0xFFFFFFFF; eedata.Version = 4; // Allocate space from unmanaged heap eedata.Manufacturer = Marshal.AllocHGlobal(32); eedata.ManufacturerID = Marshal.AllocHGlobal(16); eedata.Description = Marshal.AllocHGlobal(64); eedata.SerialNumber = Marshal.AllocHGlobal(16); // Check lengths of strings to make sure that they are within our limits // If not, trim them to make them our maximum length if (ee4232h.Manufacturer.Length > 32) ee4232h.Manufacturer = ee4232h.Manufacturer.Substring(0, 32); if (ee4232h.ManufacturerID.Length > 16) ee4232h.ManufacturerID = ee4232h.ManufacturerID.Substring(0, 16); if (ee4232h.Description.Length > 64) ee4232h.Description = ee4232h.Description.Substring(0, 64); if (ee4232h.SerialNumber.Length > 16) ee4232h.SerialNumber = ee4232h.SerialNumber.Substring(0, 16); // Set string values eedata.Manufacturer = Marshal.StringToHGlobalAnsi(ee4232h.Manufacturer); eedata.ManufacturerID = Marshal.StringToHGlobalAnsi(ee4232h.ManufacturerID); eedata.Description = Marshal.StringToHGlobalAnsi(ee4232h.Description); eedata.SerialNumber = Marshal.StringToHGlobalAnsi(ee4232h.SerialNumber); // Map non-string elements to structure // Standard elements eedata.VendorID = ee4232h.VendorID; eedata.ProductID = ee4232h.ProductID; eedata.MaxPower = ee4232h.MaxPower; eedata.SelfPowered = Convert.ToUInt16(ee4232h.SelfPowered); eedata.RemoteWakeup = Convert.ToUInt16(ee4232h.RemoteWakeup); // 4232H specific fields eedata.PullDownEnable8 = Convert.ToByte(ee4232h.PullDownEnable); eedata.SerNumEnable8 = Convert.ToByte(ee4232h.SerNumEnable); eedata.ASlowSlew = Convert.ToByte(ee4232h.ASlowSlew); eedata.ASchmittInput = Convert.ToByte(ee4232h.ASchmittInput); eedata.ADriveCurrent = ee4232h.ADriveCurrent; eedata.BSlowSlew = Convert.ToByte(ee4232h.BSlowSlew); eedata.BSchmittInput = Convert.ToByte(ee4232h.BSchmittInput); eedata.BDriveCurrent = ee4232h.BDriveCurrent; eedata.CSlowSlew = Convert.ToByte(ee4232h.CSlowSlew); eedata.CSchmittInput = Convert.ToByte(ee4232h.CSchmittInput); eedata.CDriveCurrent = ee4232h.CDriveCurrent; eedata.DSlowSlew = Convert.ToByte(ee4232h.DSlowSlew); eedata.DSchmittInput = Convert.ToByte(ee4232h.DSchmittInput); eedata.DDriveCurrent = ee4232h.DDriveCurrent; eedata.ARIIsTXDEN = Convert.ToByte(ee4232h.ARIIsTXDEN); eedata.BRIIsTXDEN = Convert.ToByte(ee4232h.BRIIsTXDEN); eedata.CRIIsTXDEN = Convert.ToByte(ee4232h.CRIIsTXDEN); eedata.DRIIsTXDEN = Convert.ToByte(ee4232h.DRIIsTXDEN); eedata.AIsVCP8 = Convert.ToByte(ee4232h.AIsVCP); eedata.BIsVCP8 = Convert.ToByte(ee4232h.BIsVCP); eedata.CIsVCP8 = Convert.ToByte(ee4232h.CIsVCP); eedata.DIsVCP8 = Convert.ToByte(ee4232h.DIsVCP); // Call FT_EE_Program ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_Program(this.ftHandle, eedata); FTDI.ErrorHandler("WriteFT4232HEEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Free unmanaged buffers Marshal.FreeHGlobal(eedata.Manufacturer); Marshal.FreeHGlobal(eedata.ManufacturerID); Marshal.FreeHGlobal(eedata.Description); Marshal.FreeHGlobal(eedata.SerialNumber); } /// /// Writes the specified values to the EEPROM of an FT232H device. /// Calls FT_EE_Program in FTD2XX DLL /// /// The EEPROM settings to be written to the device /// If the strings are too long, they will be truncated to their maximum permitted lengths /// Thrown when the current device does not match the type required by this method. public void WriteFT232HEEPROM(FT232H_EEPROM_STRUCTURE ee232h) { this.PortFunctionValidator("WriteFT232HEEPROM: FT_EE_Program", this.ftdi.NativeMethodsInstance.FT_EE_Program); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT232H that we are trying to write this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_232H) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("WriteFT232HEEPROM", ftStatus, ftErrorCondition); } // Check for VID and PID of 0x0000 if ((ee232h.VendorID == 0x0000) | (ee232h.ProductID == 0x0000)) { // Do not allow users to program the device with VID or PID of 0x0000 FTDI.ErrorHandler("WriteFT232HEEPROM", FT_STATUS.FT_INVALID_PARAMETER, FT_ERROR.FT_NO_ERROR); } FT_PROGRAM_DATA eedata = new FT_PROGRAM_DATA(); // Set up structure headers eedata.Signature1 = 0x00000000; eedata.Signature2 = 0xFFFFFFFF; eedata.Version = 5; // Allocate space from unmanaged heap eedata.Manufacturer = Marshal.AllocHGlobal(32); eedata.ManufacturerID = Marshal.AllocHGlobal(16); eedata.Description = Marshal.AllocHGlobal(64); eedata.SerialNumber = Marshal.AllocHGlobal(16); // Check lengths of strings to make sure that they are within our limits // If not, trim them to make them our maximum length if (ee232h.Manufacturer.Length > 32) ee232h.Manufacturer = ee232h.Manufacturer.Substring(0, 32); if (ee232h.ManufacturerID.Length > 16) ee232h.ManufacturerID = ee232h.ManufacturerID.Substring(0, 16); if (ee232h.Description.Length > 64) ee232h.Description = ee232h.Description.Substring(0, 64); if (ee232h.SerialNumber.Length > 16) ee232h.SerialNumber = ee232h.SerialNumber.Substring(0, 16); // Set string values eedata.Manufacturer = Marshal.StringToHGlobalAnsi(ee232h.Manufacturer); eedata.ManufacturerID = Marshal.StringToHGlobalAnsi(ee232h.ManufacturerID); eedata.Description = Marshal.StringToHGlobalAnsi(ee232h.Description); eedata.SerialNumber = Marshal.StringToHGlobalAnsi(ee232h.SerialNumber); // Map non-string elements to structure // Standard elements eedata.VendorID = ee232h.VendorID; eedata.ProductID = ee232h.ProductID; eedata.MaxPower = ee232h.MaxPower; eedata.SelfPowered = Convert.ToUInt16(ee232h.SelfPowered); eedata.RemoteWakeup = Convert.ToUInt16(ee232h.RemoteWakeup); // 232H specific fields eedata.PullDownEnableH = Convert.ToByte(ee232h.PullDownEnable); eedata.SerNumEnableH = Convert.ToByte(ee232h.SerNumEnable); eedata.ACSlowSlewH = Convert.ToByte(ee232h.ACSlowSlew); eedata.ACSchmittInputH = Convert.ToByte(ee232h.ACSchmittInput); eedata.ACDriveCurrentH = Convert.ToByte(ee232h.ACDriveCurrent); eedata.ADSlowSlewH = Convert.ToByte(ee232h.ADSlowSlew); eedata.ADSchmittInputH = Convert.ToByte(ee232h.ADSchmittInput); eedata.ADDriveCurrentH = Convert.ToByte(ee232h.ADDriveCurrent); eedata.Cbus0H = Convert.ToByte(ee232h.Cbus0); eedata.Cbus1H = Convert.ToByte(ee232h.Cbus1); eedata.Cbus2H = Convert.ToByte(ee232h.Cbus2); eedata.Cbus3H = Convert.ToByte(ee232h.Cbus3); eedata.Cbus4H = Convert.ToByte(ee232h.Cbus4); eedata.Cbus5H = Convert.ToByte(ee232h.Cbus5); eedata.Cbus6H = Convert.ToByte(ee232h.Cbus6); eedata.Cbus7H = Convert.ToByte(ee232h.Cbus7); eedata.Cbus8H = Convert.ToByte(ee232h.Cbus8); eedata.Cbus9H = Convert.ToByte(ee232h.Cbus9); eedata.IsFifoH = Convert.ToByte(ee232h.IsFifo); eedata.IsFifoTarH = Convert.ToByte(ee232h.IsFifoTar); eedata.IsFastSerH = Convert.ToByte(ee232h.IsFastSer); eedata.IsFT1248H = Convert.ToByte(ee232h.IsFT1248); eedata.FT1248CpolH = Convert.ToByte(ee232h.FT1248Cpol); eedata.FT1248LsbH = Convert.ToByte(ee232h.FT1248Lsb); eedata.FT1248FlowControlH = Convert.ToByte(ee232h.FT1248FlowControl); eedata.IsVCPH = Convert.ToByte(ee232h.IsVCP); eedata.PowerSaveEnableH = Convert.ToByte(ee232h.PowerSaveEnable); // Call FT_EE_Program ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_Program(this.ftHandle, eedata); FTDI.ErrorHandler("WriteFT232HEEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); // Free unmanaged buffers Marshal.FreeHGlobal(eedata.Manufacturer); Marshal.FreeHGlobal(eedata.ManufacturerID); Marshal.FreeHGlobal(eedata.Description); Marshal.FreeHGlobal(eedata.SerialNumber); } /// /// Writes the specified values to the EEPROM of an X-Series device. /// Calls FT_EEPROM_Program in FTD2XX DLL /// /// The EEPROM settings to be written to the device /// If the strings are too long, they will be truncated to their maximum permitted lengths /// Thrown when the current device does not match the type required by this method. public void WriteXSeriesEEPROM(FT_XSERIES_EEPROM_STRUCTURE eeX) { this.PortFunctionValidator("WriteXSeriesEEPROM: FT_EEPROM_Program", this.ftdi.NativeMethodsInstance.FT_EEPROM_Program); // Initialise ftStatus to something other than FT_OK FT_STATUS ftStatus = FT_STATUS.FT_OTHER_ERROR; FT_ERROR ftErrorCondition = FT_ERROR.FT_NO_ERROR; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Check that it is an FT232H that we are trying to write this.GetDeviceType(ref DeviceType); if (DeviceType != FT_DEVICE.FT_DEVICE_X_SERIES) { // If it is not, throw an exception ftErrorCondition = FT_ERROR.FT_INCORRECT_DEVICE; FTDI.ErrorHandler("WriteXSeriesEEPROM", ftStatus, ftErrorCondition); } // Check for VID and PID of 0x0000 if ((eeX.VendorID == 0x0000) | (eeX.ProductID == 0x0000)) { // Do not allow users to program the device with VID or PID of 0x0000 FTDI.ErrorHandler("WriteXSeriesEEPROM", FT_STATUS.FT_INVALID_PARAMETER, FT_ERROR.FT_NO_ERROR); } FT_XSERIES_DATA eeData = new FT_XSERIES_DATA(); // String manipulation... // Allocate space from unmanaged heap byte[] manufacturer = new byte[32]; byte[] manufacturerID = new byte[16]; byte[] description = new byte[64]; byte[] serialNumber = new byte[16]; // Check lengths of strings to make sure that they are within our limits // If not, trim them to make them our maximum length if (eeX.Manufacturer.Length > 32) eeX.Manufacturer = eeX.Manufacturer.Substring(0, 32); if (eeX.ManufacturerID.Length > 16) eeX.ManufacturerID = eeX.ManufacturerID.Substring(0, 16); if (eeX.Description.Length > 64) eeX.Description = eeX.Description.Substring(0, 64); if (eeX.SerialNumber.Length > 16) eeX.SerialNumber = eeX.SerialNumber.Substring(0, 16); // Set string values System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); manufacturer = encoding.GetBytes(eeX.Manufacturer); manufacturerID = encoding.GetBytes(eeX.ManufacturerID); description = encoding.GetBytes(eeX.Description); serialNumber = encoding.GetBytes(eeX.SerialNumber); // Map non-string elements to structure to be returned // Standard elements eeData.common.deviceType = (uint)FT_DEVICE.FT_DEVICE_X_SERIES; eeData.common.VendorId = eeX.VendorID; eeData.common.ProductId = eeX.ProductID; eeData.common.MaxPower = eeX.MaxPower; eeData.common.SelfPowered = Convert.ToByte(eeX.SelfPowered); eeData.common.RemoteWakeup = Convert.ToByte(eeX.RemoteWakeup); eeData.common.SerNumEnable = Convert.ToByte(eeX.SerNumEnable); eeData.common.PullDownEnable = Convert.ToByte(eeX.PullDownEnable); // X-Series specific fields // CBUS eeData.Cbus0 = eeX.Cbus0; eeData.Cbus1 = eeX.Cbus1; eeData.Cbus2 = eeX.Cbus2; eeData.Cbus3 = eeX.Cbus3; eeData.Cbus4 = eeX.Cbus4; eeData.Cbus5 = eeX.Cbus5; eeData.Cbus6 = eeX.Cbus6; // Drive Options eeData.ACDriveCurrent = eeX.ACDriveCurrent; eeData.ACSchmittInput = eeX.ACSchmittInput; eeData.ACSlowSlew = eeX.ACSlowSlew; eeData.ADDriveCurrent = eeX.ADDriveCurrent; eeData.ADSchmittInput = eeX.ADSchmittInput; eeData.ADSlowSlew = eeX.ADSlowSlew; // BCD eeData.BCDDisableSleep = eeX.BCDDisableSleep; eeData.BCDEnable = eeX.BCDEnable; eeData.BCDForceCbusPWREN = eeX.BCDForceCbusPWREN; // FT1248 eeData.FT1248Cpol = eeX.FT1248Cpol; eeData.FT1248FlowControl = eeX.FT1248FlowControl; eeData.FT1248Lsb = eeX.FT1248Lsb; // I2C eeData.I2CDeviceId = eeX.I2CDeviceId; eeData.I2CDisableSchmitt = eeX.I2CDisableSchmitt; eeData.I2CSlaveAddress = eeX.I2CSlaveAddress; // RS232 Signals eeData.InvertCTS = eeX.InvertCTS; eeData.InvertDCD = eeX.InvertDCD; eeData.InvertDSR = eeX.InvertDSR; eeData.InvertDTR = eeX.InvertDTR; eeData.InvertRI = eeX.InvertRI; eeData.InvertRTS = eeX.InvertRTS; eeData.InvertRXD = eeX.InvertRXD; eeData.InvertTXD = eeX.InvertTXD; // Hardware Options eeData.PowerSaveEnable = eeX.PowerSaveEnable; eeData.RS485EchoSuppress = eeX.RS485EchoSuppress; // Driver Option eeData.DriverType = eeX.IsVCP; // Check the size of the structure... int size = Marshal.SizeOf(eeData); // Allocate space for our pointer... IntPtr eeDataMarshal = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(eeData, eeDataMarshal, false); ftStatus = this.ftdi.NativeMethodsInstance.FT_EEPROM_Program(this.ftHandle, eeDataMarshal, (uint)size, manufacturer, manufacturerID, description, serialNumber); FTDI.ErrorHandler("WriteXSeriesEEPROM", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Reads data from the user area of the device EEPROM. /// /// An array of bytes which will be populated with the data read from the device EEPROM user area. /// The number of bytes actually read from the EEPROM user area. public void EEReadUserArea(byte[] UserAreaDataBuffer, ref uint numBytesRead) { this.PortFunctionValidator("EEReadUserArea: FT_EE_UASize", this.ftdi.NativeMethodsInstance.FT_EE_UASize); this.PortFunctionValidator("EEReadUserArea: FT_EE_UARead", this.ftdi.NativeMethodsInstance.FT_EE_UARead); uint UASize = 0; // Get size of user area to allocate an array of the correct size. // The application must also get the UA size for its copy FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_UASize(this.ftHandle, ref UASize); FTDI.ErrorHandler("EEReadUserArea:FT_EE_UASize", ftStatus, FT_ERROR.FT_NO_ERROR); // Make sure we have enough storage for the whole user area if (UserAreaDataBuffer.Length < UASize) { FTDI.ErrorHandler("EEReadUserArea", FT_STATUS.FT_OTHER_ERROR, FT_ERROR.FT_BUFFER_SIZE); } // Call FT_EE_UARead ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_UARead(this.ftHandle, UserAreaDataBuffer, UserAreaDataBuffer.Length, ref numBytesRead); FTDI.ErrorHandler("EEReadUserArea:FT_EE_UARead", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Writes data to the user area of the device EEPROM. /// /// An array of bytes which will be written to the device EEPROM user area. public void EEWriteUserArea(byte[] UserAreaDataBuffer) { this.PortFunctionValidator("EEWriteUserArea: FT_EE_UASize", this.ftdi.NativeMethodsInstance.FT_EE_UASize); this.PortFunctionValidator("EEWriteUserArea: FT_EE_UAWrite", this.ftdi.NativeMethodsInstance.FT_EE_UAWrite); // Get size of user area to allocate an array of the correct size. // The application must also get the UA size for its copy uint UASize = 0; FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_UASize(this.ftHandle, ref UASize); FTDI.ErrorHandler("EEWriteUserArea:FT_EE_UASize", ftStatus, FT_ERROR.FT_NO_ERROR); // Make sure we have enough storage for all the data in the EEPROM if (UserAreaDataBuffer.Length > UASize) { FTDI.ErrorHandler("EEWriteUserArea", FT_STATUS.FT_OTHER_ERROR, FT_ERROR.FT_BUFFER_SIZE); } // Call FT_EE_UAWrite ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_UAWrite(this.ftHandle, UserAreaDataBuffer, UserAreaDataBuffer.Length); FTDI.ErrorHandler("EEWriteUserArea:FT_EE_UAWrite", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Gets the chip type of the current device. /// /// The FTDI chip type of the current device. public void GetDeviceType(ref FT_DEVICE DeviceType) { this.PortFunctionValidator("GetDeviceType: FT_GetDeviceInfo", this.ftdi.NativeMethodsInstance.FT_GetDeviceInfo); uint DeviceID = 0; byte[] sernum = new byte[16]; byte[] desc = new byte[64]; DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Call FT_GetDeviceInfo FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetDeviceInfo(this.ftHandle, ref DeviceType, ref DeviceID, sernum, desc, IntPtr.Zero); FTDI.ErrorHandler("GetDeviceType:FT_GetDeviceInfo", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Gets the Vendor ID and Product ID of the current device. /// /// The device ID (Vendor ID and Product ID) of the current device. public void GetDeviceID(ref uint DeviceID) { this.PortFunctionValidator("GetDeviceID: FT_GetDeviceInfo", this.ftdi.NativeMethodsInstance.FT_GetDeviceInfo); FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; byte[] sernum = new byte[16]; byte[] desc = new byte[64]; // Call FT_GetDeviceInfo FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetDeviceInfo(this.ftHandle, ref DeviceType, ref DeviceID, sernum, desc, IntPtr.Zero); FTDI.ErrorHandler("GetDeviceID:FT_GetDeviceInfo", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Gets the description of the current device. /// /// The description of the current device. public void GetDescription(out string Description) { this.PortFunctionValidator("GetDescription: FT_GetDeviceInfo", this.ftdi.NativeMethodsInstance.FT_GetDeviceInfo); uint DeviceID = 0; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; byte[] sernum = new byte[16]; byte[] desc = new byte[64]; // Call FT_GetDeviceInfo FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetDeviceInfo(this.ftHandle, ref DeviceType, ref DeviceID, sernum, desc, IntPtr.Zero); FTDI.ErrorHandler("GetDescription:FT_GetDeviceInfo", ftStatus, FT_ERROR.FT_NO_ERROR); Description = Encoding.ASCII.GetString(desc); Description = Description.Substring(0, Description.IndexOf("\0")); } /// /// Gets the serial number of the current device. /// /// The serial number of the current device. public void GetSerialNumber(out string SerialNumber) { this.PortFunctionValidator("GetSerialNumber: FT_GetDeviceInfo", this.ftdi.NativeMethodsInstance.FT_GetDeviceInfo); uint DeviceID = 0; FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; byte[] sernum = new byte[16]; byte[] desc = new byte[64]; // Call FT_GetDeviceInfo FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetDeviceInfo(this.ftHandle, ref DeviceType, ref DeviceID, sernum, desc, IntPtr.Zero); FTDI.ErrorHandler("GetSerialNumber:FT_GetDeviceInfo", ftStatus, FT_ERROR.FT_NO_ERROR); SerialNumber = Encoding.ASCII.GetString(sernum); SerialNumber = SerialNumber.Substring(0, SerialNumber.IndexOf("\0")); } /// /// Gets the number of bytes available in the receive buffer. /// /// The number of bytes available to be read. public void GetRxBytesAvailable(ref uint RxQueue) { this.PortFunctionValidator("GetRxBytesAvailable: FT_GetQueueStatus", this.ftdi.NativeMethodsInstance.FT_GetQueueStatus); // Call FT_GetQueueStatus FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetQueueStatus(this.ftHandle, ref RxQueue); FTDI.ErrorHandler("GetRxBytesAvailable", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Gets the number of bytes waiting in the transmit buffer. /// /// The number of bytes waiting to be sent. public void GetTxBytesWaiting(ref uint TxQueue) { this.PortFunctionValidator("GetTxBytesWaiting: FT_GetStatus", this.ftdi.NativeMethodsInstance.FT_GetStatus); uint RxQueue = 0; uint EventStatus = 0; // Call FT_GetStatus FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetStatus(this.ftHandle, ref RxQueue, ref TxQueue, ref EventStatus); FTDI.ErrorHandler("GetTxBytesWaiting", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Gets the event type after an event has fired. Can be used to distinguish which event has been triggered when waiting on multiple event types. /// /// The type of event that has occurred. public void GetEventType(ref uint EventType) { this.PortFunctionValidator("GetEventType: FT_GetStatus", this.ftdi.NativeMethodsInstance.FT_GetStatus); uint RxQueue = 0; uint TxQueue = 0; FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetStatus(this.ftHandle, ref RxQueue, ref TxQueue, ref EventType); FTDI.ErrorHandler("GetEventType", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Gets the current modem status. /// /// A bit map representation of the current modem status. public void GetModemStatus(ref byte ModemStatus) { this.PortFunctionValidator("GetModemStatus: FT_GetModemStatus", this.ftdi.NativeMethodsInstance.FT_GetModemStatus); uint ModemLineStatus = 0; // Call FT_GetModemStatus FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetModemStatus(this.ftHandle, ref ModemLineStatus); FTDI.ErrorHandler("GetModemStatus", ftStatus, FT_ERROR.FT_NO_ERROR); ModemStatus = Convert.ToByte(ModemLineStatus & 0x000000FF); } /// /// Gets the current line status. /// /// A bit map representation of the current line status. public void GetLineStatus(ref byte LineStatus) { this.PortFunctionValidator("GetLineStatus: FT_GetModemStatus", this.ftdi.NativeMethodsInstance.FT_GetModemStatus); uint ModemLineStatus = 0; // Call FT_GetModemStatus FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetModemStatus(this.ftHandle, ref ModemLineStatus); FTDI.ErrorHandler("GetLineStatus", ftStatus, FT_ERROR.FT_NO_ERROR); LineStatus = Convert.ToByte((ModemLineStatus >> 8) & 0x000000FF); } /// /// Sets the current Baud rate. /// /// The desired Baud rate for the device. public void SetBaudRate(uint BaudRate) { this.PortFunctionValidator("SetBaudRate: FT_SetBaudRate", this.ftdi.NativeMethodsInstance.FT_SetBaudRate); // Call FT_SetBaudRate FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetBaudRate(this.ftHandle, BaudRate); FTDI.ErrorHandler("SetBaudRate", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Set the baud rate divisor. /// /// Notice: This is obsolete since the SetBaudRate accepts all possible baud rates. /// /// /// /// Divisor to use. [Obsolete("SetBaudRate can handle everything", true)] public void SetDivisor(ushort Divisor) { this.PortFunctionValidator("SetDivisor: FT_SetDivisor", this.ftdi.NativeMethodsInstance.FT_SetDivisor); // Call FT_SetBaudRate FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetDivisor(this.ftHandle, Divisor); FTDI.ErrorHandler("SetDivisor", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Sets the data bits, stop bits and parity for the device. /// /// The number of data bits for UART data. Valid values are FT_DATA_BITS.FT_DATA_7 or FT_DATA_BITS.FT_BITS_8 /// The number of stop bits for UART data. Valid values are FT_STOP_BITS.FT_STOP_BITS_1 or FT_STOP_BITS.FT_STOP_BITS_2 /// The parity of the UART data. Valid values are FT_PARITY.FT_PARITY_NONE, FT_PARITY.FT_PARITY_ODD, FT_PARITY.FT_PARITY_EVEN, FT_PARITY.FT_PARITY_MARK or FT_PARITY.FT_PARITY_SPACE public void SetDataCharacteristics(byte DataBits, byte StopBits, byte Parity) { this.PortFunctionValidator("SetDataCharacteristics: FT_SetDataCharacteristics", this.ftdi.NativeMethodsInstance.FT_SetDataCharacteristics); FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetDataCharacteristics(this.ftHandle, DataBits, StopBits, Parity); FTDI.ErrorHandler("SetDataCharacteristics", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Sets the flow control type. /// /// The type of flow control for the UART. Valid values are FT_FLOW_CONTROL.FT_FLOW_NONE, FT_FLOW_CONTROL.FT_FLOW_RTS_CTS, FT_FLOW_CONTROL.FT_FLOW_DTR_DSR or FT_FLOW_CONTROL.FT_FLOW_XON_XOFF /// The Xon character for Xon/Xoff flow control. Ignored if not using Xon/XOff flow control. /// The Xoff character for Xon/Xoff flow control. Ignored if not using Xon/XOff flow control. public void SetFlowControl(ushort FlowControl, byte Xon, byte Xoff) { this.PortFunctionValidator("SetFlowControl: FT_SetFlowControl", this.ftdi.NativeMethodsInstance.FT_SetFlowControl); // Call FT_SetFlowControl FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetFlowControl(this.ftHandle, FlowControl, Xon, Xoff); FTDI.ErrorHandler("SetFlowControl", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Asserts or de-asserts the Request To Send (RTS) line. /// /// If true, asserts RTS. If false, de-asserts RTS public void SetRTS(bool Enable) { this.PortFunctionValidator("SetRTS: FT_SetRts", this.ftdi.NativeMethodsInstance.FT_SetRts); this.PortFunctionValidator("SetRTS: FT_ClrRts", this.ftdi.NativeMethodsInstance.FT_ClrRts); if (Enable) { // Call FT_SetRts FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetRts(this.ftHandle); FTDI.ErrorHandler("SetRTS:FT_SetRts", ftStatus, FT_ERROR.FT_NO_ERROR); } else { // Call FT_ClrRts FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_ClrRts(this.ftHandle); FTDI.ErrorHandler("SetRTS:FT_ClrRts", ftStatus, FT_ERROR.FT_NO_ERROR); } } /// /// Asserts or de-asserts the Data Terminal Ready (DTR) line. /// /// If true, asserts DTR. If false, de-asserts DTR. public void SetDTR(bool Enable) { this.PortFunctionValidator("SetDTR: FT_SetDtr", this.ftdi.NativeMethodsInstance.FT_SetDtr); this.PortFunctionValidator("SetDTR: FT_ClrDtr", this.ftdi.NativeMethodsInstance.FT_ClrDtr); if (Enable) { // Call FT_SetDtr FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetDtr(this.ftHandle); FTDI.ErrorHandler("SetDTR:FT_SetDtr", ftStatus, FT_ERROR.FT_NO_ERROR); } else { // Call FT_ClrDtr FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_ClrDtr(this.ftHandle); FTDI.ErrorHandler("SetDTR:FT_ClrDtr", ftStatus, FT_ERROR.FT_NO_ERROR); } } /// /// Sets the read and write timeout values. /// /// Read timeout value in ms. A value of 0 indicates an infinite timeout. /// Write timeout value in ms. A value of 0 indicates an infinite timeout. public void SetTimeouts(uint ReadTimeout, uint WriteTimeout) { this.PortFunctionValidator("SetDTR: FT_SetTimeouts", this.ftdi.NativeMethodsInstance.FT_SetTimeouts); // Call FT_SetTimeouts FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetTimeouts(this.ftHandle, ReadTimeout, WriteTimeout); FTDI.ErrorHandler("SetTimeouts", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Sets or clears the break state. /// /// If true, sets break on. If false, sets break off. public void SetBreak(bool Enable) { this.PortFunctionValidator("SetBreak: FT_SetBreakOn", this.ftdi.NativeMethodsInstance.FT_SetBreakOn); this.PortFunctionValidator("SetBreak: FT_SetBreakOff", this.ftdi.NativeMethodsInstance.FT_SetBreakOff); if (Enable) { // Call FT_SetBreakOn FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetBreakOn(this.ftHandle); FTDI.ErrorHandler("SetBreak:FT_SetBreakOn", ftStatus, FT_ERROR.FT_NO_ERROR); } else { // Call FT_SetBreakOff FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetBreakOff(this.ftHandle); FTDI.ErrorHandler("SetBreak:FT_SetBreakOff", ftStatus, FT_ERROR.FT_NO_ERROR); } } /// /// Gets or sets the reset pipe retry count. Default value is 50. /// /// The reset pipe retry count. /// Electrically noisy environments may benefit from a larger value. public void SetResetPipeRetryCount(uint ResetPipeRetryCount) { this.PortFunctionValidator("SetResetPipeRetryCount: FT_SetResetPipeRetryCount", this.ftdi.NativeMethodsInstance.FT_SetResetPipeRetryCount); // Call FT_SetResetPipeRetryCount FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetResetPipeRetryCount(this.ftHandle, ResetPipeRetryCount); FTDI.ErrorHandler("SetResetPipeRetryCount", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Gets the current FTDIBUS.SYS driver version number. /// /// The current driver version number. public void GetDriverVersion(ref uint DriverVersion) { this.PortFunctionValidator("GetDriverVersion: FT_GetDriverVersion", this.ftdi.NativeMethodsInstance.FT_GetDriverVersion); // Call FT_GetDriverVersion FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetDriverVersion(this.ftHandle, ref DriverVersion); FTDI.ErrorHandler("GetDriverVersion", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Sets the USB deadman timeout value. Default is 5000ms. /// /// The deadman timeout value in ms. Default is 5000ms. public void SetDeadmanTimeout(uint DeadmanTimeout) { this.PortFunctionValidator("SetDeadmanTimeout: FT_SetDeadmanTimeout", this.ftdi.NativeMethodsInstance.FT_SetDeadmanTimeout); // Call FT_SetDeadmanTimeout FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetDeadmanTimeout(this.ftHandle, DeadmanTimeout); FTDI.ErrorHandler("SetDeadmanTimeout", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Sets the value of the latency timer. Default value is 16ms. /// /// The latency timer value in ms. /// Valid values are 2ms - 255ms for FT232BM, FT245BM and FT2232 devices. /// Valid values are 0ms - 255ms for other devices. public void SetLatency(byte Latency) { this.PortFunctionValidator("SetLatency: FT_SetLatencyTimer", this.ftdi.NativeMethodsInstance.FT_SetLatencyTimer); FT_DEVICE DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN; // Set Bit Mode does not apply to FT8U232AM, FT8U245AM or FT8U100AX devices this.GetDeviceType(ref DeviceType); if ((DeviceType == FT_DEVICE.FT_DEVICE_BM) || (DeviceType == FT_DEVICE.FT_DEVICE_2232)) { // Do not allow latency of 1ms or 0ms for older devices // since this can cause problems/lock up due to buffering mechanism if (Latency < 2) Latency = 2; } // Call FT_SetLatencyTimer FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetLatencyTimer(this.ftHandle, Latency); FTDI.ErrorHandler("SetLatency", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Gets the value of the latency timer. Default value is 16ms. /// /// The latency timer value in ms. public void GetLatency(ref byte Latency) { this.PortFunctionValidator("GetLatency: FT_GetLatencyTimer", this.ftdi.NativeMethodsInstance.FT_GetLatencyTimer); // Call FT_GetLatencyTimer FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetLatencyTimer(this.ftHandle, ref Latency); FTDI.ErrorHandler("GetLatency", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Sets the USB IN and OUT transfer sizes. /// /// The USB IN transfer size in bytes. public void InTransferSize(uint InTransferSize) //// Only support IN transfer sizes at the moment //// public uint InTransferSize(uint InTransferSize, uint OutTransferSize) { this.PortFunctionValidator("InTransferSize: FT_SetUSBParameters", this.ftdi.NativeMethodsInstance.FT_SetUSBParameters); uint OutTransferSize = InTransferSize; // Call FT_SetUSBParameters FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetUSBParameters(this.ftHandle, InTransferSize, OutTransferSize); FTDI.ErrorHandler("InTransferSize", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Sets an event character, an error character and enables or disables them. /// /// A character that will be trigger an IN to the host when this character is received. /// Determines if the EventChar is enabled or disabled. /// A character that will be inserted into the data stream to indicate that an error has occurred. /// Determines if the ErrorChar is enabled or disabled. public void SetCharacters(byte EventChar, bool EventCharEnable, byte ErrorChar, bool ErrorCharEnable) { this.PortFunctionValidator("SetCharacters: FT_SetChars", this.ftdi.NativeMethodsInstance.FT_SetChars); // Call FT_SetChars FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_SetChars(this.ftHandle, EventChar, Convert.ToByte(EventCharEnable), ErrorChar, Convert.ToByte(ErrorCharEnable)); FTDI.ErrorHandler("SetCharacters", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Gets the size of the EEPROM user area. /// /// The EEPROM user area size in bytes. public void EEUserAreaSize(ref uint UASize) { this.PortFunctionValidator("EEUserAreaSize: FT_EE_UASize", this.ftdi.NativeMethodsInstance.FT_EE_UASize); FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_EE_UASize(this.ftHandle, ref UASize); FTDI.ErrorHandler("EEUserAreaSize", ftStatus, FT_ERROR.FT_NO_ERROR); } /// /// Gets the corresponding COM port number for the current device. If no COM port is exposed, an empty string is returned. /// /// The COM port name corresponding to the current device. If no COM port is installed, an empty string is passed back. public void GetCOMPort(out string ComPortName) { this.PortFunctionValidator("GetCOMPort: FT_GetComPortNumber", this.ftdi.NativeMethodsInstance.FT_GetComPortNumber); // As ComPortName is an OUT paremeter, has to be assigned before returning ComPortName = string.Empty; // Call FT_GetComPortNumber Int32 ComPortNumber = -1; FT_STATUS ftStatus = this.ftdi.NativeMethodsInstance.FT_GetComPortNumber(this.ftHandle, ref ComPortNumber); FTDI.ErrorHandler("GetCOMPort", ftStatus, FT_ERROR.FT_NO_ERROR); if (ComPortNumber >= 0) { // If installed, return full COM string // This can then be passed to an instance of the SerialPort class to assign the port number. ComPortName = "COM" + ComPortNumber.ToString(); } } #endregion #region HELPER_METHODS /// /// Check the prerequisites for executing a method when connected. /// /// Name of function being checked. /// Delegate function reference. /// Thrown when the prerequisites failed validation. private void PortFunctionValidator(string functionName, object functionDelegate) { if (this.ftHandle == IntPtr.Zero) { FTDI.ErrorHandler(functionName, FT_STATUS.FT_OTHER_ERROR, FT_ERROR.FT_CHANNEL_NOT_OPEN); } FTDI.FunctionValidator(functionName, functionDelegate); } #endregion } }