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