OMAP3530 ICEPICK

The page is about OMAP3530 ICEPICK. See BeagleBoard JTAG page for more info about JTAG on OMAP3530 used at BeagleBoard.

ICEPICK infos

 * Regarding EMU0/EMU1 pins on BeagleBoard, pulling both pins down does not make Cortex-A8 CPU accessible. Only one TAP is visible (ICEPick). Therefore OpenOCD is not able to access ARM TAP. The documentation for the control of EMU0/EMU1 is very misleading:

0 0 ICEPick + default TAP(s) 0 1 ICEPick Reserved 1 0 ICEPick Wait-in-reset 1 1 ICEPick Default condition NOTES: ICEPick is always in the scan chain Default TAPs are the ARM and the ETB

This table is identical to the Davinci documentation, with one BIG difference:
 * The OMAP3xx has NO default TAP (ARM or ETB taps) which means that the configuration of EMU0-L/EMU1-L doesn't add ARM to scan chain (above table is wrong, though).
 * If you use BeagleBoard Adapter Kit with Flyswatter, make sure configure EMU0 & EMU1 the correct way. There are several possible ways, though. See connection picture how to do it the right way: In contrast to the picture EMU0 & EMU1 jumpers at JTAG adapter should be both at 1-2 position (touching J2).
 * The OMAP3xx uses a TAP router, it needs to be programmed with the information about available TAPS first, before ARM is accessible. Once the DAP has been added to the TAP router, via a programming sequence, the ARM core can be accessed.
 * TI has a good presentation describing the functionality of the ICEPick TAP Router (or generically refered to as JTAG Route Controller or JRC). The ICEPick jtag device ID is 0x0b73b02f (Manufacturer: 0x017, Part: 0xb73b, Version: 0x0) and is the same as the Davinci series.
 * ICEPICK IR length is 6
 * ARM IR length is 4
 * ICEPICK ID code is at DR 0x4 32bit length: 0x0B7AE02F
 * ARM ID code is at DR 0xE 32bit length: 0x0B6D602F
 * If above basics work, additionally MMU, cache support and some include files for A8 might be added to OpenOCD.

Adding TAPs to the Scan Chain
The TAP router must be programmed to add additional TAPs to the scan chain. The following JTAG scans must be completed before the CoreSight DAP is added to the scan chain.

Parameter : The IR pre-amble count is '0'. Parameter : The IR post-amble count is '0'. Parameter : The DR pre-amble count is '0'. Parameter : The DR post-amble count is '0'. Parameter : The IR main count is '6'. Parameter : The DR main count is '1'.
 * 1) Function  : Update the JTAG preamble and post-amble counts.

Parameter : The route to JTAG shift state is 'shortest transition'. Parameter : The JTAG shift state is 'shift-ir'. Parameter : The JTAG destination state is 'pause-ir'. Parameter : The bit length of the command is '6'. Parameter : The send data value is '0x00000007'. Parameter : The actual receive data is 'discarded'.
 * 1) Function  : Do a send-only JTAG IR/DR scan.

Parameter : The route to JTAG shift state is 'shortest transition'. Parameter : The JTAG shift state is 'shift-dr'. Parameter : The JTAG destination state is 'pause-dr'. Parameter : The bit length of the command is '8'. Parameter : The send data value is '0x00000089'. Parameter : The actual receive data is 'discarded'.
 * 1) Function  : Do a send-only JTAG IR/DR scan.

Parameter : The route to JTAG shift state is 'shortest transition'. Parameter : The JTAG shift state is 'shift-ir'. Parameter : The JTAG destination state is 'pause-ir'. Parameter : The bit length of the command is '6'. Parameter : The send data value is '0x00000002'. Parameter : The actual receive data is 'discarded'.
 * 1) Function  : Do a send-only JTAG IR/DR scan.

Parameter : The port address field is '0x0f000000'. Parameter : The port address value is '3'.
 * 1) Function  : Embed the port address in next command.

Parameter : The route to JTAG shift state is 'shortest transition'. Parameter : The JTAG shift state is 'shift-dr'. Parameter : The JTAG destination state is 'pause-dr'. Parameter : The bit length of the command is '32'. Parameter : The send data value is '0xa3002108'. Parameter : The actual receive data is 'discarded'.
 * 1) Function  : Do a send-only JTAG IR/DR scan.

Parameter : The JTAG shift state is 'shift-ir'. Parameter : The JTAG destination state is 'run-test/idle'. Parameter : The bit length of the command is '6'. Parameter : The send data value is 'all-ones'. Parameter : The actual receive data is 'discarded'.
 * 1) Function  : Do a send-only all-ones JTAG IR/DR scan.

Parameter : The count of TCLK pulses is '10'.
 * 1) Function  : Wait for a minimum number of TCLK pulses.

Parameter : The IR pre-amble count is '0'. Parameter : The IR post-amble count is '6'. Parameter : The DR pre-amble count is '0'. Parameter : The DR post-amble count is '1'. Parameter : The IR main count is '4'. Parameter : The DR main count is '1'.
 * 1) Function  : Update the JTAG preamble and post-amble counts.

Once the DAP is added to the scan chain, the debugger can communicate with the CortexA8 processor.

Screen shot of OMAP3530 scan chain from ARM's RealView ICE.

ICEPICK instructions
urjtag tool was used to get an better idea of how OMAP3 ICEPICK is supposed to work. It is easier hackable than other JTAG tools, e.g. OpenOCD.

Discovery
The following log shows a IR discovery scan of the icepick with urjtag.

Replace ' ' of the cable command with the cable type you use. E.g.


 * cable JTAGkey for Amontec JTAGkey (FT2232) Cable
 * cable Flyswatter for TinCanTools Flyswatter Cable

See help cable for a list of supported debug interfaces.

jtag> cable Connected to libftd2xx driver. jtag> detect IR length: 6 Chain length: 1 Device Id: 0 (0x0000000000000000) chain.c(133) Part 0 without active instruction chain.c(184) Part 0 without active instruction chain.c(133) Part 0 without active instruction jtag> idcode 4 Reading 4 bytes if idcode Read 00101111 11100000 01111010 00001011 jtag> discovery Detecting IR length ... 6 Detecting DR length for IR 111111 ... 1 Detecting DR length for IR 000000 ... 1 Detecting DR length for IR 000001 ... 1 Detecting DR length for IR 000010 ... 1 Detecting DR length for IR 000011 ... 1 Detecting DR length for IR 000100 ... 32 Detecting DR length for IR 000101 ... 32 Detecting DR length for IR 000110 ... 1 Detecting DR length for IR 000111 ... 8 Detecting DR length for IR 001000 ... 32 Detecting DR length for IR 001001 ... 1 Detecting DR length for IR 001010 ... 1 Detecting DR length for IR 001011 ... 1 Detecting DR length for IR 001100 ... 1 Detecting DR length for IR 001101 ... 1 Detecting DR length for IR 001110 ... 1 Detecting DR length for IR 001111 ... 1 Detecting DR length for IR 010000 ... 1 Detecting DR length for IR 010001 ... 1 Detecting DR length for IR 010010 ... 1 Detecting DR length for IR 010011 ... 1 Detecting DR length for IR 010100 ... 1 Detecting DR length for IR 010101 ... 1 Detecting DR length for IR 010110 ... 1 Detecting DR length for IR 010111 ... Warning: TDO seems to be stuck at 0 -1 Detecting DR length for IR 011000 ... Warning: TDO seems to be stuck at 0 -1 ...(even more DTO seems stucked)... Detecting DR length for IR 011100 ... Warning: TDO seems to be stuck at 0 -1 Detecting DR length for IR 011101 ... Warning: TDO seems to be stuck at 0 Detecting DR length for IR 011111 ... 1 Detecting DR length for IR 100000 ... Warning: TDO seems to be stuck at 0 -1 Detecting DR length for IR 100100 ... Warning: TDO seems to be stuck at 0 -1 .... (The rest gets the same error codes)

Note: The output of idcode command above

00101111 => 0x2F 11100000 => 0xE0 01111010 => 0x7A 00001011 => 0x0B

is the same as OpenOCD reports at startup

tap/device found: 0x0b7ae02f (Manufacturer: 0x017, Part: 0xb7ae, Version: 0x0)

Configuration
The following code snippet is part of a hackish 'omap3' command added to urjtag to verify basic ICEPICK initialization. See urjtag mailing list for complete patch. This is an urjtag implementation of above scan chain configuration documentation.

printf( _("Starting OMAP3 ICEPICK initialization sequence ... ") ); /* Switch to DR 0x7, should be 8 bit register */ register_init( ir, "000111" ); tap_capture_ir( chain ); tap_shift_register( chain, ir, NULL, EXITMODE_UPDATE); /* Write 0x89 to DR 0x7 */ drlen = 8; drin = register_init( register_alloc( drlen ), "10001001" ); tap_capture_dr( chain ); tap_shift_register( chain, drin, NULL, EXITMODE_UPDATE); register_free( drin ); /* Switch to DR 0x2 */ register_init( ir, "000010" ); tap_capture_ir( chain ); tap_shift_register( chain, ir, NULL, EXITMODE_UPDATE); /* Write 0xa3002108 to DR 0x2 */ drlen = 32; drin = register_init( register_alloc( drlen ), 			     "10100011000000000010000100001000" ); tap_capture_dr( chain ); tap_shift_register( chain, drin, NULL, EXITMODE_UPDATE); register_free( drin ); /* Switch IR to 'all-ones' */ register_init( ir, "111111" ); tap_capture_ir( chain ); tap_shift_register( chain, ir, NULL, EXITMODE_IDLE); register_free( ir ); /* Clock at least 10 TCLK in run test idle */ chain_defer_clock( chain, 0, 0, 10 ); printf( _(" - Finished\n") );