Класс-обёртка для работы с библиотекой 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.