I got my mitts on a Raspberry Pi Zero just after Christmas in a trade agreement (thanks slug). It’s been sitting here staring me in the face waiting for a job to do. About the same time the zero came, deeice was plotting to try out a modified u-boot on the zipit that squeezes a little more space out of the internal flash. Unfortunately, we haven’t got it working as intended yet. In the process deeice managed to brick one zipit by mistake and I bricked one after compiling some probably incomplete source code. Someone posted a link about using the Raspberry Pi as a JTAG debugger and since deeice got a Raspberry Pi for Christmas I figured this is a good chance to force him into getting a soldering iron and using it. :-D
Most of the links I found about using the Pi for JTAG were fairly old instructions. OpenOCD now has builtin support for the Pi as a debugger and it’s easier to setup. I still don’t have a Mini HDMI adapter so I did this all via serial and wifi. I downloaded the latest Raspbian Jessie Lite and booted up the Zero. First thing (after getting wifi connected) was to install openocd (v0.8.0 in Jessie):
pi@raspberrypi:~$ sudo apt-get update
pi@raspberrypi:~$ sudo apt-get install -y openocd
I chose to use an 8 pin double row dupont header to keep all the pins together. We only need 7 pins but we can add 3.3v on the remaining pin for use on some other JTAG-able device. The image above shows “raspi gpio #” vs “raspi header pin #” vs “jtag function” vs “my wire color”. Labeled JTAG pinout image courtesy sweetlilmre. The next step was to modify the Raspberry Pi openocd config for my home made cable.
pi@raspberrypi:~$ cp /usr/share/openocd/scripts/interface/raspberrypi-native.cfg ./
- or use mine -
pi@raspberrypi:~$ wget http://mozzwald.com/zipit/jtag/raspberrypi-native.cfg
and modify the contents (Note: I had to clock the pi cpu at 700MHz and I couldn’t get reliable flash writing with adapter_khz above 16):
# Config for using Raspberry Pi’s expansion header
# This is best used with a fast enough buffer but also
# is suitable for direct connection if the target voltage
# matches RPi’s 3.3V and the cable is short enough.
# Do not forget the GND connection, pin 6 of the expansion header.
# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET
# These depend on system clock, calibrated for stock 700MHz
# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET
bcm2835gpio_speed_coeffs 113714 28
# Each of the JTAG lines need a gpio number set: tck tms tdi tdo
# Header pin numbers: 23 22 19 21
bcm2835gpio_jtag_nums 11 25 10 9
# If you define trst or srst, use appropriate reset_config
# Header pin numbers: TRST - 24, SRST - 18
reset_config trst_and_srst separate
Next we create our Zipit Z2 specific config (or use mine):
# Config for ZipitZ2 - zipitz2.cfg
jtag newtap pxa270 cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id 0x49265013 -expected-id 0x79265013
target create pxa270.cpu xscale -endian little -chain-position pxa270.cpu -variant pxa27x
# maps to PXA internal RAM.
pxa270.cpu configure -work-area-phys 0x5c000000 -work-area-size 0x10000 -work-area-backup 0
# 8Mb Flash Bank
flash bank pxa270.flash cfi 0x00000000 0x0800000 2 2 pxa270.cpu
After the Zipit is soldered correctly to the JTAG cable, connect it to the Pi. Plug a power cable into the Zipit. Now we are ready to JTAG. Start by running openocd.
pi@raspberrypi:~$ sudo openocd -f raspberrypi-native.cfg -f zipitz2.cfg
Open On-Chip Debugger 0.8.0 (2014-10-31-08:03)
Licensed under GNU GPL v2
For bug reports, read
Info : only one transport option; autoselect ‘jtag’
BCM2835 GPIO config: tck = 11, tms = 25, tdi = 10, tdi = 9
BCM2835 GPIO config: trst = 8
BCM2835 GPIO config: srst = 24
trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain connect_deassert_srst
adapter speed: 16 kHz
Info : pxa270.cpu: hardware has 2 breakpoints and 2 watchpoints
Info : clock speed 16 kHz
Info : JTAG tap: pxa270.cpu tap/device found: 0x79265013 (mfg: 0x009, part: 0x9265, ver: 0x7)
Next, open another terminal and we will connect via telnet to openocd.
pi@raspberrypi:~$ telnet localhost 4444
Connected to localhost.
Escape character is ‘^]’.
Open On-Chip Debugger
The following steps are used to flash a new bootloader (Note: The commands are in green. The red is an error that always appears. The magenta must show “Supervisor” and not “User”)
JTAG tap: pxa270.cpu tap/device found: 0x79265013 (mfg: 0x009, part: 0x9265, ver: 0x7)
Bad value ‘00’ captured during DR or IR scan:
JTAG error while writing DCSR
target state: halted
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x380000d3 pc: 0x00000000
MMU: disabled, D-Cache: disabled, I-Cache: disabled
> flash probe 0
Flash Manufacturer/Device: 0x0089 0x8865
flash ‘cfi’ found at 0x00000000
> flash write_image erase unlock zipit-env8k-uboot/zipit-env8k-uboot.bin 0
auto erase enabled
auto unlock enabled
wrote 196608 bytes from file zipit-env8k-uboot/zipit-env8k-uboot.bin in 102.052246s (1.881 KiB/s)
Occasionally the flash would fail with an error:
> flash write_image erase unlock u-boot-z2-tiny/u-boot-z2-tiny.bin 0
auto erase enabled
auto unlock enabled
timed out while waiting for target halted
target not halted
target not halted
Execution of flash algorythm failed. Can’t fall back. Please report.
error writing to flash at address 0x00000000 at offset 0x00000000
in procedure ‘flash’
..but subsequent tries worked fine. It might be timing related. Also, I ended up adding an additional ground wire which reduced the failure rate even more.