Table of Contents
Using ftdi 2232 with linux
Install drivers for the ftdi device from here:
cd ~/Downloads wget http://www.intra2net.com/en/developer/libftdi/download/libftdi1-1.0.tar.bz2 tar xjf libftdi1-1.0.tar.bz2 cd libftdi1-1.0
Read the README.build, install build tools:
sudo apt-get install build-essential sudo apt-get install pkg-config sudo apt-get install cmake sudo apt-get install git-core sudo apt-get install doxygen
Ended up with:
Then for ruby:
sudo apt-get install ruby1.9.1 ruby1.9.1-dev rubygems1.9.1 irb1.9.1 ri1.9.1 rdoc1.9.1 build-essential libopenssl-ruby1.9.1 libssl-dev zlib1g-dev
Check installation with
ruby --version
Install dependencies:
sudo apt-get install libusb-1.0-0-dev sudo apt-get install libconfuse-dev sudo apt-get install swig python-dev sudo apt-get install libboost-all-dev sudo apt-get autoremove
Clone the git repository:
mkdir -p ~/devel/libftdi cd ~/devel/libftdi git clone git://developer.intra2net.com/libftdi
Then make libftdi:
cd libftdi/ mkdir build cd build/ cmake -DCMAKE_INSTALL_PREFIX="/usr" ../ make sudo make install
Testing ftdi 2232 devices
I have two different ftdi 2232 based devices. Testing them should reveal the same result. The OpenMoko has some issue that it cannot be opened, as can be seen below. However this does not seem to affect the JTAG functionality as can be seen further below.
TIAO USB Multi-Protocol Adapter
Test if the device TIAO USB Multi-Protocol Adapter is properly recognized with libftdi with the find_all_pp tool, which is in ../build/examples:
./find_all_pp -v 0x0403 -p 0x8a98 Found devices ( VID: 0x403, PID: 0x8a98 ) ------------------------------------------------ FTDI (0x86984b8): , , (Open FAILED)
If it throws “Open FAILED”, then it has probably a missing udev rule, giving this device the correct rights. Verify if this is the case with trying the same with sudo:
sudo ./find_all_pp -v 0x0403 -p 0x8a98 [sudo] password for fida: Found devices ( VID: 0x403, PID: 0x8a98 ) ------------------------------------------------ FTDI (0x92927c8): TIAO, TIAO USB Multi-Protocol Adapter, TIVYLJQO (Open OK)
This looks OK. To use this device without the sudo command create an udev rule. See below for more information.
OpenMoko Debug Board for Neo1973
Test if the OpenMoko Debug Board for Neo1973 is properly recognized with libftdi with the find_all_pp tool, which is in ../build/examples:
./find_all_pp -v 0x1457 -p 0x5118 fida@bona:~/devel/libftdi/libftdi/build/examples$ ./find_all_pp -v 0x1457 -p 0x5118 Found devices ( VID: 0x1457, PID: 0x5118 ) ------------------------------------------------ FTDI (0x9da3420): , , (Open FAILED)
If it throws “Open FAILED”, try the same with sudo:
sudo ./find_all_pp -v 0x1457 -p 0x5118 [sudo] password for fida: Found devices ( VID: 0x1457, PID: 0x5118 ) ------------------------------------------------ FTDI (0xa00f420): , , (Open FAILED)
The open FAILED error still appears with using sudo. To find out why this behaves differently, test it with lsusb to see if a clue can be found:
sudo lsusb Bus 002 Device 005: ID 1457:5118 First International Computer, Inc. OpenMoko Neo1973 Debug board (V2+)
The format for verbose information from lsusb is: sudo lsusb -v -s [BUS_NUMBER]:[DEVICE_NUMBER], which is in this case:
sudo lsusb -v -s 002:005
Gives:
Further reading about the OpenMoko Debug Board v3, states that the ftdi_sio module should be removed from the linux kernel and then added with specifying the vendor-id and product-id.:
rmmod ftdi_sio modprobe ftdi_sio vendor=0x1457 product=0x5118
or the equivalent in your modules.conf.
Usage without sudo: udev rules
If you read with the find_all_pp program the following (or similar) output with the Open FAILED text:
Found devices ( VID: 0x403, PID: 0x6010 ) ... FTDI (0x86984b8): , , (Open FAILED)
then give the ftdi device elevated rights with adding an udev rule. Look here or here for examples. Also here for reference to a plugdev group. Apparently a user should be member to that group.
Find which groups there are with the following command:
groups
Which shows in my case:
aida adm cdrom sudo dip plugdev lpadmin sambashare
After changing udev rules, reinitialize them with the following command:
sudo udevadm control --reload-rules
About udev rules, mind the following: In the original udev rule on openmoko.org the rule contained the meanwhile outdated SYSFS attribute. This will not work anymore and gives an error during troubleshooting the rule. Changing the SYSFS attribute into ATTR attribute is sufficient to make it work.
OpenMoko debug board udev rule
For the OpenMoko debug board this is: /etc/udev/rules.d/099_neo1973_debugboard.rules
# udev rules file for Neo1973 Debug Board v2 # ACTION!="add", GOTO="neo1973_dbg_rules_end" SUBSYSTEM!="usb", GOTO="neo1973_dbg_rules_end" ATTR{idVendor}=="1457", ATTR{idProduct}=="5118", MODE="664", GROUP="plugdev" LABEL="neo1973_dbg_rules_end"
TIAO USB Multi Protocol adapter udev rule
For the TIAO USB Multi Protocol adapter this is: /etc/udev/rules.d/098_tiao_usb_multi_protocol_adapter.rules
# udev rules file for TIAO USB Multi Protocol adapter # ACTION!="add", GOTO="tiao_usb_multi_protocol_interface_end" SUBSYSTEM!="usb", GOTO="tiao_usb_multi_protocol_interface_end" ATTR{idVendor}=="0403", ATTR{idProduct}=="8a98", MODE="664", GROUP="plugdev" LABEL="tiao_usb_multi_protocol_interface_end"
Testing ttyUSB*
When trying the serial port with cu, it may throw a “Line in use” at you:
sudo cu -eo -s 115200 -l /dev/ttyUSB0 cu: open (/dev/ttyUSB0): Permission denied cu: /dev/ttyUSB0: Line in use
A solution for this is to assign ttyUSB0 to the uucp group:
sudo chown uucp /dev/ttyUSB0
Then cu will work. To exit from a cu session, type the following: ~.
To send or receive a file via the /dev/ttyUSB0, it must be writable. Change this accordingly:
sudo chmod 666 /dev/ttyUSB0
Activity on the TxD pin can be measured at the TIAO USB Multi-Protocol Adapter when issuing this command:
sudo cat testfile.txt > /dev/ttyUSB0
The OpenMoko Debug board fails here. No activity can be seen on the TxD line. The command on the terminal seems to hang.
Testing JTAG with flash memory
An easy method to make a connection to the flash memory, which is in a 16-pin SOIC 300-mil housing, to the JTAG interface is to solder the corner points to a solid pin and use thin wires to connect to the other IC legs:
See further below for pinout from the flash memory to the corresponding JTAG interface.
apt-get installation of flashrom
With flashrom the JTAG interface is tested while being connected to flash memory. Install flashrom either with apt-get or manually (see further below).
sudo apt-get install flashrom
Manual installation of flashrom
flashrom installation depends on subversion, libftdi (has been installed already) and libftdi-dev (to be installed with sudo apt-get install libftdi-dev) to have support for ft2232_spi devices. Once installed, do:
mkdir -p ~/devel/ cd ~/devel svn co svn://flashrom.org/flashrom/trunk flashrom cd flashrom make sudo make install
OpenMoko JTAG
With using the OpenMoko Debug board wire the flash memory as explained here to the OpenMoko JTAG port. Connections are: (pin-OpenMoko,pin-W25Q128)
- 1-VCC3→2-VCC NB. pin 2 at the flash memory is also connected to pin 1 (/hold) and pin 9 (/WP)
- 5-TDI→15-DI
- 7-TMS→7-/CS
- 9-TCK→16-CLK
- 13-TDO→8-DO
Then issue the following command:
./flashrom -p ft2232_spi:type=openmoko
This should communicate with the flash memory. If it would be reading the actual memory this may take a while for large memories:
flashrom v0.9.6.1-r1657 on Linux 3.5.0-25-generic (i686) flashrom is free software, get the source code at http://www.flashrom.org Calibrating delay loop... OK. Found Winbond flash chip "W25Q128" (16384 kB, SPI) on ft2232_spi. This flash part has status UNTESTED for operations: READ ERASE WRITE The test status of this chip may have been updated in the latest development version of flashrom. If you are running the latest development version, please email a report to flashrom@flashrom.org if any of the above operations work correctly for you with this flash part. Please include the flashrom output with the additional -V option for all operations you tested (-V, -Vr, -VE, -Vw), and mention which mainboard or programmer you tested. Please mention your board in the subject line. Thanks for your help! No operations were specified.
TIAO USB Multi Protocol adapter JTAG
The 20PIN ARM JTAG connector does not work in the same way as it does for the OpenMoko JTAG connector. One of the differences is that pin 1, VTAR should be supplied from an external power supply at 3.3v. Jumper VT-SEL should be set to position 2-3, to enable this power to the buffer IC. Furthermore, using flashrom with the following command should use this default port A:
flashrom -p ft2232_spi:type=tumpa
Unfortunately the output of this shows no success as it does at the OpenMoko board:
Found Generic flash chip "unknown SPI chip (RDID)" (0 kB, SPI).
Instead use SPI2 at the TIAO tumpa board, which is mapped to port B. This works fine. Connections are:
SPI2 | EEPROM |
---|---|
MISO | DO |
VCC | VCC+/HOLD+/WP |
SCK | CLK |
MOSI | DI |
CS | /CS |
GND | GND |
And using this command:
./flashrom -p ft2232_spi:type=tumpa,port=B
will show the same result from OpenMoko:
... Found Winbond flash chip "W25Q128" (16384 kB, SPI) on ft2232_spi. ...
Since the only difference between port A and port B is that port A has a 74LVC16T245 buffer IC driving the signals MOSI, CLK and CS via a 56 Ohm resistor, I started bypassing this buffer IC and tested if port A could behave like port B. I noticed then that for proper communication the only signal that had to be bypassed was the CLK signal. By connecting CLK directly to pin 16 (TCLK) of the FT2232HL, the communication worked fine. But as soon as the CLK signal would go via the buffer IC, the CLK output (LVC16T245, pin 2) signal would be degraded to such an extend that communication with the memory chip could not be established properly. After this I understood there is nothing wrong with the TIAO JTAG board.nor with the drivers. The root cause for this is a mismatch between the output impedance of the JTAG board and the relatively long (>20cm) cables. This effect plays a substantial role at high frequency signals, which this interface is running at. I measured a CLK signal of 30Mhz. A simple solution is to shorten the cables. Instead of 20cm I strongly advise to use not more than 10cm.
As an alternative, one could try to match the output impedance of the JTAG board by adding a resistor at the MOSI, CLK and CS signals of the memory IC, presuming the cable impedance has a identical value. There are several effects which cause the delay of the CLK signal. The buffer IC gives a delay of about 4ns, the 56 Ohm resistor causes a less steep transition and an extra signal delay through 20cm cable of about 1ns. This all must be taken into account.
Another good explanation and design guidelines for (ac) termination and cabling can be found here.
Lowering the bus frequency, resulted in successful communication. This is clearly a hint that there are issues with signal integrity. With the following command there is success:
./flashrom -p ft2232_spi:divisor=4,type=tumpa,port=A
The frequency of the CLK signal lowered, but not as expected. According to Application Note 135, MPSSE Basics of the FTDI documentation the frequency can be set with the following formula:
frequency = 60MHz /((1 + divisor)*2)
The divisor is a 16-bit hex value between 0x0000 and 0xFFFF and represent the amount of 2 divisors which are chained. With a 60Mhz base clock, data rates range between 30MHz and ~460Hz and applies to the FT2232H, according to page 9 of AN 135. This formule will give the 16-bit divisor:
dwClockDivisor=(30000000/SCL_Frequency) - 1; // With SCL_Frequency in Hz. For example, an SCL_Frequency of 1 MHz will give a dwClockDivisor of 29.
And code in Application note 114, page 7 and 8 to set the registers:
... OutputBuffer[dwNumBytesToSend++] = '\x86'; //Command to set clock divisor OutputBuffer[dwNumBytesToSend++] = BYTE(dwClockDivisor & '\xFF'); //Set 0xValueL of clock divisor OutputBuffer[dwNumBytesToSend++] = BYTE(dwClockDivisor >> 8); //Set 0xValueH of clock divisor ftStatus = FT_Write(ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent); // Send out the commands dwNumBytesToSend = 0; //Clear output buffer ...
This is rather confusing implemented in flashrom since May 16th 2012. Measurements when using divisor=2 or with no divisor arguments, show a CLK signal of 30 MHz (The comments in the code say 2 is a default value). The code seems differently written than FTDI did.
To make measurements easier one can use the following one-liner, which repeats the command and activity on the bus. With this it is easier to analyze the cabling, termination and buffer circuit:
cd $HOME/devel/flashrom; while true; do ./flashrom -p ft2232_spi:divisor=4,type=tumpa,port=A; done
Intermezzo: Modifying find_all_pp
The find_all_pp tool will without arguments according to this page not find the OpenMoko debug board. To correct this, change the file at this location:
~/devel/libftdi/libftdi/examples/examples/find_all_pp.cpp
the line beginning with this:
int vid = 0x0403, pid = 0x6010, tmp = 0;
into:
int vid = 0x1457, pid = 0x5118, tmp = 0;
Rename this file into: find_all_pp2
Then make this with following line:
gcc -o find_all_pp2 ~/devel/libftdi/libftdi/examples/examples/find_all_pp2.cpp $(pkg-config --cflags --libs libftdipp1)
Please note a difference for pkg-config between c programs and c++ programs. For c programs libftdi1 is used and for c++ programs lbftdipp1
Intermezzo: JTAG clk signal integrity observations
After realizing the JTAG clk signal was in the order of 30MHz, the signal integrity in terms of transmission line properties became significant. Reflections on improper terminated cable ends as well as wrong cable impedance would have influence on the signal integrity. To be able to perform measurements on the signal, following changes were made to the TIAO JTAG interface board:
- Pin 47 of the 74LVC16T245 had been isolated from the FT2232HL.
- A separate square wave signal of 5.5 MHz, Vpp of 3.3 V, with a 50 Ohm termination close to this pins had been fed into this IC.
- The signal ground was attached to pin 45.
In documentation about the output characteristics2) of the LVC16 family, to which the 74LVC16T245 buffer IC belongs, the output impedance is about 15 Ohm. Rather than the previously used separate wires, a 1/20 inch flat cable was taken with following specifications:
- Belden AWM 2651 See 7.5, characteristic impedance of 105 Ohm, Ground-Signal-Ground configuration. Total cable length: 20cm.
The flat cable was taken from an old computer diskette drive. It was not 100% clear whether the specifications from belden.com applied actually to this cable. Initially I thought the characteristic impedance was 90 Ohm. With channel 1 showing the buffer input signal and channel 2 showing the cable end, measurements show the following:
Where RS is the sum of the output impedance and the series resistor at the output of the buffer IC.
Being unsure about the impedance of the flat cable, I tried driving the cable additionally with 105 Ohm (With and without taking into account the 15 Ohm internal buffer resistance) and 105 Ohm termination.
Interestingly, from the initial attempt to measure signal reflection, by analyzing the images, my attention fell on two things:
- The buffer output signal becomes shortly negative when the waveform returns to zero. This behavior can be seen as well at the input signal. The effects are very small when the termination is open. I think the 105 Ohm load is so relatively large, that it draws a lot of current from the buffer power supply, causing the ground plane around the buffer IC to become shortly negative when the waveform returns to zero.
- The propagation delay (round trip travel time) through 20cm of cable is about 2ns (5ns/m, 2 x 20cm)3). If a reflection occurs, it is expected this would become visible in the output signal. The images above don't make this really clearer, because the supply power problem as described above has a much larger effect.
- The output impedance of the buffer including the series resistor (Which is together 105 Ohm) cancels all bounced reflections.
After realizing the buffer output impedance cancels the bounced reflections, I measured the signal with no termination. The result looks fine and should be according to the waveform sufficient to control the memory device. The signal looks like this:
When compared to the second image which had a 97 Ohm output impedance, the square waveform has less disturbances and enables faster rise times. Two changes may have contributed to this:
- A corrected total buffer output impedance of 105 Ohm, matched the cable impedance. The default 56 Ohm resistor after the buffered output was replaced by another resistor. Together with the buffer internal resistance, 15 Ohm, this makes a total output resistance of 105 Ohm. This means a resistor of 90 Ohm (I selected 100 Ohm parallel with 910 Ohm) should be the correct value.
- An additional capacitor at the bottom of the circuit board, at the via to pin 7, Vccb, buffers the input power supply. I had to scratch some of the ground plane away, making space for a capacitor. This had to be done careful, because other vias are at near distance. For the capacitor I selected a value of 10 uF.
After the modifications I measured the clk signal from the FTDI2232H, going via the buffer:
The LVC16T245 buffer is causing a delay of about 6ns for the CLK signal.
Links and information
- http://blogas.sysadmin.lt/?p=141 Explanation of udev process
- http://www.reactivated.net/writing_udev_rules.html writing udev rules4)
- AVR Dragon as JTAG Using the AVR Dragon as JTAG interface.
- http://aeturnalus.com/robotics/mapping-ftdi-to-files-with-udev/ more about creating and troubleshooting udev rules
- http://www.milkymist.org/wiki/index.php?title=Build_the_libftdi-1.0_and_new_ftdi_eeprom Build the libftdi-1.0 and new ftdi eeprom
- JTAG at the TIAO USB Multi-Protocol Adapter Pull-up requirement?
info -q all -n /dev/ttyUSB0
udevadm info -q all -n /dev/bus/usb/002/003