PID по умолчанию для чипа серии FTDI X — 0X6015. Я использовал FT_EE_Program для PID для старого чипа 0X6001. Это сработало хорошо.
Однако эта функция не работает для нового чипа. Я использую функцию FT_EEPROM_Program, чтобы изменить PID для 0X6015. Вот мой код:
int CUsbPort::WriteEEprom_X()
{
FT_STATUS status;
m_x_series.common.VendorId = m_ftData.VendorId; // 0x0403
m_x_series.common.ProductId = m_ftData.ProductId; // 0x6015
status = FT_EEPROM_Program(m_hComm,&m_x_series, sizeof(ft_eeprom_x_series),
m_ManufacturerBuf, m_ManufacturerIdBuf, m_DescriptionBuf, m_SerialNumberBuf);
if( status != FT_OK )
return -1;
return 1;
}
Однако возвращаемое значение для состояния — FT_INVALID_PARAMETER. Пожалуйста, предоставьте предложения о том, как изменить PID. Мне удалось изменить PID с помощью утилиты FTDI FT_Prog. Я не нашел пример использования FT_EEPROM_Program.
В руководстве по программированию D2XX (FT000071) четко сказано: «По умолчанию драйвер будет поддерживать ограниченный набор VID и PID-совместимых устройств (VID 0x0403 с PID только 0x6001, 0x6010, 0x6006)» Таким образом, ваше устройство не поддерживается.
Вы найдете это утверждение в разделе замечаний всех методов, используемых FT_EEPROM_Program.
Чтобы запрограммировать ЭСППЗУ на чипе, вам нужно установить все значения в пределах m_x_series
структура, которую вы передаете FT_EEPROM_Program
, Из вашего примера кода вы можете передавать неинициализированную память в функцию программы; базовый код может проверять то, что вы отправили, и отклонять его, если значения недействительны.
Существует версия командной строки FT_Prog, которая позволит вам быстро программировать несколько чипов. Вам необходимо сгенерировать файл шаблона с новым PID, используя версию приложения с графическим интерфейсом, а затем запустить версию командной строки, передав в сгенерированный вами файл .xml.
Следующий скрипт использует FT_EE_Read()
а также FT_EE_Program()
,
FT_EE_Read()
не устанавливает Signature1
, Signature2
а также Version
,
Таким образом, они должны быть установлены до FT_EE_Program()
,
тогда нет FT_INVALID_PARAMETER
больше
#python
from cffi import FFI
class FTDIData:
""" read and write to FTDI chip
>>> ftdid = FTDIData()
>>> ftdid.VendorId = 0x1111
>>> ftdid.ProductId = 0x2222
>>> ftdid.Manufacturer = "XYZ">>> ftdid.ManufacturerId = "MI">>> ftdid.Description = "Desc">>> ftdid.SerialNumber = "SE000">>> ftdid.program()
>>> ftdid.close()
"""def __init__(self,other=None):
self.ffi = FFI()
self.ffi.cdef("""typedef struct ft_program_data {
DWORD Signature1; // Header - must be 0x00000000
DWORD Signature2; // Header - must be 0xffffffff
DWORD Version; // Header - FT_PROGRAM_DATA version
// 0 = original
// 1 = FT2232 extensions
// 2 = FT232R extensions
// 3 = FT2232H extensions
// 4 = FT4232H extensions
// 5 = FT232H extensions
WORD VendorId; // 0x0403
WORD ProductId; // 0x6001
char *Manufacturer; // "FTDI"char *ManufacturerId; // "FT"char *Description; // "USB HS Serial Converter"char *SerialNumber; // "FT000001" if fixed, or NULL
WORD MaxPower; // 0 < MaxPower <= 500
WORD PnP; // 0 = disabled, 1 = enabled
WORD SelfPowered; // 0 = bus powered, 1 = self powered
WORD RemoteWakeup; // 0 = not capable, 1 = capable
//
// Rev4 (FT232B) extensions
//
UCHAR Rev4; // non-zero if Rev4 chip, zero otherwise
UCHAR IsoIn; // non-zero if in endpoint is isochronous
UCHAR IsoOut; // non-zero if out endpoint is isochronous
UCHAR PullDownEnable; // non-zero if pull down enabled
UCHAR SerNumEnable; // non-zero if serial number to be used
UCHAR USBVersionEnable; // non-zero if chip uses USBVersion
WORD USBVersion; // BCD (0x0200 => USB2)
//
// Rev 5 (FT2232) extensions
//
UCHAR Rev5; // non-zero if Rev5 chip, zero otherwise
UCHAR IsoInA; // non-zero if in endpoint is isochronous
UCHAR IsoInB; // non-zero if in endpoint is isochronous
UCHAR IsoOutA; // non-zero if out endpoint is isochronous
UCHAR IsoOutB; // non-zero if out endpoint is isochronous
UCHAR PullDownEnable5; // non-zero if pull down enabled
UCHAR SerNumEnable5; // non-zero if serial number to be used
UCHAR USBVersionEnable5; // non-zero if chip uses USBVersion
WORD USBVersion5; // BCD (0x0200 => USB2)
UCHAR AIsHighCurrent; // non-zero if interface is high current
UCHAR BIsHighCurrent; // non-zero if interface is high current
UCHAR IFAIsFifo; // non-zero if interface is 245 FIFO
UCHAR IFAIsFifoTar; // non-zero if interface is 245 FIFO CPU target
UCHAR IFAIsFastSer; // non-zero if interface is Fast serial
UCHAR AIsVCP; // non-zero if interface is to use VCP drivers
UCHAR IFBIsFifo; // non-zero if interface is 245 FIFO
UCHAR IFBIsFifoTar; // non-zero if interface is 245 FIFO CPU target
UCHAR IFBIsFastSer; // non-zero if interface is Fast serial
UCHAR BIsVCP; // non-zero if interface is to use VCP drivers
//
// Rev 6 (FT232R) extensions
//
UCHAR UseExtOsc; // Use External Oscillator
UCHAR HighDriveIOs; // High Drive I/Os
UCHAR EndpointSize; // Endpoint size
UCHAR PullDownEnableR; // non-zero if pull down enabled
UCHAR SerNumEnableR; // non-zero if serial number to be used
UCHAR InvertTXD; // non-zero if invert TXD
UCHAR InvertRXD; // non-zero if invert RXD
UCHAR InvertRTS; // non-zero if invert RTS
UCHAR InvertCTS; // non-zero if invert CTS
UCHAR InvertDTR; // non-zero if invert DTR
UCHAR InvertDSR; // non-zero if invert DSR
UCHAR InvertDCD; // non-zero if invert DCD
UCHAR InvertRI; // non-zero if invert RI
UCHAR Cbus0; // Cbus Mux control
UCHAR Cbus1; // Cbus Mux control
UCHAR Cbus2; // Cbus Mux control
UCHAR Cbus3; // Cbus Mux control
UCHAR Cbus4; // Cbus Mux control
UCHAR RIsD2XX; // non-zero if using D2XX driver
//
// Rev 7 (FT2232H) Extensions
//
UCHAR PullDownEnable7; // non-zero if pull down enabled
UCHAR SerNumEnable7; // non-zero if serial number to be used
UCHAR ALSlowSlew; // non-zero if AL pins have slow slew
UCHAR ALSchmittInput; // non-zero if AL pins are Schmitt input
UCHAR ALDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR AHSlowSlew; // non-zero if AH pins have slow slew
UCHAR AHSchmittInput; // non-zero if AH pins are Schmitt input
UCHAR AHDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR BLSlowSlew; // non-zero if BL pins have slow slew
UCHAR BLSchmittInput; // non-zero if BL pins are Schmitt input
UCHAR BLDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR BHSlowSlew; // non-zero if BH pins have slow slew
UCHAR BHSchmittInput; // non-zero if BH pins are Schmitt input
UCHAR BHDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR IFAIsFifo7; // non-zero if interface is 245 FIFO
UCHAR IFAIsFifoTar7; // non-zero if interface is 245 FIFO CPU target
UCHAR IFAIsFastSer7; // non-zero if interface is Fast serial
UCHAR AIsVCP7; // non-zero if interface is to use VCP drivers
UCHAR IFBIsFifo7; // non-zero if interface is 245 FIFO
UCHAR IFBIsFifoTar7; // non-zero if interface is 245 FIFO CPU target
UCHAR IFBIsFastSer7; // non-zero if interface is Fast serial
UCHAR BIsVCP7; // non-zero if interface is to use VCP drivers
UCHAR PowerSaveEnable; // non-zero if using BCBUS7 to save power for self-powered designs
//
// Rev 8 (FT4232H) Extensions
//
UCHAR PullDownEnable8; // non-zero if pull down enabled
UCHAR SerNumEnable8; // non-zero if serial number to be used
UCHAR ASlowSlew; // non-zero if A pins have slow slew
UCHAR ASchmittInput; // non-zero if A pins are Schmitt input
UCHAR ADriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR BSlowSlew; // non-zero if B pins have slow slew
UCHAR BSchmittInput; // non-zero if B pins are Schmitt input
UCHAR BDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR CSlowSlew; // non-zero if C pins have slow slew
UCHAR CSchmittInput; // non-zero if C pins are Schmitt input
UCHAR CDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR DSlowSlew; // non-zero if D pins have slow slew
UCHAR DSchmittInput; // non-zero if D pins are Schmitt input
UCHAR DDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR ARIIsTXDEN; // non-zero if port A uses RI as RS485 TXDEN
UCHAR BRIIsTXDEN; // non-zero if port B uses RI as RS485 TXDEN
UCHAR CRIIsTXDEN; // non-zero if port C uses RI as RS485 TXDEN
UCHAR DRIIsTXDEN; // non-zero if port D uses RI as RS485 TXDEN
UCHAR AIsVCP8; // non-zero if interface is to use VCP drivers
UCHAR BIsVCP8; // non-zero if interface is to use VCP drivers
UCHAR CIsVCP8; // non-zero if interface is to use VCP drivers
UCHAR DIsVCP8; // non-zero if interface is to use VCP drivers
//
// Rev 9 (FT232H) Extensions
//
UCHAR PullDownEnableH; // non-zero if pull down enabled
UCHAR SerNumEnableH; // non-zero if serial number to be used
UCHAR ACSlowSlewH; // non-zero if AC pins have slow slew
UCHAR ACSchmittInputH; // non-zero if AC pins are Schmitt input
UCHAR ACDriveCurrentH; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR ADSlowSlewH; // non-zero if AD pins have slow slew
UCHAR ADSchmittInputH; // non-zero if AD pins are Schmitt input
UCHAR ADDriveCurrentH; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR Cbus0H; // Cbus Mux control
UCHAR Cbus1H; // Cbus Mux control
UCHAR Cbus2H; // Cbus Mux control
UCHAR Cbus3H; // Cbus Mux control
UCHAR Cbus4H; // Cbus Mux control
UCHAR Cbus5H; // Cbus Mux control
UCHAR Cbus6H; // Cbus Mux control
UCHAR Cbus7H; // Cbus Mux control
UCHAR Cbus8H; // Cbus Mux control
UCHAR Cbus9H; // Cbus Mux control
UCHAR IsFifoH; // non-zero if interface is 245 FIFO
UCHAR IsFifoTarH; // non-zero if interface is 245 FIFO CPU target
UCHAR IsFastSerH; // non-zero if interface is Fast serial
UCHAR IsFT1248H; // non-zero if interface is FT1248
UCHAR FT1248CpolH; // FT1248 clock polarity - clock idle high (1) or clock idle low (0)
UCHAR FT1248LsbH; // FT1248 data is LSB (1) or MSB (0)
UCHAR FT1248FlowControlH; // FT1248 flow control enable
UCHAR IsVCPH; // non-zero if interface is to use VCP drivers
UCHAR PowerSaveEnableH; // non-zero if using ACBUS7 to save power for self-powered designs
} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA;
ULONG FT_CreateDeviceInfoList(
ULONG *lpdwNumDevs
);
ULONG FT_Open(
int deviceNumber,
PVOID *pHandle
);
ULONG FT_Close(
PVOID ftHandle
);
ULONG WINAPI FT_EE_Read(
PVOID ftHandle,
PFT_PROGRAM_DATA pData
);
ULONG FT_EE_Program(
PVOID ftHandle,
PFT_PROGRAM_DATA pData
);
""")
if other:
self.ftd2xx = other.ftd2xx
self.handle = other.handle
self.data = other.data
else:
self.ftd2xx = self.ffi.dlopen("ftd2xx.dll")
pi = self.ffi.new("ULONG *")
self.ftd2xx.FT_CreateDeviceInfoList(pi)
assert pi[0] == 1, "exactly one device must hang on the PC, found "+str(pi[0])
self.handle = self.ffi.new("PVOID *")
self.ftd2xx.FT_Open(0,self.handle)
assert self.handle[0]!=self.ffi.NULL, "could not open gEstim Device"self.data = self.ffi.new("PFT_PROGRAM_DATA");
self.init_strings()
self.errors = { 0:'FT_OK',
1:'FT_INVALID_HANDLE',
2:'FT_DEVICE_NOT_FOUND',
3:'FT_DEVICE_NOT_OPENED',
4:'FT_IO_ERROR',
5:'FT_INSUFFICIENT_RESOURCES',
6:'FT_INVALID_PARAMETER',
7:'FT_INVALID_BAUD_RATE'}
err = self.ftd2xx.FT_EE_Read(self.handle[0],self.data)
if err != 0:
print("FT_EE_Read error ", self.errors[err])
def init_strings(self,Manufacturer="",ManufacturerId="",Description="",SerialNumber=""):
self._Manufacturer = self.ffi.new("char[64]",Manufacturer.encode())
self._ManufacturerId = self.ffi.new("char [16]",ManufacturerId.encode())
self._Description = self.ffi.new("char[64]",Description.encode())
self._SerialNumber = self.ffi.new("char[16]",SerialNumber.encode())
self.data[0].Manufacturer = self.ffi.cast("void*",self._Manufacturer)
self.data[0].ManufacturerId = self.ffi.cast("void*",self._ManufacturerId)
self.data[0].Description = self.ffi.cast("void*",self._Description)
self.data[0].SerialNumber = self.ffi.cast("void*",self._SerialNumber)
def program(self):
self.data[0].Signature1 = 0x00000000
self.data[0].Signature2 = 0xffffffff
self.data[0].Version = 5
self.data[0].VendorId = self.VendorId
self.data[0].ProductId = self.ProductId
self.init_strings( self.Manufacturer, self.ManufacturerId, self.Description, self.SerialNumber)
err = self.ftd2xx.FT_EE_Program(self.handle[0],self.data)
if err != 0:
print("FT_EE_Program error ", self.errors[err])
def __getattr__(self, item):
if item in self.__dict__:
return self.__dict__[item]
else:
try:
res = self.ffi.string(getattr(self.data[0],item)).decode()
return res
except TypeError:
res = getattr(self.data[0],item)
return res
def close(self):
self.ftd2xx.FT_Close(self.handle[0])