/JTAG |
JTAG
Contents
JTAG is the specification for debug ports for larger CPUs and Systems. The JTAG Port on the LPC-H2148 Board can be used to flash and debug the software on the LPC-2148 ARM7 microcontroller.
Using the JTAG interface to program the LPC is faster and easier than using a serial interface (no need to worry about getting the right serial adapter for 3,3V etc.)
JTAG Adapters
There are several interfaces for JTAG
Amontec JTAGkey-Tiny has been successfully used to program the LPC. You also need a USB cable to connect the adapter's USB Mini port to your PC's USB port and then you're ready to go.
Software
OpenOCD is an open source JTAG software. It works under several unixoid operating systems as well as on Windows.
On Mac OS X, you can use MacPorts to install this software comfortably (using the command sudo port install openocd).
The Development Page for OpenOCD describes how to compile openocd on your own.
Working with OpenOCD
Before you can flash or debug your MCU you have to tell OpenOCD something about you JTAG/Target hardware, flash/ram type/organization....
All this information is stored in a config-file which will be loaded at the startup of the application.
Detailed information can be found in the OpenOCD help system.
The Configuration File
Beginning with OpenOCD 0.4.0, its Configuration file was split into 3 Parts:
- OpenOCD/GDB Server Configuration
- Interface - Defines the dongle
- Target - Defines the JTAG Taps
OpenOCD/GDB Server Configuration
First we specify the ports where the OpenOCD should listen.
telnet_port 4444 gdb_port 3333
This is also available for download: openocd.cfg.
Interface Configuration Part
The interface configuration depends on the JTAG hardware which you are using. You will find the corresponding configuration in your OpenOCD install directory under
./scripts/interface/
I'm using the arm-usb-ocd. This is an ft2232 device.
interface ft2232 ft2232_device_desc "Olimex OpenOCD JTAG A" ft2232_layout "olimex-jtag" ft2232_vid_pid 0x15BA 0x0003
Define the target hardware
In summary the target part should contain
- Set defaults
- Create taps
- Reset configuration
- Work areas
- CPU/Chip/CPU-Core specific features
- On-Chip flash
We use the LPC2148. You will find the corresponding configuration in your OpenOCD install directory under ...
./scripts/target/
# Use RCLK. If RCLK is not available fall back to 500kHz.
#
# Depending on cabling you might be able to eek this up to 2000kHz.
jtag_rclk 200
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME lpc2148
}
if { [info exists ENDIAN] } {
set _ENDIAN $ENDIAN
} else {
set _ENDIAN little
}
if { [info exists CPUTAPID ] } {
set _CPUTAPID $CPUTAPID
} else {
set _CPUTAPID 0x4f1f0f0f
}
jtag_nsrst_delay 200
jtag_ntrst_delay 200
# NOTE!!! LPCs need reset pulled while RTCK is low. 0 to activate
# JTAG, power-on reset is not enough, i.e. you need to perform a
# reset before being able to talk to the LPC2148, attach is not possible.
reset_config trst_and_srst srst_pulls_trst
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME -variant arm7tdmi-s_r4
$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 0
$_TARGETNAME configure -event reset-init {
# Force target into ARM state
arm core_state arm
# Do not remap 0x0000-0x0020 to anything but the flash (i.e. select
# "User Flash Mode" where interrupt vectors are _not_ remapped,
# and reside in flash instead).
#
# See section 7.1 on page 32 ("Memory Mapping control register") in
# "UM10139: Volume 1: LPC214x User Manual", Rev. 02 -- 25 July 2006.
# http://www.standardics.nxp.com/support/documents/microcontrollers/pdf/user.manual.lpc2141.lpc2142.lpc2144.lpc2146.lpc2148.pdf
mwb 0xE01FC040 0x01
}
# flash bank lpc2000 <base> <size> 0 0 <target#> <variant> <clock> [calc_checksum]
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 $_TARGETNAME lpc2000_v2 12000 calc_checksum
init
proc mt_erase_lock {} {
}
proc mt_reset_init {} {
jtag_khz 100
reset run
sleep 100
reset halt
wait_halt 2
# PLL disconnect PLLCON
mww 0xE01FC080 0x01
mww 0xE01FC08C 0xAA
mww 0xE01FC08C 0x55
# PLL disable PLLCON
mww 0xE01FC080 0x00
mww 0xE01FC08C 0xAA
mww 0xE01FC08C 0x55
# no prescaler CCLKCFG
mww 0xE01FC104 0x00
# internal RC CLKSRCSEL
mww 0xE01FC10C 0x00
#### main oscil. CLKSRCSEL
#### mww 0xE01FC10C 0x01
# remap to internal flash
mww 0xE01FC040 0x01
sleep 100
jtag_khz 1500
}
proc mt_flash_bin {IMGFILE} {
mt_reset_init
arm7_9 dcc_downloads enable
arm7_9 fast_memory_access enable
sleep 10
flash probe 0
flash erase_check 0
flash banks
sleep 10
flash erase_sector 0 0 25
sleep 100
flash write_image erase $IMGFILE 0x0 bin
reset run
sleep 10
}
proc mt_flash_hex {HEXFILE} {
mt_reset_init
arm7_9 dcc_downloads enable
arm7_9 fast_memory_access enable
sleep 10
flash probe 0
sleep 10
flash write_image erase $HEXFILE 0x0 ihex
reset run
sleep 10
}
proc mt_flash_elf {ELFFILE} {
mt_reset_init
arm7_9 dcc_downloads enable
arm7_9 fast_memory_access enable
sleep 10
flash probe 0
sleep 10
flash write_image erase $ELFFILE 0x0 elf
reset run
sleep 10
}This is also available for download: lpc2148.cfg
One will notice that the clock setting in the flash bank part is 12000 and not 14765. 12000kHz is the clock speed named in the LPC2148 manual.
The next important configuration option is the calc_checksum option used in the flash bank configuration.
This option initiates the checksum calculation ( at Adr. 0x14 ) of the exception vector tables located in the first 0x00 - 0x20 addresses in the flash. If you look at the startup file where the _vectors are defined , you will see a "nop" command as placeholder for the checksum. Without the correct checksum for the exception vectors the LPC2148 will not continue to boot from the flash
Flash your FC
Manual way
1. Fire up your OpenOCD
openocd -f openocd.cfg -f olimex-arm-usb-ocd.cfg -f lpc2148.cfg
After openocd startup you should see something like this:
Open On-Chip Debugger 0.5.0-dev-00555-ge3773e3 (2010-10-12-11:30)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.berlios.de/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
RCLK - adaptive
adapter_nsrst_delay: 200
jtag_ntrst_delay: 200
trst_and_srst srst_pulls_trst srst_gates_jtag trst_push_pull srst_open_drain
Info : RCLK (adaptive clock speed) not supported - fallback to 200 kHz
Info : JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
Info : Embedded ICE version 4
Info : lpc2148.cpu: hardware has 2 breakpoint/watchpoint units
if you have problems connecting to your MCU , for example if you get the wrong device ID try to vary the jtag clock. Maybe to "jtag_rclk 500"
2. Connect with you telnet client to "localhost" port "4444" or whatever you have configured in your config script.
At first, halt the mcu:
Open On-Chip Debugger > halt target state: halted target halted in ARM state due to debug-request, current mode: System cpsr: 0xa000005f pc: 0x0002578c
You can then do some diagnosis:
> targets
targets
TargetName Type Endian TapName State
-- ------------------ ---------- ------ ------------------ ------------
0* lpc2148.cpu arm7tdmi little lpc2148.cpu halted
> poll
poll
background polling: on
TAP: lpc2148.cpu (enabled)
target state: halted
target halted in ARM state due to debug-request, current mode: System
cpsr: 0xa000005f pc: 0x0002578c
> flash info 0
flash info 0
#0 : lpc2000 at 0x00000000, size 0x0007d000, buswidth 0, chipwidth 0
# 0: 0x00000000 (0x1000 4kB) protected
# 1: 0x00001000 (0x1000 4kB) protected
# 2: 0x00002000 (0x1000 4kB) protected
# 3: 0x00003000 (0x1000 4kB) protected
# 4: 0x00004000 (0x1000 4kB) protected
# 5: 0x00005000 (0x1000 4kB) protected
# 6: 0x00006000 (0x1000 4kB) protected
# 7: 0x00007000 (0x1000 4kB) protected
# 8: 0x00008000 (0x8000 32kB) protected
# 9: 0x00010000 (0x8000 32kB) protected
# 10: 0x00018000 (0x8000 32kB) protected
# 11: 0x00020000 (0x8000 32kB) protected
# 12: 0x00028000 (0x8000 32kB) protected
# 13: 0x00030000 (0x8000 32kB) protected
# 14: 0x00038000 (0x8000 32kB) protected
# 15: 0x00040000 (0x8000 32kB) protected
# 16: 0x00048000 (0x8000 32kB) protected
# 17: 0x00050000 (0x8000 32kB) protected
# 18: 0x00058000 (0x8000 32kB) protected
# 19: 0x00060000 (0x8000 32kB) protected
# 20: 0x00068000 (0x8000 32kB) protected
# 21: 0x00070000 (0x8000 32kB) protected
# 22: 0x00078000 (0x1000 4kB) protected
# 23: 0x00079000 (0x1000 4kB) protected
# 24: 0x0007a000 (0x1000 4kB) protected
# 25: 0x0007b000 (0x1000 4kB) protected
# 26: 0x0007c000 (0x1000 4kB) protected
lpc2000 flash driver variant: 1, clk: 12000kHzIf you want to cleanup your LPC including the configuration sector use the flash erase sector command:
> flash erase_sector 0 0 25 flash erase_sector 0 0 25 erased sectors 0 through 25 on flash bank 0 in 0.232993s
Sometimes it may be necessary to unprotect the flash:
> flash protect 0 0 25 off flash protect 0 0 25 off cleared protection for sectors 0 through 25 on flash bank 0
To flash your LPC call the flash script with the file you want to flash (note that the path is relative to the cwd of openocd):
> mt_flash_bin ngos-0.60/firmware/ngos.bin
mt_flash_bin ngos-0.60/firmware/ngos.bin
100 kHz
JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.
NOTE! Severe performance degradation without fast memory access enabled. Type 'help fast'.
JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
srst pulls trst - can not reset into halted mode. Issuing halt after reset.
target state: halted
target halted in Thumb state due to debug-request, current mode: Supervisor
cpsr: 0xa00000f3 pc: 0x7fffd2d6
NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.
NOTE! Severe performance degradation without fast memory access enabled. Type 'help fast'.
1500 kHz
dcc downloads are enabled
fast memory access is enabled
flash 'lpc2000' found at 0x00000000
successfully checked erase state
# 0: 0x00000000 (0x1000 4kB) erased
# 1: 0x00001000 (0x1000 4kB) erased
# 2: 0x00002000 (0x1000 4kB) erased
# 3: 0x00003000 (0x1000 4kB) erased
# 4: 0x00004000 (0x1000 4kB) erased
# 5: 0x00005000 (0x1000 4kB) erased
# 6: 0x00006000 (0x1000 4kB) erased
# 7: 0x00007000 (0x1000 4kB) erased
# 8: 0x00008000 (0x8000 32kB) erased
# 9: 0x00010000 (0x8000 32kB) erased
# 10: 0x00018000 (0x8000 32kB) erased
# 11: 0x00020000 (0x8000 32kB) erased
# 12: 0x00028000 (0x8000 32kB) erased
# 13: 0x00030000 (0x8000 32kB) erased
# 14: 0x00038000 (0x8000 32kB) erased
# 15: 0x00040000 (0x8000 32kB) erased
# 16: 0x00048000 (0x8000 32kB) erased
# 17: 0x00050000 (0x8000 32kB) erased
# 18: 0x00058000 (0x8000 32kB) erased
# 19: 0x00060000 (0x8000 32kB) erased
# 20: 0x00068000 (0x8000 32kB) erased
# 21: 0x00070000 (0x8000 32kB) erased
# 22: 0x00078000 (0x1000 4kB) erased
# 23: 0x00079000 (0x1000 4kB) erased
# 24: 0x0007a000 (0x1000 4kB) erased
# 25: 0x0007b000 (0x1000 4kB) erased
# 26: 0x0007c000 (0x1000 4kB) not erased
#0 : lpc2000 at 0x00000000, size 0x0007d000, buswidth 0, chipwidth 0
erased sectors 0 through 25 on flash bank 0 in 0.468001s
auto erase enabled
Verification will fail since checksum in image (0xe1a00000) to be written to flash is different from calculated vector checksum (0xb9205f84).
To remove this warning modify build tools on developer PC to inject correct LPC vector checksum.
wrote 393216 bytes from file ngos-0.60/firmware/ngos.bin in 14.560740s (26.372 KiB/s)
JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)Type shutdown to end OpenOCD and enjoy your NGOS
All-in-One command
You can use the -c parameter of OpenOCD to execute commands:
openocd -f openocd.cfg -f olimex-arm-usb-ocd.cfg -f lpc2148.cfg -c halt -c targets -c poll -c "mt_flash_bin ngos-0.60/firmware/ngos.bin" -c shutdown
