EmbeddedRelated.com
Forums

Timer problems when debugging with LPC2148

Started by a6o4o June 26, 2007
Hi

I am pretty new in the LPC world, coming from the MSP430. I really am
not very happy with the LPC yet, I really have a hard time getting
used to it after being spoiled by the MSP430. But maybe it's just
because I am new and I just don't understand all of it.

I am since days trying to find an error in my code but can't find the
error and the circunstance of the bad debugging of my LPC2148 doesn't
make it easy. I found many other problems but I somehow could solve
them.
I got a little OS (ported from the MSP430) with dispatcher,
kerneleventqueue with sendevents, timerevents etc. I got the big
problems with the timer event handling.
I have Timer0 running at 1/2 CPU clock from 0 to FFFFFFFF. (60MHz)
I am using Crossworks (nice GUI, bad compiler) and Olimex Wiggler on
LPT1.
MR1 is set to FFFFFFFF to check overflow and MR0 is the next timer
event that needs to be called.
It took me 2 days to find out that writing T0IR |= 0x00000001 cleared
the WHOLE register instead of bit0! NO idea if this is a Crossworks
problem or LPC! I changed it now to = and since then it works.

I also sometimes could see in the debugger that when I do reenable the
Timer0 interrupt VICIntEnable = 0x00000010; that it DOESN'T set it?!
(I did set the VINIntClr = 0x00000000; before to make sure it's set
back to 0, don't know if that's needed? I understood it like that from
the manual)
I did step by step in the ASM code and it DOES set the VICIntEnable to
1 and then 1 step later it gets reset to 0?! Why could that be?

What also bugs me a lot: I can't really debug like I did on the
MSP430. When I step by step with the debugger the Timer counter T0TC
makes HUGES jumps! I mean, I step ONE code line and the Timercounter
steps 300-600ms worth of counts!?! I can't debug like that since it
messes up my whole timereventqueue handling when working step by step
to check if everything is ok. On the MSP430 it would count the timer
so much steps as the core would need to execute the codeline.
What do I do wrong? I didn't find anything about this here when doing
a search.

What I also observed, I get for example a T0IR flag set showing that
an INT is set. The Timer0 VICIntEnable is set to 0x00000010 and I keep
debugging step by step hoping that it jumps to the Timer Interrupt ISR
I got, but it doens't?! On the MSP430 it would jump inmediattly to the
jumper routing. (and yes, I do set the Vectoradress to 0 at the end of
the ISR)

One other thing: I had many short global interrupt disables/enables
(used the crosswork compiler command, couldn't find any info about
this on the NXP user manual?!) during changing the timerevent queue
and so.
But I had really HUGE problems and the debugger hardly worked! It
would stop on a breakpoint sometimes, sometimes not, you couldn't step
by step otherwise it would crash etc.
I changed all global interrupts to

srOld = VICIntEnable; // store the old value

VICIntClr = 0xFFFFFFF0; // disable ints

VICIntClr = 0x00000000; // enables ints
VICIntEnable = srOld;

I store the enable int value in a variable, set all ints to 0 except
the first 4 (Arm Core and Watchdog stuff, I thought I shouldn't change
those) and restore the it by moving the variable back to the enable
register. Since this workaround the debugger seems to work again
better.

But is that normal?? On the MSP430 I never had such a hassle with
disabling global ints?

Things like that make it frustrating for me working on this LPC but
maybe it's just me doing things wrong...

I would be happy about any hint or help...

thank you

Michel

An Engineer's Guide to the LPC2100 Series

----- Original Message -----
From: "a6o4o"
To:
Sent: Tuesday, June 26, 2007 7:11 AM
Subject: [lpc2000] Timer problems when debugging with LPC2148
> Hi
>
> I am pretty new in the LPC world, coming from the MSP430. I really am
> not very happy with the LPC yet, I really have a hard time getting
> used to it after being spoiled by the MSP430. But maybe it's just
> because I am new and I just don't understand all of it.
>
> I am since days trying to find an error in my code but can't find the
> error and the circunstance of the bad debugging of my LPC2148 doesn't
> make it easy. I found many other problems but I somehow could solve
> them.
> I got a little OS (ported from the MSP430) with dispatcher,
> kerneleventqueue with sendevents, timerevents etc. I got the big
> problems with the timer event handling.
> I have Timer0 running at 1/2 CPU clock from 0 to FFFFFFFF. (60MHz)
> I am using Crossworks (nice GUI, bad compiler) and Olimex Wiggler on
> LPT1.
> MR1 is set to FFFFFFFF to check overflow and MR0 is the next timer
> event that needs to be called.
> It took me 2 days to find out that writing T0IR |= 0x00000001 cleared
> the WHOLE register instead of bit0! NO idea if this is a Crossworks
> problem or LPC! I changed it now to = and since then it works.

T0IR is an 8 bit register! T0IR |= 0x01 works for me.

Leon
I remember having strange jumps, etc. in the debugger when I had the compiler optimization level too high. Try setting it to no optimization and see if that helps. There might also be an issue with ARM vs Thumb code, but am not sure.

Arthur

----- Original Message ----
From: Leon
To: l...
Sent: Tuesday, June 26, 2007 11:11:49 AM
Subject: Re: [lpc2000] Timer problems when debugging with LPC2148

----- Original Message -----

From: "a6o4o"

To:

Sent: Tuesday, June 26, 2007 7:11 AM

Subject: [lpc2000] Timer problems when debugging with LPC2148

> Hi

>

> I am pretty new in the LPC world, coming from the MSP430. I really am

> not very happy with the LPC yet, I really have a hard time getting

> used to it after being spoiled by the MSP430. But maybe it's just

> because I am new and I just don't understand all of it.

>

> I am since days trying to find an error in my code but can't find the

> error and the circunstance of the bad debugging of my LPC2148 doesn't

> make it easy. I found many other problems but I somehow could solve

> them.

> I got a little OS (ported from the MSP430) with dispatcher,

> kerneleventqueue with sendevents, timerevents etc. I got the big

> problems with the timer event handling.

> I have Timer0 running at 1/2 CPU clock from 0 to FFFFFFFF. (60MHz)

> I am using Crossworks (nice GUI, bad compiler) and Olimex Wiggler on

> LPT1.

> MR1 is set to FFFFFFFF to check overflow and MR0 is the next timer

> event that needs to be called.

> It took me 2 days to find out that writing T0IR |= 0x00000001 cleared

> the WHOLE register instead of bit0! NO idea if this is a Crossworks

> problem or LPC! I changed it now to = and since then it works.

T0IR is an 8 bit register! T0IR |= 0x01 works for me.

Leon



____________________________________________________________________________________
Shape Yahoo! in your own image. Join our Network Research Panel today! http://surveylink.yahoo.com/gmrs/yahoo_panel_invite.asp?a=7
--- In l..., "a6o4o" wrote:

> It took me 2 days to find out that writing T0IR |= 0x00000001
cleared
> the WHOLE register instead of bit0! NO idea if this is a Crossworks
> problem or LPC! I changed it now to = and since then it works.

It's a USER problem. From NXP documentation:

"If an interrupt is generated then the corresponding bit in the IR
will be high. Otherwise, the bit will be low. Writing a logic one to
the corresponding IR bit will reset the interrupt. Writing a zero has
no effect."

Hence if you or-in a 1 you reset all interrupts.

With respect to your other VIC problems, note that the VIC is read-
sensitive irrespective of whether you are reading from the CPU or
over JTAG. You *will* have problems if you single-step code and
display or watch the VIC regsiters; symptoms include lost interrupts,
interrupts not firing, and so on.

-- Paul.
Few more words:
When you stop the core (by single stepping) it doesn't stop the clock
to the peripherals - so all timers, UART's are running. That's why
you can not see the timer to increment count by count.
This may introduce a problem, if you use it as a time base by just
adding some constant to the previous value of the match register,
like this:
T0MR0 += TMR_PERIOD;
It works perfect if the core is running continuously, but if you stop
it the timer runs away and the next interrupt will happen after 2^32
clocks. So, it is a good practice is you also check if the new value
is not away from the current TC count:

temp_long = T0MR0 + TMR_PERIOD;
T0TCR = 0x00;
if ((temp_long - T0TC) > TMR_PERIOD) {
temp_long = T0TC + TMR_PERIOD;
}
T0MR0 = temp_long;
T0TCR = 0x01;

Regards,
Ivan
yes, after many retries I found this also out... I did stop the timer
now for the parts I wanted to debugg... really annoying but it seems
to work and since the timer runs so fast it's not as critical...

thanx guys!

--- In l..., "i_ivanov2001"
wrote:
> Few more words:
> When you stop the core (by single stepping) it doesn't stop the
clock
> to the peripherals - so all timers, UART's are running. That's why
> you can not see the timer to increment count by count.
> This may introduce a problem, if you use it as a time base by just
> adding some constant to the previous value of the match register,
> like this:
> T0MR0 += TMR_PERIOD;
> It works perfect if the core is running continuously, but if you
stop
> it the timer runs away and the next interrupt will happen after
2^32
> clocks. So, it is a good practice is you also check if the new
value
> is not away from the current TC count:
>
> temp_long = T0MR0 + TMR_PERIOD;
> T0TCR = 0x00;
> if ((temp_long - T0TC) > TMR_PERIOD) {
> temp_long = T0TC + TMR_PERIOD;
> }
> T0MR0 = temp_long;
> T0TCR = 0x01;
>
> Regards,
> Ivan
>