Reply by nutleycottage June 23, 20092009-06-23
Hi Kevin,

You can remove the

VIC_Address = 0;

from the interrupt handler - the irq_handler will do this. The source code to ctl_set_isr and irq_handler is in the system files folder of the project.

Regards
Michael

>
> Tim:
>
> Thanks for the code. I made a few changes, such as only starting the timer after running the CTL methods, but still no luck. It goes into the ISR at the appropriate moment (after a 1s delay), but once it's in there is just keeps endlessly going back with no delay at all. I went back and looked at some 2148 code I had working, and pretty much the same ISR and timer configuration works properly and will flash an LED on and off every second. I'm really stumped on this, though, since (to my flawed eyes) the Timer initialisation looks OK, as well as the ISR. Perhaps there is something I'm not aware of with the new vectored interrupt handler in the 2378/2478?
>
> Kevin.
>
> // Configure Timer1
> SCB_PCONP |= SCB_PCONP_PCTIM1; // Add power to Timer 1
> T1_TCR = T_TCR_CR; // Reset timer
> T1_PR = 0; // Set prescalar to 0
> T1_IR = T_IR_MR1; // Reset all interrupt flags
> T1_MR1 = 60000000 / 4; // Set timer match register (0.25 sec)
> T1_MCR = T_MCR_MR1R | T_MCR_MR1I; // Raise an interrupt and reset on match/MR1
> ctl_set_isr( // Set interrupt using CTL (vector, priority, trigger, isr, oldisr)
> VIC_Channel_Timer1,
> 2,
> CTL_ISR_TRIGGER_FIXED,
> timer1_isr,
> 0);
> ctl_unmask_isr(VIC_Channel_Timer1); // Unmas interrupt using CTL
> T1_TCR = T_TCR_CE; // Enable Timer1 interrupt
>
> // Enable interrupts using Crossworks CTL
> ctl_global_interrupts_enable();
>
> ....
>
> // Handle TIMER1 interrupt
> void timer1_isr(void)
> {
> int setBreakpoint = 0;
>
> T1_IR = T_IR_MR1; // Clear timer interrupt
> VIC_Address = 0; // Signal end of interrupt
> }
>

An Engineer's Guide to the LPC2100 Series

Reply by Paul Curtis June 22, 20092009-06-22
Kevin,

> > Well, there is something special that needs to happen in the timer
> interrupt in addition to the usual reschedule after an interrupt that can
> change thread state - the OS has to increment its tick timer and timeout
> waits and sleeps. Somewhere in your timer initialization, something
should
> set up a call to something like 'ctl_increment_tick_from_isr()', perhaps
by
> loading this function into a static so that it can be later called from
the
> timer interrupt handler.
> >
> > Are you doing this OK?
>
> Martin:
>
> Thanks for the reply. I don't suppose you have any examples, since I'm
not
> really clear on exactly what I should be modifying? I'm not actually
using
> any of the tasking functionality (which would obviously require a 'tick'
> interrupt) or the timer methods built into the CTL (I prefer to use
> standard GCC code as much as possible). For the moment, I am simply
> writing something where the only code present is the Timer initialisation
> and ISR just to make sure it is all working well before adding in
FreeRTOS.
> But I plan to use the same code to handle USB and Serial interrupts as
> well, which is why I wasn't using the CTL Timer code.

Please, help yourself... :-( Look at the examples we ship.

In V1 and V2:

Install the LPC2000 CPU support package and the EA LPC2468 package (2478
isn't so different).

Click Tools > Show Installed Packages.
Click EA 2468 OEM package.
Click LPC2468 OEM Samples Solution

Take a look at the timer_interrupt project.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks V2 is out for LPC1700, LPC3100, LPC3200, SAM9, and more!

Reply by Tim Mitchell June 22, 20092009-06-22
----Original Message----
From: l...
[mailto:l...] On Behalf Of Kevin
Townsend Sent: 22 June 2009 10:42 To:
l... Subject: [lpc2000] Re: Min.
Requirements for VIC in Crossworks w/2478

> Tim:
>
> Thanks for the code. I made a few changes, such as only
> starting the timer after running the CTL methods, but
> still no luck. It goes into the ISR at the appropriate
> moment (after a 1s delay), but once it's in there is just
> keeps endlessly going back with no delay at all. I went
> back and looked at some 2148 code I had working, and
> pretty much the same ISR and timer configuration works
> properly and will flash an LED on and off every second.
> I'm really stumped on this, though, since (to my flawed
> eyes) the Timer initialisation looks OK, as well as the
> ISR. Perhaps there is something I'm not aware of with
> the new vectored interrupt handler in the 2378/2478?
>

Mine is running on 2478, so I don't think so.
You don't need to access the VIC at all when using CTL for interrupts,
so you don't need the VIC_Address=0 line.
Have you tried doing T1_IR=0xFF to reset all the int flags together? Cos
it sounds like an interrupt flag is remaining set.

--
Tim Mitchell

Reply by Kevin Townsend June 22, 20092009-06-22
Tim:

Thanks for the code. I made a few changes, such as only starting the timer after running the CTL methods, but still no luck. It goes into the ISR at the appropriate moment (after a 1s delay), but once it's in there is just keeps endlessly going back with no delay at all. I went back and looked at some 2148 code I had working, and pretty much the same ISR and timer configuration works properly and will flash an LED on and off every second. I'm really stumped on this, though, since (to my flawed eyes) the Timer initialisation looks OK, as well as the ISR. Perhaps there is something I'm not aware of with the new vectored interrupt handler in the 2378/2478?

Kevin.

// Configure Timer1
SCB_PCONP |= SCB_PCONP_PCTIM1; // Add power to Timer 1
T1_TCR = T_TCR_CR; // Reset timer
T1_PR = 0; // Set prescalar to 0
T1_IR = T_IR_MR1; // Reset all interrupt flags
T1_MR1 = 60000000 / 4; // Set timer match register (0.25 sec)
T1_MCR = T_MCR_MR1R | T_MCR_MR1I; // Raise an interrupt and reset on match/MR1
ctl_set_isr( // Set interrupt using CTL (vector, priority, trigger, isr, oldisr)
VIC_Channel_Timer1,
2,
CTL_ISR_TRIGGER_FIXED,
timer1_isr,
0);
ctl_unmask_isr(VIC_Channel_Timer1); // Unmas interrupt using CTL
T1_TCR = T_TCR_CE; // Enable Timer1 interrupt

// Enable interrupts using Crossworks CTL
ctl_global_interrupts_enable();

....

// Handle TIMER1 interrupt
void timer1_isr(void)
{
int setBreakpoint = 0;

T1_IR = T_IR_MR1; // Clear timer interrupt
VIC_Address = 0; // Signal end of interrupt
}

Reply by Kevin Townsend June 22, 20092009-06-22
> Well, there is something special that needs to happen in the timer interrupt in addition to the usual reschedule after an interrupt that can change thread state - the OS has to increment its tick timer and timeout waits and sleeps. Somewhere in your timer initialization, something should set up a call to something like 'ctl_increment_tick_from_isr()', perhaps by loading this function into a static so that it can be later called from the timer interrupt handler.
>
> Are you doing this OK?

Martin:

Thanks for the reply. I don't suppose you have any examples, since I'm not really clear on exactly what I should be modifying? I'm not actually using any of the tasking functionality (which would obviously require a 'tick' interrupt) or the timer methods built into the CTL (I prefer to use standard GCC code as much as possible). For the moment, I am simply writing something where the only code present is the Timer initialisation and ISR just to make sure it is all working well before adding in FreeRTOS. But I plan to use the same code to handle USB and Serial interrupts as well, which is why I wasn't using the CTL Timer code.

Even without this, though, you think I need to configure or increment the interrupt 'tick' counter?

Kevin

Reply by mjames_doveridge June 22, 20092009-06-22
--- In l..., "Kevin Townsend" wrote:
>
> Is there something special that you need to do to clear/reset the interrupts when working with the CTL (I've looked at the documentation and nothing stood out to me, other than some routines to handle higher priority interrupts)?
>

Well, there is something special that needs to happen in the timer interrupt in addition to the usual reschedule after an interrupt that can change thread state - the OS has to increment its tick timer and timeout waits and sleeps. Somewhere in your timer initialization, something should set up a call to something like 'ctl_increment_tick_from_isr()', perhaps by loading this function into a static so that it can be later called from the timer interrupt handler.

Are you doing this OK?

Rgds,
Martin

Reply by Tim Mitchell June 22, 20092009-06-22
This is my working Crossworks timer interrupt using CTL, if it's any
help.
The only major difference is that I'm clearing all the interrupt flags
by setting TxIR to 0xFF (because I am not using any other interrupts on
this timer) whereas you are clearing a specific interrupt bit.

#include
#include
#include

static void T1Isr (void)
{
static unsigned char x;

T1IR = 0xff; //reset all interrrupt flags

x++;
/* other code */
}

And this is the setup for it...

//set up timer 1 interrupt
T1TCR = 0x02; //stop and reset timer
T1PR = 0x00; //set prescaler to zero
T1MR0 = (14400000 / 1000); //set int every 1ms
T1IR = 0xff; //reset all interrrupt flags
T1MCR = 0x03; //interrupt and reset counter on match MR0
ctl_set_isr(5, 0, CTL_ISR_TRIGGER_FIXED, T1Isr, 0);
ctl_unmask_isr(5);
T1TCR = 0x01; //start timer

--
Tim Mitchell

Reply by Felipe de Andrade Neves Lavratti June 22, 20092009-06-22
Mate! Welcome to the group of the timer issue! I got exactually the same
issue as you did, still found no solution! This topic will be of high use to
me!

2009/6/21 Kevin Townsend

> Is there something special that you need to do to clear/reset the
> interrupts when working with the CTL (I've looked at the documentation and
> nothing stood out to me, other than some routines to handle higher priority
> interrupts)?
>
> Once I go into the ISR, it continually fires (every 'tick', rather than
> during the specified delay of 1 second). With manually handled interrupts
> it's usually just a matter of signaling the end of the interrupt (in
> Timer/EINT/etc.) and clearing 'VIC_Address' as follows, but that doesn't
> seem to do it in this case:
>
> #define T0_IR (*(pREG32 (0xe0004000)))
> #define T_IR_MR0 (0x00000001)
> #define VIC_Address (*(pREG32 (0xffffff00)))
>
> // Handle TIMER0 interrupt
> void timer0_isr(void)
> {
> T0_IR = T_IR_MR0; // Clear timer interrupt
> VIC_Address = 0; // Signal end of interrupt
> }
>
> I think the timer initialisation is OK (it's set to raise an interrupt and
> reset when a match occurs), and it's more or less the same code that has
> worked for me on the 2100s (with the same timer I believe):
>
> // From page 627 of UM10237 v.2
> #define T0_MCR (*(pREG32 (0xe0004014)))
> #define T_MCR_MR0R (0x00000002)
> #define T_MCR_MR0I (0x00000001)
> ...
> // Configure Timer0
> SCB_PCONP |= SCB_PCONP_PCTIM0; // Add power to Timer 0
> T0_TCR = T_TCR_CR; // Reset timer
> T0_MR0 = 60000000 / 1; // Set timer match register (1 sec)
> T0_MCR = T_MCR_MR0R | T_MCR_MR0I; // Raise an interrupt and reset on
> match/MR0
> T0_TCR = T_TCR_CE; // Enable Timer0 interrupt
>
> Feel free to tell me to go crawl back under a rock, though, if it's just
> something plainly and obviously 'wrong' with my code. I'm used to feeling
> like a bit of an idiot by now. :-)
>
>
>


Reply by lpc2100_fan June 22, 20092009-06-22
--- In l..., "Kevin Townsend" wrote:

Curiously, I can get the interrupts (modified below) to work on the actual hardware with a JTAG debugger, but the interrupt never fires in the ARM Simulator.

Hi Kevin,

the only simulator that includes peripherals (as far as I know) is the Keil simulator. You can test the logic of your code with the instruction set simulator but there is no interaction with hardware components possible. The Keil simulator simulates the whole device. You always need to check whether the particular MCU is fully supported by the Keil simulator, afaIk, the LPC2478 is supported.

Bob
http://www.mcu-related.com

Reply by Kevin Townsend June 21, 20092009-06-21
Is there something special that you need to do to clear/reset the interrupts when working with the CTL (I've looked at the documentation and nothing stood out to me, other than some routines to handle higher priority interrupts)?

Once I go into the ISR, it continually fires (every 'tick', rather than during the specified delay of 1 second). With manually handled interrupts it's usually just a matter of signaling the end of the interrupt (in Timer/EINT/etc.) and clearing 'VIC_Address' as follows, but that doesn't seem to do it in this case:

#define T0_IR (*(pREG32 (0xe0004000)))
#define T_IR_MR0 (0x00000001)
#define VIC_Address (*(pREG32 (0xffffff00)))

// Handle TIMER0 interrupt
void timer0_isr(void)
{
T0_IR = T_IR_MR0; // Clear timer interrupt
VIC_Address = 0; // Signal end of interrupt
}

I think the timer initialisation is OK (it's set to raise an interrupt and reset when a match occurs), and it's more or less the same code that has worked for me on the 2100s (with the same timer I believe):

// From page 627 of UM10237 v.2
#define T0_MCR (*(pREG32 (0xe0004014)))
#define T_MCR_MR0R (0x00000002)
#define T_MCR_MR0I (0x00000001)
...
// Configure Timer0
SCB_PCONP |= SCB_PCONP_PCTIM0; // Add power to Timer 0
T0_TCR = T_TCR_CR; // Reset timer
T0_MR0 = 60000000 / 1; // Set timer match register (1 sec)
T0_MCR = T_MCR_MR0R | T_MCR_MR0I; // Raise an interrupt and reset on match/MR0
T0_TCR = T_TCR_CE; // Enable Timer0 interrupt

Feel free to tell me to go crawl back under a rock, though, if it's just something plainly and obviously 'wrong' with my code. I'm used to feeling like a bit of an idiot by now. :-)