Класс-обёртка для работы с библиотекой FTD2XX на Visual Basic .NET
Предлагается класс-обёртка для работы с библиотекой ftd2xx.dll, которая позволяет управлять различными микросхемами фирмы FTDI.
За основу данного кода взят проект класса-обёртки на языке C# с официального сайта FTDI. По сравнению с данным примером, классу был придан более объектно-ориентированный стиль. Кроме того, класс был разделён на два класса. В первом классе Ftdi находится базовая функциональность, которая чаще всего нужна для работы с микросхемами FTDI. Во втором содержится код, необходимый для работы с ЭСППЗУ микросхем FTDI.
Замечу, что пришлось все члены типа IntPtr переделать на тип Integer. Это связано с тем, что в Visual Studio 2019 при работе с IntPtr возникает ошибка BC30657. Микрософт до сих пор не исправила её (Visual Studio 2019 версия 16.6.3), хотя они в курсе проблемы.

При этом при вызове нативных функций, которые требуют тип IntPtr, получить его можно двумя способами: либо создавая новый объект, инициализируя его значением целого числа integerValue:
New IntPtr(integerValue)
Либо через приведение типов:
CType(integerValue, IntPtr)
Также можно обратить внимание на вызов делегатов, которые повсеместно встречаются в коде при обращении к нативным функциям в библиотеке. При получении делегата по указателю, его можно вызвать тоже двумя способами. Например, в методе открытия устройства OpenByIndex() встречается такое:
Dim tFT_Open As OpenDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(pFT_Open), GetType(OpenDelegate)), OpenDelegate) 'получение делегата по указателю status = tFT_Open.Invoke(index, ftHandle) 'использование делегата
Это эквивалентно более краткой записи, когда можно опустить указание метода Invoke() и сразу записать аргументы, передаваемые делегату (или пустые скобки, если аргументы не передаются):
status = tFT_Open(index, ftHandle)
Нативные (родные) функции, методы – в данном контексте имеются в виду функции Windows, для выполнения которых необходимо обратиться к Windows API. Это функции, которые выполняются не средой .NET Framework, а непосредственно операционной системой. В противоположность нативному коду, существует т.н. «управляемый» код. Он выполняется под управлением фреймворка .NET, а точнее CLR – общеязыковой исполняющей среды. Нативный код также называют «неуправляемый».
В данном классе используются лишь три нативных метода, которые объявляются с атрибутом DllImport в классе Ftdi. Все они берутся из динамически загружаемой библиотеки Windows kernel32.dll.
Базовые функции для работы с микросхемами FTDI
Imports System.Runtime.InteropServices
Imports System.Runtime.Serialization
Imports System.Threading
Imports System.Text
Namespace FTD2XX_NET
''' <summary>
''' Класс для работы с устройствами FTDI.
''' </summary>
Public Class Ftdi
Implements IDisposable
#Region "CTORs"
''' <summary>
''' Конструктор по умолчанию, который не открывает устройство.
''' </summary>
Public Sub New()
'ничего не делает
End Sub
''' <summary>
''' Конструктор, который открывает заданное устройство по индексу.
''' </summary>
''' <param name="index">Индекс устройства.</param>
Public Sub New(index As Integer)
Me.New()
OpenByIndex(index)
End Sub
''' <summary>
''' Конструктор, который открывает заданное устройство по серийному номеру.
''' </summary>
''' <param name="serial">Серийный номер. Должен точно соответствовать даже регистром.</param>
Public Sub New(serial As String)
Me.New()
OpenBySerialNumber(serial)
End Sub
''' <summary>
''' Освобождает библиотеку ftd2xx.
''' </summary>
Public Shared Sub UnloadLibrary()
If FreeLibrary(Ftd2xxDllHandle) Then
_Ftd2xxDllHandle = CLOSED_HANDLE
Debug.WriteLine("Library unloaded.")
End If
End Sub
#End Region '/CTORs
#Region "КОНСТАНТЫ"
Public Const FT_DEFAULT_BAUD_RATE As UInteger = 9600UI
Public Const FT_COM_PORT_NOT_ASSIGNED As Integer = -1
Public Const FT_DEFAULT_DEADMAN_TIMEOUT As UInteger = 5000UI
Public Const FT_DEFAULT_LATENCY As Byte = 16
Public Const FT_DEFAULT_IN_TRANSFER_SIZE As UInteger = 4096UI
Public Const FT_DEFAULT_OUT_TRANSFER_SIZE As UInteger = 4096UI
Private Const CLOSED_HANDLE As Integer = 0
Private Const NOT_INIT As Integer = -1
#End Region '/КОНСТАНТЫ
#Region "READ-ONLY PROPS"
''' <summary>
''' Путь к библиотеке ftd2xx.
''' </summary>
Public Shared ReadOnly Property LibPath As String
Get
Return _LibPath
End Get
End Property
Private Shared _LibPath As String = "ftd2xx.dll"
''' <summary>
''' Объект для работы с ПЗУ.
''' </summary>
Public ReadOnly Property Eeprom As FTD2XX_NET.Eeprom
Get
If (_Eeprom Is Nothing) Then
_Eeprom = New Eeprom(Ftd2xxDllHandle, FtHandle, DeviceType)
End If
Return _Eeprom
End Get
End Property
Private _Eeprom As FTD2XX_NET.Eeprom
''' <summary>
''' Загружена ли библиотека.
''' </summary>
Public Shared ReadOnly Property IsLibraryLoaded As Boolean
Get
Return (Ftd2xxDllHandle <> CLOSED_HANDLE)
End Get
End Property
''' <summary>
''' Открыто ли устройство.
''' </summary>
Public ReadOnly Property IsDeviceOpen As Boolean
Get
Return (FtHandle <> CLOSED_HANDLE)
End Get
End Property
''' <summary>
''' Признак канала (A, B и т.д.).
''' </summary>
Private ReadOnly Property InterfaceIdentifier As String
Get
If (_InterfaceIdentifier.Length = 0) AndAlso IsLibraryLoaded AndAlso IsDeviceOpen Then
Dim devType As FT_DEVICE = DeviceType
If (devType = FT_DEVICE.FT_DEVICE_2232) OrElse (devType = FT_DEVICE.FT_DEVICE_2232H) OrElse (devType = FT_DEVICE.FT_DEVICE_4232H) Then
_InterfaceIdentifier = Description().Substring(Description.Length - 1)
End If
End If
Return _InterfaceIdentifier
End Get
End Property
Private _InterfaceIdentifier As String = ""
''' <summary>
''' Тип текущего чипа FTDI.
''' </summary>
Public ReadOnly Property DeviceType As FT_DEVICE
Get
If (_DeviceType = FT_DEVICE.FT_DEVICE_UNKNOWN) AndAlso IsLibraryLoaded AndAlso IsDeviceOpen Then
Dim devType As FT_DEVICE = FT_DEVICE.FT_DEVICE_UNKNOWN
Dim num As UInteger = 0
Dim sn As Byte() = New Byte(15) {}
Dim descr As Byte() = New Byte(63) {}
Dim dlg As GetDeviceInfoDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_GetDeviceInfo, IntPtr), GetType(GetDeviceInfoDelegate)), GetDeviceInfoDelegate)
Dim status As FT_STATUS = dlg(FtHandle, devType, num, sn, descr, 0)
_DeviceType = devType
End If
Return _DeviceType
End Get
End Property
Private _DeviceType As FT_DEVICE = FT_DEVICE.FT_DEVICE_UNKNOWN
''' <summary>
''' Vendor ID и Product ID текущего устройства.
''' </summary>
Public ReadOnly Property DeviceID As UInteger
Get
If (_DeviceID = 0) AndAlso IsLibraryLoaded AndAlso IsDeviceOpen Then
Dim devid As UInteger
Dim dev As FT_DEVICE = FT_DEVICE.FT_DEVICE_UNKNOWN
Dim sn As Byte() = New Byte(15) {}
Dim descr As Byte() = New Byte(63) {}
Dim dlg As GetDeviceInfoDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_GetDeviceInfo, IntPtr), GetType(GetDeviceInfoDelegate)), GetDeviceInfoDelegate)
Dim status As FT_STATUS = dlg(FtHandle, dev, devid, sn, descr, 0)
_DeviceID = devid
End If
Return _DeviceID
End Get
End Property
Private _DeviceID As UInteger = 0
''' <summary>
''' Описание текущего устройства.
''' </summary>
Public ReadOnly Property Description As String
Get
If (_Description.Length = 0) AndAlso IsLibraryLoaded AndAlso IsDeviceOpen Then
Dim sn As Byte() = New Byte(15) {}
Dim descr As Byte() = New Byte(63) {}
Dim num As UInteger = 0UI
Dim dev As FT_DEVICE = FT_DEVICE.FT_DEVICE_UNKNOWN
Dim dlg As GetDeviceInfoDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_GetDeviceInfo, IntPtr), GetType(GetDeviceInfoDelegate)), GetDeviceInfoDelegate)
Dim status As FT_STATUS = dlg(FtHandle, dev, num, sn, descr, 0)
Dim d As String = Encoding.ASCII.GetString(descr)
_Description = d.Substring(0, d.IndexOf(vbNullChar))
End If
Return _Description
End Get
End Property
Private _Description As String = String.Empty
''' <summary>
''' Серийный номер устройства.
''' </summary>
Public ReadOnly Property SerialNumber As String
Get
If (_SerialNumber.Length = 0) AndAlso IsLibraryLoaded AndAlso IsDeviceOpen Then
Dim sn As Byte() = New Byte(15) {}
Dim descr As Byte() = New Byte(63) {}
Dim num As UInteger = 0UI
Dim dev As FT_DEVICE = FT_DEVICE.FT_DEVICE_UNKNOWN
Dim dlg As GetDeviceInfoDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_GetDeviceInfo, IntPtr), GetType(GetDeviceInfoDelegate)), GetDeviceInfoDelegate)
Dim status As FT_STATUS = dlg(FtHandle, dev, num, sn, descr, 0)
Dim serNum As String = Encoding.ASCII.GetString(sn)
_SerialNumber = serNum.Substring(0, serNum.IndexOf(vbNullChar))
End If
Return _SerialNumber
End Get
End Property
Private _SerialNumber As String = String.Empty
''' <summary>
''' Текущая версия драйвера FTDIBUS.SYS.
''' </summary>
Public ReadOnly Property DriverVersion As UInteger
Get
If (_DriverVersion = 0) AndAlso (Pft_GetDriverVersion <> NOT_INIT) Then
Dim dlg As GetDriverVersionDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_GetDriverVersion), GetType(GetDriverVersionDelegate)), GetDriverVersionDelegate)
Dim status As FT_STATUS = dlg(FtHandle, _DriverVersion)
End If
Return _DriverVersion
End Get
End Property
Private _DriverVersion As UInteger = 0
''' <summary>
''' Текущая версия драйвера FTD2XX.DLL.
''' </summary>
Public Shared ReadOnly Property LibraryVersion As UInteger
Get
If (_LibraryVersion = 0) Then
Dim pft_GetLibraryVersion As Integer = GetProcAddress(Ftd2xxDllHandle, "FT_GetLibraryVersion")
Dim dlg As GetLibraryVersionDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(pft_GetLibraryVersion), GetType(GetLibraryVersionDelegate)), GetLibraryVersionDelegate)
Dim status As FT_STATUS = dlg.Invoke(_LibraryVersion)
End If
Return _LibraryVersion
End Get
End Property
Private Shared _LibraryVersion As UInteger = 0
#End Region '/READ-ONLY PROPS
#Region "ОТКРЫТИЕ, ЗАКРЫТИЕ"
'Дескриптор устройства:
Private FtHandle As Integer = CLOSED_HANDLE
''' <summary>
''' Открывает устройство FTDI по индексу <paramref name="index"/>.
''' </summary>
''' <remarks>
''' Это не гарантирует открытие заданного устройства.
''' </remarks>
Public Sub OpenByIndex(index As Integer)
Dim dlg As OpenDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_Open), GetType(OpenDelegate)), OpenDelegate)
Dim status As FT_STATUS = dlg(CUInt(index), FtHandle)
If (status = FT_STATUS.FT_OK) Then
Dim uWordLength As Byte = 8
Dim uStopBits As Byte = 0
Dim uParity As Byte = 0
Dim dDlg As SetDataCharacteristicsDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_SetDataCharacteristics), GetType(SetDataCharacteristicsDelegate)), SetDataCharacteristicsDelegate)
status = dDlg(FtHandle, uWordLength, uStopBits, uParity)
CheckErrors(status)
Dim usFlowControl As UShort = 0US
Dim uXon As Byte = 17
Dim uXoff As Byte = 19
Dim fDlg As SetFlowControlDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_SetFlowControl), GetType(SetFlowControlDelegate)), SetFlowControlDelegate)
status = fDlg(FtHandle, usFlowControl, uXon, uXoff)
CheckErrors(status)
Dim dwBaudRate As UInteger = FT_DEFAULT_BAUD_RATE
Dim bDlg As SetBaudRateDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_SetBaudRate), GetType(SetBaudRateDelegate)), SetBaudRateDelegate)
status = bDlg(FtHandle, dwBaudRate)
Else
FtHandle = CLOSED_HANDLE
End If
CheckErrors(status)
End Sub
''' <summary>
''' Открывает устройство FTDI по серийному номеру <paramref name="serialnumber"/>.
''' </summary>
Public Sub OpenBySerialNumber(serialnumber As String)
Dim dlg As OpenExDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_OpenEx, IntPtr), GetType(OpenExDelegate)), OpenExDelegate)
Dim status As FT_STATUS = dlg(serialnumber, FT_OPEN_BY.SERIAL_NUMBER, FtHandle)
If (status = FT_STATUS.FT_OK) Then
Dim uWordLength As Byte = 8
Dim uStopBits As Byte = 0
Dim uParity As Byte = 0
Dim dDlg As SetDataCharacteristicsDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetDataCharacteristics, IntPtr), GetType(SetDataCharacteristicsDelegate)), SetDataCharacteristicsDelegate)
status = dDlg(FtHandle, uWordLength, uStopBits, uParity)
CheckErrors(status)
Dim usFlowControl As UShort = 0US
Dim uXon As Byte = 17
Dim uXoff As Byte = 19
Dim fDlg As SetFlowControlDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetFlowControl, IntPtr), GetType(SetFlowControlDelegate)), SetFlowControlDelegate)
status = fDlg(FtHandle, usFlowControl, uXon, uXoff)
CheckErrors(status)
Dim dwBaudRate As UInteger = FT_DEFAULT_BAUD_RATE
Dim bDlg As SetBaudRateDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetBaudRate, IntPtr), GetType(SetBaudRateDelegate)), SetBaudRateDelegate)
status = bDlg(FtHandle, dwBaudRate)
Else
FtHandle = CLOSED_HANDLE
End If
CheckErrors(status)
End Sub
''' <summary>
''' Открывает устройство FTDI по описанию <paramref name="description"/>.
''' </summary>
Public Sub OpenByDescription(description As String)
Dim dlg As OpenExDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_OpenEx, IntPtr), GetType(OpenExDelegate)), OpenExDelegate)
Dim status As FT_STATUS = dlg(description, FT_OPEN_BY.DESCRIPTION, FtHandle)
If (status = FT_STATUS.FT_OK) Then
Dim uWordLength As Byte = 8
Dim uStopBits As Byte = 0
Dim uParity As Byte = 0
Dim dDlg As SetDataCharacteristicsDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetDataCharacteristics, IntPtr), GetType(SetDataCharacteristicsDelegate)), SetDataCharacteristicsDelegate)
status = dDlg(FtHandle, uWordLength, uStopBits, uParity)
CheckErrors(status)
Dim usFlowControl As UShort = 0US
Dim uXon As Byte = 17
Dim uXoff As Byte = 19
Dim fDlg As SetFlowControlDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetFlowControl, IntPtr), GetType(SetFlowControlDelegate)), SetFlowControlDelegate)
status = fDlg(FtHandle, usFlowControl, uXon, uXoff)
CheckErrors(status)
Dim dwBaudRate As UInteger = FT_DEFAULT_BAUD_RATE
Dim bDlg As SetBaudRateDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetBaudRate, IntPtr), GetType(SetBaudRateDelegate)), SetBaudRateDelegate)
status = bDlg(FtHandle, dwBaudRate)
Else
FtHandle = CLOSED_HANDLE
End If
CheckErrors(status)
End Sub
''' <summary>
''' Открывает устройство FTDI по физическому расположению <paramref name="location"/>.
''' </summary>
Public Sub OpenByLocation(location As UInteger)
Dim dlg As OpenExLocDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_OpenEx, IntPtr), GetType(OpenExLocDelegate)), OpenExLocDelegate)
Dim status As FT_STATUS = dlg(location, FT_OPEN_BY.LOCATION, FtHandle)
If (status = FT_STATUS.FT_OK) Then
Dim uWordLength As Byte = 8
Dim uStopBits As Byte = 0
Dim uParity As Byte = 0
Dim dDlg As SetDataCharacteristicsDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetDataCharacteristics, IntPtr), GetType(SetDataCharacteristicsDelegate)), SetDataCharacteristicsDelegate)
status = dDlg(FtHandle, uWordLength, uStopBits, uParity)
CheckErrors(status)
Dim usFlowControl As UShort = 0US
Dim uXon As Byte = 17
Dim uXoff As Byte = 19
Dim fDlg As SetFlowControlDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetFlowControl, IntPtr), GetType(SetFlowControlDelegate)), SetFlowControlDelegate)
status = fDlg(FtHandle, usFlowControl, uXon, uXoff)
CheckErrors(status)
Dim dwBaudRate As UInteger = FT_DEFAULT_BAUD_RATE
Dim bDlg As SetBaudRateDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetBaudRate, IntPtr), GetType(SetBaudRateDelegate)), SetBaudRateDelegate)
status = bDlg(FtHandle, dwBaudRate)
Else
FtHandle = CLOSED_HANDLE
End If
CheckErrors(status)
End Sub
''' <summary>
''' Закрывает открытое устройство.
''' </summary>
Public Sub Close()
If (FtHandle <> CLOSED_HANDLE) AndAlso (Pft_Close <> NOT_INIT) Then
Dim dlg As CloseDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_Close), GetType(CloseDelegate)), CloseDelegate)
Dim status As FT_STATUS = dlg.Invoke(FtHandle)
CheckErrors(status)
If (status = FT_STATUS.FT_OK) Then
FtHandle = CLOSED_HANDLE
End If
End If
End Sub
#End Region '/ОТКРЫТИЕ, ЗАКРЫТИЕ
#Region "ИНФО"
''' <summary>
''' Возвращает число доступных устройств FTDI.
''' </summary>
Public Shared Function GetNumberOfDevices() As Integer
Dim devCount As UInteger = 0
Dim dlg As CreateDeviceInfoListDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_CreateDeviceInfoList), GetType(CreateDeviceInfoListDelegate)), CreateDeviceInfoListDelegate)
Dim status As FT_STATUS = dlg.Invoke(devCount)
CheckErrors(status)
Return CInt(devCount)
End Function
''' <summary>
''' Возвращает информацию обо всех доступных устройствах FTDI.
''' </summary>
Public Shared Function GetDeviceList() As FT_DEVICE_INFO_NODE()
Dim numDevices As UInteger = 0UI
Dim dlg As CreateDeviceInfoListDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_CreateDeviceInfoList), GetType(CreateDeviceInfoListDelegate)), CreateDeviceInfoListDelegate)
Dim status As FT_STATUS = dlg(numDevices)
CheckErrors(status)
If (numDevices > 0) Then
Dim devicelist(CInt(numDevices - 1)) As FT_DEVICE_INFO_NODE
Dim gdiDeleg As GetDeviceInfoDetailDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_GetDeviceInfoDetail), GetType(GetDeviceInfoDetailDelegate)), GetDeviceInfoDetailDelegate)
For i As Integer = 0 To CInt(numDevices - 1)
devicelist(i) = New FT_DEVICE_INFO_NODE()
Dim sn As Byte() = New Byte(15) {}
Dim descr As Byte() = New Byte(63) {}
status = gdiDeleg(CUInt(i), devicelist(i).Flags, devicelist(i).Type, devicelist(i).ID, devicelist(i).LocId, sn, descr, devicelist(i).FtHandle)
CheckErrors(status)
devicelist(i).SerialNumber = Encoding.ASCII.GetString(sn)
devicelist(i).Description = Encoding.ASCII.GetString(descr)
Dim endOfStringIndex As Integer = devicelist(i).SerialNumber.IndexOf(vbNullChar)
If (endOfStringIndex <> -1) Then
devicelist(i).SerialNumber = devicelist(i).SerialNumber.Substring(0, endOfStringIndex)
End If
endOfStringIndex = devicelist(i).Description.IndexOf(vbNullChar)
If (endOfStringIndex <> -1) Then
devicelist(i).Description = devicelist(i).Description.Substring(0, endOfStringIndex)
End If
Next
Return devicelist
End If
Return New FT_DEVICE_INFO_NODE() {}
End Function
''' <summary>
''' Возвращает число доступных байтов в приёмном буфере.
''' </summary>
Public Function GetRxBytesAvailable() As Integer
Dim rxQueue As UInteger
Dim dlg As GetQueueStatusDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_GetQueueStatus, IntPtr), GetType(GetQueueStatusDelegate)), GetQueueStatusDelegate)
Dim status As FT_STATUS = dlg(FtHandle, rxQueue)
CheckErrors(status)
Return CInt(rxQueue)
End Function
''' <summary>
''' Возвращает ожидающее число байтов в передающем буфере.
''' </summary>
Public Function GetTxBytesWaiting() As Integer
Dim txQueue As UInteger
Dim inTxLen As UInteger = 0UI
Dim eventType As UInteger = 0UI
Dim dlg As GetStatusDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_GetStatus, IntPtr), GetType(GetStatusDelegate)), GetStatusDelegate)
Dim status As FT_STATUS = dlg(FtHandle, inTxLen, txQueue, eventType)
CheckErrors(status)
Return CInt(txQueue)
End Function
''' <summary>
''' Возвращает тип события после его возникновения.
''' </summary>
''' <remarks>
''' Можно использовать чтобы определить, какое событие сработало, когда ожидаются осбытия разных типов.
''' </remarks>
Public Function GetEventType() As FT_EVENTS
Dim eventType As UInteger
Dim inTxLen As UInteger = 0UI
Dim txQueue As UInteger = 0UI
Dim dlg As GetStatusDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_GetStatus, IntPtr), GetType(GetStatusDelegate)), GetStatusDelegate)
Dim status As FT_STATUS = dlg(FtHandle, inTxLen, txQueue, eventType)
CheckErrors(status)
Return CType(eventType, FT_EVENTS)
End Function
''' <summary>
''' Возвращает текущее состояние модема (битовую маску).
''' </summary>
Public Function GetModemStatus() As FT_MODEM_STATUS
Dim s As UInteger = 0UI
Dim dlg As GetModemStatusDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_GetModemStatus, IntPtr), GetType(GetModemStatusDelegate)), GetModemStatusDelegate)
Dim status As FT_STATUS = dlg.Invoke(FtHandle, s)
CheckErrors(status)
Dim modemStatus As FT_MODEM_STATUS = CType(s And &HFF, FT_MODEM_STATUS)
Return modemStatus
End Function
''' <summary>
''' Возвращает текущее состояние линии (битовую маску).
''' </summary>
Public Function GetLineStatus() As FT_LINE_STATUS
Dim s As UInteger = 0UI
Dim dlg As GetModemStatusDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_GetModemStatus, IntPtr), GetType(GetModemStatusDelegate)), GetModemStatusDelegate)
Dim status As FT_STATUS = dlg.Invoke(FtHandle, s)
CheckErrors(status)
Dim lineStatus As FT_LINE_STATUS = CType((s >> 8) And &HFF, FT_LINE_STATUS)
Return lineStatus
End Function
''' <summary>
''' Возвращает назначенный порт или пустую строку, если порт не был назначен.
''' </summary>
Public Function GetComPort() As String
Dim portNum As Integer = FT_COM_PORT_NOT_ASSIGNED
Dim dlg As GetComPortNumberDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_GetComPortNumber, IntPtr), GetType(GetComPortNumberDelegate)), GetComPortNumberDelegate)
Dim status As FT_STATUS = dlg(FtHandle, portNum)
CheckErrors(status)
If (portNum <> FT_COM_PORT_NOT_ASSIGNED) Then
Return $"COM{portNum}"
End If
Return String.Empty
End Function
''' <summary>
''' Возвращает состояние выводов входа/выхода (битовую маску).
''' </summary>
Public Function GetPinStates() As Byte
Dim bitMode As Byte
Dim dlg As GetBitModeDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_GetBitMode, IntPtr), GetType(GetBitModeDelegate)), GetBitModeDelegate)
Dim status As FT_STATUS = dlg(FtHandle, bitMode)
CheckErrors(status)
Return bitMode
End Function
#End Region '/ИНФО
#Region "ПАРАМЕТРЫ"
''' <summary>
''' Задаёт битрейт.
''' </summary>
''' <param name="baudRate">Желаемый битрейт устройства, бит/сек.</param>
Public Sub SetBaudRate(Optional baudRate As Integer = FT_DEFAULT_BAUD_RATE)
Dim dlg As SetBaudRateDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetBaudRate, IntPtr), GetType(SetBaudRateDelegate)), SetBaudRateDelegate)
Dim status As FT_STATUS = dlg(FtHandle, CUInt(baudRate))
CheckErrors(status)
End Sub
''' <summary>
''' Устанавливает число битов данных, стоповых и тип проверки чётности.
''' </summary>
''' <param name="dataBits">Число битов данных.</param>
''' <param name="stopBits">Число стоповых бит.</param>
''' <param name="parity">Тип проверки чётности.</param>
Public Sub SetDataCharacteristics(dataBits As FT_DATA_BITS, stopBits As FT_STOP_BITS, parity As FT_PARITY)
Dim dlg As SetDataCharacteristicsDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetDataCharacteristics, IntPtr), GetType(SetDataCharacteristicsDelegate)), SetDataCharacteristicsDelegate)
Dim status As FT_STATUS = dlg(FtHandle, dataBits, stopBits, parity)
CheckErrors(status)
End Sub
''' <summary>
''' Устанавливает тип управления потоком данных.
''' </summary>
''' <param name="flowControl">Тип управления потоком.</param>
''' <param name="xOn">Символ Xon для Xon/Xoff. Игнорируется, если Xon/XOff не используется.</param>
''' <param name="xOff">Символ Xoff для Xon/Xoff. Игнорируется, если Xon/XOff не используется.</param>
Public Sub SetFlowControl(flowControl As FT_FLOW_CONTROL, Optional xOn As Byte = 0, Optional xOff As Byte = 0)
Dim dlg As SetFlowControlDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetFlowControl, IntPtr), GetType(SetFlowControlDelegate)), SetFlowControlDelegate)
Dim status As FT_STATUS = dlg(FtHandle, flowControl, xOn, xOff)
CheckErrors(status)
End Sub
''' <summary>
''' Выставляет или сбрасывает линию Request To Send (RTS).
''' </summary>
''' <param name="enable">True выставляет, False сбрасывает RTS.</param>
Public Sub SetRts(enable As Boolean)
Dim status As FT_STATUS = FT_STATUS.FT_OTHER_ERROR
If enable Then
Dim dlg As SetRtsDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetRts, IntPtr), GetType(SetRtsDelegate)), SetRtsDelegate)
status = dlg.Invoke(FtHandle)
Else
Dim dlg As ClrRtsDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_ClrRts, IntPtr), GetType(ClrRtsDelegate)), ClrRtsDelegate)
status = dlg.Invoke(FtHandle)
End If
CheckErrors(status)
End Sub
''' <summary>
''' Выставляет или сбрасывает линию Data Terminal Ready (DTR).
''' </summary>
''' <param name="enable">True выставляет, False сбрасывает DTR.</param>
Public Sub SetDtr(enable As Boolean)
Dim status As FT_STATUS = FT_STATUS.FT_OTHER_ERROR
If enable Then
Dim dlg As SetDtrDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetDtr, IntPtr), GetType(SetDtrDelegate)), SetDtrDelegate)
status = dlg.Invoke(FtHandle)
Else
Dim dlg As ClrDtrDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_ClrDtr, IntPtr), GetType(ClrDtrDelegate)), ClrDtrDelegate)
status = dlg.Invoke(FtHandle)
End If
CheckErrors(status)
End Sub
''' <summary>
''' Устанавливает время ожидания чтения и записи.
''' </summary>
''' <param name="readTimeout">Время ожидания при чтении, мс. Значение "0" означает бесконечное ожидание.</param>
''' <param name="writeTimeout">Время ожидания при записи, мс. Значение "0" означает бесконечное ожидание.</param>
Public Sub SetTimeouts(readTimeout As UInteger, writeTimeout As UInteger)
Dim dlg As SetTimeoutsDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(Pft_SetTimeouts, IntPtr), GetType(SetTimeoutsDelegate)), SetTimeoutsDelegate)
Dim status As FT_STATUS = dlg(FtHandle, readTimeout, writeTimeout)
CheckErrors(status)
End Sub
''' <summary>
''' Устанавливает или сбрасывает состояние прерывания.
''' </summary>
''' <param name="enable">True включает, False выключает.</param>
Public Sub SetBreak(enable As Boolean)
Dim status As FT_STATUS = FT_STATUS.FT_OTHER_ERROR
If enable Then
Dim dlg As SetBreakOnDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_SetBreakOn), GetType(SetBreakOnDelegate)), SetBreakOnDelegate)
status = dlg(FtHandle)
Else
Dim dlg As SetBreakOffDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_SetBreakOff), GetType(SetBreakOffDelegate)), SetBreakOffDelegate)
status = dlg(FtHandle)
End If
CheckErrors(status)
End Sub
''' <summary>
''' Задаёт число повторов (reset pipe retry count). По умолчанию 50.
''' </summary>
''' <param name="resetPipeRetryCount">Число повторов. В электрически шумных средах бОльшие значения лучше.</param>
Public Sub SetResetPipeRetryCount(resetPipeRetryCount As Integer)
Dim dlg As SetResetPipeRetryCountDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_SetResetPipeRetryCount), GetType(SetResetPipeRetryCountDelegate)), SetResetPipeRetryCountDelegate)
Dim status As FT_STATUS = dlg(FtHandle, CUInt(resetPipeRetryCount))
CheckErrors(status)
End Sub
''' <summary>
''' Задаёт время простоя шины USB.
''' </summary>
''' <param name="deadmanTimeout">Время простоя, мс.</param>
Public Sub SetDeadmanTimeout(Optional deadmanTimeout As UInteger = FT_DEFAULT_DEADMAN_TIMEOUT)
Dim dlg As SetDeadmanTimeoutDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_SetDeadmanTimeout), GetType(SetDeadmanTimeoutDelegate)), SetDeadmanTimeoutDelegate)
Dim status As FT_STATUS = dlg(FtHandle, deadmanTimeout)
CheckErrors(status)
End Sub
''' <summary>
''' Задаёт задержку в шине USB.
''' </summary>
''' <param name="latency">Задержка, мс.
''' Значения 2...255 мс для FT232BM, FT245BM и FT2232.
''' Значения 0...255 мс для прочих устройств.</param>
Public Sub SetLatency(Optional latency As Byte = FT_DEFAULT_LATENCY)
If (latency < 2) Then
If ((DeviceType = FT_DEVICE.FT_DEVICE_BM) OrElse (DeviceType = FT_DEVICE.FT_DEVICE_2232)) Then
latency = 2
End If
End If
Dim dlg As SetLatencyTimerDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_SetLatencyTimer), GetType(SetLatencyTimerDelegate)), SetLatencyTimerDelegate)
Dim status As FT_STATUS = dlg(FtHandle, latency)
CheckErrors(status)
End Sub
''' <summary>
''' Получает значение задержки, мс.
''' </summary>
Public Function GetLatency() As Byte
Dim latency As Byte
Dim dlg As GetLatencyTimerDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_GetLatencyTimer), GetType(GetLatencyTimerDelegate)), GetLatencyTimerDelegate)
Dim status As FT_STATUS = dlg(FtHandle, latency)
CheckErrors(status)
Return latency
End Function
''' <summary>
''' Задаёт размеры передающего и принимающего буферов USB.
''' </summary>
''' <param name="inSize">Резмер в байтах входящего буфера USB. Кратно 64. Значение по умолчанию 4 кб.</param>
''' <param name="outSize">Резмер в байтах исходящего буфера USB. Кратно 64. Значение по умолчанию 4 кб.</param>
Public Sub SetTransferSize(Optional inSize As Integer = FT_DEFAULT_IN_TRANSFER_SIZE, Optional outSize As Integer = FT_DEFAULT_OUT_TRANSFER_SIZE)
Dim dlg As SetUsbParametersDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_SetUSBParameters), GetType(SetUsbParametersDelegate)), SetUsbParametersDelegate)
Dim status As FT_STATUS = dlg.Invoke(FtHandle, CUInt(inSize), CUInt(outSize))
CheckErrors(status)
End Sub
''' <summary>
''' Задаёт символы для событий "получение данных" и "возникновение ошибки".
''' </summary>
''' <param name="eventChar">Символ, который будет вызывать передачу в данных хост при его получении.</param>
''' <param name="eventCharEnable">Включает (True) или выключает (False) символ <paramref name="eventChar"/>.</param>
''' <param name="errorChar">Символ, который будет вставлен в поток данных, чтобы показать возникновение ошибки.</param>
''' <param name="errorCharEnable">Включает (True) или выключает (False) символ <paramref name="errorChar"/>.</param>
Public Sub SetCharacters(eventChar As Byte, eventCharEnable As Boolean, errorChar As Byte, errorCharEnable As Boolean)
Dim dlg As SetCharsDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_SetChars), GetType(SetCharsDelegate)), SetCharsDelegate)
Dim status As FT_STATUS = dlg(FtHandle, eventChar, Convert.ToByte(eventCharEnable), errorChar, Convert.ToByte(errorCharEnable))
CheckErrors(status)
End Sub
#End Region '/ПАРАМЕТРЫ
#Region "ЧТЕНИЕ, ЗАПИСЬ"
''' <summary>
''' Читает данные из открытого устройства.
''' </summary>
''' <param name="numBytesToRead">Число байтов, которые нужно прочитать.</param>
Public Function Read(numBytesToRead As Integer) As Byte()
Dim data(numBytesToRead - 1) As Byte
If (data.Length < numBytesToRead) Then
numBytesToRead = data.Length
End If
Dim numBytesRed As UInteger
Dim dlg As ReadDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_Read), GetType(ReadDelegate)), ReadDelegate)
Dim status As FT_STATUS = dlg(FtHandle, data, CUInt(numBytesToRead), numBytesRed)
CheckErrors(status)
Return data
End Function
''' <summary>
''' Записывает данные в открытое устройство и возвращает число реально переданных данных.
''' </summary>
''' <param name="data">Массив данных для записи.</param>
''' <param name="numBytesToWrite">Число байтов для записи.</param>
Public Function Write(data As Byte(), numBytesToWrite As Integer) As Integer
Dim numBytesWritten As UInteger = 0UI
Dim dlg As WriteDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_Write), GetType(WriteDelegate)), WriteDelegate)
Dim status As FT_STATUS = dlg(FtHandle, data, CUInt(numBytesToWrite), numBytesWritten)
CheckErrors(status)
Return CInt(numBytesWritten)
End Function
#End Region '/ЧТЕНИЕ, ЗАПИСЬ
#Region "УПРАВЛЕНИЕ"
''' <summary>
''' Сбрасывает открытое устройство.
''' </summary>
Public Sub ResetDevice()
Dim dlg As ResetDeviceDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_ResetDevice), GetType(ResetDeviceDelegate)), ResetDeviceDelegate)
Dim status As FT_STATUS = dlg(FtHandle)
CheckErrors(status)
End Sub
''' <summary>
''' Очищает заданные буферы.
''' Purge buffer constant definitions.
''' </summary>
Public Sub Purge(purgeMask As FT_PURGE)
Dim dlg As PurgeDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_Purge), GetType(PurgeDelegate)), PurgeDelegate)
Dim status As FT_STATUS = dlg(FtHandle, purgeMask)
CheckErrors(status)
End Sub
''' <summary>
''' Регистрирует уведомление о событиях.
''' </summary>
''' <remarks>
''' После регистрации уведомления, событие может быть перехвачено методами ожидания <see cref="EventWaitHandle.WaitOne()"/>.
''' Если мониторятся несколько типов событий, вызывающее событие можно определить вызовом метода <see cref="GetEventType()"/>.
''' </remarks>
''' <param name="eventMask">Тип сигнального события.</param>
''' <param name="eventHandle">Указатель обработчика события.</param>
Public Sub SetEventNotification(eventMask As FT_EVENTS, eventHandle As EventWaitHandle)
Dim dlg As SetEventNotificationDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_SetEventNotification), GetType(SetEventNotificationDelegate)), SetEventNotificationDelegate)
Dim status As FT_STATUS = dlg.Invoke(FtHandle, eventMask, eventHandle.SafeWaitHandle)
CheckErrors(status)
End Sub
''' <summary>
''' Останавливает работу планировщика шины USB (опрос заданий).
''' </summary>
Public Sub StopInTask()
Dim dlg As StopInTaskDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_StopInTask), GetType(StopInTaskDelegate)), StopInTaskDelegate)
Dim status As FT_STATUS = dlg(FtHandle)
CheckErrors(status)
End Sub
''' <summary>
''' Возобновляет работу планировщика заданий шины USB (опрос заданий).
''' </summary>
Public Sub RestartInTask()
Dim dlg As RestartInTaskDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_RestartInTask), GetType(RestartInTaskDelegate)), RestartInTaskDelegate)
Dim status As FT_STATUS = dlg(FtHandle)
CheckErrors(status)
End Sub
''' <summary>
''' Перезагружает порт устройства.
''' </summary>
Public Sub ResetPort()
Dim dlg As ResetPortDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_ResetPort), GetType(ResetPortDelegate)), ResetPortDelegate)
Dim status As FT_STATUS = dlg(FtHandle)
CheckErrors(status)
End Sub
''' <summary>
''' Вызывает перенумерацию устройств на шине USB. Эквивалентно извлечению и вставке устройства USB.
''' </summary>
Public Sub CyclePort()
Dim dlg As CyclePortDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_CyclePort), GetType(CyclePortDelegate)), CyclePortDelegate)
Dim status As FT_STATUS = dlg.Invoke(FtHandle)
CheckErrors(status)
Dim cDlg As CloseDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_Close), GetType(CloseDelegate)), CloseDelegate)
status = cDlg.Invoke(FtHandle)
If (status = FT_STATUS.FT_OK) Then
FtHandle = CLOSED_HANDLE
End If
CheckErrors(status)
End Sub
''' <summary>
''' Переводит устройство в заданный режим.
''' </summary>
''' <param name="mask">Задаёт направления выводов. 0 соответствует ВХОДУ, 1 - ВЫХОДУ.
''' В режиме CBUS Bit Bang, верхняя тетрада байта задаёт направление, а нижняя - уровень (0 - низкий, 1 - высокий).
''' </param>
''' <param name="bitMode">Режим работы.
''' <list type="bullet">
''' <item>Для FT232H валидны <see cref="FT_BIT_MODES.FT_BIT_MODE_RESET"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_MPSSE"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_SYNC_BITBANG"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_CBUS_BITBANG"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_MCU_HOST"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_FAST_SERIAL"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_SYNC_FIFO"/>.</item>
''' <item>Для FT2232H валидны <see cref="FT_BIT_MODES.FT_BIT_MODE_RESET"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_MPSSE"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_SYNC_BITBANG"/>, FT_BIT_MODE_MCU_HOST, FT_BIT_MODE_FAST_SERIAL, FT_BIT_MODE_SYNC_FIFO.</item>
''' <item>Для FT4232H валидны <see cref="FT_BIT_MODES.FT_BIT_MODE_RESET"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_MPSSE"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_SYNC_BITBANG"/>.</item>
''' <item>Для FT232R валидны <see cref="FT_BIT_MODES.FT_BIT_MODE_RESET"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_SYNC_BITBANG"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_CBUS_BITBANG"/>.</item>
''' <item>Для FT245R валидны <see cref="FT_BIT_MODES.FT_BIT_MODE_RESET"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_SYNC_BITBANG"/>.</item>
''' <item>Для FT2232 валидны <see cref="FT_BIT_MODES.FT_BIT_MODE_RESET"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_MPSSE"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_SYNC_BITBANG"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_MCU_HOST"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_FAST_SERIAL"/>.</item>
''' <item>Для FT232B и FT245B валидны <see cref="FT_BIT_MODES.FT_BIT_MODE_RESET"/>, <see cref="FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG"/>.</item>
''' </list>
''' </param>
Public Sub SetBitMode(mask As Byte, bitMode As FT_BIT_MODES)
Dim status As FT_STATUS = FT_STATUS.FT_OTHER_ERROR
Select Case DeviceType
Case FT_DEVICE.FT_DEVICE_AM
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
Case FT_DEVICE.FT_DEVICE_100AX
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
Case FT_DEVICE.FT_DEVICE_BM
If (bitMode <> FT_BIT_MODES.FT_BIT_MODE_RESET) Then
If ((bitMode And 1) = 0) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
End If
Case FT_DEVICE.FT_DEVICE_2232
If (bitMode <> FT_BIT_MODES.FT_BIT_MODE_RESET) Then
If ((bitMode And &H1F) = 0) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
If (bitMode = FT_BIT_MODES.FT_BIT_MODE_MPSSE) AndAlso (Me.InterfaceIdentifier <> "A") Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
End If
Case FT_DEVICE.FT_DEVICE_232R
If (bitMode <> FT_BIT_MODES.FT_BIT_MODE_RESET) Then
If ((bitMode And 37) = 0) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
End If
Case FT_DEVICE.FT_DEVICE_2232H
If (bitMode <> FT_BIT_MODES.FT_BIT_MODE_RESET) Then
If ((bitMode And 95) = 0) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
If ((bitMode = FT_BIT_MODES.FT_BIT_MODE_MCU_HOST) Or (bitMode = FT_BIT_MODES.FT_BIT_MODE_SYNC_FIFO)) AndAlso (Me.InterfaceIdentifier <> "A") Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
End If
Case FT_DEVICE.FT_DEVICE_4232H
If (bitMode <> FT_BIT_MODES.FT_BIT_MODE_RESET) Then
If ((bitMode And 7) = 0) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
If (bitMode = FT_BIT_MODES.FT_BIT_MODE_MPSSE) AndAlso (Me.InterfaceIdentifier <> "A") AndAlso (Me.InterfaceIdentifier <> "B") Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
End If
Case FT_DEVICE.FT_DEVICE_232H
If (bitMode > FT_BIT_MODES.FT_BIT_MODE_SYNC_FIFO) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
End Select
If (DeviceType = FT_DEVICE.FT_DEVICE_AM) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
ElseIf (DeviceType = FT_DEVICE.FT_DEVICE_100AX) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
ElseIf (DeviceType = FT_DEVICE.FT_DEVICE_BM) AndAlso (bitMode <> FT_BIT_MODES.FT_BIT_MODE_RESET) Then
If ((bitMode And 1) = 0) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
ElseIf (DeviceType = FT_DEVICE.FT_DEVICE_2232) AndAlso (bitMode <> FT_BIT_MODES.FT_BIT_MODE_RESET) Then
If ((bitMode And &H1F) = 0) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
If (bitMode = FT_BIT_MODES.FT_BIT_MODE_MPSSE) AndAlso (Me.InterfaceIdentifier <> "A") Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
ElseIf (DeviceType = FT_DEVICE.FT_DEVICE_232R) AndAlso (bitMode <> FT_BIT_MODES.FT_BIT_MODE_RESET) Then
If ((bitMode And 37) = 0) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
ElseIf (DeviceType = FT_DEVICE.FT_DEVICE_2232H) AndAlso (bitMode <> FT_BIT_MODES.FT_BIT_MODE_RESET) Then
If ((bitMode And 95) = 0) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
If ((bitMode = FT_BIT_MODES.FT_BIT_MODE_MCU_HOST) Or (bitMode = FT_BIT_MODES.FT_BIT_MODE_SYNC_FIFO)) AndAlso (Me.InterfaceIdentifier <> "A") Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
ElseIf (DeviceType = FT_DEVICE.FT_DEVICE_4232H) AndAlso (bitMode <> FT_BIT_MODES.FT_BIT_MODE_RESET) Then
If ((bitMode And 7) = 0) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
If (bitMode = FT_BIT_MODES.FT_BIT_MODE_MPSSE) AndAlso (Me.InterfaceIdentifier <> "A") AndAlso (Me.InterfaceIdentifier <> "B") Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
ElseIf (DeviceType = FT_DEVICE.FT_DEVICE_232H) AndAlso (bitMode <> FT_BIT_MODES.FT_BIT_MODE_RESET) AndAlso (bitMode > FT_BIT_MODES.FT_BIT_MODE_SYNC_FIFO) Then
CheckErrors(status, FT_ERROR.FT_INVALID_BITMODE)
End If
Dim dlg As SetBitModeDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_SetBitMode), GetType(SetBitModeDelegate)), SetBitModeDelegate)
status = dlg.Invoke(FtHandle, mask, bitMode)
CheckErrors(status)
End Sub
''' <summary>
''' Возвращает состояние бита по индексу <paramref name="index"/>.
''' </summary>
Public Function GetGpio(index As Integer) As Boolean
Dim b As Byte = GetPinStates()
Return CBool((b >> index) And 1)
End Function
''' <summary>
''' Устанавливает для выбранного GPIO значение <paramref name="value"/>.
''' </summary>
''' <remarks>
''' 1 - ВЫХОД, 0 - ВХОД.
''' SetBitMode(0000_1111, Mode) 'all gpio high
''' SetBitMode(0001_1111, Mode) 'gpio0 low
''' SetBitMode(0010_1111, Mode) 'gpio1 low
''' SetBitMode(0100_1111, Mode) 'gpio2 low
''' SetBitMode(1000_1111, Mode) 'gpio3 low
''' </remarks>
Public Sub SetGpio(index As Integer, value As Boolean)
If (index < 0) OrElse (index > 3) Then
Throw New ArgumentException("Номер GPIO должен лежать в диапазоне от 0 до 3.")
End If
Dim b As Byte = GetPinStates()
Dim bv As New Specialized.BitVector32(b)
Dim shift As Integer = 4 + index
bv(1 << shift) = value
Dim mask As Byte = CByte(bv.Data Xor &HFF)
SetBitMode(mask, FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG) 'TODO Проверить выставление GPIO!!!
End Sub
''' <summary>
''' Получает данные от FT4222 используя командный интерфейс вендора.
''' </summary>
Public Sub VendorCmdGet(request As UShort, buf As Byte(), len As UShort)
Dim dlg As VendorCmdGetDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_VendorCmdGet), GetType(VendorCmdGetDelegate)), VendorCmdGetDelegate)
Dim status As FT_STATUS = dlg(FtHandle, request, buf, len)
CheckErrors(status)
End Sub
''' <summary>
''' Выставляет данные FT4222 используя командный интерфейс вендора.
''' </summary>
Public Sub VendorCmdSet(request As UShort, buf As Byte(), len As UShort)
Dim dlg As VendorCmdSetDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_VendorCmdSet), GetType(VendorCmdSetDelegate)), VendorCmdSetDelegate)
Dim status As FT_STATUS = dlg(FtHandle, request, buf, len)
CheckErrors(status)
End Sub
''' <summary>
''' Проверяет изменения состава аппаратуры на шине USB.
''' </summary>
''' <remarks>
''' Эквивалентно нажатию кнопки "Обновить конфигурацию оборудования" в менеджере устройств.
''' </remarks>
Public Shared Sub Rescan()
Dim dlg As RescanDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_Rescan), GetType(RescanDelegate)), RescanDelegate)
Dim status As FT_STATUS = dlg.Invoke()
CheckErrors(status)
End Sub
''' <summary>
''' Принудительно перезагружает драйверы для устройств с заданными VID и PID.
''' </summary>
''' <remarks>Если VID и PID равны 0, будет перезагружен драйвер USB хаба, что вызовет перезагрузку всех подключённых к шине USB устройств.</remarks>
Public Shared Sub Reload(vendorID As UShort, productID As UShort)
Dim dlg As ReloadDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(Pft_Reload), GetType(ReloadDelegate)), ReloadDelegate)
Dim status As FT_STATUS = dlg(vendorID, productID)
CheckErrors(status)
End Sub
#End Region '/УПРАВЛЕНИЕ
#Region "HELPERS"
''' <summary>
''' Проверяет результат выполнения метода и выбрасывает исключение, если статус с ошибкой.
''' </summary>
Public Shared Sub CheckErrors(status As FT_STATUS, Optional additionalInfo As FT_ERROR = FT_ERROR.FT_NO_ERROR)
Select Case status
Case FT_STATUS.FT_OK
'ничего не делаем
Case FT_STATUS.FT_OTHER_ERROR
Throw New FT_EXCEPTION("Ошибка при попытке соединения с устройством FTDI.")
Case FT_STATUS.FT_INVALID_HANDLE
Throw New FT_EXCEPTION("Неверный дескриптор устройства FTDI.")
Case FT_STATUS.FT_DEVICE_NOT_FOUND
Throw New FT_EXCEPTION("Устройство FTDI не найдено.")
Case FT_STATUS.FT_DEVICE_NOT_OPENED
Throw New FT_EXCEPTION("Устройство FTDI не открыто.")
Case FT_STATUS.FT_IO_ERROR
Throw New FT_EXCEPTION("Ошибка ввода-вывода устройства FTDI.")
Case FT_STATUS.FT_INSUFFICIENT_RESOURCES
Throw New FT_EXCEPTION("Недостаточно ресурсов.")
Case FT_STATUS.FT_INVALID_PARAMETER
Throw New FT_EXCEPTION("Неверный параметр вызываемой функции FTD2XX.")
Case FT_STATUS.FT_INVALID_BAUD_RATE
Throw New FT_EXCEPTION("Неверный битрейт устройства FTDI.")
Case FT_STATUS.FT_DEVICE_NOT_OPENED_FOR_ERASE
Throw New FT_EXCEPTION("Устройство FTDI не открыто для стирания ЭСППЗУ.")
Case FT_STATUS.FT_DEVICE_NOT_OPENED_FOR_WRITE
Throw New FT_EXCEPTION("Устройство FTDI не открыто для записи.")
Case FT_STATUS.FT_FAILED_TO_WRITE_DEVICE
Throw New FT_EXCEPTION("Сбой при попытке записи в устройство FTDI.")
Case FT_STATUS.FT_EEPROM_READ_FAILED
Throw New FT_EXCEPTION("Сбой чтения EEPROM устройства FTDI.")
Case FT_STATUS.FT_EEPROM_WRITE_FAILED
Throw New FT_EXCEPTION("Сбой записи EEPROM устройства FTDI.")
Case FT_STATUS.FT_EEPROM_ERASE_FAILED
Throw New FT_EXCEPTION("Сбой при стирании EEPROM устройства FTDI.")
Case FT_STATUS.FT_EEPROM_NOT_PRESENT
Throw New FT_EXCEPTION("EEPROM не подходит для устройства FTDI.")
Case FT_STATUS.FT_EEPROM_NOT_PROGRAMMED
Throw New FT_EXCEPTION("EEPROM устройства FTDI не запрограммировано.")
Case FT_STATUS.FT_INVALID_ARGS
Throw New FT_EXCEPTION("Неверные аргументы при вызове функции FTD2XX.")
End Select
Select Case additionalInfo
Case FT_ERROR.FT_NO_ERROR
Return
Case FT_ERROR.FT_INCORRECT_DEVICE
Throw New FT_EXCEPTION("Тип текущего устройства не совпадает со структурой памяти EEPROM.")
Case FT_ERROR.FT_INVALID_BITMODE
Throw New FT_EXCEPTION("Указанный битовый режим не является допустимым для текущего устройства.")
Case FT_ERROR.FT_BUFFER_SIZE
Throw New FT_EXCEPTION("Предоставленный буфер имеет недостаточный размер.")
Case Else
Debug.WriteLine("Значение не содержится в перечислении FT_ERROR.")
End Select
End Sub
#End Region '/HELPERS
#Region "NATIVE"
''' <summary>
''' Задаёт произвольный путь к библиотеке ftd2xx.
''' </summary>
Public Shared Sub SetLibraryPath(libPath As String)
UnloadLibrary()
_LibPath = libPath
End Sub
<DllImport("kernel32.dll", SetLastError:=True)>
Private Shared Function LoadLibrary(dllToLoad As String) As Integer
End Function
<DllImport("kernel32.dll", SetLastError:=True)>
Private Shared Function FreeLibrary(hModule As Integer) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True)>
Private Shared Function GetProcAddress(hModule As Integer, procedureName As String) As Integer
End Function
''' <summary>
''' Дескриптор библиотеки ftd2xx.
''' </summary>
Private Shared ReadOnly Property Ftd2xxDllHandle As Integer
Get
If (_Ftd2xxDllHandle = CLOSED_HANDLE) Then
_Ftd2xxDllHandle = LoadLibrary(LibPath)
If (Not IsLibraryLoaded) Then
Throw New FT_EXCEPTION("Ошибка загрузки библиотеки ftd2xx.dll.")
End If
FindFunctionPointers()
End If
Return _Ftd2xxDllHandle
End Get
End Property
Private Shared _Ftd2xxDllHandle As Integer = CLOSED_HANDLE
Private Shared ReadOnly Property Pft_CreateDeviceInfoList As Integer
Get
If (_Pft_CreateDeviceInfoList = NOT_INIT) Then
_Pft_CreateDeviceInfoList = GetProcAddress(Ftd2xxDllHandle, "FT_CreateDeviceInfoList")
End If
Return _Pft_CreateDeviceInfoList
End Get
End Property
Private Shared _Pft_CreateDeviceInfoList As Integer = NOT_INIT
Private Shared ReadOnly Property Pft_Close As Integer
Get
If (_Pft_Close = NOT_INIT) Then
_Pft_Close = GetProcAddress(Ftd2xxDllHandle, "FT_Close")
End If
Return _Pft_Close
End Get
End Property
Private Shared _Pft_Close As Integer = NOT_INIT
Private Shared ReadOnly Property Pft_GetComPortNumber As Integer
Get
If (_Pft_GetComPortNumber = NOT_INIT) Then
_Pft_GetComPortNumber = GetProcAddress(Ftd2xxDllHandle, "FT_GetComPortNumber")
End If
Return _Pft_GetComPortNumber
End Get
End Property
Private Shared _Pft_GetComPortNumber As Integer = NOT_INIT
'Статические поля:
Private Shared Pft_GetDeviceInfoDetail As Integer = NOT_INIT
Private Shared Pft_Open As Integer = NOT_INIT
Private Shared Pft_OpenEx As Integer = NOT_INIT
Private Shared Pft_Read As Integer = NOT_INIT
Private Shared Pft_Write As Integer = NOT_INIT
Private Shared Pft_GetQueueStatus As Integer = NOT_INIT
Private Shared Pft_GetModemStatus As Integer = NOT_INIT
Private Shared Pft_GetStatus As Integer = NOT_INIT
Private Shared Pft_SetBaudRate As Integer = NOT_INIT
Private Shared Pft_SetDataCharacteristics As Integer = NOT_INIT
Private Shared Pft_SetFlowControl As Integer = NOT_INIT
Private Shared Pft_SetDtr As Integer = NOT_INIT
Private Shared Pft_ClrDtr As Integer = NOT_INIT
Private Shared Pft_SetRts As Integer = NOT_INIT
Private Shared Pft_ClrRts As Integer = NOT_INIT
Private Shared Pft_ResetDevice As Integer = NOT_INIT
Private Shared Pft_ResetPort As Integer = NOT_INIT
Private Shared Pft_CyclePort As Integer = NOT_INIT
Private Shared Pft_Rescan As Integer = NOT_INIT
Private Shared Pft_Reload As Integer = NOT_INIT
Private Shared Pft_Purge As Integer = NOT_INIT
Private Shared Pft_SetTimeouts As Integer = NOT_INIT
Private Shared Pft_SetBreakOn As Integer = NOT_INIT
Private Shared Pft_SetBreakOff As Integer = NOT_INIT
Private Shared Pft_GetDeviceInfo As Integer = NOT_INIT
Private Shared Pft_SetResetPipeRetryCount As Integer = NOT_INIT
Private Shared Pft_StopInTask As Integer = NOT_INIT
Private Shared Pft_RestartInTask As Integer = NOT_INIT
Private Shared Pft_GetDriverVersion As Integer = NOT_INIT
Private Shared Pft_SetDeadmanTimeout As Integer = NOT_INIT
Private Shared Pft_SetChars As Integer = NOT_INIT
Private Shared Pft_SetEventNotification As Integer = NOT_INIT
Private Shared Pft_SetLatencyTimer As Integer = NOT_INIT
Private Shared Pft_GetLatencyTimer As Integer = NOT_INIT
Private Shared Pft_SetBitMode As Integer = NOT_INIT
Private Shared Pft_GetBitMode As Integer = NOT_INIT
Private Shared Pft_SetUSBParameters As Integer = NOT_INIT
Private Shared Pft_VendorCmdGet As Integer = NOT_INIT
Private Shared Pft_VendorCmdSet As Integer = NOT_INIT
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function CreateDeviceInfoListDelegate(ByRef numdevs As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function GetDeviceInfoDetailDelegate(index As UInteger, ByRef flags As UInteger, ByRef chiptype As FT_DEVICE, ByRef id As UInteger, ByRef locid As UInteger, serialnumber As Byte(), description As Byte(), ByRef ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function OpenDelegate(index As UInteger, ByRef ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function OpenExDelegate(devstring As String, dwFlags As FT_OPEN_BY, ByRef ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function OpenExLocDelegate(devloc As UInteger, dwFlags As UInteger, ByRef ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function CloseDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function ReadDelegate(ftHandle As Integer, lpBuffer As Byte(), dwBytesToRead As UInteger, ByRef lpdwBytesReturned As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function WriteDelegate(ftHandle As Integer, lpBuffer As Byte(), dwBytesToWrite As UInteger, ByRef lpdwBytesWritten As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function GetQueueStatusDelegate(ftHandle As Integer, ByRef lpdwAmountInRxQueue As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function GetModemStatusDelegate(ftHandle As Integer, ByRef lpdwModemStatus As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function GetStatusDelegate(ftHandle As Integer, ByRef lpdwAmountInRxQueue As UInteger, ByRef lpdwAmountInTxQueue As UInteger, ByRef lpdwEventStatus As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetBaudRateDelegate(ftHandle As Integer, dwBaudRate As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetDataCharacteristicsDelegate(ftHandle As Integer, uWordLength As Byte, uStopBits As Byte, uParity As Byte) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetFlowControlDelegate(ftHandle As Integer, usFlowControl As UShort, uXon As Byte, uXoff As Byte) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetDtrDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function ClrDtrDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetRtsDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function ClrRtsDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function ResetDeviceDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function ResetPortDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function CyclePortDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function RescanDelegate() As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function ReloadDelegate(wVID As UShort, wPID As UShort) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function PurgeDelegate(ftHandle As Integer, dwMask As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetTimeoutsDelegate(ftHandle As Integer, dwReadTimeout As UInteger, dwWriteTimeout As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetBreakOnDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetBreakOffDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function GetDeviceInfoDelegate(ftHandle As Integer, ByRef pftType As FT_DEVICE, ByRef lpdwID As UInteger, pcSerialNumber As Byte(), pcDescription As Byte(), pvDummy As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetResetPipeRetryCountDelegate(ftHandle As Integer, dwCount As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function StopInTaskDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function RestartInTaskDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function GetDriverVersionDelegate(ftHandle As Integer, ByRef lpdwDriverVersion As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function GetLibraryVersionDelegate(ByRef lpdwLibraryVersion As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetDeadmanTimeoutDelegate(ftHandle As Integer, dwDeadmanTimeout As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetCharsDelegate(ftHandle As Integer, uEventCh As Byte, uEventChEn As Byte, uErrorCh As Byte, uErrorChEn As Byte) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetEventNotificationDelegate(ftHandle As Integer, dwEventMask As UInteger, hEvent As SafeHandle) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function GetComPortNumberDelegate(ftHandle As Integer, ByRef dwComPortNumber As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetLatencyTimerDelegate(ftHandle As Integer, ucLatency As Byte) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function GetLatencyTimerDelegate(ftHandle As Integer, ByRef ucLatency As Byte) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetBitModeDelegate(ftHandle As Integer, ucMask As Byte, ucMode As Byte) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function GetBitModeDelegate(ftHandle As Integer, ByRef ucMode As Byte) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function SetUsbParametersDelegate(ftHandle As Integer, dwInTransferSize As UInteger, dwOutTransferSize As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function VendorCmdGetDelegate(ftHandle As Integer, request As UShort, buf As Byte(), len As UShort) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function VendorCmdSetDelegate(ftHandle As Integer, request As UShort, buf As Byte(), len As UShort) As FT_STATUS
''' <summary>
''' Ищет указатели на нативные функции в библиотеке ftd2xx.
''' </summary>
Private Shared Sub FindFunctionPointers()
If (Pft_GetDeviceInfoDetail = NOT_INIT) Then
Pft_GetDeviceInfoDetail = GetProcAddress(Ftd2xxDllHandle, "FT_GetDeviceInfoDetail")
End If
If (Pft_Open = NOT_INIT) Then
Pft_Open = GetProcAddress(Ftd2xxDllHandle, "FT_Open")
End If
If (Pft_OpenEx = NOT_INIT) Then
Pft_OpenEx = GetProcAddress(Ftd2xxDllHandle, "FT_OpenEx")
End If
If (Pft_Read = NOT_INIT) Then
Pft_Read = GetProcAddress(Ftd2xxDllHandle, "FT_Read")
End If
If (Pft_Write = NOT_INIT) Then
Pft_Write = GetProcAddress(Ftd2xxDllHandle, "FT_Write")
End If
If (Pft_GetQueueStatus = NOT_INIT) Then
Pft_GetQueueStatus = GetProcAddress(Ftd2xxDllHandle, "FT_GetQueueStatus")
End If
If (Pft_GetModemStatus = NOT_INIT) Then
Pft_GetModemStatus = GetProcAddress(Ftd2xxDllHandle, "FT_GetModemStatus")
End If
If (Pft_GetStatus = NOT_INIT) Then
Pft_GetStatus = GetProcAddress(Ftd2xxDllHandle, "FT_GetStatus")
End If
If (Pft_SetBaudRate = NOT_INIT) Then
Pft_SetBaudRate = GetProcAddress(Ftd2xxDllHandle, "FT_SetBaudRate")
End If
If (Pft_SetDataCharacteristics = NOT_INIT) Then
Pft_SetDataCharacteristics = GetProcAddress(Ftd2xxDllHandle, "FT_SetDataCharacteristics")
End If
If (Pft_SetFlowControl = NOT_INIT) Then
Pft_SetFlowControl = GetProcAddress(Ftd2xxDllHandle, "FT_SetFlowControl")
End If
If (Pft_SetDtr = NOT_INIT) Then
Pft_SetDtr = GetProcAddress(Ftd2xxDllHandle, "FT_SetDtr")
End If
If (Pft_ClrDtr = NOT_INIT) Then
Pft_ClrDtr = GetProcAddress(Ftd2xxDllHandle, "FT_ClrDtr")
End If
If (Pft_SetRts = NOT_INIT) Then
Pft_SetRts = GetProcAddress(Ftd2xxDllHandle, "FT_SetRts")
End If
If (Pft_ClrRts = NOT_INIT) Then
Pft_ClrRts = GetProcAddress(Ftd2xxDllHandle, "FT_ClrRts")
End If
If (Pft_ResetDevice = NOT_INIT) Then
Pft_ResetDevice = GetProcAddress(Ftd2xxDllHandle, "FT_ResetDevice")
End If
If (Pft_ResetPort = NOT_INIT) Then
Pft_ResetPort = GetProcAddress(Ftd2xxDllHandle, "FT_ResetPort")
End If
If (Pft_CyclePort = NOT_INIT) Then
Pft_CyclePort = GetProcAddress(Ftd2xxDllHandle, "FT_CyclePort")
End If
If (Pft_Rescan = NOT_INIT) Then
Pft_Rescan = GetProcAddress(Ftd2xxDllHandle, "FT_Rescan")
End If
If (Pft_Reload = NOT_INIT) Then
Pft_Reload = GetProcAddress(Ftd2xxDllHandle, "FT_Reload")
End If
If (Pft_Purge = NOT_INIT) Then
Pft_Purge = GetProcAddress(Ftd2xxDllHandle, "FT_Purge")
End If
If (Pft_SetTimeouts = NOT_INIT) Then
Pft_SetTimeouts = GetProcAddress(Ftd2xxDllHandle, "FT_SetTimeouts")
End If
If (Pft_SetBreakOn = NOT_INIT) Then
Pft_SetBreakOn = GetProcAddress(Ftd2xxDllHandle, "FT_SetBreakOn")
End If
If (Pft_SetBreakOff = NOT_INIT) Then
Pft_SetBreakOff = GetProcAddress(Ftd2xxDllHandle, "FT_SetBreakOff")
End If
If (Pft_GetDeviceInfo = NOT_INIT) Then
Pft_GetDeviceInfo = GetProcAddress(Ftd2xxDllHandle, "FT_GetDeviceInfo")
End If
If (Pft_SetResetPipeRetryCount = NOT_INIT) Then
Pft_SetResetPipeRetryCount = GetProcAddress(Ftd2xxDllHandle, "FT_SetResetPipeRetryCount")
End If
If (Pft_StopInTask = NOT_INIT) Then
Pft_StopInTask = GetProcAddress(Ftd2xxDllHandle, "FT_StopInTask")
End If
If (Pft_RestartInTask = NOT_INIT) Then
Pft_RestartInTask = GetProcAddress(Ftd2xxDllHandle, "FT_RestartInTask")
End If
If (Pft_GetDriverVersion = NOT_INIT) Then
Pft_GetDriverVersion = GetProcAddress(Ftd2xxDllHandle, "FT_GetDriverVersion")
End If
If (Pft_SetDeadmanTimeout = NOT_INIT) Then
Pft_SetDeadmanTimeout = GetProcAddress(Ftd2xxDllHandle, "FT_SetDeadmanTimeout")
End If
If (Pft_SetChars = NOT_INIT) Then
Pft_SetChars = GetProcAddress(Ftd2xxDllHandle, "FT_SetChars")
End If
If (Pft_SetEventNotification = NOT_INIT) Then
Pft_SetEventNotification = GetProcAddress(Ftd2xxDllHandle, "FT_SetEventNotification")
End If
If (Pft_SetLatencyTimer = NOT_INIT) Then
Pft_SetLatencyTimer = GetProcAddress(Ftd2xxDllHandle, "FT_SetLatencyTimer")
End If
If (Pft_GetLatencyTimer = NOT_INIT) Then
Pft_GetLatencyTimer = GetProcAddress(Ftd2xxDllHandle, "FT_GetLatencyTimer")
End If
If (Pft_SetBitMode = NOT_INIT) Then
Pft_SetBitMode = GetProcAddress(Ftd2xxDllHandle, "FT_SetBitMode")
End If
If (Pft_GetBitMode = NOT_INIT) Then
Pft_GetBitMode = GetProcAddress(Ftd2xxDllHandle, "FT_GetBitMode")
End If
If (Pft_SetUSBParameters = NOT_INIT) Then
Pft_SetUSBParameters = GetProcAddress(Ftd2xxDllHandle, "FT_SetUSBParameters")
End If
If (Pft_VendorCmdGet = NOT_INIT) Then
Pft_VendorCmdGet = GetProcAddress(Ftd2xxDllHandle, "FT_VendorCmdGet")
End If
If (Pft_VendorCmdSet = NOT_INIT) Then
Pft_VendorCmdSet = GetProcAddress(Ftd2xxDllHandle, "FT_VendorCmdSet")
End If
End Sub
#End Region '/NATIVE
#Region "NESTED TYPES"
Public Enum FT_STATUS
FT_OK
FT_INVALID_HANDLE
FT_DEVICE_NOT_FOUND
FT_DEVICE_NOT_OPENED
FT_IO_ERROR
FT_INSUFFICIENT_RESOURCES
FT_INVALID_PARAMETER
FT_INVALID_BAUD_RATE
FT_DEVICE_NOT_OPENED_FOR_ERASE
FT_DEVICE_NOT_OPENED_FOR_WRITE
FT_FAILED_TO_WRITE_DEVICE
FT_EEPROM_READ_FAILED
FT_EEPROM_WRITE_FAILED
FT_EEPROM_ERASE_FAILED
FT_EEPROM_NOT_PRESENT
FT_EEPROM_NOT_PROGRAMMED
FT_INVALID_ARGS
FT_OTHER_ERROR
End Enum
Public Enum FT_OPEN_BY As UInteger
SERIAL_NUMBER = 1UI
DESCRIPTION = 2UI
LOCATION = 4UI
End Enum
Public Enum FT_ERROR
FT_NO_ERROR
FT_INCORRECT_DEVICE
FT_INVALID_BITMODE
FT_BUFFER_SIZE
End Enum
Public Enum FT_DATA_BITS As Byte
FT_BITS_7 = 7
FT_BITS_8 = 8
End Enum
Public Enum FT_STOP_BITS As Byte
FT_STOP_BITS_1 = 0
FT_STOP_BITS_2 = 2
End Enum
Public Enum FT_PARITY As Byte
FT_PARITY_NONE
FT_PARITY_ODD
FT_PARITY_EVEN
FT_PARITY_MARK
FT_PARITY_SPACE
End Enum
<Flags()>
Public Enum FT_FLOW_CONTROL As UShort
FT_FLOW_NONE = &H0
FT_FLOW_RTS_CTS = &H100
FT_FLOW_DTR_DSR = &H200
FT_FLOW_XON_XOFF = &H400
End Enum
''' <summary>
''' Purge buffer constant definitions.
''' </summary>
<Flags()>
Public Enum FT_PURGE As Byte
''' <summary>
''' Очистить приёмный буфер.
''' </summary>
FT_PURGE_RX = 1
''' <summary>
''' Очистить передающий буфер.
''' </summary>
FT_PURGE_TX = 2
End Enum
<Flags()>
Public Enum FT_MODEM_STATUS As Byte
None = 0
''' <summary>
''' Состояние модема "Clear To Send".
''' </summary>
FT_CTS = &H10
''' <summary>
''' Состояние модема "Data Set Ready".
''' </summary>
FT_DSR = &H20
''' <summary>
''' Состояние модема "Ring Indicator".
''' </summary>
FT_RI = &H40
''' <summary>
''' Состояние модема "Data Carrier Detect".
''' </summary>
FT_DCD = &H80
End Enum
<Flags()>
Public Enum FT_LINE_STATUS As Byte
None = 0
''' <summary>
''' Статус линии "Overrun Error".
''' </summary>
FT_OE = 2
''' <summary>
''' Статус линии "Parity Error".
''' </summary>
FT_PE = 4
''' <summary>
''' Статус линии "Framing Error".
''' </summary>
FT_FE = 8
''' <summary>
''' Статус линии "Break Interrupt".
''' </summary>
FT_BI = 16
End Enum
<Flags()>
Public Enum FT_EVENTS As UInteger
''' <summary>
''' Событие по получению управляющего символа.
''' </summary>
FT_EVENT_RXCHAR = 1UI
''' <summary>
''' Событие по изменению статуса модема.
''' </summary>
FT_EVENT_MODEM_STATUS = 2UI
''' <summary>
''' Событие по изменению статуса линии.
''' </summary>
FT_EVENT_LINE_STATUS = 4UI
End Enum
<Flags()>
Public Enum FT_BIT_MODES As Byte
FT_BIT_MODE_RESET = 0
FT_BIT_MODE_ASYNC_BITBANG = 1
FT_BIT_MODE_MPSSE = 2
FT_BIT_MODE_SYNC_BITBANG = 4
FT_BIT_MODE_MCU_HOST = 8
FT_BIT_MODE_FAST_SERIAL = 16
FT_BIT_MODE_CBUS_BITBANG = 32
FT_BIT_MODE_SYNC_FIFO = 64
End Enum
Public Enum FT_CBUS_OPTIONS As Byte
FT_CBUS_TXDEN
FT_CBUS_PWRON
FT_CBUS_RXLED
FT_CBUS_TXLED
FT_CBUS_TXRXLED
FT_CBUS_SLEEP
FT_CBUS_CLK48
FT_CBUS_CLK24
FT_CBUS_CLK12
FT_CBUS_CLK6
FT_CBUS_IOMODE
FT_CBUS_BITBANG_WR
FT_CBUS_BITBANG_RD
End Enum
Public Enum FT_232H_CBUS_OPTIONS As Byte
FT_CBUS_TRISTATE
FT_CBUS_RXLED
FT_CBUS_TXLED
FT_CBUS_TXRXLED
FT_CBUS_PWREN
FT_CBUS_SLEEP
FT_CBUS_DRIVE_0
FT_CBUS_DRIVE_1
FT_CBUS_IOMODE
FT_CBUS_TXDEN
FT_CBUS_CLK30
FT_CBUS_CLK15
FT_CBUS_CLK7_5
End Enum
Public Enum FT_XSERIES_CBUS_OPTIONS As Byte
FT_CBUS_TRISTATE
FT_CBUS_RXLED
FT_CBUS_TXLED
FT_CBUS_TXRXLED
FT_CBUS_PWREN
FT_CBUS_SLEEP
FT_CBUS_Drive_0
FT_CBUS_Drive_1
FT_CBUS_GPIO
FT_CBUS_TXDEN
FT_CBUS_CLK24MHz
FT_CBUS_CLK12MHz
FT_CBUS_CLK6MHz
FT_CBUS_BCD_Charger
FT_CBUS_BCD_Charger_N
FT_CBUS_I2C_TXE
FT_CBUS_I2C_RXF
FT_CBUS_VBUS_Sense
FT_CBUS_BitBang_WR
FT_CBUS_BitBang_RD
FT_CBUS_Time_Stamp
FT_CBUS_Keep_Awake
End Enum
Public Enum FT_FLAGS As UInteger
FT_FLAGS_OPENED = 1UI
FT_FLAGS_HISPEED = 2UI
End Enum
Public Enum FT_DRIVE_CURRENT As Byte
FT_DRIVE_CURRENT_4MA = 4
FT_DRIVE_CURRENT_8MA = 8
FT_DRIVE_CURRENT_12MA = 12
FT_DRIVE_CURRENT_16MA = 16
End Enum
Public Enum FT_DEVICE As UInteger
FT_DEVICE_BM = 0
FT_DEVICE_AM
FT_DEVICE_100AX
FT_DEVICE_UNKNOWN
FT_DEVICE_2232
FT_DEVICE_232R
FT_DEVICE_2232H
FT_DEVICE_4232H
FT_DEVICE_232H
FT_DEVICE_X_SERIES
FT_DEVICE_4222H_0
FT_DEVICE_4222H_1_2
FT_DEVICE_4222H_3
FT_DEVICE_4222_PROG
End Enum
Public Structure FT_DEVICE_INFO_NODE
Public Flags As UInteger
Public Type As FT_DEVICE
Public ID As UInteger
Public LocId As UInteger
Public SerialNumber As String
Public Description As String
Public FtHandle As Integer
End Structure
<Serializable()>
Public Class FT_EXCEPTION
Inherits Exception
Public Sub New()
End Sub
Public Sub New(message As String)
MyBase.New(message)
End Sub
Public Sub New(message As String, inner As Exception)
MyBase.New(message, inner)
End Sub
Protected Sub New(info As SerializationInfo, context As StreamingContext)
MyBase.New(info, context)
End Sub
End Class '/FT_EXCEPTION
#End Region '/NESTED TYPES
#Region "DISPOSABLE"
Private DisposedValue As Boolean
Protected Overridable Sub Dispose(disposing As Boolean)
If (Not DisposedValue) Then
If disposing Then
Close()
End If
DisposedValue = True
End If
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region '/DISPOSABLE
End Class '/Ftdi
End Namespace
Также большой по объёму класс Eeprom. Он содержит большое число структур, которые описывают то, каким образом хранятся данные в ППЗУ различных типов микросхем FTDI. Если вы не планируете работать с ПЗУ своей микросхемы, то можно не использовать этот класс. Для этого следует исключить из только что описанного класса Ftdi свойство Eeprom.
Функции для работы с ППЗУ микросхем FTDI
Imports System.Runtime.InteropServices
Imports System.Text
Imports FTD2XX_NET.Ftdi
Namespace FTD2XX_NET
''' <summary>
''' Работа с ППЗУ микросхем FTDI.
''' </summary>
Public Class Eeprom
#Region "CTOR"
Private ReadOnly FtHandle As Integer
Private ReadOnly DeviceType As FT_DEVICE
Friend Sub New(ftDllHandle As Integer, ftHandle As Integer, devType As FT_DEVICE)
Me.FtHandle = ftHandle
Me.DeviceType = devType
FindEeFunctionPointers(ftDllHandle)
End Sub
#End Region '/CTOR
#Region "ЧТЕНИЕ ППЗУ"
''' <summary>
''' Читает из ПЗУ и возвращает одно слово данных по адресу <paramref name="address"/>.
''' </summary>
''' <param name="address">Адрес ячейки памяти.</param>
Public Function ReadEeprom(address As UInteger) As UShort
Dim value As UShort
Dim dlg As ReadEeDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_ReadEE, IntPtr), GetType(ReadEeDelegate)), ReadEeDelegate)
Dim status As FT_STATUS = dlg(FtHandle, address, value)
CheckErrors(status)
Return value
End Function
''' <summary>
''' Читает данные из ПЗУ устройства.
''' </summary>
Public Function ReadEeprom() As FT_EEPROM_DATA
Select Case DeviceType
Case FT_DEVICE.FT_DEVICE_BM
Return ReadFt232bEeprom()
Case FT_DEVICE.FT_DEVICE_2232
Return ReadFt2232Eeprom()
Case FT_DEVICE.FT_DEVICE_232R
Return ReadFt232rEeprom()
Case FT_DEVICE.FT_DEVICE_2232H
Return ReadFt2232hEeprom()
Case FT_DEVICE.FT_DEVICE_4232H
Return ReadFt4232hEeprom()
Case FT_DEVICE.FT_DEVICE_232H
Return ReadFt232hEeprom()
Case FT_DEVICE.FT_DEVICE_X_SERIES
Return ReadXSeriesEeprom()
End Select
Throw New FT_EXCEPTION("Ошибка чтения ППЗУ.")
End Function
Private Function ReadFt232bEeprom() As FT232B_EEPROM_STRUCTURE
Dim ee232b As New FT232B_EEPROM_STRUCTURE()
Dim programData As New FT_PROGRAM_DATA() With {
.Signature1 = 0UI,
.Signature2 = UInteger.MaxValue,
.Version = 2UI,
.Manufacturer = Marshal.AllocHGlobal(32),
.ManufacturerID = Marshal.AllocHGlobal(16),
.Description = Marshal.AllocHGlobal(64),
.SerialNumber = Marshal.AllocHGlobal(16)
}
Dim dlg As EeReadDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_Read, IntPtr), GetType(EeReadDelegate)), EeReadDelegate)
Dim status As FT_STATUS = dlg(FtHandle, programData)
ee232b.Manufacturer = Marshal.PtrToStringAnsi(programData.Manufacturer)
ee232b.ManufacturerID = Marshal.PtrToStringAnsi(programData.ManufacturerID)
ee232b.Description = Marshal.PtrToStringAnsi(programData.Description)
ee232b.SerialNumber = Marshal.PtrToStringAnsi(programData.SerialNumber)
Marshal.FreeHGlobal(programData.Manufacturer)
Marshal.FreeHGlobal(programData.ManufacturerID)
Marshal.FreeHGlobal(programData.Description)
Marshal.FreeHGlobal(programData.SerialNumber)
CheckErrors(status) 'статус проверяем после выгрузки всех неуправляемых ресурсов
ee232b.VendorID = programData.VendorID
ee232b.ProductID = programData.ProductID
ee232b.MaxPower = programData.MaxPower
ee232b.SelfPowered = Convert.ToBoolean(programData.SelfPowered)
ee232b.RemoteWakeup = Convert.ToBoolean(programData.RemoteWakeup)
ee232b.PullDownEnable = Convert.ToBoolean(programData.PullDownEnable)
ee232b.SerNumEnable = Convert.ToBoolean(programData.SerNumEnable)
ee232b.USBVersionEnable = Convert.ToBoolean(programData.USBVersionEnable)
ee232b.USBVersion = programData.USBVersion
Return ee232b
End Function
Private Function ReadFt2232Eeprom() As FT2232_EEPROM_STRUCTURE
Dim ee2232 As New FT2232_EEPROM_STRUCTURE()
Dim programData As New FT_PROGRAM_DATA() With {
.Signature1 = 0UI,
.Signature2 = UInteger.MaxValue,
.Version = 2UI,
.Manufacturer = Marshal.AllocHGlobal(32),
.ManufacturerID = Marshal.AllocHGlobal(16),
.Description = Marshal.AllocHGlobal(64),
.SerialNumber = Marshal.AllocHGlobal(16)
}
Dim dlg As EeReadDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_Read, IntPtr), GetType(EeReadDelegate)), EeReadDelegate)
Dim status As FT_STATUS = dlg.Invoke(FtHandle, programData)
ee2232.Manufacturer = Marshal.PtrToStringAnsi(programData.Manufacturer)
ee2232.ManufacturerID = Marshal.PtrToStringAnsi(programData.ManufacturerID)
ee2232.Description = Marshal.PtrToStringAnsi(programData.Description)
ee2232.SerialNumber = Marshal.PtrToStringAnsi(programData.SerialNumber)
Marshal.FreeHGlobal(programData.Manufacturer)
Marshal.FreeHGlobal(programData.ManufacturerID)
Marshal.FreeHGlobal(programData.Description)
Marshal.FreeHGlobal(programData.SerialNumber)
CheckErrors(status) 'статус проверяем после выгрузки всех неуправляемых ресурсов
ee2232.VendorID = programData.VendorID
ee2232.ProductID = programData.ProductID
ee2232.MaxPower = programData.MaxPower
ee2232.SelfPowered = Convert.ToBoolean(programData.SelfPowered)
ee2232.RemoteWakeup = Convert.ToBoolean(programData.RemoteWakeup)
ee2232.PullDownEnable = Convert.ToBoolean(programData.PullDownEnable5)
ee2232.SerNumEnable = Convert.ToBoolean(programData.SerNumEnable5)
ee2232.USBVersionEnable = Convert.ToBoolean(programData.USBVersionEnable5)
ee2232.USBVersion = programData.USBVersion5
ee2232.AIsHighCurrent = Convert.ToBoolean(programData.AIsHighCurrent)
ee2232.BIsHighCurrent = Convert.ToBoolean(programData.BIsHighCurrent)
ee2232.IFAIsFifo = Convert.ToBoolean(programData.IFAIsFifo)
ee2232.IFAIsFifoTar = Convert.ToBoolean(programData.IFAIsFifoTar)
ee2232.IFAIsFastSer = Convert.ToBoolean(programData.IFAIsFastSer)
ee2232.AIsVCP = Convert.ToBoolean(programData.AIsVCP)
ee2232.IFBIsFifo = Convert.ToBoolean(programData.IFBIsFifo)
ee2232.IFBIsFifoTar = Convert.ToBoolean(programData.IFBIsFifoTar)
ee2232.IFBIsFastSer = Convert.ToBoolean(programData.IFBIsFastSer)
ee2232.BIsVCP = Convert.ToBoolean(programData.BIsVCP)
Return ee2232
End Function
Private Function ReadFt232rEeprom() As FT232R_EEPROM_STRUCTURE
Dim ee232r As New FT232R_EEPROM_STRUCTURE()
Dim programData As New FT_PROGRAM_DATA() With {
.Signature1 = 0UI,
.Signature2 = UInteger.MaxValue,
.Version = 2UI,
.Manufacturer = Marshal.AllocHGlobal(32),
.ManufacturerID = Marshal.AllocHGlobal(16),
.Description = Marshal.AllocHGlobal(64),
.SerialNumber = Marshal.AllocHGlobal(16)
}
Dim rdDlg As EeReadDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_Read, IntPtr), GetType(EeReadDelegate)), EeReadDelegate)
Dim status As FT_STATUS = rdDlg(FtHandle, programData)
ee232r.Manufacturer = Marshal.PtrToStringAnsi(programData.Manufacturer)
ee232r.ManufacturerID = Marshal.PtrToStringAnsi(programData.ManufacturerID)
ee232r.Description = Marshal.PtrToStringAnsi(programData.Description)
ee232r.SerialNumber = Marshal.PtrToStringAnsi(programData.SerialNumber)
Marshal.FreeHGlobal(programData.Manufacturer)
Marshal.FreeHGlobal(programData.ManufacturerID)
Marshal.FreeHGlobal(programData.Description)
Marshal.FreeHGlobal(programData.SerialNumber)
CheckErrors(status) 'статус проверяем после выгрузки всех неуправляемых ресурсов
ee232r.VendorID = programData.VendorID
ee232r.ProductID = programData.ProductID
ee232r.MaxPower = programData.MaxPower
ee232r.SelfPowered = Convert.ToBoolean(programData.SelfPowered)
ee232r.RemoteWakeup = Convert.ToBoolean(programData.RemoteWakeup)
ee232r.UseExtOsc = Convert.ToBoolean(programData.UseExtOsc)
ee232r.HighDriveIOs = Convert.ToBoolean(programData.HighDriveIOs)
ee232r.EndpointSize = programData.EndpointSize
ee232r.PullDownEnable = Convert.ToBoolean(programData.PullDownEnableR)
ee232r.SerNumEnable = Convert.ToBoolean(programData.SerNumEnableR)
ee232r.InvertTXD = Convert.ToBoolean(programData.InvertTXD)
ee232r.InvertRXD = Convert.ToBoolean(programData.InvertRXD)
ee232r.InvertRTS = Convert.ToBoolean(programData.InvertRTS)
ee232r.InvertCTS = Convert.ToBoolean(programData.InvertCTS)
ee232r.InvertDTR = Convert.ToBoolean(programData.InvertDTR)
ee232r.InvertDSR = Convert.ToBoolean(programData.InvertDSR)
ee232r.InvertDCD = Convert.ToBoolean(programData.InvertDCD)
ee232r.InvertRI = Convert.ToBoolean(programData.InvertRI)
ee232r.Cbus0 = programData.Cbus0
ee232r.Cbus1 = programData.Cbus1
ee232r.Cbus2 = programData.Cbus2
ee232r.Cbus3 = programData.Cbus3
ee232r.Cbus4 = programData.Cbus4
ee232r.RIsD2XX = Convert.ToBoolean(programData.RIsD2XX)
Return ee232r
End Function
Private Function ReadFt2232hEeprom() As FT2232H_EEPROM_STRUCTURE
Dim ee2232h As New FT2232H_EEPROM_STRUCTURE()
Dim programData As New FT_PROGRAM_DATA() With {
.Signature1 = 0UI,
.Signature2 = UInteger.MaxValue,
.Version = 3UI,
.Manufacturer = Marshal.AllocHGlobal(32),
.ManufacturerID = Marshal.AllocHGlobal(16),
.Description = Marshal.AllocHGlobal(64),
.SerialNumber = Marshal.AllocHGlobal(16)
}
Dim dlg As EeReadDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_Read, IntPtr), GetType(EeReadDelegate)), EeReadDelegate)
Dim status As FT_STATUS = dlg(FtHandle, programData)
ee2232h.Manufacturer = Marshal.PtrToStringAnsi(programData.Manufacturer)
ee2232h.ManufacturerID = Marshal.PtrToStringAnsi(programData.ManufacturerID)
ee2232h.Description = Marshal.PtrToStringAnsi(programData.Description)
ee2232h.SerialNumber = Marshal.PtrToStringAnsi(programData.SerialNumber)
Marshal.FreeHGlobal(programData.Manufacturer)
Marshal.FreeHGlobal(programData.ManufacturerID)
Marshal.FreeHGlobal(programData.Description)
Marshal.FreeHGlobal(programData.SerialNumber)
CheckErrors(status) 'статус проверяем после выгрузки всех неуправляемых ресурсов
ee2232h.VendorID = programData.VendorID
ee2232h.ProductID = programData.ProductID
ee2232h.MaxPower = programData.MaxPower
ee2232h.SelfPowered = Convert.ToBoolean(programData.SelfPowered)
ee2232h.RemoteWakeup = Convert.ToBoolean(programData.RemoteWakeup)
ee2232h.PullDownEnable = Convert.ToBoolean(programData.PullDownEnable7)
ee2232h.SerNumEnable = Convert.ToBoolean(programData.SerNumEnable7)
ee2232h.ALSlowSlew = Convert.ToBoolean(programData.ALSlowSlew)
ee2232h.ALSchmittInput = Convert.ToBoolean(programData.ALSchmittInput)
ee2232h.ALDriveCurrent = programData.ALDriveCurrent
ee2232h.AHSlowSlew = Convert.ToBoolean(programData.AHSlowSlew)
ee2232h.AHSchmittInput = Convert.ToBoolean(programData.AHSchmittInput)
ee2232h.AHDriveCurrent = programData.AHDriveCurrent
ee2232h.BLSlowSlew = Convert.ToBoolean(programData.BLSlowSlew)
ee2232h.BLSchmittInput = Convert.ToBoolean(programData.BLSchmittInput)
ee2232h.BLDriveCurrent = programData.BLDriveCurrent
ee2232h.BHSlowSlew = Convert.ToBoolean(programData.BHSlowSlew)
ee2232h.BHSchmittInput = Convert.ToBoolean(programData.BHSchmittInput)
ee2232h.BHDriveCurrent = programData.BHDriveCurrent
ee2232h.IFAIsFifo = Convert.ToBoolean(programData.IFAIsFifo7)
ee2232h.IFAIsFifoTar = Convert.ToBoolean(programData.IFAIsFifoTar7)
ee2232h.IFAIsFastSer = Convert.ToBoolean(programData.IFAIsFastSer7)
ee2232h.AIsVCP = Convert.ToBoolean(programData.AIsVCP7)
ee2232h.IFBIsFifo = Convert.ToBoolean(programData.IFBIsFifo7)
ee2232h.IFBIsFifoTar = Convert.ToBoolean(programData.IFBIsFifoTar7)
ee2232h.IFBIsFastSer = Convert.ToBoolean(programData.IFBIsFastSer7)
ee2232h.BIsVCP = Convert.ToBoolean(programData.BIsVCP7)
ee2232h.PowerSaveEnable = Convert.ToBoolean(programData.PowerSaveEnable)
Return ee2232h
End Function
Private Function ReadFt4232hEeprom() As FT4232H_EEPROM_STRUCTURE
Dim ee4232h As New FT4232H_EEPROM_STRUCTURE()
Dim programData As New FT_PROGRAM_DATA() With {
.Signature1 = 0UI,
.Signature2 = UInteger.MaxValue,
.Version = 4UI,
.Manufacturer = Marshal.AllocHGlobal(32),
.ManufacturerID = Marshal.AllocHGlobal(16),
.Description = Marshal.AllocHGlobal(64),
.SerialNumber = Marshal.AllocHGlobal(16)
}
Dim dlg As EeReadDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_Read, IntPtr), GetType(EeReadDelegate)), EeReadDelegate)
Dim status As FT_STATUS = dlg(FtHandle, programData)
ee4232h.Manufacturer = Marshal.PtrToStringAnsi(programData.Manufacturer)
ee4232h.ManufacturerID = Marshal.PtrToStringAnsi(programData.ManufacturerID)
ee4232h.Description = Marshal.PtrToStringAnsi(programData.Description)
ee4232h.SerialNumber = Marshal.PtrToStringAnsi(programData.SerialNumber)
Marshal.FreeHGlobal(programData.Manufacturer)
Marshal.FreeHGlobal(programData.ManufacturerID)
Marshal.FreeHGlobal(programData.Description)
Marshal.FreeHGlobal(programData.SerialNumber)
CheckErrors(status) 'статус проверяем после выгрузки всех неуправляемых ресурсов
ee4232h.VendorID = programData.VendorID
ee4232h.ProductID = programData.ProductID
ee4232h.MaxPower = programData.MaxPower
ee4232h.SelfPowered = Convert.ToBoolean(programData.SelfPowered)
ee4232h.RemoteWakeup = Convert.ToBoolean(programData.RemoteWakeup)
ee4232h.PullDownEnable = Convert.ToBoolean(programData.PullDownEnable8)
ee4232h.SerNumEnable = Convert.ToBoolean(programData.SerNumEnable8)
ee4232h.ASlowSlew = Convert.ToBoolean(programData.ASlowSlew)
ee4232h.ASchmittInput = Convert.ToBoolean(programData.ASchmittInput)
ee4232h.ADriveCurrent = programData.ADriveCurrent
ee4232h.BSlowSlew = Convert.ToBoolean(programData.BSlowSlew)
ee4232h.BSchmittInput = Convert.ToBoolean(programData.BSchmittInput)
ee4232h.BDriveCurrent = programData.BDriveCurrent
ee4232h.CSlowSlew = Convert.ToBoolean(programData.CSlowSlew)
ee4232h.CSchmittInput = Convert.ToBoolean(programData.CSchmittInput)
ee4232h.CDriveCurrent = programData.CDriveCurrent
ee4232h.DSlowSlew = Convert.ToBoolean(programData.DSlowSlew)
ee4232h.DSchmittInput = Convert.ToBoolean(programData.DSchmittInput)
ee4232h.DDriveCurrent = programData.DDriveCurrent
ee4232h.ARIIsTXDEN = Convert.ToBoolean(programData.ARIIsTXDEN)
ee4232h.BRIIsTXDEN = Convert.ToBoolean(programData.BRIIsTXDEN)
ee4232h.CRIIsTXDEN = Convert.ToBoolean(programData.CRIIsTXDEN)
ee4232h.DRIIsTXDEN = Convert.ToBoolean(programData.DRIIsTXDEN)
ee4232h.AIsVCP = Convert.ToBoolean(programData.AIsVCP8)
ee4232h.BIsVCP = Convert.ToBoolean(programData.BIsVCP8)
ee4232h.CIsVCP = Convert.ToBoolean(programData.CIsVCP8)
ee4232h.DIsVCP = Convert.ToBoolean(programData.DIsVCP8)
Return ee4232h
End Function
Private Function ReadFt232hEeprom() As FT232H_EEPROM_STRUCTURE
Dim ee232h As New FT232H_EEPROM_STRUCTURE()
Dim programData As New FT_PROGRAM_DATA() With {
.Signature1 = 0UI,
.Signature2 = UInteger.MaxValue,
.Version = 5UI,
.Manufacturer = Marshal.AllocHGlobal(32),
.ManufacturerID = Marshal.AllocHGlobal(16),
.Description = Marshal.AllocHGlobal(64),
.SerialNumber = Marshal.AllocHGlobal(16)
}
Dim dlg As EeReadDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(PFt_EE_Read), GetType(EeReadDelegate)), EeReadDelegate)
Dim status As FT_STATUS = dlg(FtHandle, programData)
ee232h.Manufacturer = Marshal.PtrToStringAnsi(programData.Manufacturer)
ee232h.ManufacturerID = Marshal.PtrToStringAnsi(programData.ManufacturerID)
ee232h.Description = Marshal.PtrToStringAnsi(programData.Description)
ee232h.SerialNumber = Marshal.PtrToStringAnsi(programData.SerialNumber)
Marshal.FreeHGlobal(programData.Manufacturer)
Marshal.FreeHGlobal(programData.ManufacturerID)
Marshal.FreeHGlobal(programData.Description)
Marshal.FreeHGlobal(programData.SerialNumber)
CheckErrors(status) 'статус проверяем после выгрузки всех неуправляемых ресурсов
ee232h.VendorID = programData.VendorID
ee232h.ProductID = programData.ProductID
ee232h.MaxPower = programData.MaxPower
ee232h.SelfPowered = Convert.ToBoolean(programData.SelfPowered)
ee232h.RemoteWakeup = Convert.ToBoolean(programData.RemoteWakeup)
ee232h.PullDownEnable = Convert.ToBoolean(programData.PullDownEnableH)
ee232h.SerNumEnable = Convert.ToBoolean(programData.SerNumEnableH)
ee232h.ACSlowSlew = Convert.ToBoolean(programData.ACSlowSlewH)
ee232h.ACSchmittInput = Convert.ToBoolean(programData.ACSchmittInputH)
ee232h.ACDriveCurrent = programData.ACDriveCurrentH
ee232h.ADSlowSlew = Convert.ToBoolean(programData.ADSlowSlewH)
ee232h.ADSchmittInput = Convert.ToBoolean(programData.ADSchmittInputH)
ee232h.ADDriveCurrent = programData.ADDriveCurrentH
ee232h.Cbus0 = CType(programData.Cbus0H, FT_232H_CBUS_OPTIONS)
ee232h.Cbus1 = CType(programData.Cbus1H, FT_232H_CBUS_OPTIONS)
ee232h.Cbus2 = CType(programData.Cbus2H, FT_232H_CBUS_OPTIONS)
ee232h.Cbus3 = CType(programData.Cbus3H, FT_232H_CBUS_OPTIONS)
ee232h.Cbus4 = CType(programData.Cbus4H, FT_232H_CBUS_OPTIONS)
ee232h.Cbus5 = CType(programData.Cbus5H, FT_232H_CBUS_OPTIONS)
ee232h.Cbus6 = CType(programData.Cbus6H, FT_232H_CBUS_OPTIONS)
ee232h.Cbus7 = CType(programData.Cbus7H, FT_232H_CBUS_OPTIONS)
ee232h.Cbus8 = CType(programData.Cbus8H, FT_232H_CBUS_OPTIONS)
ee232h.Cbus9 = CType(programData.Cbus9H, FT_232H_CBUS_OPTIONS)
ee232h.IsFifo = Convert.ToBoolean(programData.IsFifoH)
ee232h.IsFifoTar = Convert.ToBoolean(programData.IsFifoTarH)
ee232h.IsFastSer = Convert.ToBoolean(programData.IsFastSerH)
ee232h.IsFT1248 = Convert.ToBoolean(programData.IsFT1248H)
ee232h.FT1248Cpol = Convert.ToBoolean(programData.FT1248CpolH)
ee232h.FT1248Lsb = Convert.ToBoolean(programData.FT1248LsbH)
ee232h.FT1248FlowControl = Convert.ToBoolean(programData.FT1248FlowControlH)
ee232h.IsVCP = Convert.ToBoolean(programData.IsVCPH)
ee232h.PowerSaveEnable = Convert.ToBoolean(programData.PowerSaveEnableH)
Return ee232h
End Function
Private Function ReadXSeriesEeprom() As FT_XSERIES_EEPROM_STRUCTURE
Dim eeX As New FT_XSERIES_EEPROM_STRUCTURE()
Dim header As New FT_EEPROM_HEADER() With {.DeviceType = FT_DEVICE.FT_DEVICE_X_SERIES}
Dim programData As New FT_XSERIES_DATA() With {.common = header}
Dim strSize As Integer = Marshal.SizeOf(programData)
Dim intPtr As IntPtr = Marshal.AllocHGlobal(strSize)
Marshal.StructureToPtr(programData, intPtr, False)
Dim man As Byte() = New Byte(31) {}
Dim id As Byte() = New Byte(15) {}
Dim descr As Byte() = New Byte(63) {}
Dim sn As Byte() = New Byte(15) {}
Dim dlg As EepromReadDelegate = CType(Marshal.GetDelegateForFunctionPointer(New IntPtr(PFt_EEPROM_Read), GetType(EepromReadDelegate)), EepromReadDelegate)
Dim status As FT_STATUS = dlg.Invoke(FtHandle, intPtr, CUInt(strSize), man, id, descr, sn)
programData = CType(Marshal.PtrToStructure(intPtr, GetType(FT_XSERIES_DATA)), FT_XSERIES_DATA)
Dim utf8Encoding As New UTF8Encoding()
eeX.Manufacturer = utf8Encoding.GetString(man)
eeX.ManufacturerID = utf8Encoding.GetString(id)
eeX.Description = utf8Encoding.GetString(descr)
eeX.SerialNumber = utf8Encoding.GetString(sn)
eeX.VendorID = programData.common.VendorId
eeX.ProductID = programData.common.ProductId
eeX.MaxPower = programData.common.MaxPower
eeX.SelfPowered = Convert.ToBoolean(programData.common.SelfPowered)
eeX.RemoteWakeup = Convert.ToBoolean(programData.common.RemoteWakeup)
eeX.SerNumEnable = Convert.ToBoolean(programData.common.SerNumEnable)
eeX.PullDownEnable = Convert.ToBoolean(programData.common.PullDownEnable)
eeX.Cbus0 = CType(programData.Cbus0, FT_XSERIES_CBUS_OPTIONS)
eeX.Cbus1 = CType(programData.Cbus1, FT_XSERIES_CBUS_OPTIONS)
eeX.Cbus2 = CType(programData.Cbus2, FT_XSERIES_CBUS_OPTIONS)
eeX.Cbus3 = CType(programData.Cbus3, FT_XSERIES_CBUS_OPTIONS)
eeX.Cbus4 = CType(programData.Cbus4, FT_XSERIES_CBUS_OPTIONS)
eeX.Cbus5 = CType(programData.Cbus5, FT_XSERIES_CBUS_OPTIONS)
eeX.Cbus6 = CType(programData.Cbus6, FT_XSERIES_CBUS_OPTIONS)
eeX.ACDriveCurrent = programData.ACDriveCurrent
eeX.ACSchmittInput = programData.ACSchmittInput
eeX.ACSlowSlew = programData.ACSlowSlew
eeX.ADDriveCurrent = programData.ADDriveCurrent
eeX.ADSchmittInput = programData.ADSchmittInput
eeX.ADSlowSlew = programData.ADSlowSlew
eeX.BCDDisableSleep = programData.BCDDisableSleep
eeX.BCDEnable = programData.BCDEnable
eeX.BCDForceCbusPWREN = programData.BCDForceCbusPWREN
eeX.FT1248Cpol = programData.FT1248Cpol
eeX.FT1248FlowControl = programData.FT1248FlowControl
eeX.FT1248Lsb = programData.FT1248Lsb
eeX.I2CDeviceId = programData.I2CDeviceId
eeX.I2CDisableSchmitt = programData.I2CDisableSchmitt
eeX.I2CSlaveAddress = programData.I2CSlaveAddress
eeX.InvertCTS = programData.InvertCTS
eeX.InvertDCD = programData.InvertDCD
eeX.InvertDSR = programData.InvertDSR
eeX.InvertDTR = programData.InvertDTR
eeX.InvertRI = programData.InvertRI
eeX.InvertRTS = programData.InvertRTS
eeX.InvertRXD = programData.InvertRXD
eeX.InvertTXD = programData.InvertTXD
eeX.PowerSaveEnable = programData.PowerSaveEnable
eeX.RS485EchoSuppress = programData.RS485EchoSuppress
eeX.IsVCP = programData.DriverType
Marshal.DestroyStructure(intPtr, GetType(FT_XSERIES_DATA))
Marshal.FreeHGlobal(intPtr)
CheckErrors(status) 'статус проверяем после выгрузки всех неуправляемых ресурсов
Return eeX
End Function
#End Region '/ЧТЕНИЕ ППЗУ
#Region "ЗАПИСЬ ППЗУ"
''' <summary>
''' Стирает ПЗУ устройства.
''' </summary>
''' <remarks>
''' Для устройств FT232R и FT245R функция недоступна.
''' </remarks>
Public Sub EraseEeprom()
If (DeviceType = FT_DEVICE.FT_DEVICE_232R) Then
CheckErrors(FT_STATUS.FT_INVALID_PARAMETER, FT_ERROR.FT_INCORRECT_DEVICE)
End If
Dim dlg As EraseEeDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EraseEE, IntPtr), GetType(EraseEeDelegate)), EraseEeDelegate)
Dim status As FT_STATUS = dlg(FtHandle)
CheckErrors(status)
End Sub
''' <summary>
''' Записывает в ПЗУ по заданному адресу <paramref name="address"/> слово данных <paramref name="value"/>.
''' </summary>
Public Sub WriteEeprom(address As UInteger, value As UShort)
Dim dlg As WriteEeDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_WriteEE, IntPtr), GetType(WriteEeDelegate)), WriteEeDelegate)
Dim status As FT_STATUS = dlg(FtHandle, address, value)
CheckErrors(status)
End Sub
''' <summary>
''' Записывает заданную конфигурацию <paramref name="data"/> в ПЗУ микросхемы FTDI.
''' </summary>
Public Sub WriteEeprom(data As FT_EEPROM_DATA)
Select Case DeviceType
Case FT_DEVICE.FT_DEVICE_BM
WriteFt232bEeprom(CType(data, FT232B_EEPROM_STRUCTURE))
Case FT_DEVICE.FT_DEVICE_2232
WriteFt2232Eeprom(CType(data, FT2232_EEPROM_STRUCTURE))
Case FT_DEVICE.FT_DEVICE_232R
WriteFt232rEeprom(CType(data, FT232R_EEPROM_STRUCTURE))
Case FT_DEVICE.FT_DEVICE_2232H
WriteFt2232hEeprom(CType(data, FT2232H_EEPROM_STRUCTURE))
Case FT_DEVICE.FT_DEVICE_4232H
WriteFt4232hEeprom(CType(data, FT4232H_EEPROM_STRUCTURE))
Case FT_DEVICE.FT_DEVICE_232H
WriteFt232hEeprom(CType(data, FT232H_EEPROM_STRUCTURE))
Case FT_DEVICE.FT_DEVICE_X_SERIES
WriteXSeriesEeprom(CType(data, FT_XSERIES_EEPROM_STRUCTURE))
Case Else
CheckErrors(FT_STATUS.FT_OTHER_ERROR, FT_ERROR.FT_INCORRECT_DEVICE)
End Select
End Sub
Private Sub WriteFt232bEeprom(ee232b As FT232B_EEPROM_STRUCTURE)
Dim status As FT_STATUS = FT_STATUS.FT_OTHER_ERROR
If (ee232b.VendorID = 0US) OrElse (ee232b.ProductID = 0US) Then
CheckErrors(FT_STATUS.FT_INVALID_PARAMETER)
End If
If (ee232b.Manufacturer.Length > 32) Then
ee232b.Manufacturer = ee232b.Manufacturer.Substring(0, 32)
End If
If (ee232b.ManufacturerID.Length > 16) Then
ee232b.ManufacturerID = ee232b.ManufacturerID.Substring(0, 16)
End If
If (ee232b.Description.Length > 64) Then
ee232b.Description = ee232b.Description.Substring(0, 64)
End If
If (ee232b.SerialNumber.Length > 16) Then
ee232b.SerialNumber = ee232b.SerialNumber.Substring(0, 16)
End If
Dim programData As New FT_PROGRAM_DATA() With {
.Signature1 = 0UI,
.Signature2 = UInteger.MaxValue,
.Version = 2UI,
.Manufacturer = Marshal.AllocHGlobal(32),
.ManufacturerID = Marshal.AllocHGlobal(16),
.Description = Marshal.AllocHGlobal(64),
.SerialNumber = Marshal.AllocHGlobal(16),
.VendorID = ee232b.VendorID,
.ProductID = ee232b.ProductID,
.MaxPower = ee232b.MaxPower,
.SelfPowered = Convert.ToUInt16(ee232b.SelfPowered),
.RemoteWakeup = Convert.ToUInt16(ee232b.RemoteWakeup),
.Rev4 = Convert.ToByte(True),
.PullDownEnable = Convert.ToByte(ee232b.PullDownEnable),
.SerNumEnable = Convert.ToByte(ee232b.SerNumEnable),
.USBVersionEnable = Convert.ToByte(ee232b.USBVersionEnable),
.USBVersion = ee232b.USBVersion
}
programData.Manufacturer = Marshal.StringToHGlobalAnsi(ee232b.Manufacturer)
programData.ManufacturerID = Marshal.StringToHGlobalAnsi(ee232b.ManufacturerID)
programData.Description = Marshal.StringToHGlobalAnsi(ee232b.Description)
programData.SerialNumber = Marshal.StringToHGlobalAnsi(ee232b.SerialNumber)
Dim dlg As EeProgramDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_Program, IntPtr), GetType(EeProgramDelegate)), EeProgramDelegate)
status = dlg(FtHandle, programData)
Marshal.FreeHGlobal(programData.Manufacturer)
Marshal.FreeHGlobal(programData.ManufacturerID)
Marshal.FreeHGlobal(programData.Description)
Marshal.FreeHGlobal(programData.SerialNumber)
CheckErrors(status) 'статус проверяем после освобождения всех неуправляемых ресурсов
End Sub
Private Sub WriteFt2232Eeprom(ee2232 As FT2232_EEPROM_STRUCTURE)
Dim status As FT_STATUS = FT_STATUS.FT_OTHER_ERROR
If (ee2232.VendorID = 0US) OrElse (ee2232.ProductID = 0US) Then
CheckErrors(FT_STATUS.FT_INVALID_PARAMETER)
End If
If (ee2232.Manufacturer.Length > 32) Then
ee2232.Manufacturer = ee2232.Manufacturer.Substring(0, 32)
End If
If (ee2232.ManufacturerID.Length > 16) Then
ee2232.ManufacturerID = ee2232.ManufacturerID.Substring(0, 16)
End If
If (ee2232.Description.Length > 64) Then
ee2232.Description = ee2232.Description.Substring(0, 64)
End If
If (ee2232.SerialNumber.Length > 16) Then
ee2232.SerialNumber = ee2232.SerialNumber.Substring(0, 16)
End If
Dim programData As New FT_PROGRAM_DATA() With {
.Signature1 = 0UI,
.Signature2 = UInteger.MaxValue,
.Version = 2UI,
.Manufacturer = Marshal.AllocHGlobal(32),
.ManufacturerID = Marshal.AllocHGlobal(16),
.Description = Marshal.AllocHGlobal(64),
.SerialNumber = Marshal.AllocHGlobal(16),
.VendorID = ee2232.VendorID,
.ProductID = ee2232.ProductID,
.MaxPower = ee2232.MaxPower,
.SelfPowered = Convert.ToUInt16(ee2232.SelfPowered),
.RemoteWakeup = Convert.ToUInt16(ee2232.RemoteWakeup),
.Rev5 = Convert.ToByte(True),
.PullDownEnable5 = Convert.ToByte(ee2232.PullDownEnable),
.SerNumEnable5 = Convert.ToByte(ee2232.SerNumEnable),
.USBVersionEnable5 = Convert.ToByte(ee2232.USBVersionEnable),
.USBVersion5 = ee2232.USBVersion,
.AIsHighCurrent = Convert.ToByte(ee2232.AIsHighCurrent),
.BIsHighCurrent = Convert.ToByte(ee2232.BIsHighCurrent),
.IFAIsFifo = Convert.ToByte(ee2232.IFAIsFifo),
.IFAIsFifoTar = Convert.ToByte(ee2232.IFAIsFifoTar),
.IFAIsFastSer = Convert.ToByte(ee2232.IFAIsFastSer),
.AIsVCP = Convert.ToByte(ee2232.AIsVCP),
.IFBIsFifo = Convert.ToByte(ee2232.IFBIsFifo),
.IFBIsFifoTar = Convert.ToByte(ee2232.IFBIsFifoTar),
.IFBIsFastSer = Convert.ToByte(ee2232.IFBIsFastSer),
.BIsVCP = Convert.ToByte(ee2232.BIsVCP)
}
programData.Manufacturer = Marshal.StringToHGlobalAnsi(ee2232.Manufacturer)
programData.ManufacturerID = Marshal.StringToHGlobalAnsi(ee2232.ManufacturerID)
programData.Description = Marshal.StringToHGlobalAnsi(ee2232.Description)
programData.SerialNumber = Marshal.StringToHGlobalAnsi(ee2232.SerialNumber)
Dim dlg As EeProgramDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_Program, IntPtr), GetType(EeProgramDelegate)), EeProgramDelegate)
status = dlg(FtHandle, programData)
Marshal.FreeHGlobal(programData.Manufacturer)
Marshal.FreeHGlobal(programData.ManufacturerID)
Marshal.FreeHGlobal(programData.Description)
Marshal.FreeHGlobal(programData.SerialNumber)
CheckErrors(status) 'статус проверяем после освобождения всех неуправляемых ресурсов
End Sub
Private Sub WriteFt232rEeprom(ee232r As FT232R_EEPROM_STRUCTURE)
Dim status As FT_STATUS = FT_STATUS.FT_OTHER_ERROR
If (ee232r.VendorID = 0US) OrElse (ee232r.ProductID = 0US) Then
CheckErrors(FT_STATUS.FT_INVALID_PARAMETER)
End If
If (ee232r.Manufacturer.Length > 32) Then
ee232r.Manufacturer = ee232r.Manufacturer.Substring(0, 32)
End If
If (ee232r.ManufacturerID.Length > 16) Then
ee232r.ManufacturerID = ee232r.ManufacturerID.Substring(0, 16)
End If
If (ee232r.Description.Length > 64) Then
ee232r.Description = ee232r.Description.Substring(0, 64)
End If
If (ee232r.SerialNumber.Length > 16) Then
ee232r.SerialNumber = ee232r.SerialNumber.Substring(0, 16)
End If
Dim programData As New FT_PROGRAM_DATA() With {
.Signature1 = 0UI,
.Signature2 = UInteger.MaxValue,
.Version = 2UI,
.Manufacturer = Marshal.AllocHGlobal(32),
.ManufacturerID = Marshal.AllocHGlobal(16),
.Description = Marshal.AllocHGlobal(64),
.SerialNumber = Marshal.AllocHGlobal(16),
.VendorID = ee232r.VendorID,
.ProductID = ee232r.ProductID,
.MaxPower = ee232r.MaxPower,
.SelfPowered = Convert.ToUInt16(ee232r.SelfPowered),
.RemoteWakeup = Convert.ToUInt16(ee232r.RemoteWakeup),
.PullDownEnableR = Convert.ToByte(ee232r.PullDownEnable),
.SerNumEnableR = Convert.ToByte(ee232r.SerNumEnable),
.UseExtOsc = Convert.ToByte(ee232r.UseExtOsc),
.HighDriveIOs = Convert.ToByte(ee232r.HighDriveIOs),
.EndpointSize = 64,
.InvertTXD = Convert.ToByte(ee232r.InvertTXD),
.InvertRXD = Convert.ToByte(ee232r.InvertRXD),
.InvertRTS = Convert.ToByte(ee232r.InvertRTS),
.InvertCTS = Convert.ToByte(ee232r.InvertCTS),
.InvertDTR = Convert.ToByte(ee232r.InvertDTR),
.InvertDSR = Convert.ToByte(ee232r.InvertDSR),
.InvertDCD = Convert.ToByte(ee232r.InvertDCD),
.InvertRI = Convert.ToByte(ee232r.InvertRI),
.Cbus0 = ee232r.Cbus0,
.Cbus1 = ee232r.Cbus1,
.Cbus2 = ee232r.Cbus2,
.Cbus3 = ee232r.Cbus3,
.Cbus4 = ee232r.Cbus4,
.RIsD2XX = Convert.ToByte(ee232r.RIsD2XX)
}
programData.Manufacturer = Marshal.StringToHGlobalAnsi(ee232r.Manufacturer)
programData.ManufacturerID = Marshal.StringToHGlobalAnsi(ee232r.ManufacturerID)
programData.Description = Marshal.StringToHGlobalAnsi(ee232r.Description)
programData.SerialNumber = Marshal.StringToHGlobalAnsi(ee232r.SerialNumber)
Dim dlg As EeProgramDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_Program, IntPtr), GetType(EeProgramDelegate)), EeProgramDelegate)
status = dlg(FtHandle, programData)
Marshal.FreeHGlobal(programData.Manufacturer)
Marshal.FreeHGlobal(programData.ManufacturerID)
Marshal.FreeHGlobal(programData.Description)
Marshal.FreeHGlobal(programData.SerialNumber)
CheckErrors(status) 'статус проверяем после освобождения всех неуправляемых ресурсов
End Sub
Private Sub WriteFt2232hEeprom(ee2232h As FT2232H_EEPROM_STRUCTURE)
Dim status As FT_STATUS = FT_STATUS.FT_OTHER_ERROR
If (ee2232h.VendorID = 0US) OrElse (ee2232h.ProductID = 0US) Then
CheckErrors(FT_STATUS.FT_INVALID_PARAMETER)
End If
If (ee2232h.Manufacturer.Length > 32) Then
ee2232h.Manufacturer = ee2232h.Manufacturer.Substring(0, 32)
End If
If (ee2232h.ManufacturerID.Length > 16) Then
ee2232h.ManufacturerID = ee2232h.ManufacturerID.Substring(0, 16)
End If
If (ee2232h.Description.Length > 64) Then
ee2232h.Description = ee2232h.Description.Substring(0, 64)
End If
If (ee2232h.SerialNumber.Length > 16) Then
ee2232h.SerialNumber = ee2232h.SerialNumber.Substring(0, 16)
End If
Dim programData As New FT_PROGRAM_DATA() With {
.Signature1 = 0UI,
.Signature2 = UInteger.MaxValue,
.Version = 3UI,
.Manufacturer = Marshal.AllocHGlobal(32),
.ManufacturerID = Marshal.AllocHGlobal(16),
.Description = Marshal.AllocHGlobal(64),
.SerialNumber = Marshal.AllocHGlobal(16),
.VendorID = ee2232h.VendorID,
.ProductID = ee2232h.ProductID,
.MaxPower = ee2232h.MaxPower,
.SelfPowered = Convert.ToUInt16(ee2232h.SelfPowered),
.RemoteWakeup = Convert.ToUInt16(ee2232h.RemoteWakeup),
.PullDownEnable7 = Convert.ToByte(ee2232h.PullDownEnable),
.SerNumEnable7 = Convert.ToByte(ee2232h.SerNumEnable),
.ALSlowSlew = Convert.ToByte(ee2232h.ALSlowSlew),
.ALSchmittInput = Convert.ToByte(ee2232h.ALSchmittInput),
.ALDriveCurrent = ee2232h.ALDriveCurrent,
.AHSlowSlew = Convert.ToByte(ee2232h.AHSlowSlew),
.AHSchmittInput = Convert.ToByte(ee2232h.AHSchmittInput),
.AHDriveCurrent = ee2232h.AHDriveCurrent,
.BLSlowSlew = Convert.ToByte(ee2232h.BLSlowSlew),
.BLSchmittInput = Convert.ToByte(ee2232h.BLSchmittInput),
.BLDriveCurrent = ee2232h.BLDriveCurrent,
.BHSlowSlew = Convert.ToByte(ee2232h.BHSlowSlew),
.BHSchmittInput = Convert.ToByte(ee2232h.BHSchmittInput),
.BHDriveCurrent = ee2232h.BHDriveCurrent,
.IFAIsFifo7 = Convert.ToByte(ee2232h.IFAIsFifo),
.IFAIsFifoTar7 = Convert.ToByte(ee2232h.IFAIsFifoTar),
.IFAIsFastSer7 = Convert.ToByte(ee2232h.IFAIsFastSer),
.AIsVCP7 = Convert.ToByte(ee2232h.AIsVCP),
.IFBIsFifo7 = Convert.ToByte(ee2232h.IFBIsFifo),
.IFBIsFifoTar7 = Convert.ToByte(ee2232h.IFBIsFifoTar),
.IFBIsFastSer7 = Convert.ToByte(ee2232h.IFBIsFastSer),
.BIsVCP7 = Convert.ToByte(ee2232h.BIsVCP),
.PowerSaveEnable = Convert.ToByte(ee2232h.PowerSaveEnable)
}
programData.Manufacturer = Marshal.StringToHGlobalAnsi(ee2232h.Manufacturer)
programData.ManufacturerID = Marshal.StringToHGlobalAnsi(ee2232h.ManufacturerID)
programData.Description = Marshal.StringToHGlobalAnsi(ee2232h.Description)
programData.SerialNumber = Marshal.StringToHGlobalAnsi(ee2232h.SerialNumber)
Dim dlg As EeProgramDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_Program, IntPtr), GetType(EeProgramDelegate)), EeProgramDelegate)
status = dlg(FtHandle, programData)
Marshal.FreeHGlobal(programData.Manufacturer)
Marshal.FreeHGlobal(programData.ManufacturerID)
Marshal.FreeHGlobal(programData.Description)
Marshal.FreeHGlobal(programData.SerialNumber)
CheckErrors(status) 'статус проверяем после освобождения всех неуправляемых ресурсов
End Sub
Private Sub WriteFt4232hEeprom(ee4232h As FT4232H_EEPROM_STRUCTURE)
Dim status As FT_STATUS = FT_STATUS.FT_OTHER_ERROR
If (ee4232h.VendorID = 0US) OrElse (ee4232h.ProductID = 0US) Then
CheckErrors(FT_STATUS.FT_INVALID_PARAMETER)
End If
If (ee4232h.Manufacturer.Length > 32) Then
ee4232h.Manufacturer = ee4232h.Manufacturer.Substring(0, 32)
End If
If (ee4232h.ManufacturerID.Length > 16) Then
ee4232h.ManufacturerID = ee4232h.ManufacturerID.Substring(0, 16)
End If
If (ee4232h.Description.Length > 64) Then
ee4232h.Description = ee4232h.Description.Substring(0, 64)
End If
If (ee4232h.SerialNumber.Length > 16) Then
ee4232h.SerialNumber = ee4232h.SerialNumber.Substring(0, 16)
End If
Dim programData As New FT_PROGRAM_DATA() With {
.Signature1 = 0UI,
.Signature2 = UInteger.MaxValue,
.Version = 4UI,
.Manufacturer = Marshal.AllocHGlobal(32),
.ManufacturerID = Marshal.AllocHGlobal(16),
.Description = Marshal.AllocHGlobal(64),
.SerialNumber = Marshal.AllocHGlobal(16),
.VendorID = ee4232h.VendorID,
.ProductID = ee4232h.ProductID,
.MaxPower = ee4232h.MaxPower,
.SelfPowered = Convert.ToUInt16(ee4232h.SelfPowered),
.RemoteWakeup = Convert.ToUInt16(ee4232h.RemoteWakeup),
.PullDownEnable8 = Convert.ToByte(ee4232h.PullDownEnable),
.SerNumEnable8 = Convert.ToByte(ee4232h.SerNumEnable),
.ASlowSlew = Convert.ToByte(ee4232h.ASlowSlew),
.ASchmittInput = Convert.ToByte(ee4232h.ASchmittInput),
.ADriveCurrent = ee4232h.ADriveCurrent,
.BSlowSlew = Convert.ToByte(ee4232h.BSlowSlew),
.BSchmittInput = Convert.ToByte(ee4232h.BSchmittInput),
.BDriveCurrent = ee4232h.BDriveCurrent,
.CSlowSlew = Convert.ToByte(ee4232h.CSlowSlew),
.CSchmittInput = Convert.ToByte(ee4232h.CSchmittInput),
.CDriveCurrent = ee4232h.CDriveCurrent,
.DSlowSlew = Convert.ToByte(ee4232h.DSlowSlew),
.DSchmittInput = Convert.ToByte(ee4232h.DSchmittInput),
.DDriveCurrent = ee4232h.DDriveCurrent,
.ARIIsTXDEN = Convert.ToByte(ee4232h.ARIIsTXDEN),
.BRIIsTXDEN = Convert.ToByte(ee4232h.BRIIsTXDEN),
.CRIIsTXDEN = Convert.ToByte(ee4232h.CRIIsTXDEN),
.DRIIsTXDEN = Convert.ToByte(ee4232h.DRIIsTXDEN),
.AIsVCP8 = Convert.ToByte(ee4232h.AIsVCP),
.BIsVCP8 = Convert.ToByte(ee4232h.BIsVCP),
.CIsVCP8 = Convert.ToByte(ee4232h.CIsVCP),
.DIsVCP8 = Convert.ToByte(ee4232h.DIsVCP)
}
programData.Manufacturer = Marshal.StringToHGlobalAnsi(ee4232h.Manufacturer)
programData.ManufacturerID = Marshal.StringToHGlobalAnsi(ee4232h.ManufacturerID)
programData.Description = Marshal.StringToHGlobalAnsi(ee4232h.Description)
programData.SerialNumber = Marshal.StringToHGlobalAnsi(ee4232h.SerialNumber)
Dim dlg As EeProgramDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_Program, IntPtr), GetType(EeProgramDelegate)), EeProgramDelegate)
status = dlg(FtHandle, programData)
Marshal.FreeHGlobal(programData.Manufacturer)
Marshal.FreeHGlobal(programData.ManufacturerID)
Marshal.FreeHGlobal(programData.Description)
Marshal.FreeHGlobal(programData.SerialNumber)
CheckErrors(status) 'статус проверяем после освобождения всех неуправляемых ресурсов
End Sub
Private Sub WriteFt232hEeprom(ee232h As FT232H_EEPROM_STRUCTURE)
Dim status As FT_STATUS = FT_STATUS.FT_OTHER_ERROR
If (ee232h.VendorID = 0US) OrElse (ee232h.ProductID = 0US) Then
CheckErrors(FT_STATUS.FT_INVALID_PARAMETER)
End If
If (ee232h.Manufacturer.Length > 32) Then
ee232h.Manufacturer = ee232h.Manufacturer.Substring(0, 32)
End If
If (ee232h.ManufacturerID.Length > 16) Then
ee232h.ManufacturerID = ee232h.ManufacturerID.Substring(0, 16)
End If
If (ee232h.Description.Length > 64) Then
ee232h.Description = ee232h.Description.Substring(0, 64)
End If
If (ee232h.SerialNumber.Length > 16) Then
ee232h.SerialNumber = ee232h.SerialNumber.Substring(0, 16)
End If
Dim programData As New FT_PROGRAM_DATA() With {
.Signature1 = 0UI,
.Signature2 = UInteger.MaxValue,
.Version = 5UI,
.Manufacturer = Marshal.AllocHGlobal(32),
.ManufacturerID = Marshal.AllocHGlobal(16),
.Description = Marshal.AllocHGlobal(64),
.SerialNumber = Marshal.AllocHGlobal(16),
.VendorID = ee232h.VendorID,
.ProductID = ee232h.ProductID,
.MaxPower = ee232h.MaxPower,
.SelfPowered = Convert.ToUInt16(ee232h.SelfPowered),
.RemoteWakeup = Convert.ToUInt16(ee232h.RemoteWakeup),
.PullDownEnableH = Convert.ToByte(ee232h.PullDownEnable),
.SerNumEnableH = Convert.ToByte(ee232h.SerNumEnable),
.ACSlowSlewH = Convert.ToByte(ee232h.ACSlowSlew),
.ACSchmittInputH = Convert.ToByte(ee232h.ACSchmittInput),
.ACDriveCurrentH = ee232h.ACDriveCurrent,
.ADSlowSlewH = Convert.ToByte(ee232h.ADSlowSlew),
.ADSchmittInputH = Convert.ToByte(ee232h.ADSchmittInput),
.ADDriveCurrentH = ee232h.ADDriveCurrent,
.Cbus0H = CType(ee232h.Cbus0, FT_CBUS_OPTIONS),
.Cbus1H = CType(ee232h.Cbus1, FT_CBUS_OPTIONS),
.Cbus2H = CType(ee232h.Cbus2, FT_CBUS_OPTIONS),
.Cbus3H = CType(ee232h.Cbus3, FT_CBUS_OPTIONS),
.Cbus4H = CType(ee232h.Cbus4, FT_CBUS_OPTIONS),
.Cbus5H = CType(ee232h.Cbus5, FT_CBUS_OPTIONS),
.Cbus6H = CType(ee232h.Cbus6, FT_CBUS_OPTIONS),
.Cbus7H = CType(ee232h.Cbus7, FT_CBUS_OPTIONS),
.Cbus8H = CType(ee232h.Cbus8, FT_CBUS_OPTIONS),
.Cbus9H = CType(ee232h.Cbus9, FT_CBUS_OPTIONS),
.IsFifoH = Convert.ToByte(ee232h.IsFifo),
.IsFifoTarH = Convert.ToByte(ee232h.IsFifoTar),
.IsFastSerH = Convert.ToByte(ee232h.IsFastSer),
.IsFT1248H = Convert.ToByte(ee232h.IsFT1248),
.FT1248CpolH = Convert.ToByte(ee232h.FT1248Cpol),
.FT1248LsbH = Convert.ToByte(ee232h.FT1248Lsb),
.FT1248FlowControlH = Convert.ToByte(ee232h.FT1248FlowControl),
.IsVCPH = Convert.ToByte(ee232h.IsVCP),
.PowerSaveEnableH = Convert.ToByte(ee232h.PowerSaveEnable)
}
programData.Manufacturer = Marshal.StringToHGlobalAnsi(ee232h.Manufacturer)
programData.ManufacturerID = Marshal.StringToHGlobalAnsi(ee232h.ManufacturerID)
programData.Description = Marshal.StringToHGlobalAnsi(ee232h.Description)
programData.SerialNumber = Marshal.StringToHGlobalAnsi(ee232h.SerialNumber)
Dim dlg As EeProgramDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_Program, IntPtr), GetType(EeProgramDelegate)), EeProgramDelegate)
status = dlg(FtHandle, programData)
Marshal.FreeHGlobal(programData.Manufacturer)
Marshal.FreeHGlobal(programData.ManufacturerID)
Marshal.FreeHGlobal(programData.Description)
Marshal.FreeHGlobal(programData.SerialNumber)
CheckErrors(status) 'статус проверяем после освобождения всех неуправляемых ресурсов
End Sub
Private Sub WriteXSeriesEeprom(eeX As FT_XSERIES_EEPROM_STRUCTURE)
Dim status As FT_STATUS = FT_STATUS.FT_OTHER_ERROR
If (eeX.VendorID = 0US) OrElse (eeX.ProductID = 0US) Then
CheckErrors(FT_STATUS.FT_INVALID_PARAMETER)
End If
If (eeX.Manufacturer.Length > 32) Then
eeX.Manufacturer = eeX.Manufacturer.Substring(0, 32)
End If
If (eeX.ManufacturerID.Length > 16) Then
eeX.ManufacturerID = eeX.ManufacturerID.Substring(0, 16)
End If
If (eeX.Description.Length > 64) Then
eeX.Description = eeX.Description.Substring(0, 64)
End If
If (eeX.SerialNumber.Length > 16) Then
eeX.SerialNumber = eeX.SerialNumber.Substring(0, 16)
End If
Dim programData As New FT_XSERIES_DATA() With {
.Cbus0 = CType(eeX.Cbus0, FT_CBUS_OPTIONS),
.Cbus1 = CType(eeX.Cbus1, FT_CBUS_OPTIONS),
.Cbus2 = CType(eeX.Cbus2, FT_CBUS_OPTIONS),
.Cbus3 = CType(eeX.Cbus3, FT_CBUS_OPTIONS),
.Cbus4 = CType(eeX.Cbus4, FT_CBUS_OPTIONS),
.Cbus5 = CType(eeX.Cbus5, FT_CBUS_OPTIONS),
.Cbus6 = CType(eeX.Cbus6, FT_CBUS_OPTIONS),
.ACDriveCurrent = eeX.ACDriveCurrent,
.ACSchmittInput = eeX.ACSchmittInput,
.ACSlowSlew = eeX.ACSlowSlew,
.ADDriveCurrent = eeX.ADDriveCurrent,
.ADSchmittInput = eeX.ADSchmittInput,
.ADSlowSlew = eeX.ADSlowSlew,
.BCDDisableSleep = eeX.BCDDisableSleep,
.BCDEnable = eeX.BCDEnable,
.BCDForceCbusPWREN = eeX.BCDForceCbusPWREN,
.FT1248Cpol = eeX.FT1248Cpol,
.FT1248FlowControl = eeX.FT1248FlowControl,
.FT1248Lsb = eeX.FT1248Lsb,
.I2CDeviceId = eeX.I2CDeviceId,
.I2CDisableSchmitt = eeX.I2CDisableSchmitt,
.I2CSlaveAddress = eeX.I2CSlaveAddress,
.InvertCTS = eeX.InvertCTS,
.InvertDCD = eeX.InvertDCD,
.InvertDSR = eeX.InvertDSR,
.InvertDTR = eeX.InvertDTR,
.InvertRI = eeX.InvertRI,
.InvertRTS = eeX.InvertRTS,
.InvertRXD = eeX.InvertRXD,
.InvertTXD = eeX.InvertTXD,
.PowerSaveEnable = eeX.PowerSaveEnable,
.RS485EchoSuppress = eeX.RS485EchoSuppress,
.DriverType = eeX.IsVCP
}
programData.Common.DeviceType = FT_DEVICE.FT_DEVICE_X_SERIES
programData.Common.VendorId = eeX.VendorID
programData.Common.ProductId = eeX.ProductID
programData.Common.MaxPower = eeX.MaxPower
programData.Common.SelfPowered = Convert.ToByte(eeX.SelfPowered)
programData.Common.RemoteWakeup = Convert.ToByte(eeX.RemoteWakeup)
programData.Common.SerNumEnable = Convert.ToByte(eeX.SerNumEnable)
programData.Common.PullDownEnable = Convert.ToByte(eeX.PullDownEnable)
Dim utf8Encoding As UTF8Encoding = New UTF8Encoding()
Dim manufacturer As Byte() = utf8Encoding.GetBytes(eeX.Manufacturer)
Dim manufacturerID As Byte() = utf8Encoding.GetBytes(eeX.ManufacturerID)
Dim description As Byte() = utf8Encoding.GetBytes(eeX.Description)
Dim serialnumber As Byte() = utf8Encoding.GetBytes(eeX.SerialNumber)
Dim programDataSize As Integer = Marshal.SizeOf(programData)
Dim ptr As IntPtr = Marshal.AllocHGlobal(programDataSize)
Marshal.StructureToPtr(programData, ptr, False)
Dim dlg As EepromProgramDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EEPROM_Program, IntPtr), GetType(EepromProgramDelegate)), EepromProgramDelegate)
status = dlg(FtHandle, ptr, CUInt(programDataSize), manufacturer, manufacturerID, description, serialnumber)
CheckErrors(status) 'статус проверяем после освобождения всех неуправляемых ресурсов
End Sub
#End Region '/ЗАПИСЬ ППЗУ
#Region "ПОЛЬЗОВАТЕЛЬСКАЯ ОБЛАСТЬ ППЗУ FTDI"
''' <summary>
''' Размер пользовательской области ПЗУ в байтах.
''' </summary>
Public ReadOnly Property UserAreaSize As Integer
Get
If (_UserAreaSize = NOT_INIT) Then
Dim uaSize As UInteger
Dim dlg As EeUaSizeDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_UASize, IntPtr), GetType(EeUaSizeDelegate)), EeUaSizeDelegate)
Dim status As FT_STATUS = dlg(FtHandle, uaSize)
CheckErrors(status)
_UserAreaSize = CInt(uaSize)
End If
Return _UserAreaSize
End Get
End Property
Private _UserAreaSize As Integer = NOT_INIT
''' <summary>
''' Читает данные пользовательской области ПЗУ.
''' </summary>
Public Function ReadUserArea() As Byte()
Dim userAreaDataBuffer As Byte() = New Byte() {}
Dim bufSize As UInteger = 0UI
Dim dlg As EeUaSizeDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_UASize, IntPtr), GetType(EeUaSizeDelegate)), EeUaSizeDelegate)
Dim status As FT_STATUS = dlg(FtHandle, bufSize)
ReDim userAreaDataBuffer(CInt(bufSize - 1))
If (userAreaDataBuffer.Length >= bufSize) Then
Dim numBytesWereRead As UInteger = 0
Dim rdDlg As EeUaReadDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_UARead, IntPtr), GetType(EeUaReadDelegate)), EeUaReadDelegate)
status = status Or rdDlg(FtHandle, userAreaDataBuffer, userAreaDataBuffer.Length, numBytesWereRead)
End If
CheckErrors(status)
Return userAreaDataBuffer
End Function
''' <summary>
''' Записывает данные в пользовательскую область ПЗУ.
''' </summary>
Public Sub WriteUserArea(data As Byte())
Dim bufSize As UInteger = 0UI
Dim dlg As EeUaSizeDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_UASize, IntPtr), GetType(EeUaSizeDelegate)), EeUaSizeDelegate)
Dim status As FT_STATUS = dlg(FtHandle, bufSize)
If (data.Length <= bufSize) Then
Dim wDlg As EeUaWriteDelegate = CType(Marshal.GetDelegateForFunctionPointer(CType(PFt_EE_UAWrite, IntPtr), GetType(EeUaWriteDelegate)), EeUaWriteDelegate)
status = status Or wDlg(FtHandle, data, data.Length)
End If
CheckErrors(status)
End Sub
#End Region '/ПОЛЬЗОВАТЕЛЬСКАЯ ОБЛАСТЬ ППЗУ FTDI
#Region "СТРУКТУРЫ ОБЪЕКТОВ В ППЗУ FTDI"
<StructLayout(LayoutKind.Sequential, Pack:=4)>
Private Structure FT_PROGRAM_DATA
Public Signature1 As UInteger
Public Signature2 As UInteger
Public Version As UInteger
Public VendorID As UShort
Public ProductID As UShort
Public Manufacturer As IntPtr
Public ManufacturerID As IntPtr
Public Description As IntPtr
Public SerialNumber As IntPtr
Public MaxPower As UShort
Public PnP As UShort
Public SelfPowered As UShort
Public RemoteWakeup As UShort
'FT232B extensions
Public Rev4 As Byte
Public IsoIn As Byte
Public IsoOut As Byte
Public PullDownEnable As Byte
Public SerNumEnable As Byte
Public USBVersionEnable As Byte
Public USBVersion As USB_VERSION
'FT2232D extensions
Public Rev5 As Byte
Public IsoInA As Byte
Public IsoInB As Byte
Public IsoOutA As Byte
Public IsoOutB As Byte
Public PullDownEnable5 As Byte
Public SerNumEnable5 As Byte
Public USBVersionEnable5 As Byte
Public USBVersion5 As USB_VERSION
Public AIsHighCurrent As Byte
Public BIsHighCurrent As Byte
Public IFAIsFifo As Byte
Public IFAIsFifoTar As Byte
Public IFAIsFastSer As Byte
Public AIsVCP As Byte
Public IFBIsFifo As Byte
Public IFBIsFifoTar As Byte
Public IFBIsFastSer As Byte
'FT232R extensions
Public BIsVCP As Byte
Public UseExtOsc As Byte
Public HighDriveIOs As Byte
Public EndpointSize As Byte
Public PullDownEnableR As Byte
Public SerNumEnableR As Byte
Public InvertTXD As Byte 'non-zero if invert TXD
Public InvertRXD As Byte 'non-zero if invert RXD
Public InvertRTS As Byte 'non-zero if invert RTS
Public InvertCTS As Byte 'non-zero if invert CTS
Public InvertDTR As Byte 'non-zero if invert DTR
Public InvertDSR As Byte 'non-zero if invert DSR
Public InvertDCD As Byte 'non-zero if invert DCD
Public InvertRI As Byte 'non-zero if invert RI
Public Cbus0 As FT_CBUS_OPTIONS 'Cbus Mux control - Ignored for FT245R
Public Cbus1 As FT_CBUS_OPTIONS 'Cbus Mux control - Ignored for FT245R
Public Cbus2 As FT_CBUS_OPTIONS 'Cbus Mux control - Ignored for FT245R
Public Cbus3 As FT_CBUS_OPTIONS 'Cbus Mux control - Ignored for FT245R
Public Cbus4 As FT_CBUS_OPTIONS 'Cbus Mux control - Ignored for FT245R
Public RIsD2XX As Byte 'Default to loading VCP
'FT2232H extensions
Public PullDownEnable7 As Byte
Public SerNumEnable7 As Byte
Public ALSlowSlew As Byte 'non-zero if AL pins have slow slew
Public ALSchmittInput As Byte 'non-zero if AL pins are Schmitt input
Public ALDriveCurrent As FT_DRIVE_CURRENT
Public AHSlowSlew As Byte 'non-zero if AH pins have slow slew
Public AHSchmittInput As Byte 'non-zero if AH pins are Schmitt input
Public AHDriveCurrent As FT_DRIVE_CURRENT
Public BLSlowSlew As Byte 'non-zero if BL pins have slow slew
Public BLSchmittInput As Byte 'non-zero if BL pins are Schmitt input
Public BLDriveCurrent As FT_DRIVE_CURRENT
Public BHSlowSlew As Byte 'non-zero if BH pins have slow slew
Public BHSchmittInput As Byte 'non-zero if BH pins are Schmitt input
Public BHDriveCurrent As FT_DRIVE_CURRENT
Public IFAIsFifo7 As Byte 'non-zero if interface is 245 FIFO
Public IFAIsFifoTar7 As Byte 'non-zero if interface is 245 FIFO CPU target
Public IFAIsFastSer7 As Byte 'non-zero if interface is Fast serial
Public AIsVCP7 As Byte 'non-zero if interface is to use VCP drivers
Public IFBIsFifo7 As Byte 'non-zero if interface is 245 FIFO
Public IFBIsFifoTar7 As Byte 'non-zero if interface is 245 FIFO CPU target
Public IFBIsFastSer7 As Byte 'non-zero if interface is Fast serial
Public BIsVCP7 As Byte 'non-zero if interface is to use VCP drivers
Public PowerSaveEnable As Byte 'non-zero if using BCBUS7 to save power for self-powered designs
'FT4232H extensions
Public PullDownEnable8 As Byte
Public SerNumEnable8 As Byte
Public ASlowSlew As Byte 'non-zero if AL pins have slow slew
Public ASchmittInput As Byte 'non-zero if AL pins are Schmitt input
Public ADriveCurrent As FT_DRIVE_CURRENT
Public BSlowSlew As Byte 'non-zero if AH pins have slow slew
Public BSchmittInput As Byte 'non-zero if AH pins are Schmitt input
Public BDriveCurrent As FT_DRIVE_CURRENT
Public CSlowSlew As Byte 'non-zero if BL pins have slow slew
Public CSchmittInput As Byte 'non-zero if BL pins are Schmitt input
Public CDriveCurrent As FT_DRIVE_CURRENT
Public DSlowSlew As Byte 'non-zero if BH pins have slow slew
Public DSchmittInput As Byte 'non-zero if BH pins are Schmitt input
Public DDriveCurrent As FT_DRIVE_CURRENT
Public ARIIsTXDEN As Byte
Public BRIIsTXDEN As Byte
Public CRIIsTXDEN As Byte
Public DRIIsTXDEN As Byte
Public AIsVCP8 As Byte 'non-zero if interface is to use VCP drivers
Public BIsVCP8 As Byte 'non-zero if interface is to use VCP drivers
Public CIsVCP8 As Byte 'non-zero if interface is to use VCP drivers
Public DIsVCP8 As Byte 'non-zero if interface is to use VCP drivers
'FT232H extensions
Public PullDownEnableH As Byte 'non-zero if pull down enabled
Public SerNumEnableH As Byte 'non-zero if serial number to be used
Public ACSlowSlewH As Byte 'non-zero if AC pins have slow slew
Public ACSchmittInputH As Byte 'non-zero if AC pins are Schmitt input
Public ACDriveCurrentH As FT_DRIVE_CURRENT
Public ADSlowSlewH As Byte 'non-zero if AD pins have slow slew
Public ADSchmittInputH As Byte 'non-zero if AD pins are Schmitt input
Public ADDriveCurrentH As FT_DRIVE_CURRENT
Public Cbus0H As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus1H As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus2H As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus3H As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus4H As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus5H As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus6H As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus7H As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus8H As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus9H As FT_CBUS_OPTIONS 'Cbus Mux control
Public IsFifoH As Byte 'non-zero if interface is 245 FIFO
Public IsFifoTarH As Byte 'non-zero if interface is 245 FIFO CPU target
Public IsFastSerH As Byte 'non-zero if interface is Fast serial
Public IsFT1248H As Byte 'non-zero if interface is FT1248
Public FT1248CpolH As Byte 'FT1248 clock polarity
Public FT1248LsbH As Byte 'FT1248 data is LSB (1) or MSB (0)
Public FT1248FlowControlH As Byte 'FT1248 flow control enable
Public IsVCPH As Byte 'non-zero if interface is to use VCP drivers
Public PowerSaveEnableH As Byte 'non-zero if using ACBUS7 to save power for self-powered designs
End Structure
<StructLayout(LayoutKind.Sequential, Pack:=4)>
Private Structure FT_EEPROM_HEADER
Public DeviceType As FT_DEVICE 'FTxxxx device type to be programmed
'Device descriptor options
Public VendorId As UShort '0x0403
Public ProductId As UShort '0x6001
Public SerNumEnable As Byte 'non-zero if serial number to be used
'Config descriptor options
''' <summary>
''' 0...500.
''' </summary>
Public MaxPower As UShort
''' <summary>
''' 1 = self powered, 0 = bus powered.
''' </summary>
Public SelfPowered As Byte
''' <summary>
''' 1 = capable, 0 = not capable.
''' </summary>
Public RemoteWakeup As Byte
'Hardware options
Public PullDownEnable As Byte 'non-zero if pull down in suspend enabled
End Structure
<StructLayout(LayoutKind.Sequential, Pack:=4)>
Private Structure FT_XSERIES_DATA
Public Common As FT_EEPROM_HEADER
Public ACSlowSlew As Byte 'non-zero if AC bus pins have slow slew
Public ACSchmittInput As Byte 'non-zero if AC bus pins are Schmitt input
Public ACDriveCurrent As FT_DRIVE_CURRENT
Public ADSlowSlew As Byte 'non-zero if AD bus pins have slow slew
Public ADSchmittInput As Byte 'non-zero if AD bus pins are Schmitt input
Public ADDriveCurrent As FT_DRIVE_CURRENT
'CBUS options
Public Cbus0 As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus1 As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus2 As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus3 As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus4 As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus5 As FT_CBUS_OPTIONS 'Cbus Mux control
Public Cbus6 As FT_CBUS_OPTIONS 'Cbus Mux control
'UART signal options
Public InvertTXD As Byte 'non-zero if invert TXD
Public InvertRXD As Byte 'non-zero if invert RXD
Public InvertRTS As Byte 'non-zero if invert RTS
Public InvertCTS As Byte 'non-zero if invert CTS
Public InvertDTR As Byte 'non-zero if invert DTR
Public InvertDSR As Byte 'non-zero if invert DSR
Public InvertDCD As Byte 'non-zero if invert DCD
Public InvertRI As Byte ' non-zero if invert RI
' Battery Charge Detect options
''' <summary>
''' Enable Battery Charger Detection.
''' </summary>
Public BCDEnable As Byte
''' <summary>
''' Asserts the power enable signal on CBUS when charging port detected.
''' </summary>
Public BCDForceCbusPWREN As Byte
''' <summary>
''' Forces the device never to go into sleep mode.
''' </summary>
Public BCDDisableSleep As Byte
' I2C options
''' <summary>
''' I2C slave device address.
''' </summary>
Public I2CSlaveAddress As UShort
''' <summary>
''' I2C device ID.
''' </summary>
Public I2CDeviceId As UInteger
''' <summary>
''' Disable I2C Schmitt trigger.
''' </summary>
Public I2CDisableSchmitt As Byte
' FT1248 options
''' <summary>
''' FT1248 clock polarity - clock idle high (1) or clock idle low (0)
''' </summary>
Public FT1248Cpol As Byte
''' <summary>
''' FT1248 data is LSB (1) or MSB (0).
''' </summary>
Public FT1248Lsb As Byte
''' <summary>
''' FT1248 flow control enable.
''' </summary>
Public FT1248FlowControl As Byte
'Hardware options
Public RS485EchoSuppress As Byte
Public PowerSaveEnable As Byte
'Driver option
Public DriverType As Byte
End Structure
Public Class FT_EEPROM_DATA
Public VendorID As UShort = &H403US
Public ProductID As UShort = &H6001US
Public Manufacturer As String = "FTDI"
''' <summary>
''' Аббревиатура производителя, которая используется как префикс в автоматически генерируемых серийных номерах.
''' </summary>
Public ManufacturerID As String = "FT"
Public Description As String = "USB-Serial Converter"
Public SerialNumber As String = ""
''' <summary>
''' Максимальная мощность, требующаяся устройству.
''' </summary>
Public MaxPower As UShort = &H90
''' <summary>
''' Показывает, устройство имеет свой собственный источник питания (self-powered) или берёт питание от USB порта (bus-powered).
''' </summary>
Public SelfPowered As Boolean
''' <summary>
''' Определяет, может ли устройство выводить ПК из режима ожидания, переключая линию RI.
''' </summary>
Public RemoteWakeup As Boolean
End Class
Public Class FT232B_EEPROM_STRUCTURE : Inherits FT_EEPROM_DATA
''' <summary>
''' Определяет, притянуты ли выводы IO, когда устройство в режиме ожидания.
''' </summary>
Public PullDownEnable As Boolean
''' <summary>
''' Используется ли серийный номер.
''' </summary>
Public SerNumEnable As Boolean = True
''' <summary>
''' Determines if the USB version number is enabled.
''' </summary>
Public USBVersionEnable As Boolean = True
''' <summary>
''' The USB version number.
''' </summary>
Public USBVersion As USB_VERSION = USB_VERSION.VER_20
End Class
Public Class FT2232_EEPROM_STRUCTURE : Inherits FT_EEPROM_DATA
''' <summary>
''' Определяет, притянуты ли выводы IO, когда устройство в режиме ожидания.
''' </summary>
Public PullDownEnable As Boolean
''' <summary>
''' Determines if the serial number is enabled.
''' </summary>
Public SerNumEnable As Boolean = True
''' <summary>
''' Determines if the USB version number is enabled.
''' </summary>
Public USBVersionEnable As Boolean = True
''' <summary>
''' The USB version number.
''' </summary>
Public USBVersion As USB_VERSION = USB_VERSION.VER_20
''' <summary>
''' Enables high current IOs on channel A.
''' </summary>
Public AIsHighCurrent As Boolean
''' <summary>
''' Enables high current IOs on channel B.
''' </summary>
Public BIsHighCurrent As Boolean
''' <summary>
''' Determines if channel A is in FIFO mode.
''' </summary>
Public IFAIsFifo As Boolean
''' <summary>
''' Determines if channel A is in FIFO target mode.
''' </summary>
Public IFAIsFifoTar As Boolean
''' <summary>
''' Determines if channel A is in fast serial mode.
''' </summary>
Public IFAIsFastSer As Boolean
''' <summary>
''' Determines if channel A loads the VCP driver.
''' </summary>
Public AIsVCP As Boolean = True
''' <summary>
''' Determines if channel B is in FIFO mode.
''' </summary>
Public IFBIsFifo As Boolean
''' <summary>
''' Determines if channel B is in FIFO target mode.
''' </summary>
Public IFBIsFifoTar As Boolean
''' <summary>
''' Determines if channel B is in fast serial mode.
''' </summary>
Public IFBIsFastSer As Boolean
''' <summary>
''' Determines if channel B loads the VCP driver.
''' </summary>
Public BIsVCP As Boolean = True
End Class
''' <summary>
''' EEPROM для FT232R и FT245R.
''' </summary>
Public Class FT232R_EEPROM_STRUCTURE : Inherits FT_EEPROM_DATA
''' <summary>
''' Disables the FT232R internal clock source.
''' If the device has external oscillator enabled it must have an external oscillator fitted to function.
''' </summary>
Public UseExtOsc As Boolean
''' <summary>
''' Enables high current IOs.
''' </summary>
Public HighDriveIOs As Boolean
''' <summary>
''' Sets the endpoint size. This should always be set to 64.
''' </summary>
Public EndpointSize As Byte = 64
''' <summary>
''' Determines if IOs are pulled down when the device is in suspend.
''' </summary>
Public PullDownEnable As Boolean
''' <summary>
''' Determines if the serial number is enabled.
''' </summary>
Public SerNumEnable As Boolean = True
''' <summary>
''' Inverts the sense of the TXD line.
''' </summary>
Public InvertTXD As Boolean
''' <summary>
''' Inverts the sense of the RXD line.
''' </summary>
Public InvertRXD As Boolean
''' <summary>
''' Inverts the sense of the RTS line.
''' </summary>
Public InvertRTS As Boolean
''' <summary>
''' Inverts the sense of the CTS line.
''' </summary>
Public InvertCTS As Boolean
''' <summary>
''' Inverts the sense of the DTR line.
''' </summary>
Public InvertDTR As Boolean
''' <summary>
''' Inverts the sense of the DSR line.
''' </summary>
Public InvertDSR As Boolean
''' <summary>
''' Inverts the sense of the DCD line.
''' </summary>
Public InvertDCD As Boolean
''' <summary>
''' Inverts the sense of the RI line.
''' </summary>
Public InvertRI As Boolean
Public Cbus0 As FT_CBUS_OPTIONS = FT_CBUS_OPTIONS.FT_CBUS_SLEEP
Public Cbus1 As FT_CBUS_OPTIONS = FT_CBUS_OPTIONS.FT_CBUS_SLEEP
Public Cbus2 As FT_CBUS_OPTIONS = FT_CBUS_OPTIONS.FT_CBUS_SLEEP
Public Cbus3 As FT_CBUS_OPTIONS = FT_CBUS_OPTIONS.FT_CBUS_SLEEP
Public Cbus4 As FT_CBUS_OPTIONS = FT_CBUS_OPTIONS.FT_CBUS_SLEEP
''' <summary>
''' Determines if the VCP driver is loaded.
''' </summary>
Public RIsD2XX As Boolean
End Class
Public Class FT2232H_EEPROM_STRUCTURE : Inherits FT_EEPROM_DATA
''' <summary>
''' Determines if IOs are pulled down when the device is in suspend.
''' </summary>
Public PullDownEnable As Boolean
''' <summary>
''' Determines if the serial number is enabled.
''' </summary>
Public SerNumEnable As Boolean = True
''' <summary>
''' Determines if AL pins have a slow slew rate.
''' </summary>
Public ALSlowSlew As Boolean
''' <summary>
''' Determines if the AL pins have a Schmitt input.
''' </summary>
Public ALSchmittInput As Boolean
''' <summary>
''' Determines the AL pins drive current in mA.
''' </summary>
Public ALDriveCurrent As FT_DRIVE_CURRENT = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA
''' <summary>
''' Determines if AH pins have a slow slew rate.
''' </summary>
Public AHSlowSlew As Boolean
''' <summary>
''' Determines if the AH pins have a Schmitt input.
''' </summary>
Public AHSchmittInput As Boolean
''' <summary>
''' Determines the AH pins drive current in mA.
''' </summary>
Public AHDriveCurrent As FT_DRIVE_CURRENT = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA
''' <summary>
''' Determines if BL pins have a slow slew rate.
''' </summary>
Public BLSlowSlew As Boolean
''' <summary>
''' Determines if the BL pins have a Schmitt input.
''' </summary>
Public BLSchmittInput As Boolean
''' <summary>
''' Determines the BL pins drive current in mA.
''' </summary>
Public BLDriveCurrent As FT_DRIVE_CURRENT = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA
''' <summary>
''' Determines if BH pins have a slow slew rate.
''' </summary>
Public BHSlowSlew As Boolean
''' <summary>
''' Determines if the BH pins have a Schmitt input.
''' </summary>
Public BHSchmittInput As Boolean
''' <summary>
''' Determines the BH pins drive current in mA.
''' </summary>
Public BHDriveCurrent As FT_DRIVE_CURRENT = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA
''' <summary>
''' Determines if channel A is in FIFO mode.
''' </summary>
Public IFAIsFifo As Boolean
''' <summary>
''' Determines if channel A is in FIFO target mode.
''' </summary>
Public IFAIsFifoTar As Boolean
''' <summary>
''' Determines if channel A is in fast serial mode.
''' </summary>
Public IFAIsFastSer As Boolean
''' <summary>
''' Determines if channel A loads the VCP driver.
''' </summary>
Public AIsVCP As Boolean = True
''' <summary>
''' Determines if channel B is in FIFO mode.
''' </summary>
Public IFBIsFifo As Boolean
''' <summary>
''' Determines if channel B is in FIFO target mode.
''' </summary>
Public IFBIsFifoTar As Boolean
''' <summary>
''' Determines if channel B is in fast serial mode.
''' </summary>
Public IFBIsFastSer As Boolean
''' <summary>
''' Determines if channel B loads the VCP driver.
''' </summary>
Public BIsVCP As Boolean = True
''' <summary>
''' For self-powered designs, keeps the FT2232H in low power state until BCBUS7 is high.
''' </summary>
Public PowerSaveEnable As Boolean
End Class
Public Class FT4232H_EEPROM_STRUCTURE : Inherits FT_EEPROM_DATA
''' <summary>
''' Determines if IOs are pulled down when the device is in suspend.
''' </summary>
Public PullDownEnable As Boolean
''' <summary>
''' Determines if the serial number is enabled.
''' </summary>
Public SerNumEnable As Boolean = True
''' <summary>
''' Determines if A pins have a slow slew rate.
''' </summary>
Public ASlowSlew As Boolean
''' <summary>
''' Determines if the A pins have a Schmitt input.
''' </summary>
Public ASchmittInput As Boolean
''' <summary>
''' Determines the A pins drive current in mA.
''' </summary>
Public ADriveCurrent As FT_DRIVE_CURRENT = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA
''' <summary>
''' Determines if B pins have a slow slew rate.
''' </summary>
Public BSlowSlew As Boolean
''' <summary>
''' Determines if the B pins have a Schmitt input.
''' </summary>
Public BSchmittInput As Boolean
''' <summary>
''' Determines the B pins drive current in mA.
''' </summary>
Public BDriveCurrent As FT_DRIVE_CURRENT = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA
''' <summary>
''' Determines if C pins have a slow slew rate.
''' </summary>
Public CSlowSlew As Boolean
''' <summary>
''' Determines if the C pins have a Schmitt input.
''' </summary>
Public CSchmittInput As Boolean
''' <summary>
''' Determines the C pins drive current in mA.
''' </summary>
Public CDriveCurrent As FT_DRIVE_CURRENT = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA
''' <summary>
''' Determines if D pins have a slow slew rate.
''' </summary>
Public DSlowSlew As Boolean
''' <summary>
''' Determines if the D pins have a Schmitt input.
''' </summary>
Public DSchmittInput As Boolean
''' <summary>
''' Determines the D pins drive current in mA.
''' </summary>
Public DDriveCurrent As FT_DRIVE_CURRENT = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA
''' <summary>
''' RI of port A acts as RS485 transmit enable (TXDEN).
''' </summary>
Public ARIIsTXDEN As Boolean
''' <summary>
''' RI of port B acts as RS485 transmit enable (TXDEN).
''' </summary>
Public BRIIsTXDEN As Boolean
''' <summary>
''' RI of port C acts as RS485 transmit enable (TXDEN).
''' </summary>
Public CRIIsTXDEN As Boolean
''' <summary>
''' RI of port D acts as RS485 transmit enable (TXDEN).
''' </summary>
Public DRIIsTXDEN As Boolean
''' <summary>
''' Determines if channel A loads the VCP driver.
''' </summary>
Public AIsVCP As Boolean = True
''' <summary>
''' Determines if channel B loads the VCP driver.
''' </summary>
Public BIsVCP As Boolean = True
''' <summary>
''' Determines if channel C loads the VCP driver.
''' </summary>
Public CIsVCP As Boolean = True
''' <summary>
''' Determines if channel D loads the VCP driver.
''' </summary>
Public DIsVCP As Boolean = True
End Class
Public Class FT232H_EEPROM_STRUCTURE : Inherits FT_EEPROM_DATA
''' <summary>
''' Determines if IOs are pulled down when the device is in suspend.
''' </summary>
Public PullDownEnable As Boolean
''' <summary>
''' Determines if the serial number is enabled.
''' </summary>
Public SerNumEnable As Boolean = True
''' <summary>
''' Determines if AC pins have a slow slew rate.
''' </summary>
Public ACSlowSlew As Boolean
''' <summary>
''' Determines if the AC pins have a Schmitt input.
''' </summary>
Public ACSchmittInput As Boolean
''' <summary>
''' Determines the AC pins drive current in mA.
''' </summary>
Public ACDriveCurrent As FT_DRIVE_CURRENT = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA
''' <summary>
''' Determines if AD pins have a slow slew rate.
''' </summary>
Public ADSlowSlew As Boolean
''' <summary>
''' Determines if the AD pins have a Schmitt input.
''' </summary>
Public ADSchmittInput As Boolean
''' <summary>
''' Determines the AD pins drive current in mA.
''' </summary>
Public ADDriveCurrent As FT_DRIVE_CURRENT = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA
''' <summary>
''' Sets the function of the CBUS0 pin for FT232H devices.
''' </summary>
Public Cbus0 As FT_232H_CBUS_OPTIONS = FT_232H_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS1 pin for FT232H devices.
''' </summary>
Public Cbus1 As FT_232H_CBUS_OPTIONS = FT_232H_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS2 pin for FT232H devices.
''' </summary>
Public Cbus2 As FT_232H_CBUS_OPTIONS = FT_232H_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS3 pin for FT232H devices.
''' </summary>
Public Cbus3 As FT_232H_CBUS_OPTIONS = FT_232H_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS4 pin for FT232H devices.
''' </summary>
Public Cbus4 As FT_232H_CBUS_OPTIONS = FT_232H_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS5 pin for FT232H devices.
''' </summary>
Public Cbus5 As FT_232H_CBUS_OPTIONS = FT_232H_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS6 pin for FT232H devices.
''' </summary>
Public Cbus6 As FT_232H_CBUS_OPTIONS = FT_232H_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS7 pin for FT232H devices.
''' </summary>
Public Cbus7 As FT_232H_CBUS_OPTIONS = FT_232H_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS8 pin for FT232H devices.
''' </summary>
Public Cbus8 As FT_232H_CBUS_OPTIONS = FT_232H_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS9 pin for FT232H devices.
''' </summary>
Public Cbus9 As FT_232H_CBUS_OPTIONS = FT_232H_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Determines if the device is in FIFO mode.
''' </summary>
Public IsFifo As Boolean
''' <summary>
''' Determines if the device is in FIFO target mode.
''' </summary>
Public IsFifoTar As Boolean
''' <summary>
''' Determines if the device is in fast serial mode.
''' </summary>
Public IsFastSer As Boolean
''' <summary>
''' Determines if the device is in FT1248 mode.
''' </summary>
Public IsFT1248 As Boolean
''' <summary>
''' Determines FT1248 mode clock polarity.
''' </summary>
Public FT1248Cpol As Boolean
''' <summary>
''' Determines if data is ent MSB (0) or LSB (1) in FT1248 mode.
''' </summary>
Public FT1248Lsb As Boolean
''' <summary>
''' Determines if FT1248 mode uses flow control.
''' </summary>
Public FT1248FlowControl As Boolean
''' <summary>
''' Determines if the VCP driver is loaded.
''' </summary>
Public IsVCP As Boolean = True
''' <summary>
''' For self-powered designs, keeps the FT232H in low power state until ACBUS7 is high.
''' </summary>
Public PowerSaveEnable As Boolean
End Class
Public Class FT_XSERIES_EEPROM_STRUCTURE : Inherits FT_EEPROM_DATA
''' <summary>
''' Determines if IOs are pulled down when the device Is in suspend.
''' </summary>
Public PullDownEnable As Boolean
''' <summary>
''' Determines if the serial number is enabled.
''' </summary>
Public SerNumEnable As Boolean = True
''' <summary>
''' Determines if the USB version number is enabled.
''' </summary>
Public USBVersionEnable As Boolean = True
''' <summary>
''' The USB version number.
''' </summary>
Public USBVersion As USB_VERSION = USB_VERSION.VER_20
''' <summary>
''' Determines if AC pins have a slow slew rate.
''' </summary>
Public ACSlowSlew As Byte
''' <summary>
''' Determines if the AC pins have a Schmitt input.
''' </summary>
Public ACSchmittInput As Byte
''' <summary>
''' Determines the AC pins drive current in mA.
''' </summary>
Public ACDriveCurrent As FT_DRIVE_CURRENT = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA
''' <summary>
''' Determines if AD pins have a slow slew rate.
''' </summary>
Public ADSlowSlew As Byte
''' <summary>
''' Determines if AD pins have a schmitt input.
''' </summary>
Public ADSchmittInput As Byte
''' <summary>
''' Determines the AD pins drive current in mA.
''' </summary>
Public ADDriveCurrent As FT_DRIVE_CURRENT = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA
''' <summary>
''' Sets the function of the CBUS0 pin for FT232H devices.
''' </summary>
Public Cbus0 As FT_XSERIES_CBUS_OPTIONS = FT_XSERIES_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS1 pin for FT232H devices.
''' </summary>
Public Cbus1 As FT_XSERIES_CBUS_OPTIONS = FT_XSERIES_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS2 pin for FT232H devices.
''' </summary>
Public Cbus2 As FT_XSERIES_CBUS_OPTIONS = FT_XSERIES_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS3 pin for FT232H devices.
''' </summary>
Public Cbus3 As FT_XSERIES_CBUS_OPTIONS = FT_XSERIES_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS4 pin for FT232H devices.
''' </summary>
Public Cbus4 As FT_XSERIES_CBUS_OPTIONS = FT_XSERIES_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS5 pin for FT232H devices.
''' </summary>
Public Cbus5 As FT_XSERIES_CBUS_OPTIONS = FT_XSERIES_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Sets the function of the CBUS6 pin for FT232H devices.
''' </summary>
Public Cbus6 As FT_XSERIES_CBUS_OPTIONS = FT_XSERIES_CBUS_OPTIONS.FT_CBUS_TRISTATE
''' <summary>
''' Inverts the sense of the TXD line.
''' </summary>
Public InvertTXD As Byte
''' <summary>
''' Inverts the sense of the RXD line.
''' </summary>
Public InvertRXD As Byte
''' <summary>
''' Inverts the sense of the RTS line.
''' </summary>
Public InvertRTS As Byte
''' <summary>
''' Inverts the sense of the CTS line.
''' </summary>
Public InvertCTS As Byte
''' <summary>
''' Inverts the sense of the DTR line.
''' </summary>
Public InvertDTR As Byte
''' <summary>
''' Inverts the sense of the DSR line.
''' </summary>
Public InvertDSR As Byte
''' <summary>
''' Inverts the sense of the DCD line.
''' </summary>
Public InvertDCD As Byte
''' <summary>
''' Inverts the sense of the RI line.
''' </summary>
Public InvertRI As Byte
''' <summary>
''' Determines whether the Battery Charge Detection option is enabled.
''' </summary>
Public BCDEnable As Byte
''' <summary>
''' Asserts the power enable signal on CBUS when charging port detected.
''' </summary>
Public BCDForceCbusPWREN As Byte
''' <summary>
''' Forces the device never to go into sleep mode.
''' </summary>
Public BCDDisableSleep As Byte
''' <summary>
''' I2C slave device address.
''' </summary>
Public I2CSlaveAddress As UShort
''' <summary>
''' I2C device ID.
''' </summary>
Public I2CDeviceId As UInteger
''' <summary>
''' Disable I2C Schmitt trigger.
''' </summary>
Public I2CDisableSchmitt As Byte
''' <summary>
''' FT1248 clock polarity - clock idle high (1) or clock idle low (0).
''' </summary>
Public FT1248Cpol As Byte
''' <summary>
''' FT1248 data is LSB (1) or MSB (0).
''' </summary>
Public FT1248Lsb As Byte
''' <summary>
''' FT1248 flow control enable.
''' </summary>
Public FT1248FlowControl As Byte
''' <summary>
''' Enable RS485 Echo Suppression.
''' </summary>
Public RS485EchoSuppress As Byte
''' <summary>
''' Enable Power Save mode.
''' </summary>
Public PowerSaveEnable As Byte
''' <summary>
''' Determines whether the VCP driver is loaded.
''' </summary>
Public IsVCP As Byte
End Class
#End Region '/СТРУКТУРЫ ОБЪЕКТОВ В ППЗУ FTDI
#Region "УКАЗАТЕЛИ НА ФУНКЦИИ БИБЛИОТЕКИ ДЛЯ РАБОТЫ С ППЗУ"
Private Const NOT_INIT As Integer = -1
Private Shared PFt_ReadEE As Integer = NOT_INIT
Private Shared PFt_WriteEE As Integer = NOT_INIT
Private Shared PFt_EraseEE As Integer = NOT_INIT
Private Shared PFt_EE_UASize As Integer = NOT_INIT
Private Shared PFt_EE_UARead As Integer = NOT_INIT
Private Shared PFt_EE_UAWrite As Integer = NOT_INIT
Private Shared PFt_EE_Read As Integer = NOT_INIT
Private Shared PFt_EE_Program As Integer = NOT_INIT
Private Shared PFt_EEPROM_Read As Integer = NOT_INIT
Private Shared PFt_EEPROM_Program As Integer = NOT_INIT
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function EeReadDelegate(ftHandle As Integer, ByRef pData As FT_PROGRAM_DATA) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function EeProgramDelegate(ftHandle As Integer, ByRef pData As FT_PROGRAM_DATA) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function EepromReadDelegate(ftHandle As Integer, eepromData As IntPtr, eepromDataSize As UInteger, manufacturer As Byte(), manufacturerID As Byte(), description As Byte(), serialnumber As Byte()) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function EepromProgramDelegate(ftHandle As Integer, eepromData As IntPtr, eepromDataSize As UInteger, manufacturer As Byte(), manufacturerID As Byte(), description As Byte(), serialnumber As Byte()) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function WriteEeDelegate(ftHandle As Integer, dwWordOffset As UInteger, wValue As UShort) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function EraseEeDelegate(ftHandle As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function EeUaSizeDelegate(ftHandle As Integer, ByRef dwSize As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function EeUaReadDelegate(ftHandle As Integer, pucData As Byte(), dwDataLen As Integer, ByRef lpdwDataRead As UInteger) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function EeUaWriteDelegate(ftHandle As Integer, pucData As Byte(), dwDataLen As Integer) As FT_STATUS
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Private Delegate Function ReadEeDelegate(ftHandle As Integer, dwWordOffset As UInteger, ByRef lpwValue As UShort) As FT_STATUS
Private Shared Sub FindEeFunctionPointers(ftd2xxDllHandle As Integer)
If (PFt_ReadEE = NOT_INIT) Then
PFt_ReadEE = GetProcAddress(ftd2xxDllHandle, "FT_ReadEE")
End If
If (PFt_WriteEE = NOT_INIT) Then
PFt_WriteEE = GetProcAddress(ftd2xxDllHandle, "FT_WriteEE")
End If
If (PFt_EraseEE = NOT_INIT) Then
PFt_EraseEE = GetProcAddress(ftd2xxDllHandle, "FT_EraseEE")
End If
If (PFt_EE_UASize = NOT_INIT) Then
PFt_EE_UASize = GetProcAddress(ftd2xxDllHandle, "FT_EE_UASize")
End If
If (PFt_EE_UARead = NOT_INIT) Then
PFt_EE_UARead = GetProcAddress(ftd2xxDllHandle, "FT_EE_UARead")
End If
If (PFt_EE_UAWrite = NOT_INIT) Then
PFt_EE_UAWrite = GetProcAddress(ftd2xxDllHandle, "FT_EE_UAWrite")
End If
If (PFt_EE_Read = NOT_INIT) Then
PFt_EE_Read = GetProcAddress(ftd2xxDllHandle, "FT_EE_Read")
End If
If (PFt_EE_Program = NOT_INIT) Then
PFt_EE_Program = GetProcAddress(ftd2xxDllHandle, "FT_EE_Program")
End If
If (PFt_EEPROM_Read = NOT_INIT) Then
PFt_EEPROM_Read = GetProcAddress(ftd2xxDllHandle, "FT_EEPROM_Read")
End If
If (PFt_EEPROM_Program = NOT_INIT) Then
PFt_EEPROM_Program = GetProcAddress(ftd2xxDllHandle, "FT_EEPROM_Program")
End If
End Sub
<DllImport("kernel32.dll", SetLastError:=True)>
Private Shared Function GetProcAddress(hModule As Integer, procedureName As String) As Integer
End Function
#End Region '/УКАЗАТЕЛИ НА ФУНКЦИИ БИБЛИОТЕКИ ДЛЯ РАБОТЫ С ППЗУ
#Region "ПЕРЕЧИСЛЕНИЯ"
Public Enum FT_DRIVE_CURRENT As Byte
FT_DRIVE_CURRENT_4MA = 4
FT_DRIVE_CURRENT_8MA = 8
FT_DRIVE_CURRENT_12MA = 12
FT_DRIVE_CURRENT_16MA = 16
End Enum
Public Enum FT_232H_CBUS_OPTIONS As Byte
FT_CBUS_TRISTATE = 0
FT_CBUS_RXLED = 1
FT_CBUS_TXLED = &H2
FT_CBUS_TXRXLED = &H3
FT_CBUS_PWREN = &H4
FT_CBUS_SLEEP = &H5
FT_CBUS_DRIVE_0 = &H6
FT_CBUS_DRIVE_1 = &H7
FT_CBUS_IOMODE = &H8
FT_CBUS_TXDEN = &H9
FT_CBUS_CLK30 = &HA
FT_CBUS_CLK15 = &HB
FT_CBUS_CLK7_5 = &HC
End Enum
Public Enum FT_XSERIES_CBUS_OPTIONS As Byte
FT_CBUS_TRISTATE = &H0
FT_CBUS_RXLED = &H1
FT_CBUS_TXLED = &H2
FT_CBUS_TXRXLED = &H3
FT_CBUS_PWREN = &H4
FT_CBUS_SLEEP = &H5
FT_CBUS_Drive_0 = &H6
FT_CBUS_Drive_1 = &H7
FT_CBUS_GPIO = &H8
FT_CBUS_TXDEN = &H9
FT_CBUS_CLK24MHz = &HA
FT_CBUS_CLK12MHz = &HB
FT_CBUS_CLK6MHz = &HC
FT_CBUS_BCD_Charger = &HD
FT_CBUS_BCD_Charger_N = &HE
FT_CBUS_I2C_TXE = &HF
FT_CBUS_I2C_RXF = &H10
FT_CBUS_VBUS_Sense = &H11
FT_CBUS_BitBang_WR = &H12
FT_CBUS_BitBang_RD = &H13
FT_CBUS_Time_Stamp = &H14
FT_CBUS_Keep_Awake = &H15
End Enum
Public Enum USB_VERSION As UShort
VER_11 = &H110
VER_20 = &H200
End Enum
#End Region '/ПЕРЕЧИСЛЕНИЯ
End Class '/Eeprom
End Namespace
Использовать данный класс можно, например, так:
Console.WriteLine($"Число подключённых устройств FTDI: {Ftdi.GetNumberOfDevices()}")
Using ft as New FTD2XX_NET.Ftdi(0)
Console.WriteLine("Открыто устройство с индексом 0.")
Console.WriteLine($"Описание: {ft.Description}")
Console.WriteLine($"Серийный номер: {ft.SerialNumber}")
Console.WriteLine($"Размер пользовательского ПЗУ: {ft.Eeprom.UserAreaSize} байт")
End Using
Ещё один интересный момент – использование уведомлений о событии. Например, можно задать уведомление о приходе данных на вход микросхемы FTDI:
Dim ftEvent As New AutoResetEvent(False) 'объявляем сигнальный объект ft.SetEventNotification(FT_EVENTS.FT_EVENT_RXCHAR, ftEvent) 'назначаем ему событие прихода данных
Далее где-то в коде можно подождать, пока сработает это уведомление:
If ftEvent.WaitOne() Then ...
'какая-то обработка данных
Чтобы всё работало, в системе должен быть установлен драйвер для устройства FTDI, а также в заданной директории (путь задаётся в классе Ftdi) должна находиться dll-ка FTD2XX.DLL, которую необходимо скачать с сайта производителя.
Понятно, что данный код несовершенен, и я буду его периодически обновлять. Все самые свежие обновления данного класса Ftdi будут размещаться в репозитории на GitHub.
