Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
465 views
in Technique[技术] by (71.8m points)

usb - Using FTDI D2XX drivers with Python from Raspberry Pi on raspbian soft-float

We have a USB device controlled by FTDI's D2XX drivers. It's currently controlled from a Windows machine via a Python interface and as a fun project I tried moving the control to a Raspberry Pi (about 1/10th the cost of a PC, not including the OS cost).

There were many hurdles to clear, but after a few weeks I finally found all the answers and got it working. The answers were spread across several forums so as a thank you to the Stack Overflow community I thought I'd consolidate them here.

First, the project required:

  • An operating system: I picked up the latest "Wheezy" Raspbian (hard-float 2012-12-16) from the Raspberry Pi webpage. This included Python.
  • The FTDI D2XX drivers to talk to our FTDI device.
  • A Python interface to the D2XX driver. I used PyUSB
  • Our Python script

I downloaded the Wheezy distribution and used Win32DiskImager to write to a 4 GB SD card. The Raspberry Pi booted with no problems. I then unpacked the D2XX library (libftd2xx.so) and installed it into /usr/local/lib.

PyUSB (1.6) currently is tested only against Windows, but they provide the source code. It's pretty straightforward to compile a copy for Raspberry Pi. Basically, modify setup.py to link to the libftd2xx.so library (no need to copy it). Also edit d2xx/_d2xx.c to comment out the routines with no Linux implementation (currently ftobj_Rescan, ftobj_Reload ftobj_GetComPortNumber). Copy WinTypes.h and ftd2xx.h from the FTDI D2XX driver download (in the release) directory into ftdi-win32 and run python setup.py install which will compile and install the Python module.

Once all that was done I wrote a simple Python script to talk to the FTDI chip. Note you need to run via sudo.

import d2xx
jd = d2xx.open(0)
pd = jd.eeRead()
print pd

The d2xx module could not seem to find the libftd2xx.so file. So, I tweaked the setup.py script to link to the static copy of the library, libftd2xx.a. Voila, I had my first clue of the problem: The D2XX library was built using soft-float, and my Wheezy distribution was configured to use floating point registers. That is, the gcc on my system generated code that was binary incompatible with the D2XX libraries and would not allow them to be linked to.

To fix this I downloaded the soft-float debian "wheezy" distribution (2012-08-08) and wrote to the 4 GB SD card. This time the image would not boot. After looking around I found this helpful answer. In short, there's a problem with the boot image for the soft-float so that for some Raspberry Pi boards, it won't boot. The solution is to replace the start.elf file on the soft-float distribution with one that does work e.g. a copy from the hard-float Raspbian image. Fortunately, the SD card has two partitions: a FAT one and an ext3(?) one. The boot image is on the FAT partition, so it was trivial to pop the hard-float SD card into a Windows box, copy the start.elf file, pop in the soft-float SD card and update its start.elf with the hard-float one. After that, the Raspberry Pi booted no problem.

After installing FTDI's D2XX drivers and building a d2xx Python module from PyUSB, I tried the test script again. Again it failed. The d2xx module could read the libftd2xx.so library no problem, but for some reason could just not talk to the device.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I wasn't sure where the problem lay: Was it PyUSB, an issue with FTDI's libftd2xx.so or some issue with the Debian distribution?

With the FTDI package there's a test, under release/examples/EEPROM/read. You must build it, but that's simply a matter of typing make. Running it (via sudo), it failed to open the USB device, so clearly it wasn't PyUSB. After poking around, I found a reference to a driver, ftdi_sio, and that it could conflict with other D2XX drivers. So, using lsmod, I saw ftdi_sio was already installed by default, so I ran rmmod ftdi_sio. After that, everything worked. The read command should show something like this:

Library version = 0x10112
Opening port 0
FT_Open succeeded.  Handle is 0xf7d240
FT_GetDeviceInfo succeeded.  Device is type 4.
FT_EE_Read succeeded.
Signature1 = 0
Signature2 = -1
Version = 1
VendorId = 0x0407
ProductId = 0x6009
Manufacturer = MagicIncorporated
ManufacturerId = wo
Description = MyCompany Test Board
SerialNumber = testit_028
MaxPower = 44
PnP = 1
SelfPowered = 0
RemoteWakeup = 1
2232RC:
-------
    Rev5 = 0x1
    IsoInA = 0x0
    IsoInB = 0x0
    IsoOutA = 0x0
    IsoOutB = 0x0
    PullDownEnable5 = 0x0
    SerNumEnable5 = 0x0
    USBVersionEnable5 = 0x0
    USBVersion5 = 0x110
    AIsHighCurrent = 0x0
    BIsHighCurrent = 0x0
    IFAIsFifo = 0x0
    IFAIsFifoTar = 0x0
    IFAIsFastSer = 0x0
    AIsVCP = 0x0
    IFBIsFifo = 0x0
    IFBIsFifoTar = 0x0
    IFBIsFastSer = 0x0
    BIsVCP = 0x0
Returning 0

I also switched from PyUSB to ftd2xx, because it's pure python, but it wasn't strictly necessary.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...