如何使用 pylibftdi 连接到 FT230?

How do I connect to an FT230 with pylibftdi?

我只有一个 FTDI FT230X 连接到我的机器。 我可以使用 lsusb:

查看设备
$ lsusb
Bus 002 Device 005: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Bus 002 Device 004: ID 046d:c408 Logitech, Inc. Marble Mouse (4-button)
...
Bus 003 Device 010: ID 0403:6015 Future Technology Devices International, Ltd Bridge(I2C/SPI/UART/FIFO)
...

0403:6015 条目是 FT230X。 我想在 Python 谈谈这件事,所以我们

>>> import pylibftdi
>>> dev = pylibftdi.Device()

但收到一条错误消息阅读

~/.virtualenvs/labrad/local/lib/python2.7/site-packages/pylibftdi/device.pyc in __init__(self, device_id, mode, encoding, lazy_open, chunk_size, interface_select, device_index, auto_detach, **kwargs)
    114         # lazy_open tells us not to open immediately.
    115         if not lazy_open:
--> 116             self.open()
    117 
    118     def __del__(self):

~/.virtualenvs/labrad/local/lib/python2.7/site-packages/pylibftdi/device.pyc in open(self)
    154             self.fdll.ftdi_deinit(byref(self.ctx))
    155             del self.ctx
--> 156             raise FtdiError(msg)
    157 
    158         if self.auto_detach and self.driver.libftdi_version().major > 0:

FtdiError: device not found (-3)

我们也可以尝试明确指定序列号:

>>> import usb.core
>>> devs = list(usb.core.find(find_all=True))
>>> for x in str(devs).split(','):
        print(x)
[<DEVICE ID 051d:0002 on Bus 002 Address 005>
<DEVICE ID 046d:c408 on Bus 002 Address 004>
<DEVICE ID 04ca:006e on Bus 002 Address 003>
<DEVICE ID 8087:0024 on Bus 002 Address 002>
<DEVICE ID 1d6b:0002 on Bus 002 Address 001>
<DEVICE ID 1d6b:0003 on Bus 004 Address 001>
<DEVICE ID 1366:0101 on Bus 003 Address 009>
<DEVICE ID 0403:6015 on Bus 003 Address 010>  # <-- that one
<DEVICE ID 1d6b:0002 on Bus 003 Address 001>
<DEVICE ID 1050:0211 on Bus 001 Address 003>
<DEVICE ID 8087:0024 on Bus 001 Address 002>
<DEVICE ID 1d6b:0002 on Bus 001 Address 001>]

>>> my_dev = devs[7]
>>> ser = devs.serial_number
>>> import pylibftdi
>>> pylibftdi.Device(ser)

同样的错误。

为什么会这样? pylibftdi documentation 声称 Device 构造函数应该使用第一个可用的设备,而在我的例子中只有一个。 说 "device not found" 的错误消息让我想知道 pylibftdi 使用的驱动程序是否支持 FT230X,我认为在我的情况下是 libftdi1

pylibftdi 有一个硬编码的 USB 产品 ID (idProduct) 列表,它将在 pylibftdi.driver.USB_PID_LIST 中搜索。这里不包括FT230X芯片,也不查询libftdi底层库支持的芯片:

来自 pylibftdi/driver.py:

# Opening / searching for a device uses this list of IDs to search
# by default. These can be extended directly after import if required.
FTDI_VENDOR_ID = 0x0403
USB_VID_LIST = [FTDI_VENDOR_ID]
USB_PID_LIST = [0x6001, 0x6010, 0x6011, 0x6014]

不幸的是,这似乎不起作用:

>>> import pylibftdi
>>> pylibftdi.driver.USB_PID_LIST.append(0x6015)
>>> print(["%04x " % x for x in pylibftdi.USB_PID_LIST])
['6001 ', '6010 ', '6011 ', '6014 ', '6015 ']
>>> dev = pylibftdi.Device()  
Segmentation fault

这里的问题好像是pylibftdi调用libusb设置auto-detach的时候。如果我执行以下操作,它似乎会起作用:

>>> import pylibftdi
>>> pylibftdi.driver.USB_PID_LIST.append(0x6015)
>>> print(["%04x " % x for x in pylibftdi.USB_PID_LIST])  
['6001 ', '6010 ', '6011 ', '6014 ', '6015 ']
>>> dev = pylibftdi.Device(auto_detach=False)  
>>> dev
<pylibftdi.device.Device at 0x7f586d08f350>

对我来说,这不会阻止 libftdi 成功分离内核驱动程序(/dev/ttyUSB0 在我 运行 时消失),但它确实会阻止会话关闭后重新连接。