JTAG

From ArmadeusWiki
Revision as of 22:40, 11 April 2009 by Jorasse (Talk | contribs)

Jump to: navigation, search

[SSinyagin] I'm trying to get use of JTAG for U-Boot debugging and FPGA debugging with chipscope for example.

Please note that the jtag feature can be replaced (most of the time) by the debugging tools provided with the Armadeus BSP without any hardware specific device. :-)

Building a JTAG connector for apf27Dev board

First you need a decent JTAG connector. The description below produces a 20-pin male JTAG connectior with standard ARM pinout.

List of material and part numbers at Conrad:

  • 2x20-pin header, 2.54mm pitch (Conrad: 741973)
  • ATA/IDE cable (Conrad: 971742)
  • 2x10-pin IDC low profile header, 2.54mm pitch (Conrad: 743534)
  • 20-way flat cable, 1.27mm pitch (Conrad: 609463)

Assembling it all together:

  1. Solder the 40-pin header onto the J19 connector on the apf27dev board
  2. Cut off a ~10cm piece from the ATA cable with the 40pin plug at the end.
  3. Cut off ~10cm from 20-way flat cable
  4. Carefully attach the 20-pin header to the flat cable. The thing is easy to break and it requires some forcing. Better buy a spare piece in advance.
  5. Use a knife and a cutting pad and dissect the cable endings, ~3cm long. Dissect the whole width of the 20-way cable and only pins 40 to 31 on the 40-way ATA cable.
  6. Strip the cable endings
  7. Solder the two cables together, as specified below:
ARM JTAG 20-pin cable apf27dev J19 40-pin cable
1 - VREF (+2.8v) J9 pin 2 OR J19 pin 39 with a 68 ohm resistor inline
2 - Vddh (+3.3v) 39
3 - nTRST 33
4, 6, 8, 10, 12, 14, 16, 18, 20 - Vss (ground) 31, 34, 40
5 - TDI 35
7 - TMS 36
9 - TCK 37
11 - RTCK (optional) J22 pin 2 (TCK_OWIRE)
13 –TDO 38
15 – nSRST (optional) wired to apf27 R76 on cpu side: http://www.armadeus.com/_downloads/apf27/hardware/apf27_V1.2_top_assembly.pdf

JTAG Probe

I'm using the Amontec JTAGkey adapter. It has a male 20-pin plug and a 20-way female-to-female cable which fits directly into the cable as described above. A cheaper solution would be to use the Amontec JTAGkey-Tiny and install a 20-pin female plug on on the connector cable for apf27dev.

Configure the board for JTAG

In case of an APF27 equipped with a FPGA it MUST be powered before using the jtag. At startup the fpga is low power by cutting down the VCCAUX and VCCINT supplies until some data are loaded in the fpga. The simplest way to activate the fpga is to enable the U-Boot firmware_autoload feature. Under U-Boot set the environment variable firmware_autoload to 1 and save the environment variables to enable the fpga on reset:

BIOS> setenv firmware_autoload 1
BIOS> saveenv 
Saving Environment to NAND...
Erasing Nand...
Erasing at 0xe0000 -- 100% complete.
Writing to Nand... done
BIOS> reset
 ...

Install and configuring OpenOCD

yet to be done. First it requires 2 libraries libusb and libftdi (libftd2xxx from ftdi). download and install the latest libftdi: http://www.intra2net.com/en/developer/libftdi/download/libftdi-0.15.tar.gz

>./configure
>make
>sudo make install

then openocd: http://developer.berlios.de/projects/openocd

> ./bootstrap
...
>./configure --enable-ft2232_libftdi
...
>make
...
>sudo make install
...

Basic tests show that cable works as expected. You can use the following configuration file with jtagkey and openocd.


telnet_port 4444
gdb_port 3333
# GDB can also flash my flash!
gdb_memory_map enable
gdb_flash_program enable


interface ft2232
ft2232_device_desc "Amontec JTAGkey"
ft2232_layout jtagkey
ft2232_vid_pid 0x0403 0xcff8
jtag_khz 6000


# The APF27 board has a IMX27 chip and one fpga spartan3 200k
#source [find board/apf27.cfg]
#source [find target/imx27.cfg]
reset_config trst_and_srst

set  _CHIPNAME imx27
set  _ENDIAN little

# The bs tap
set _BSTAPID 0x1b900f0f
jtag newtap $_CHIPNAME bs \
  -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_BSTAPID

# The CPU tap
set _CPUTAPID 0x07926121
jtag newtap $_CHIPNAME cpu \
  -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID

set _TARGETNAME [format "%s.cpu" $_CHIPNAME]
target create $_TARGETNAME arm926ejs \
    -endian $_ENDIAN -chain-position $_TARGETNAME -variant arm926ejs

$_TARGETNAME configure \
  -work-area-virt 0xffff4c00 -work-area-phys 0xffff4c00 \
  -work-area-size  0x8000 -work-area-backup 1


arm7_9 dcc_downloads enable
#endof target/imx27.cfg

jtag newtap xc3s200a.fpga fpga \
	-irlen 6 \
	-irmask 0x3f \
	-ircapture 0x9 \
	-expected-id 0x2218093

$_TARGETNAME configure -event gdb-attach { reset init }
$_TARGETNAME configure -event reset-init { apf27_init }

proc apf27_init { } {
	# This setup puts RAM at 0xA0000000

	# reset the board correctly
	#reset run
	#reset halt

        # reset keeping fpga alive
 	soft_reset_halt 
	halt


	mww 0x10000000 0x20040304
	mww 0x10020000 0x00000000
	mww 0x10000004 0xDFFBFCFB
	mww 0x10020004 0xFFFFFFFF

	sleep 100

	# ========================================
	#  Configure DDR on CSD0 -- initial reset
	# ========================================
	mww 0x10027818 0x0000080F 
	mww 0xD8001010 0x0000000C 

	# ========================================
	#  Configure DDR on CSD0 -- wait 5000 cycle 
	# ========================================
	mww 0x10027828 0x55555555 
	mww 0x10027830 0x55555555 
	mww 0x10027834 0x55555555 
	mww 0x10027838 0x00005005 
	mww 0x1002783C 0x15555555 

	mww 0xD8001004 0x00695728

	mww 0xD8001000 0x92100000 
	mww 0xA0000F00 0x0

	mww 0xD8001000 0xA2100000 
	mww 0xA0000F00 0x0
	mww 0xA0000F00 0x0
	mww 0xA0000F00 0x0
	mww 0xA0000F00 0x0

	mww 0xD8001000 0xA2100000 
	mww 0xA0000F00 0x0
	mww 0xA0000F00 0x0
	mww 0xA0000F00 0x0
	mww 0xA0000F00 0x0

	mww 0xD8001000 0xB2100000 
	mwb 0xA0000033 0xDA
	mwb 0xA2000000 0x00

	mww 0xD8001000 0x82126080 
}

launch openocd with this config file and test the connection from a telnet terminal to send commands reset, soft_reset_halt, halt. Without the nSRST line wired to the board it is still possible to reset the apf27 with the reset button. ;-)

> openocd

6000 kHz
dcc downloads are enabled
Info : JTAG tap: imx27.bs tap/device found: 0x1b900f0f (Manufacturer: 0x787, Part: 0xb900, Version: 0x1)
Info : JTAG Tap/device matched
Info : JTAG tap: imx27.cpu tap/device found: 0x07926121 (Manufacturer: 0x090, Part: 0x7926, Version: 0x0)
Info : JTAG Tap/device matched
Info : JTAG tap: xc3s400a.fpga.fpga tap/device found: 0x02220093 (Manufacturer: 0x049, Part: 0x2220, Version: 0x0)
Info : JTAG Tap/device matched
Warn : no tcl port specified, using default port 6666
...

and from another terminal:

>  telnet 127.0.0.1 4444 

Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Open On-Chip Debugger
> reset
JTAG tap: imx27.bs tap/device found: 0x1b900f0f (Manufacturer: 0x787, Part: 0xb900, Version: 0x1)
JTAG Tap/device matched
JTAG tap: imx27.cpu tap/device found: 0x07926121 (Manufacturer: 0x090, Part: 0x7926, Version: 0x0)
JTAG Tap/device matched
JTAG tap: xc3s400a.fpga.fpga tap/device found: 0x02220093 (Manufacturer: 0x049, Part: 0x2220, Version: 0x0)
JTAG Tap/device matched

> soft_reset_halt
requesting target halt and executing a soft reset
target state: halted
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x000000d3 pc: 0x00000000
MMU: disabled, D-Cache: disabled, I-Cache: disabled

> halt
...

Working with BDI2000

Firstly, check if your BDI2000 is rev C (see on the back of the probe, near the serial number). If your probe is A or B, it does not support target supply voltage less than 3.0 V. In this cas, there might be a solution putting a serial resistor, see above Building a JTAG connector for apf27Dev board.

The BDI2000 probe comes with a firmware (bdiGDB) that make one able to connect directly GDB (GNU debugger) to the BDI2000 via ethernet. In the following example, we use a precompiled GDB from CodeSourcery. But any GDB configured for an ARM target might work.

You can use the following configuration file with BDI2000. It has been built like OpenOCD configuration file.

; bdiGDB configuration for ARMadeus APF27 board
; ---------------------------------------------
; Jonathan ILIAS-PILLET
;
; Many settings translated from OpenOCD's one, thanks to SSinyagin and Jorasse
[INIT]

; to be done : memory map

;This setup puts RAM at 0xA0000000

; reset the board correctly

wm32 0x10000000 0x20040304
wm32 0x10020000 0x00000000
wm32 0x10000004 0xDFFBFCFB
wm32 0x10020004 0xFFFFFFFF

delay 100

; ========================================
;  Configure DDR on CSD0 -- initial reset
; ========================================
wm32 0x10027818 0x0000080F
wm32 0xD8001010 0x0000000C

; ========================================
;  Configure DDR on CSD0 -- wait 5000 cycle 
; ========================================
wm32 0x10027828 0x55555555
wm32 0x10027830 0x55555555
wm32 0x10027834 0x55555555
wm32 0x10027838 0x00005005
wm32 0x1002783C 0x15555555

wm32 0xD8001004 0x00695728

wm32 0xD8001000 0x92100000
wm32 0xA0000F00 0x0

wm32 0xD8001000 0xA2100000
wm32 0xA0000F00 0x0
wm32 0xA0000F00 0x0
wm32 0xA0000F00 0x0
wm32 0xA0000F00 0x0

wm32 0xD8001000 0xB2100000
wm8 0xA0000033 0xDA
wm8 0xA2000000 0x00

wm32 0xD8001000 0x82126080


[TARGET]
CPUTYPE     ARM926E             ; processor core
CLOCK       1                   ; JTAG clock 1 = 16 MHz, 6 = 200KHz (last setting used only for testing)
WAKEUP      200                 ; millisecond to wait after a reset to let target start
SCANPRED    1 6                 ; JTAG chain starts with FGPA (spartan3), it has a 6 bits Instruction Register
SCANSUCC    1 4                 ; i.MX27 JTAG Controller, not used but present in the JTAG chain
TRST        OPENDRAIN           ; pullup provided by iMX27 (§7.4 JTAG Controller Pin List)
RESET       NONE
ENDIAN      LITTLE              ; memory model is little endian
;VECTOR      CATCH 0x1f          ; not used now
BREAKMODE   HARD                ; hardware breakpoints
;BREAKMODE   SOFT 0xDFFFDFFF     ;SOFT or HARD, ARM / Thumb break code
BDIMODE     AGENT

[HOST]
DEBUGPORT   2001                ; TCP port to connect GDB to
FORMAT      ELF                 ; format of image files
LOAD        MANUAL              ; load code manually after reset
PROMPT      APF27>

[FLASH]
; to be done

[REGS]
FILE    reg926e.def

You can also use the optionnal register file below :

;Register definition for ARM926E
;===============================
;
; name: user defined name of the register
; type: the type of the register
;       GPR     general purpose register
;       CP15    CP15 register
;       MM      memory mapped register
;       DMMx    direct memory mapped register with offset
;               x = 1..4
;               the base is defined in the configuration file
;               e.g. DMM1 0x02200000
; addr: the number, adddress or offset of the register
; size  the size of the register (8,16 or 32)
;
;name           type    addr            size
;-------------------------------------------
;
;
; CP15 Registers
;
;  Register Numbers for 926E:
;  +-------+-------+-------+-------+
;  | | | | | | | | | | | | | | | | |
;  +-+-----+-+-----+-------+-------+
;  |-|opc_1|-|opc_2|  CRm  |  nbr  |
;  +-+-----+-+-----+-------+-------+
;
;
id              CP15    0x0000          32      ;ID code
cache           CP15    0x0100          32      ;Cache type
tcm             CP15    0x0200          32      ;TCM status
control         CP15    0x0001          32      ;Control
ttb             CP15    0x0002          32      ;Translation table base
dac             CP15    0x0003          32      ;Domain access control
dfsr            CP15    0x0005          32      ;Data fault status
ifsr            CP15    0x0105          32      ;Inst fault status
far             CP15    0x0006          32      ;Fault address
;
fcsr            CP15    0x000d          32      ;Fast context switch PID
context         CP15    0x010d          32      ;Context ID
;

Now, we want to connect GDB to the BDI probe. Here are the IP addresses choosen for the example :

  • 192.168.5.1 is the host, where GDB runs
  • 192.168.5.2 is the BDI2000's address

GDB command and its output should looks like this :

(gdb) target remote 192.168.5.2:2001
Remote debugging using 192.168.5.2:2001
0xaff20cb4 in ?? ()

Open issues

  • TRST does not stop the CPU

TRST and SRST together reset the CPU

  • FPGA chip is not visible when OpenOCD detcts the TAPs.

FPGA chip is in low power mode at startup. Load some data in the fpga to enable it in jtag chain.

  • From Bootstrap mode FPGA and CPU are not accessible.

Yes, be sure to remove the bootstrap jumper to be able to use jtag. There is a small hardware modification to fix it but this change will disable the low power features.