EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Debug JTAG - SCAN_N

Started by krisgorn April 4, 2006
In datasheet of ARM7TDMI-S is writing that instruction SCAN_N load 0x8
value into register but I always get 0x0 value on LPC2138 (and another
LPC2000 family chips).
When I run my code with ARM7TDMI core chips (AT91SAM7, OKI ML67) I get
proper value 0x8.
Any suggestions?

Regards

An Engineer's Guide to the LPC2100 Series

That's a bug in the LPC2000s. I asked Philips support, but they didn't know
(or didn't care) about it. Anyway, it's not a real problem, you just can't
rely on the SCAN_N value to ensure JTAG communication is correct.

Regards,

Dominic

On Tuesday 04 April 2006 22:01, krisgorn wrote:
> In datasheet of ARM7TDMI-S is writing that instruction SCAN_N load 0x8
> value into register but I always get 0x0 value on LPC2138 (and another
> LPC2000 family chips).
> When I run my code with ARM7TDMI core chips (AT91SAM7, OKI ML67) I get
> proper value 0x8.
> Any suggestions?
>
> Regards
Thanks!!

I have another problem with debugging.

My code works fine with ARM7TDMI (AT91SAM7, OKI ML67) except reading
RAM memory of LPC2000. Writing of RAM works fine on LPC2000.

When I run code:

Put in R0 Addr = 0xA0000000 (R0 writing OK)

NOP bit33=0
NOP bit33=1
LDMIA R0!, {R1-R8} bit33=0
RESTART
INTEST
NOP bit33=0

I've get:

R0: 0x40000060
R1-R8: 0XE1A00000

In R0 should be 0x40000020. It look like the LDMIA R0!, {R1-R8} is
three times executing.

When I run this code with AT91SAM7 I've get correct value of
R0: 0x00200020 and in R1-R8 values of RAM.

Regards
I suspect that if you add a NOP after the LDMIA
instruction so that the LDMIA is in the decode stage
before you kick off the restart then you will get the
expected results.

It appears that the core isn't going back up to full
speed and when you think you are reading out the value
of the registers with a STM instruction, you are
actually getting your NOPs (the 0xE1A00000 values in
R1-R8 are the MOV R0,R0 instruction) thrown back at
you. You probably aren't clocking out the registers
from the STM instruction but instead you are clocking
in the data for the LDMIA so the NOPs are staying on
the data bus when you come back around to read them
since the core thinks it is reading from the data bus
and not writing to it.

Shouldn't you be expecting 0xa0000020 back in R0 and
not 0x40000020?

--- krisgorn wrote:
> When I run code:
>
> Put in R0 Addr = 0xA0000000 (R0 writing OK)
>
> NOP bit33=0
> NOP bit33=1
> LDMIA R0!, {R1-R8} bit33=0
> RESTART
> INTEST
> NOP bit33=0
>
> I've get:
>
> R0: 0x40000060
> R1-R8: 0XE1A00000
__________________________________________________
--- In l..., Stanley Frederickson
wrote:
>
> I suspect that if you add a NOP after the LDMIA
> instruction so that the LDMIA is in the decode stage
> before you kick off the restart then you will get the
> expected results.
>
> It appears that the core isn't going back up to full
> speed and when you think you are reading out the value
> of the registers with a STM instruction, you are
> actually getting your NOPs (the 0xE1A00000 values in
> R1-R8 are the MOV R0,R0 instruction) thrown back at
> you. You probably aren't clocking out the registers
> from the STM instruction but instead you are clocking
> in the data for the LDMIA so the NOPs are staying on
> the data bus when you come back around to read them
> since the core thinks it is reading from the data bus
> and not writing to it.
>
> Shouldn't you be expecting 0xa0000020 back in R0 and
> not 0x40000020?

I made mistake. In my last message should be
"Put in R0 Addr = 0x40000000 (R0 writing OK)"
so I expecting 0x40000020 back in R0.

I add NOP after LDMIA and now I get:

R0: 0x40000020
R1: NOP
R2-R8: correct values of RAM from address 0x40000004.

In R0 is NOP but should be value of RAM from address 0x40000000.

Reading of registers is OK becouse I always get this same values.

Thanks and regards
Sounds like you are getting pretty close.

> Reading of registers is OK becouse I always get this
> same values.
The reading results sound like they are consistent but
wrong so I am suspicious that this is where your
problem now lies.

Are the contents of R2-R8 correct or does R2 actually
contain what you would have expected to have been
returned in R1? If so, then this means that you are
missing a NOP between the STM instruction and the
operation where you actually start reading the
contents of the registers out over the databus. Is it
possible that you are using the wrong machine code for
your STM instruction so that it is missing the R1
register from the bitmask? This coupled with a
missing NOP or the use of STMDB would give you the
results that you mention below.

> In R0 is NOP but should be value of RAM from address
> 0x40000000.
I take it that you are actually talking about R1 here
and not R0?

Hope this helps?
--- krisgorn wrote:
> I add NOP after LDMIA and now I get:
>
> R0: 0x40000020
> R1: NOP
> R2-R8: correct values of RAM from address
> 0x40000004.

__________________________________________________
> Are the contents of R2-R8 correct or does R2 actually
> contain what you would have expected to have been
> returned in R1?

I write what I get precisely:

R0: 0x400000020 <- OK
R1: machine code of instruction which I put after LDM (I testing with
few instruction), here should be values of memory from 0x4000000
R2: values of memory from 0x4000004 <- OK
R3: values of memory from 0x4000008 <- OK
etc.

It isn't problem with NOP before and after STM instruction.
Machine code of all instruction is good.

My code (with or without putting instruction after LDM) working well
with AT91SAM7S64 and ML67Q5003 and with LPC2000 like above (I test it
with LPC2129, LPC2138, LPC2148). I know that this is ARM7TDMI cores,
not ARM7TMDI-S like in Philips ARM but I don't find any difference in
data sheet in debug of this core. Thats is magic for me, especialy
that writing memory and writing/reding ICE registes works OK.
I look in few open source soft for debugging of ARM7 and in all of
them was not instruction after LDM. Just RESTART after instruction
which is running at system speed.

Thanks and regards
This is the Atmel document that I used while I was
writing my JTAG based debugger for the LPC chips:
http://www.atmel.com/dyn/resources/prod_documents/doc2668.pdf

It was page 15 of this document where I saw the
reference to the NOP after the LD instruction (the
document is using a LDR instruction but I was using a
LDM instruction) to put the instruction in the decode
stage before the restart. I also saw this mentioned
in at least one other part of the document as well
(page 18 with the full-speed STMIA). I didn't do this
when I first wrote my memory reading code and I just
got gibberish back. Once I added it, everything
started to work as I expected.

You mentioned in your original e-mail that you end the
memory load with the following 2 JTAG commands:
RESTART
INTEST

Do you also read the DSR ICE register to determine if
the core is back in the halted state or know that you
are just waiting long enough for the full-speed memory
access to occur? I have also found that the RESTART
command switches the TAP back to scan chain 0. What
happens if you insert a SCAN_N (chain 2) command
between the RESTART and INTEST commands? The
functionality of scan chain 0 will definitely be
different between various chip vendors.
__________________________________________________

The 2024 Embedded Online Conference