使用Python的FTDI库

使用Python的FTDI库,python,ftdi,Python,Ftdi,我的项目需要使用FTDI d2xx芯片在GUI应用程序和PMBus连接板之间进行通信。我想用python语言代替中的C++ 我找到了一个名为 但是我在网上找不到任何关于如何使用这个库的例子。如何使用FT_Write和FT_Read发送接收命令?是否有人有使用此库的知识或经验,或者我可以使用类似的库?任何帮助都将不胜感激。谢谢一种可能性是您可以使用更积极维护的库pylibftdi。看 另一种可能性是,Stackoverflow上可能存在解决您问题的问题。请参阅和相关问题。假设此问题仍然有效-以下是

我的项目需要使用FTDI d2xx芯片在GUI应用程序和PMBus连接板之间进行通信。我想用python语言代替

中的C++ 我找到了一个名为


但是我在网上找不到任何关于如何使用这个库的例子。如何使用FT_Write和FT_Read发送接收命令?是否有人有使用此库的知识或经验,或者我可以使用类似的库?任何帮助都将不胜感激。谢谢

一种可能性是您可以使用更积极维护的库
pylibftdi
。看


另一种可能性是,Stackoverflow上可能存在解决您问题的问题。请参阅和相关问题。

假设此问题仍然有效-以下是如何使用I2C模式的示例。必须将正确的dll/so提供/放置在与脚本相同的文件夹中。对于unix系统,必须卸载标准驱动程序。有关详细信息,请参见例如此处


谢谢你的回答。我之前检查过pylibftdi,但在他的网站上他说它不支持我在项目中使用的d2xx驱动程序。我在堆栈溢出上看到了这个问题,但我没有回答如何实际使用库的问题。我真的是新手,所以我正在寻找一些示例代码如何使用这个库编写和读取命令。谢谢你的回答。我还尝试使用libMPSSE.dll,并编写了类似于您的示例的包装器。很可能我的I2C_DISABLE_3PHASE_时钟位有问题。在I2CChannelConfig结构中,使用1(I2C\u禁用\u 3PHASE\u时钟)初始化选项字段时,I2C时钟具有正确的频率,但数据在两个时钟边缘上均无效。当我用0(3相时钟启用)初始化选项字段时,问题就开始了。(2)I2C时钟的频率与之前声明的频率不同(总是更高),并且会出现小故障。数据在两个时钟边缘上也无效。我复制了您的示例,其行为与我的代码相同。-chn_conf=I2C.I2CChannelConfig(clk,1,0)-chn_conf=I2C.I2CChannelConfig(clk,1,1)你知道原因是什么吗,可能是内部时钟错误?我从来没有检查过。然而,我只是查看了FTDI文档,并注意到下面一行:第8页上用于启用3相时钟的Version1.2Corrected命令。正确的命令是0x8C而不是0x8D。2020-05-26-来源:。我必须检查其含义。好的,我检查了ftdi_i2c.c。看起来MPSSE_CMD_ENABLE_3PHASE_CLOCKING=0x8C已正确传递给MPSSE引擎,而在禁用场景中,没有写入任何内容(即没有0x8D)。所以,也许这就是为什么会搞砸的原因。您可以尝试使用添加到MPSSE引擎写入的适当命令重新编译MPSSE_i2c。另一种选择是完全跳过MPSSE_i2c,直接在python中重新实现它。
class I2C:
    START_BIT           = 0x01
    STOP_BIT            = 0x02
    BREAK_ON_NACK       = 0x04
    NACK_LAST_BYTE      = 0x08
    FAST_TRANSFER_BYTES = 0x10
    FAST_TRANSFER_BITS  = 0x20
    FAST_TRANSFER       = 0x30
    NO_ADDRESS          = 0x40

    class InitError(Exception):
        pass

    class I2CChannelConfig(ctypes.Structure):
        _fields_ = [("ClockRate",   ctypes.c_int),
                    ("LatencyTimer",ctypes.c_ubyte),
                    ("Options",     ctypes.c_uint32)]
        
    def __init__(self, I2C_chn_no, clk=400000):
        self.libMPSSE = None
        try:            self.libMPSSE = ctypes.cdll.LoadLibrary("libMPSSE64.dll")
        except OSError: pass
        try:            self.libMPSSE = ctypes.cdll.LoadLibrary("libMPSSE32.dll")
        except OSError: pass
        try:            self.libMPSSE = ctypes.cdll.LoadLibrary("./libMPSSE.so")
        except OSError: pass

        if self.libMPSSE is None: raise I2C.InitError("no MPSSE lib found")

        chn_count           = ctypes.c_uint32()
        chn_conf            = I2C.I2CChannelConfig(clk,1,0)
        self.handle         = ctypes.c_void_p()

        ret = self.libMPSSE.I2C_GetNumChannels(ctypes.byref(chn_count))
        module_logger.debug("I2C_GetNumChannels status: %d number of channels: %d"%(ret,chn_count.value))
        if ret: raise I2C.InitError("I2C_GetNumChannels failed with errorcode %d"%ret)

        ret = self.libMPSSE.I2C_OpenChannel(I2C_chn_no, ctypes.byref(self.handle))
        module_logger.debug("I2C_OpenChannel status: %d handle: %s"%(ret, self.handle))
        if ret: raise I2C.InitError("I2C_OpenChannel failed with errorcode %d"%ret)

        ret = self.libMPSSE.I2C_InitChannel(self.handle,ctypes.byref(chn_conf))
        module_logger.debug("I2C_InitChannel status: %d"%ret)
        if ret: raise I2C.InitError("I2C_InitChannel failed with errorcode %d"%ret)

    def close(self):
        if self.libMPSSE:
            ret = self.libMPSSE.I2C_CloseChannel(self.handle)
            module_logger.debug("I2C_CloseChannel status: %d"%ret)
            del self.libMPSSE
            self.libMPSSE = None

    def __del__(self):
        self.close()
        
    def send(self, I2C_addr, raw):
        sent = ctypes.c_int32()
        buf  = ctypes.create_string_buffer(raw,len(raw))

        module_logger.debug("sending via I2C msg len: %d raw:\n%s" % (len(raw), raw))

        ret = self.libMPSSE.I2C_DeviceWrite(self.handle, I2C_addr, len(raw), buf, ctypes.byref(sent), I2C.START_BIT|I2C.STOP_BIT)#|I2C_TRANSFER_OPTION.FAST_TRANSFER_BYTES ignores the ACK
        module_logger.debug("I2C_DeviceWrite status: %d transfered: %d of %d"%(ret,sent.value,len(raw)))

        if ret or sent.value != len(raw):
            module_logger.warning("sending via I2C failed with ret code %d. Sent %d byte of %d." % (ret, sent.value, len(raw)))
            return False

        return True