JTAG connection with OpenOCD and FTDI cable

Posted on 2013/08/04


Some time ago I bought several electronic parts to play with. One of these products is the FTDI C232HM-EDHSL-0, which is a USB-to-spaghetti dongle that connects a PC to an embedded product using many protocols (USART, SPI, I2C, JTAG, …).

FTDI C232HM cable

FTDI C232HM cable

In particular, JTAG is a kind of connection that is commonly used to test and debug integrated circuits. My goal is to use this cable to create a JTAG connection between my PC and an electronic board, as shown in the following image.

JTAG connection with C232HM

JTAG connection with C232HM

In order to perform this connection, I needed the following equipment:

  • A JTAG adapter: in my case the C232HM
  • A “Device Under Test”, in other words an integrated circuit mounted on a board with JTAG connectors: in my case the Olimex STM32-P152
  • A PC with relevant software and drivers: in my case I have a Debian Linux box with OpenOCD 0.5.0 and FTDI libraries 0.20 (libftdi1 Debian package).

When I insert the C232HM USB plug into the PC, these are the messages I get from the kernel:

$ dmesg
[10909.856093] usb 5-2.1: new high-speed USB device number 7 using ehci-pci
[10909.952085] usb 5-2.1: New USB device found, idVendor=0403, idProduct=6014
[10909.952091] usb 5-2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[10909.952095] usb 5-2.1: Product: C232HM-EDHSL-0
[10909.952099] usb 5-2.1: Manufacturer: FTDI
[10909.952103] usb 5-2.1: SerialNumber: FTV9J8DR
[10910.018460] usbcore: registered new interface driver usbserial
[10910.018479] usbcore: registered new interface driver usbserial_generic
[10910.018492] usbserial: USB Serial support registered for generic
[10910.024490] usbcore: registered new interface driver ftdi_sio
[10910.024509] usbserial: USB Serial support registered for FTDI USB Serial Device
[10910.024589] ftdi_sio 5-2.1:1.0: FTDI USB Serial Device converter detected
[10910.024628] usb 5-2.1: Detected FT232H
[10910.024630] usb 5-2.1: Number of endpoints 2
[10910.024633] usb 5-2.1: Endpoint 1 MaxPacketSize 512
[10910.024636] usb 5-2.1: Endpoint 2 MaxPacketSize 512
[10910.024638] usb 5-2.1: Setting MaxPacketSize 512
[10910.024879] usb 5-2.1: FTDI USB Serial Device converter now attached to ttyUSB0

In order to connect to this device with OpenOCD, I need to write a configuration file (that I named “c232hm-edhsl-0.cfg“) and pass it to OpenOCD. The file contains:

interface ft2232
ft2232_layout usbjtag
ft2232_vid_pid 0x0403 0x6014
adapter_khz 1000

From OpenOCD user’s guide, these configurations are needed to connect with an FTDI chip.

The layout is a setting that tells OpenOCD how to manage the I/Os of the FTDI chip that are not the basic JTAG signals (TCK, TMS, TDI, TDO), in my case it doesn’t matter since I have no intention of using them.

From FT232H data sheet, the FTDI chip is able to sustain 30Mbps, which means a TCK clock frequency of 30MHz, but in our case I want to keep it as low as 1MHz (adapter_khz 1000) until I feel that the setup is stable enough.

When I run OpenOCD with this configuration, the result is:

$ openocd -f c232hm-edhsl-0.cfg
Open On-Chip Debugger 0.5.0 (2011-08-11-06:56)
Licensed under GNU GPL v2
For bug reports, read
Info : only one transport option; autoselect 'jtag'
1000 kHz
Error: unable to open ftdi device: inappropriate permissions on device!
in procedure 'init'

This error appears because the Linux service “udev” assigns access rights based on its rules when a device is plugged in, and these rules are restrictive by default, allowing access only to the administrator.

When OpenOCD is installed in a Debian system, a new udev rule file is created in “/lib/udev/rules.d/60-openocd.rules“. This file contains the following rules:

ACTION!="add|change", GOTO="openocd_rules_end"
SUBSYSTEM!="usb", GOTO="openocd_rules_end"
ENV{DEVTYPE}!="usb_device", GOTO="openocd_rules_end"

# Olimex ARM-USB-OCD
ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="0003", MODE="664", GROUP="plugdev"


# Hilscher NXHX Boards
ATTRS{idVendor}=="0640", ATTRS{idProduct}=="0028", MODE="664", GROUP="plugdev"


I remand to udev man pages for the rules syntax, but it is sufficient to say that I want my device to be accessible for plugdev group that my user is already a part of. In many Linux distributions the normal users are automatically added to plugdev group in order to be able to plug in a USB drive and access the file system inside it.

I added (as root) another rule near the end of the file, before the LABEL line:

ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", MODE="664", GROUP="plugdev"


There is usually no need to tell udev to reload its rules, anyway the “udevadm control --reload-rules” command run as root should take care of that.

The OpenOCD output now becomes:

1000 kHz
Info : clock speed 1000 kHz
Warn : There are no enabled taps.  AUTO PROBING MIGHT NOT WORK!!
Error: JTAG scan chain interrogation failed: all ones
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Warn : Bypassing JTAG setup events due to errors
Warn : gdb services need one or more targets defined

This message means the FTDI chip tried to read from TDO some data, but the signal is stuck to a high level (all ones), and the reason is that I did not attach the pins to anything (up to now), and the pin has probably a pull-up resistance that keeps it high when floating. The next step is to connect the C232HM to the board.

The Olimex P152 board user manual indicates that the board has a common 20-pin JTAG connector (whose pinout is easily available on the web). I need to connect TCK, TMS, TDI and TDO that are the basic JTAG signals, and GND to give a common voltage reference. From C232HM data sheet I can get the mapping of the colored wires to their functions. By crossing the information I get:

  • TCK: orange wire on pin 9 of the JTAG 20-pin connector
  • TMS: brown wire on pin 7
  • TDI: yellow wire on pin 5
  • TDO: green wire on pin 13
  • GND: black wire on any one of pins 4,6,8,10,12,14,16,18,20

The resulting connection is shown in the image.

JTAG wiring between STM32-P152 and C232HM

JTAG wiring between STM32-P152 and C232HM

I then power up the board (by connecting it to the PC with an USB cable) and run OpenOCD again. This time the output is:

Warn : There are no enabled taps. AUTO PROBING MIGHT NOT WORK!!</pre>
Warn : AUTO auto0.tap - use "jtag newtap auto0 tap -expected-id 0x4ba00477 ..."
Warn : AUTO auto1.tap - use "jtag newtap auto1 tap -expected-id 0x06416041 ..."
Warn : AUTO auto0.tap - use "... -irlen 4"
Warn : AUTO auto1.tap - use "... -irlen 5"
Warn : gdb services need one or more targets defined

This output means that OpenOCD is trying to scan the JTAG chain for TAPs, and its automatic procedure is finding two taps: one with ID code 0x4ba00477 and Instruction Register length of 4 bits, and one with ID code 0x06416041 and Instruction Register length of 5 bits. I verified in the STM32L152 user manual that these are indeed the ID codes of the two taps present inside the chip, which means OpenOCD is reading the correct values through FTDI chip and so the board is connected properly.

My next step is to connect with the Cortex-M3 core that runs inside the STM32 chip, using a GDB debugger and OpenOCD. Stay tuned.

Posted in: Embedded