修改FTDI的PID为FTDI X系列

Change PID for FTDI for FTDI X Series

本文关键字:FTDI 系列 PID 修改      更新时间:2023-10-16

FTDI X系列芯片的默认PID为0X6015。我曾经使用FT_EE_Program到旧芯片0X6001的PID。效果很好。然而,该功能不适用于新芯片。我正在使用FT_EEPROM_Program函数来更改0X6015的PID。下面是我的代码:

 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;
  }

但是,status的返回值是FT_INVALID_PARAMETER。请提供修改PID的建议我能够使用FTDI实用程序FT_Prog更改PID。我没有找到使用FT_EEPROM_Program的示例。

D2XX程序员指南(FT000071)明确指出:"默认情况下,驱动程序将支持一组有限的VID和PID匹配设备(VID 0x0403仅与PID 0x6001, 0x6010, 0x6006匹配)"所以你的设备不被支持。

您可以在FT_EEPROM_Program使用的所有方法的注释部分找到这条语句。

要对芯片上的EEPROM进行编程,您需要设置传递给FT_EEPROM_Programm_x_series结构中的所有值。从您的示例代码中,您可以将未初始化的内存传递给程序函数;底层代码可能正在验证您所发送的内容,如果值无效则拒绝它。

有一个命令行版本的FT_Prog,将允许您快速编程多个芯片。你需要使用应用程序的GUI版本生成一个带有新PID的模板文件,然后运行命令行版本,传入你生成的.xml文件。

下面的脚本使用FT_EE_Read()FT_EE_Program()FT_EE_Read()不设置Signature1Signature2Version。所以这些需要设置在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])