Confusion about reset_config

Hello!

I am somewhat confused about the reset_config operation. The description on http://openfacts.berlios.de/index-en.ph … figuration suggests there are broken boards/processors/jtag-adapters. Now I am not completely sure whether my setup is such a broken one and what consequences this might have.

The description says, there are

(e.g. Philips LPC2000 “broken” board layout)

What does that mean? Is this just one specific board with an lpc2000? Or is this lpc20xx series? Or lpc2xxx?

My board has the lpc2292 and srst is connected to the reset pin of the processor while trst is connected to processor’s trst. Is this a “broken” configuration? How would a proper config look like? Does the amontec jtagkey have separate srst/trst?

I want to use the reset_halt or reset_init operation mode because the processor would crash with run_and_init if it starts executing instructions from a non-programmed flash. So I tried this:

#daemon configuration
telnet_port 4444
gdb_port 3333

#interface
interface ft2232
ft2232_device_desc "Amontec JTAGkey A"
ft2232_layout jtagkey
ft2232_vid_pid 0x0403 0xcff8
jtag_speed 1
#use combined on interfaces or targets that can't set TRST/SRST separately
reset_config trst_and_srst
# srst_pulls_trst

#jtag scan chain
#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)
jtag_device 4 0x1 0xf 0xe
#jtag_nsrst_delay 333
#jtag_ntrst_delay 333

#target configuration
daemon_startup reset
#target <type> <startup mode>
#target arm7tdmi <reset mode> <chainpos> <endianness> <variant>
#target arm7tdmi little run_and_init 0 arm7tdmi-s_r4
target arm7tdmi little reset_halt 0 arm7tdmi-s_r4
target_script 0 reset h2222_init.script
run_and_halt_time 0 30
#working_area 0 0x40000000 0x40000 nobackup

But I get this:

Info:    openocd.c:84 main(): Open On-Chip Debugger (2006-11-22 14:00 CEST)
Warning: jtag.c:1045 jtag_read_buffer(): value captured during scan didn't pass the requested check: captured: 0x00 check_value: 0x01 check_mask: 0x0f
Warning: jtag.c:1045 jtag_read_buffer(): value captured during scan didn't pass the requested check: captured: 0x00 check_value: 0x01 check_mask: 0x0f
Error:   armv4_5.c:186 armv4_5_mode_to_number(): invalid mode value encountered
Error:   arm7_9_common.c:972 arm7_9_debug_entry(): cpsr contains invalid mode value - communication failure
Error:   target.c:1054 handle_target(): couldn't poll target, exiting
Command exited with non-zero status 255

Is there any way to get this working?

Sorry if the documentation in the Wiki isn’t clear enough. The part you quoted has a comma after “LPC2000” which is meant to indicate an enumeration. It would have been more appropriate to write “e.g. Philips LPC2000 or broken board layouts”.

The LPC2000 can’t be debugged out of reset because the uC internally asserts nTRST whenever nSRST is asserted (srst_pulls_trst). This is necessary to make the LPC’s content read protection (CRP) work, which relies on being able to disable the JTAG port before an intruder gets control over the core. The course of action is:

  • Debugger asserts nSRST

  • LPC asserts nTRST, too, putting the debug logic in reset state (clears all breakpoints)

  • Normally, a debugger would now program the EmbeddedICE macrocell to request debug entry, which would cause the core to enter debug mode before the first instruction can be executed - this isn’t possible because nTRST is held asserted, and the debugger can’t access JTAG

  • The debugger releases nSRST

  • LPCs releases nTRST, too

  • The LPC starts fetching instructions from its internal bootloader

  • The bootloader disables the JTAG port by unconditionally switching the pins to GPIO mode within the first three instructions. That window is too narrow for a debugger to get control over the target

  • If CRP isn’t enabled, the JTAG port is reenabled later (only if RTCK was pulled low)

If you want to debug own code out of reset, put an infinite loop (0xeafffffe) at the reset vector, and manually advance to the beginning of your reset handler.

Best regards,

Dominic

Dominic:
Sorry if the documentation in the Wiki isn’t clear enough. The part you quoted has a comma after “LPC2000” which is meant to indicate an enumeration. It would have been more appropriate to write “e.g. Philips LPC2000 or broken board layouts”.

Should it not read "lpc2xxx or broken board layouts" then?

If you want to debug own code out of reset, put an infinite loop (0xeafffffe) at the reset vector, and manually advance to the beginning of your reset handler.

But isn't there a chicken-egg problem here? How to get the reset-vector and this infinite-loop instruction into memory? Would it be possible to write them into RAM via boundary-scan?

Should it not read “lpc2xxx or broken board layouts” then?

Sorry, I don't understand what you mean.

But isn’t there a chicken-egg problem here? How to get the reset-vector and this infinite-loop instruction into memory? Would it be possible to write them into RAM via boundary-scan?

I was talking about the case where you have your own code in flash (internal or external), and you're interested in debugging that codes reset behaviour. Getting your code there is easy - use the LPC2000's built-in bootloader, or use the OpenOCD to write the flash.

Regards,

Dominic

Dominic:

Should it not read “lpc2xxx or broken board layouts” then?

Sorry, I don't understand what you mean.
Well, the confusion is whether e.g. lpc2292 is affected by the problem. "lpc2xxx" would indicate that it is affected. "lpc2000" suggests that only this specific chip is affected.

But isn’t there a chicken-egg problem here? How to get the reset-vector and this infinite-loop instruction into memory? Would it be possible to write them into RAM via boundary-scan?

I was talking about the case where you have your own code in flash (internal or external), and you're interested in debugging that codes reset behaviour.
So we were talking about different things...I was talking about bootstrapping virgin hardware and getting the code into the flash.

Getting your code there is easy - use the LPC2000’s built-in bootloader, or use the OpenOCD to write the flash.

But the builtin-bootloader works only over rs232. And openocd will fail to recognize the target if there's no valid program to execute until JTAG gets the processor halted.

Well, the confusion is whether e.g. lpc2292 is affected by the problem. “lpc2xxx” would indicate that it is affected. “lpc2000” suggests that only this specific chip is affected.

There is no LPC2000 afaik. I'm using the term LPC2000 when I mean any ARM7 based NXP microcontroller.

But the builtin-bootloader works only over rs232. And openocd will fail to recognize the target if there’s no valid program to execute until JTAG gets the processor halted.

Have the LPC enter the built-in bootloader. This gives you a known target state with working JTAG.

Regards,

Dominic

Dominic:

Well, the confusion is whether e.g. lpc2292 is affected by the problem. “lpc2xxx” would indicate that it is affected. “lpc2000” suggests that only this specific chip is affected.

There is no LPC2000 afaik. I'm using the term LPC2000 when I mean any ARM7 based NXP microcontroller.
I see. I just wanted to point out that for light-minded readers like me ;-) the term lpc2xxx would make this fact more obvious.

But the builtin-bootloader works only over rs232. And openocd will fail to recognize the target if there’s no valid program to execute until JTAG gets the processor halted.

Have the LPC enter the built-in bootloader. This gives you a known target state with working JTAG.
How do I do this via JTAG? I thought this can be done only over serial line?

How do I do this via JTAG? I thought this can be done only over serial line?

The bootloader is entered when P0.14 is held low during reset. How this is accomplished depends on your board. On my Olimex LPC-H2294 there's a dip-switch that allows P0.14 to be pulled low.

You don’t need to talk to the bootloader - it’s enough if it just sits there waiting for communication on a serial line.

Regards,

Dominic