Interrupt Timer 0 lpc2148

After reading all the forum I found about my problem, I am asking help ! I would like to trigger an interrupt on timer0 every 10 ms and it doesn’t work at all ! Maybe it comes from the Startup file but I have no idea where !

Here is my code :

Startup.S

/***********************************************************************/
/*  This file is part of the uVision/ARM development tools             */
/*  Copyright KEIL ELEKTRONIK GmbH 2002-2005                           */
/***********************************************************************/
/*                                                                     */
/*  STARTUP.S:  Startup file for Philips LPC2000 device series         */
/*                                                                     */
/***********************************************************************/

/* 
   This file has been heavily modified for the GNU-Toolchain by:
   Martin Thomas, Kaiserslautern, Germany
   <mthomas@rhrk.uni-kl.de>
   http://www.siwawi.arubi.uni-kl.de/avr_projects
   
   If it does not work for you: don't blame Keil or Philips. 
*/

/* 
//*** <<< Use Configuration Wizard in Context Menu >>> *** 
*/


/*
 *  The STARTUP.S code is executed after CPU Reset. This file may be 
 *  translated with the following SET symbols. In uVision these SET 
 *  symbols are entered under Options - ASM - Set.
 *
 *  REMAP: when set the startup code initializes the register MEMMAP 
 *  which overwrites the settings of the CPU configuration pins. The 
 *  startup and interrupt vectors are remapped from:
 *     0x00000000  default setting (not remapped)
 *     0x80000000  when EXTMEM_MODE is used
 *     0x40000000  when RAM_MODE is used
 *
 *  EXTMEM_MODE: when set the device is configured for code execution
 *  from external memory starting at address 0x80000000. The startup
 *  vectors are located to 0x80000000.
 *
 *  RAM_MODE: when set the device is configured for code execution
 *  from on-chip RAM starting at address 0x40000000. The startup
 *  vectors are located to 0x40000000.
 */

/* Map Preprocessor definitions to assembler definitions/symbols */

.set EXTMEM_MODE, 0

#ifdef ROM_RUN
.set RAM_MODE, 0
#ifdef VECTORS_IN_RAM
.set REMAP, 1
.set VECTREMAPPED, 1
#else
.set REMAP, 0
.set VECTREMAPPED, 0
#endif
#endif

#ifdef RAM_RUN
.set RAM_MODE, 1
.set REMAP, 1
.set VECTREMAPPED, 0
#endif



.if (RAM_MODE)
.print "RAM_MODE enabled"
.else
.print "ROM_MODE enabled"
.endif

.if (REMAP)
.print "remapping enabled"
.endif

.if (VECTREMAPPED)
.print "Vectors at start of RAM"
.else
.print "Vectors at start of Code"
.endif


// Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs

        .set Mode_USR, 0x10
        .set Mode_FIQ, 0x11
        .set Mode_IRQ, 0x12
        .set Mode_SVC, 0x13
        .set Mode_ABT, 0x17
        .set Mode_UND, 0x1B
        .set Mode_SYS, 0x1F

        .set I_Bit, 0x80    /* when I bit is set, IRQ is disabled */
        .set F_Bit, 0x40    /* when F bit is set, FIQ is disabled */


/*
// <h> Stack Configuration (Stack Sizes in Bytes)
//   <o0> Undefined Mode      <0x0-0xFFFFFFFF:4>
//   <o1> Supervisor Mode     <0x0-0xFFFFFFFF:4>
//   <o2> Abort Mode          <0x0-0xFFFFFFFF:4>
//   <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:4>
//   <o4> Interrupt Mode      <0x0-0xFFFFFFFF:4>
//   <o5> User/System Mode    <0x0-0xFFFFFFFF:4>
// </h>
*/
        .set UND_Stack_Size, 0x00000080
        .set SVC_Stack_Size, 0x00000080
        .set ABT_Stack_Size, 0x00000080
        .set FIQ_Stack_Size, 0x00000080
        .set IRQ_Stack_Size, 0x00000200
        //.set USR_Stack_Size, 0x00000800
		.set USR_Stack_Size, 0x00001000

#if 0
AREA   STACK, DATA, READWRITE, ALIGN=2 
        DS   (USR_Stack_Size+3)&~3  ; Stack for User/System Mode 
        DS   (SVC_Stack_Size+3)&~3  ; Stack for Supervisor Mode
        DS   (IRQ_Stack_Size+3)&~3  ; Stack for Interrupt Mode
        DS   (FIQ_Stack_Size+3)&~3  ; Stack for Fast Interrupt Mode 
        DS   (ABT_Stack_Size+3)&~3  ; Stack for Abort Mode
        DS   (UND_Stack_Size+3)&~3  ; Stack for Undefined Mode
#endif

.arm
.section .stack, "w"
.align 4
        .space (USR_Stack_Size+3)&~3  // Stack for User/System Mode 
        .space (SVC_Stack_Size+3)&~3  // Stack for Supervisor Mode
        .space (IRQ_Stack_Size+3)&~3  // Stack for Interrupt Mode
        .space (FIQ_Stack_Size+3)&~3  // Stack for Fast Interrupt Mode 
        .space (ABT_Stack_Size+3)&~3  // Stack for Abort Mode
        .space (UND_Stack_Size+3)&~3  // Stack for Undefined Mode
Top_Stack:


// VPBDIV definitions
        .set VPBDIV, 0xE01FC100  /* VPBDIV Address */

/*
//  VPBDIV Setup
//  Peripheral Bus Clock Rate
//   <o1.0..1>   VPBDIV: VPB Clock
//               <0=> VPB Clock = CPU Clock / 4
//               <1=> VPB Clock = CPU Clock
//               <2=> VPB Clock = CPU Clock / 2
//   <o1.4..5>   XCLKDIV: XCLK Pin
//               <0=> XCLK Pin = CPU Clock / 4
//               <1=> XCLK Pin = CPU Clock
//               <2=> XCLK Pin = CPU Clock / 2
// 
*/
        .set VPBDIV_SETUP, 1
        .set VPBDIV_Val, 0x00000000


// Phase Locked Loop (PLL) definitions
        .set PLL_BASE,      0xE01FC080  /* PLL Base Address */
        .set PLLCON_OFS,    0x00        /* PLL Control Offset*/
        .set PLLCFG_OFS,    0x04        /* PLL Configuration Offset */
        .set PLLSTAT_OFS,   0x08        /* PLL Status Offset */
        .set PLLFEED_OFS,   0x0C        /* PLL Feed Offset */
        .set PLLCON_PLLE,   (1<<0)      /* PLL Enable */
        .set PLLCON_PLLC,   (1<<1)      /* PLL Connect */
        .set PLLCFG_MSEL,   (0x1F<<0)   /* PLL Multiplier */
        .set PLLCFG_PSEL,   (0x03<<5)   /* PLL Divider */
        .set PLLSTAT_PLOCK, (1<<10)     /* PLL Lock Status */

/*
//  PLL Setup
// <i> Phase Locked Loop
// <i> CCLK - Processor Clock
// <i> Fcco - PLL Oscillator
//   <o1.0..4>   MSEL: PLL Multiplier Selection
//               <1-32><#-1>
//               <i> PLL Multiplier "M" Value
//               <i> CCLK = M * Fosc
//   <o1.5..6>   PSEL: PLL Divider Selection
//               <0=> 1   <1=> 2   <2=> 4   <3=> 8
//               <i> PLL Divider "P" Value
//               <i> Fcco = CCLK * 2 * P
//               <i> 156MHz <= Fcco <= 320MHz
// 
*/
 //       .set PLL_SETUP,  1
        .set PLLCFG_Val, 0x00000024


// Memory Accelerator Module (MAM) definitions
        .set MAM_BASE,   0xE01FC000  /* MAM Base Address */
        .set MAMCR_OFS,  0x00        /* MAM Control Offset*/
        .set MAMTIM_OFS, 0x04        /* MAM Timing Offset */

/*
//  MAM Setup
// <i> Memory Accelerator Module
//   <o1.0..1>   MAM Control
//               <0=> Disabled
//               <1=> Partially Enabled
//               <2=> Fully Enabled
//               <i> Mode
//   <o2.0..2>   MAM Timing
//               <0=> Reserved  <1=> 1   <2=> 2   <3=> 3
//               <4=> 4         <5=> 5   <6=> 6   <7=> 7
//               <i> Fetch Cycles
// 
*/
//        .set MAM_SETUP,    1
        .set MAMCR_Val,    0x00000002
        .set MAMTIM_Val,   0x00000004


// Starupt Code must be linked first at Address at which it expects to run.

.if     (EXTMEM_MODE)
        .set CODE_BASE,  0x80000000
.elseif (RAM_MODE)
        .set CODE_BASE,  0x40000000
.else
        .set CODE_BASE,  0x00000000
.endif

#if 0
AREA   STARTUPCODE, CODE, AT CODE_BASE   // READONLY, ALIGN=4
       PUBLIC  __startup

       EXTERN  CODE32 (?C?INIT)

__startup       PROC    CODE32

// Pre-defined interrupt handlers that may be directly 
// overwritten by C interrupt functions
EXTERN CODE32 (Undef_Handler?A)
EXTERN CODE32 (SWI_Handler?A)
EXTERN CODE32 (PAbt_Handler?A)
EXTERN CODE32 (DAbt_Handler?A)
EXTERN CODE32 (IRQ_Handler?A)
EXTERN CODE32 (FIQ_Handler?A)
#endif

.text
.arm

.if (VECTREMAPPED)
.print "Vectors in section .vectmapped -> .data"
.section .vectmapped, "ax"
.else
.print "Vectors in section .vectorg -> .text"
.section .vectorg, "ax"
.endif

// Pre-defined interrupt handlers that may be directly 
// overwritten by C interrupt functions
.extern Undef_Handler
.extern SWI_Handler
.extern PAbt_Handler
.extern DAbt_Handler
.extern IRQ_Handler
.extern FIQ_Handler


// Exception Vectors
// Mapped to Address 0.
// Absolute addressing mode must be used.

__Vectors:      LDR     PC,Reset_Addr         
                LDR     PC,Undef_Addr
                LDR     PC,SWI_Addr
                LDR     PC,PAbt_Addr
                LDR     PC,DAbt_Addr
                NOP                            /* Reserved Vector */
				LDR     PC,[PC, #-0x0FF0]      /* Vector from VicVectAddr */
                LDR     PC,IRQ_Wrapper_Addr
                LDR     PC,FIQ_Addr

Reset_Addr:       .word     Reset_Handler
Undef_Addr:       .word     Undef_Handler
// SWI_Addr:         .word     SWI_Handler
// SWI_Wrapper_Addr: .word     SWI_Wrapper
SWI_Addr:         .word     0      /* in swi_handler.S */
PAbt_Addr:        .word     PAbt_Handler
DAbt_Addr:        .word     DAbt_Handler
                  .word     0                      /* Reserved Address */
IRQ_Addr:         .word    IRQ_Handler
IRQ_Wrapper_Addr: .word    __IRQ_Wrapper
FIQ_Addr:         .word     FIQ_Handler

Undef_Handler:  B       Undef_Handler
/* SWI_Handler:    B       SWI_Handler */
PAbt_Handler:   B       PAbt_Handler
DAbt_Handler:   B       DAbt_Handler
IRQ_Handler:    B       IRQ_Handler 
FIQ_Handler:    B       FIQ_Handler

.size   __Vectors, . - __Vectors



.arm
.section .init, "ax"

.if (VECTREMAPPED)
/* mthomas: Dummy used during startup - mind the nops since the 
   flash-utility will overwrite the "reserved vector"-address
   with the checksum */
				B Reset_Handler
				NOP
				NOP
				NOP
				NOP
				NOP  /* Reserved Address */
				NOP
				NOP
.endif

.arm
.section .init, "ax"
.global __startup
.func __startup
__startup:

Reset_Handler:  


// Memory Mapping
                .set MEMMAP, 0xE01FC040  /* Memory Mapping Control */

.if (REMAP)
                LDR     R0, =MEMMAP
.if     (EXTMEM_MODE)                
                MOV     R1, #3
.elseif (RAM_MODE) || (VECTREMAPPED)
.print "MEMMAP to 2 on init"
                MOV     R1, #2
.else
                MOV     R1, #1
.endif
                STR     R1, [R0]
.endif

// Setup Stack for each mode
                LDR     R0, =Top_Stack

// Enter Undefined Instruction Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_UND|I_Bit|F_Bit
                MOV     SP, R0
                SUB     R0, R0, #UND_Stack_Size

// Enter Abort Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_ABT|I_Bit|F_Bit
                MOV     SP, R0
                SUB     R0, R0, #ABT_Stack_Size

// Enter FIQ Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_FIQ|I_Bit|F_Bit
                MOV     SP, R0
                SUB     R0, R0, #FIQ_Stack_Size

// Enter IRQ Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_IRQ|I_Bit|F_Bit
                MOV     SP, R0
                SUB     R0, R0, #IRQ_Stack_Size

// Enter Supervisor Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_SVC|I_Bit|F_Bit
                MOV     SP, R0
                SUB     R0, R0, #SVC_Stack_Size

// Enter User Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_SYS /* Interrupts enabled */
//				MSR     CPSR_c, #Mode_USR|I_Bit|F_Bit /* Interrupts disabled */
                MOV     SP, R0


.if (RAM_MODE==0)
/* Relocate .data section (Copy from ROM to RAM) */
                LDR     R1, =_etext 
                LDR     R2, =_data 
                LDR     R3, =_edata 
                CMP     R2, R3
                BEQ     DataIsEmpty
LoopRel:        CMP     R2, R3 
                LDRLO   R0, [R1], #4 
                STRLO   R0, [R2], #4 
                BLO     LoopRel 
DataIsEmpty:
.endif
 
/* Clear .bss section (Zero init) */
                MOV     R0, #0 
                LDR     R1, =__bss_start__ 
                LDR     R2, =__bss_end__ 
                CMP     R1,R2
                BEQ     BSSIsEmpty
LoopZI:         CMP     R1, R2 
                STRLO   R0, [R1], #4 
                BLO     LoopZI 
BSSIsEmpty:


// call C++ constructors of global objects
		LDR 	r0, =__ctors_start__
		LDR 	r1, =__ctors_end__
ctor_loop:
		CMP 	r0, r1
		BEQ 	ctor_end
		LDR 	r2, [r0], #4
		STMFD 	sp!, {r0-r1}
		MOV 	lr, pc
		MOV 	pc, r2
		LDMFD 	sp!, {r0-r1}
		B 		ctor_loop
ctor_end:

// Enter the C code
                //LDR     R0,=INIT
                LDR     R0,=main
                TST     R0,#1             // Bit-0 set: main is Thumb
                LDREQ   LR,=__exit_ARM    // ARM Mode
                LDRNE   LR,=__exit_THUMB  // Thumb Mode
                BX      R0

.size   __startup, . - __startup
.endfunc

.arm
.global __exit_ARM
.func __exit_ARM
__exit_ARM:
                B       __exit_ARM
.size   __exit_ARM, . - __exit_ARM
.endfunc

.thumb
.global __exit_THUMB
.func __exit_THUMB
__exit_THUMB:
                B       __exit_THUMB
.size   __exit_THUMB, . - __exit_THUMB
.endfunc


/* mthomas: the following code is inspired by various examples and
   documents from ARM, Atmel, Anglia Designs and others */


.text
.arm

.if (VECTREMAPPED)
.print "Handlers in section .vectmapped -> .data"
.section .vectmapped, "ax"
.else
.print "Handlers in section .vectorg -> .code/.text"
.section .vectorg, "ax"
.endif

.set VIC_base_addr, 0xFFFFF000
.set VIC_vect_offs, 0x30

        .arm
        .global __IRQ_Wrapper
        .func   __IRQ_Wrapper
__IRQ_Wrapper:
/*- Manage Exception Entry  */
/*- Adjust and save LR_irq in IRQ stack  */
            sub         lr, lr, #4
            stmfd       sp!, {lr}

/*- Save SPSR need to be saved for nested interrupt */
            mrs         r14, SPSR
            stmfd       sp!, {r14}

/*- Save and r0 in IRQ stack  */
            stmfd       sp!, {r0}

/*- Write in the IVR to support Protect Mode  */
/*- No effect in Normal Mode  */
/*- De-assert the NIRQ and clear the source in Protect Mode */
/* R14 = LR */
            ldr         r14, =VIC_base_addr
            ldr         r0 , [r14, #VIC_vect_offs]
            /*str         r14, [r14, #VIC_vect_offs]*/

/*- Enable Interrupt and Switch in Supervisor Mode */
            msr         CPSR_c, #Mode_SVC

/*- Save scratch/used registers and LR in User Stack */
            /*stmfd       sp!, { r1-r3, r12, r14}*/
            stmfd       sp!, { r1-r12, r14 }

/*- Branch to the routine pointed by the VIC-Vector-Address  */
            mov         r14, pc
            bx          r0
/*- Restore scratch/used registers and LR from User Stack*/
            /* ldmia       sp!, { r1-r3, r12, r14} */
            ldmia       sp!, { r1-r12, r14 }

/*- Disable Interrupt and switch back in IRQ mode */
            msr         CPSR_c, #I_Bit | Mode_IRQ

#if 0
/* VICVectAddr=0 is already done in the ISRs of the Philips-Examples 
   so commented out here */
/*- Mark the End of Interrupt on the VIC */
            ldr         r14, =VIC_base_addr
            str         r14, [r14, #VIC_vect_offs]
#endif

/*- Restore SPSR_irq and r0 from IRQ stack */
            ldmia       sp!, {r0}

/*- Restore SPSR_irq and r0 from IRQ stack */
            ldmia       sp!, {r14}
            msr         SPSR_cxsf, r14

/*- Restore adjusted  LR_irq from IRQ stack directly in the PC */
            ldmia       sp!, {pc}^

.size   __IRQ_Wrapper, . - __IRQ_Wrapper
.endfunc


#if 0
/* mthomas:
   Wrapper to call a C swi-Function declared with 
   void SWI_Handler(int swi_num, int *regs)
   Inspired by Anglia Designs example 
   -- not used here - see swi_handler.S
*/
        .arm
        .global __SWI_Wrapper
        .func   __SWI_Wrapper
__SWI_Wrapper:                       /* r0 holds swi number */
        STMFD   sp!,{r0-r12,lr}    /* Save The workspace plus the current return */
                                   /* address lr_ mode into the stack */
        MRS     r1, spsr           /* Save the spsr_mode into r1 */
        STMFD   sp!, {r1}          /* Save spsr */
        MOV     r1, sp             /* load regs */
        LDR     r0,=SWI_Handler    
        MOV     lr, pc
        BX      r0                 /* call the C-funcktion */
        LDMFD   sp!, {r1}          /* Restore the saved spsr_mode into r1 */
        MSR     spsr_cxsf, r1      /* Restore spsr_mode */
        LDMFD   sp!, {r0-r12,pc}   /* Return to the instruction following */
                                   /* the exception interrupt */
        .size   __SWI_Wrapper, . - __SWI_Wrapper
        .endfunc
#endif

#if 0
/* mthomas: not used here - reminder for future tests */
		.arm
		.global __IRQ_Wrapper
		.func __IRQ_Wrapper
__IRQ_Wrapper:
		SUB		lr, lr, #4				/* Update the link register */
		STMFD	sp!,{r0-r12,lr}	        /* Save The workspace plus the current return */
										/* address lr_ mode into the stack */
		MRS		r1, spsr				/* Save the spsr_mode into r1 */
		STMFD	sp!, {r1}				/* Save spsr */
		LDR		lr, =ReturnAddress		/* Read the return address. */
		LDR		r0, =VIC_base_addr      /* Load VIC Base-Address */
		LDR		r1, [r0, #VIC_vect_offs] /* Load ISR-Address from VICVectAddr */
		bx      r1                      /* Branch to the IRQ handler. */
ReturnAddress:
		LDR     r2, =VIC_base_addr      /* clear Interrupt */
		MOV     r3, #0
		STR     R3, [R2, #VIC_vect_offs] /* by writing to VICVectAddr */
		LDMFD	sp!, {r1}				/* Restore the saved spsr_mode into r1 */
		MSR		spsr_cxsf, r1			/* Restore spsr_mode */
		LDMFD	sp!, {r0-r12,pc}^	    /* Return to the instruction following */
										/* the exception interrupt */
.size   __IRQ_Wrapper, . - __IRQ_Wrapper
.endfunc
#endif

.end

TIMER0 :

satic unsigned long int tFreq;

void timer0Init(unsigned long int freq)
{
	tFreq=freq;
	T0PR=Fcclk/tFreq;			//Set up the prescaler for a 'freq' frequency
	T0CTCR=0;					//Timer Mode
	T0TCR |=0X01;				//Enable the clock
	//T0MCR=0x0003;				//Interrupt and Reset Timer on Match
	//T0MR0=(50000/TIMER_FREQ);	
}

void timer0Match(int mr, unsigned long int freq, char mode)
{
	unsigned long int mfreq = tFreq/freq;		//Get the Match Register value by dividing timer frequency by request match frequency

	switch(mr)
	{
		case 0:
			T0MR0 = mfreq;
			T0MCR = (mode<<0);		
			break;
		case 1:
			T0MR1 = mfreq;
			T0MCR = (mode<<3);
			break;
		case 2:
			T0MR2 = mfreq;
			T0MCR = (mode<<6);
			break;
		case 3:
			T0MR3 = mfreq;
			T0MCR = (mode<<9);
			break;
		default:
			break;
	}
}

char timer0IntFlag=0;
long int ms=0;

//Usage: None (Automatically Called by FW)
//Inputs: None
//This function is a global interrupt called by a match on the Timer 0 match.  
void ISR_Timer0(void)
{
	rprintf("timer0 interrupt\n");
	//Interrupt Code Here
	timer0IntFlag+=1;
	
	//Keep track of the number of milliseconds
	ms++;
	
	//Clear the interrupt and update the VIC priority
	T0IR = 0x01;
	VICVectAddr =0;						
}

MAIN :

//*******************************************************
//					Main Code
//*******************************************************
int main (void)
{
	
	//Initialize ARM I/O
	bootUp();			//Init. I/O ports, Comm protocols and interrupts
	LEDoff();
	timer0Init(1000000);
	timer0Match(0, 1000, interruptOnMatch | resetOnMatch);
	enableIRQ();
	
	
	
	while(1);


    return 0;
}



//Usage: bootUp();
//Inputs: None
//This function initializes the serial port, the SD card, the I/O pins and the interrupts
void bootUp(void)
{
	// initialise FCCLK--------------------
	PLLCON = 1;			// enable PLL
	PLLCFG = (1 << 5) | 4; // P = 2, M = 5
	PLLFEED = 0xAA;
	PLLFEED = 0x55;
	
	///- I0DIR: GPIO port Direction control Register, it controls the direction of each port pin
	///- XBEE module is not used
	///- IODIR0 |= (LED| XBEE_EN);
	IODIR0 |= LED; ///P0.15 is set as an output
	
	while ((PLLSTAT & (1 << 10)) == 0);

	PLLCON = 3;			// enable and connect
	PLLFEED = 0xAA;
	PLLFEED = 0x55;
	
	MAMCR=0x02;
	MAMTIM=0x04;
	//--------------------------------------
	
	//Initialize UART for RPRINTF
	init_serial0(115200);
	rprintf_devopen(putc_serial0); //Init rprintf			

	///- The APB Divider determines the relationship between the processor clock (CCLK) and the
	///- clock used by peripheral devices (PCLK). 
	///- VPBDIV = 1 APB bus clock is the same as the processor clock.
	VPBDIV=1;		// Set PCLK equal to the System Clock
	VICIntSelect = ~(INT_TIMER0);
	VICVectCntl0 = 0x20 | 4;						//Timer 0 Interrupt
	VICVectAddr0 = (unsigned int)ISR_Timer0;
	rprintf("boot up\n");

	
}

I will be very very thankful for any help :slight_smile:

This is the code I use with Rowley CrossWorks for an LPC2148 Timer 0 interrupt every 20 ms:

void Initialise(void)
{
  // initialise PLL

  PLL0CFG=0x24;      // Cclk = 60Mhz
  PLL0CON=0x01;
  PLL0FEED=0xAA;
  PLL0FEED=0x55;
  while(!(PLL0STAT & 0x0400))
	;
  PLL0CON=0x3;
  PLL0FEED=0xAA;
  PLL0FEED=0x55;

  // initialise MAM and VPB

  MAMTIM=0x3;       // 3 cycles to read from FLASH
  MAMCR=0x2;        // MAM functions fully enabled
  APBDIV=0x02;      // Pclk = 30MHz

  // initialise pclk (30 MHz)
  unsigned long pclk = liblpc2000_get_pclk(liblpc2000_get_cclk(OSCILLATOR_CLOCK_FREQUENCY));
 
  // initialise TIMER0
  T0TCR = 0; /* Reset timer 0 */
  T0PR = 0; /* Set the timer 0 prescale counter */
  T0MR0 = pclk/50 - 1; /* Set time 0 match register to generate an interrupt every 20 ms */
  T0MCR = 3; /* Generate interrupt and reset counter on match */
  T0TCR = 1; /* Start timer 0 */

  // setup CTL stuff for Timer 0
  ctl_set_isr(4, 0, CTL_ISR_TRIGGER_FIXED, timer0ISR, 0);
  ctl_unmask_isr(4);

  // enable global interrupts
  ctl_global_interrupts_enable();
}
//---------------------- Timer 0 ISR every 20 ms -----------------//

static void timer0ISR(void)
{
  //ISR code goes here

   T0IR = 0xFF;  // Clear the timer 0 interrupt
}

You’ll have to write your own code for the CTL (CrossWorks Tasking Library) functions.

hey! Thanks for the answer, I forgot to tell you that I’m working with WinARM and so I can’t use CTL.

The main problem of my interrupt is that the program crashes after starting the timer0 …

As I said, write your own code to replace the CTL functions. My software definitely works.

Your crt0.S file has a lot of extra junk in it. There are quite a few problems, including that your vector table has an extra entry in it. It looks like you have some IRQ wrapper functions, but they’re not being called. Here are crt0.S, LPC2148-ROM.ld, and example timer code that should get you up and running:

crt0.S

/* ***************************************************************************************************************

	crt.s						STARTUP  ASSEMBLY  CODE 
								-----------------------


	Module includes the interrupt vectors and start-up code.

  *************************************************************************************************************** */

/* Stack Sizes */
.set  UND_STACK_SIZE, 0x00000004		/* stack for "undefined instruction" interrupts is 4 bytes  */
.set  ABT_STACK_SIZE, 0x00000004		/* stack for "abort" interrupts is 4 bytes                  */
.set  FIQ_STACK_SIZE, 0x00000004		/* stack for "FIQ" interrupts  is 4 bytes         			*/
.set  IRQ_STACK_SIZE, 0x00000004		/* stack for "IRQ" normal interrupts is 4 bytes    			*/
.set  SVC_STACK_SIZE, 0x00000004		/* stack for "SVC" supervisor mode is 4 bytes  				*/



/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */
.set  MODE_USR, 0x10            		/* Normal User Mode 										*/
.set  MODE_FIQ, 0x11            		/* FIQ Processing Fast Interrupts Mode 						*/
.set  MODE_IRQ, 0x12            		/* IRQ Processing Standard Interrupts Mode 					*/
.set  MODE_SVC, 0x13            		/* Supervisor Processing Software Interrupts Mode 			*/
.set  MODE_ABT, 0x17            		/* Abort Processing memory Faults Mode 						*/
.set  MODE_UND, 0x1B            		/* Undefined Processing Undefined Instructions Mode 		*/
.set  MODE_SYS, 0x1F            		/* System Running Priviledged Operating System Tasks  Mode	*/

.set  I_BIT, 0x80               		/* when I bit is set, IRQ is disabled (program status registers) */
.set  F_BIT, 0x40               		/* when F bit is set, FIQ is disabled (program status registers) */
.set  NO_INT, (I_BIT | F_BIT)			/*mask to disable IRQ and FIQ */

.text
.arm

.global	Reset_Handler
.global _startup
.func   _startup

_startup:

# Exception Vectors

_vectors:       ldr     PC, Reset_Addr         
                ldr     PC, Undef_Addr
                ldr     PC, SWI_Addr
                ldr     PC, PAbt_Addr
                ldr     PC, DAbt_Addr
                nop							/* Reserved Vector (holds Philips ISP checksum) */
                ldr		PC, IRQ_Addr		/* see page 71 of "Insiders Guide to the Philips ARM7-Based Microcontrollers" by Trevor Martin  */
				ldr     PC, FIQ_Addr

Reset_Addr:     .word   Reset_Handler		/* defined in this module below  */
Undef_Addr:     .word   UNDEF_Routine		/* defined in sys.c  */
SWI_Addr:       .word   SWI_Routine			/* defined in sys.c  */
PAbt_Addr:      .word   UNDEF_Routine		/* defined in sys.c  */
DAbt_Addr:      .word   UNDEF_Routine		/* defined in sys.c  */
IRQ_Addr:       .word   ARM_irq				/* defined in this module below  */
FIQ_Addr:       .word   FIQ_Routine			/* defined in sys.c  */
                .word   0					/* rounds the vectors and ISR addresses to 64 bytes total  */


# Reset Handler

Reset_Handler:  

				/* Setup a stack for each mode - note that this only sets up a usable stack
				for User mode.   Also each mode is setup with interrupts initially disabled. */
    			  
    			ldr   r0, =_stack_end
    			msr   CPSR_c, #MODE_UND|I_BIT|F_BIT 	/* Undefined Instruction Mode  */
    			mov   sp, r0
    			sub   r0, r0, #UND_STACK_SIZE
    			msr   CPSR_c, #MODE_ABT|I_BIT|F_BIT 	/* Abort Mode */
    			mov   sp, r0
    			sub   r0, r0, #ABT_STACK_SIZE
    			msr   CPSR_c, #MODE_FIQ|I_BIT|F_BIT 	/* FIQ Mode */
    			mov   sp, r0	
   				sub   r0, r0, #FIQ_STACK_SIZE
    			msr   CPSR_c, #MODE_IRQ|I_BIT|F_BIT 	/* IRQ Mode */
    			mov   sp, r0
    			sub   r0, r0, #IRQ_STACK_SIZE
    			msr   CPSR_c, #MODE_SVC|I_BIT|F_BIT 	/* Supervisor Mode */
    			mov   sp, r0
    			sub   r0, r0, #SVC_STACK_SIZE
    			msr   CPSR_c, #MODE_SYS|I_BIT|F_BIT 	/* User Mode */
    			mov   sp, r0

				/* copy .data section (Copy from ROM to RAM) */
                ldr     R1, =_flash_data_start
                ldr     R2, =_data
                ldr     R3, =_edata
2:        		cmp     R2, R3
                ldrlo   R0, [R1], #4
                strlo   R0, [R2], #4
                blo     2b

				/* Clear .bss section (Zero init)  */
                mov     R0, #0
                ldr     R1, =_bss_start
                ldr     R2, =_bss_end
3:				cmp     R1, R2
                strlo   R0, [R1], #4
                blo     3b

				/* Enter the C code  */
                b       main

.endfunc

.func ARM_irq
ARM_irq:
	MOV r13,r0						/* save r0 in r13_IRQ */
	SUB r0,lr,#4					/* put return address in r0_SYS */
	MOV lr,r1						/* save r1 in r14_IRQ (lr) */
	MRS r1,spsr						/* put the SPSR in r1_SYS */
	MSR cpsr_c,#(MODE_SYS | I_BIT)	/* SYSTEM mode, no IRQ/FIQ enabled! */
	STMFD sp!,{r0,r1}				/* save SPSR and PC on SYS stack */
	STMFD sp!,{r2-r3,r12,lr}			/* save AAPCS-clobbered regs on SYS stack */
	MOV r0,sp						/* make the sp_SYS visible to IRQ mode */
	SUB sp,sp,#(2*4)				/* make room for stacking (r0_SYS, r1_SYS) */
	MSR cpsr_c,#(MODE_IRQ | I_BIT)	/* IRQ mode, IRQ/FIQ disabled */
	STMFD r0!,{r13,r14}				/* finish saving the context (r0_SYS,r1_SYS)*/
	MSR cpsr_c,#(MODE_SYS | I_BIT)	/* SYSTEM mode, IRQ disabled */

	/* Enter user IRQ C Code by jumping to value of VICVectAddr */
	LDR r12,=0xFFFFF030				/* VICVectAddr: contains pointer to C function to execute */
	MOV lr,pc						/* copy the return address to link register */
	ldr pc, [r12]
	/* Exit user C code */

	MSR cpsr_c,#(MODE_SYS | NO_INT) /* SYSTEM mode, IRQ/FIQ disabled */
	MOV r0,sp						/* make sp_SYS visible to IRQ mode */
	ADD sp,sp,#(8*4)				/* fake unstacking 8 registers from sp_SYS */
	MSR cpsr_c,#(MODE_IRQ | NO_INT) /* IRQ mode, both IRQ/FIQ disabled */
	MOV sp,r0						/* copy sp_SYS to sp_IRQ */
	LDR r0,[sp,#(7*4)]				/* load the saved SPSR from the stack */
	MSR spsr_cxsf,r0				/* copy it into spsr_IRQ */
	LDMFD sp,{r0-r3,r12,lr}^			/* unstack all saved USER/SYSTEM registers */
	NOP								/* can't access banked reg immediately */
	LDR lr,[sp,#(6*4)]				/* load return address from the SYS stack */
	MOVS pc,lr						/* return restoring CPSR from SPSR */

.endfunc
.end
/* ****************************************************************************************************** */
/*   demo2148_blink_flash.cmd				LINKER  SCRIPT                                                */
/*                                                                                                        */
/*                                                                                                        */
/*   The Linker Script defines how the code and data emitted by the GNU C compiler and assembler are  	  */
/*   to be loaded into memory (code goes into FLASH, variables go into RAM).                 			  */
/*                                                                                                        */
/*   Any symbols defined in the Linker Script are automatically global and available to the rest of the   */
/*   program.                                                                                             */
/*                                                                                                        */
/*   To force the linker to use this LINKER SCRIPT, just add the -T demo2148_blink_flash.cmd directive    */
/*   to the linker flags in the makefile.                                                                 */
/*                                                                                                        */
/*   			LFLAGS  =  -Map main.map -nostartfiles -T demo2148_blink_flash.cmd                        */
/*                                                                                                        */
/*                                                                                                        */
/*   The Philips boot loader supports the ISP (In System Programming) via the serial port and the IAP     */
/*   (In Application Programming) for flash programming from within your application.                     */
/*                                                                                                        */
/*   The boot loader uses RAM memory and we MUST NOT load variables or code in these areas.               */
/*                                                                                                        */
/*   RAM used by boot loader:  0x40000120 - 0x400001FF  (223 bytes) for ISP variables                     */
/*                             0x40007FE0 - 0x4000FFFF  (32 bytes)  for ISP and IAP variables             */
/*                             0x40007EE0 - 0x40007FE0  (256 bytes) stack for ISP and IAP                 */
/*                                                                                                        */
/*                                                                                                        */
/*                              MEMORY MAP                                                                */
/*                      |                                 |0x40008000                                     */
/*            .-------->|---------------------------------|                                               */
/*            .         |     variables and stack         |0x40007FFF                                     */
/*         ram_isp_high |     for Philips boot loader     |                                               */
/*            .         |     32 + 256 = 288 bytes        |                                               */
/*            .         |                                 |                                     		  */
/*            .         |   Do not put anything here      |0x40007EE0                                     */
/*            .-------->|---------------------------------|                                               */
/*                      |    UDF Stack  4 bytes           |0x40007EDC  <---------- _stack_end             */
/*            .-------->|---------------------------------|                                               */
/*                      |    ABT Stack  4 bytes           |0x40007ED8                                     */
/*            .-------->|---------------------------------|                                               */
/*                      |    FIQ Stack  4 bytes           |0x40007ED4                                     */
/*            .-------->|---------------------------------|                                               */
/*                      |    IRQ Stack  4 bytes           |0x40007ED0                                     */
/*            .-------->|---------------------------------|                                               */
/*                      |    SVC Stack  4 bytes           |0x40007ECC                                     */
/*            .-------->|---------------------------------|                                               */
/*            .         |                                 |0x40007EC8 			                          */
/*            .         |     stack area for user program |                                               */
/*            .         |               |                 |                                               */
/*            .         |               |                 |                                               */
/*            .         |               |                 |                                               */
/*            .         |               V                 |                                               */
/*            .         |                                 |                                               */
/*            .         |                                 |                                               */
/*            .         |                                 |                                               */
/*            .         |          free ram               |                                               */
/*           ram        |                                 |                                               */
/*            .         |                                 |                                               */
/*            .         |                                 |                                               */
/*            .         |.................................|0x40000234 <---------- _bss_end                */
/*            .         |                                 |                                               */
/*            .         |  .bss   uninitialized variables |                                               */
/*            .         |.................................|0x40000218 <---------- _bss_start, _edata      */
/*            .         |                                 |                                               */
/*            .         |  .data  initialized variables   |                                               */
/*            .         |                                 |0x40000200 <---------- _data                   */
/*            .-------->|---------------------------------|                                               */
/*            .         |     variables used by           |0x400001FF                                     */
/*         ram_isp_low  |     Philips boot loader         |                                               */
/*            .         |           223 bytes             |0x40000120                                     */
/*            .-------->|---------------------------------|                                               */
/*            .         |                                 |0x4000011F                                     */
/*         ram_vectors  |          free ram               |                                               */
/*            .         |---------------------------------|0x40000040                                     */
/*            .         |                                 |0x4000003F                                     */
/*            .         |  Interrupt Vectors (re-mapped)  |                                               */
/*            .         |          64 bytes               |0x40000000                                     */
/*            .-------->|---------------------------------|                                               */
/*                      |                                 |                                               */
/*                                                                                                        */
/*                                                                                                        */
/*                                                                                                        */
/*                      |                                 |                                               */
/*           .--------> |---------------------------------|                                               */
/*           .          |                                 |0x0001FFFF                                     */
/*           .          |                                 |                                               */
/*           .          |                                 |                                               */
/*           .          |                                 |                                               */
/*           .          |                                 |                                               */
/*           .          |                                 |                                               */
/*           .          |       unused flash eprom        |                                               */
/*           .          |                                 |                                               */
/*           .          |.................................|0x0000032c                                     */
/*           .          |                                 |                                               */
/*           .          |      copy of .data area         |                                               */
/*         flash        |                                 |                                               */
/*           .          |---------------------------------|0x00000314 <----------- _etext                 */
/*           .          |                                 |                                               */
/*           .          |                                 |0x00000180  main                               */
/*           .          |                                 |0x00000278  feed                               */
/*           .          |         main()                  |0x000002c4  FIQ_Routine                        */
/*           .          |                                 |0x000002d8  SWI_Routine                        */
/*           .          |                                 |0x000002ec  UNDEF_Routine	                  */
/*           .          |                                 |0x000002b0  IRQ_routine                        */
/*           .          |---------------------------------|0x000001cc  initialize                         */
/*           .          |                                 |0x000000D4                                     */
/*           .          |         Startup Code            |                                               */
/*           .          |         (assembler)             |                                               */
/*           .          |                                 |                                               */
/*           .          |---------------------------------|0x00000040 Reset_Handler                       */
/*           .          |                                 |0x0000003F                                     */
/*           .          | Interrupt Vector Table (unused) |                                               */
/*           .          |          64 bytes               |                                               */
/*           .--------->|---------------------------------|0x00000000 _startup                            *
/*                                                                                                        */
/*                                                                                                        */
/*    The easy way to prevent the linker from loading anything into a memory area is to define            */
/*    a MEMORY region for it and then avoid assigning any .text, .data or .bss sections into it.          */
/*                                                                                                        */
/*                                                                                                        */
/*             MEMORY                                                                                     */
/*             {                                                                                          */
/*                ram_isp_low(A)  : ORIGIN = 0x40000120, LENGTH = 223                                     */
/*                                                                                                        */
/*             }                                                                                          */
/*                                                                                                        */
/*                                                                                                        */
/*  Author:  James P. Lynch                                                                               */
/*                                                                                                        */
/* ****************************************************************************************************** */


/* identify the Entry Point  */

ENTRY(_startup)



/* specify the LPC2148 memory areas  */

MEMORY 
{
	flash     			: ORIGIN = 0x00000000, LENGTH = 512k	/* FLASH ROM 					           */	
	ram_isp_low(A)		: ORIGIN = 0x40000120, LENGTH = 223		/* variables used by Philips ISP bootloader	*/
	ram   				: ORIGIN = 0x40000200, LENGTH = 32513   /* free RAM area							*/
	ram_isp_high(A)		: ORIGIN = 0x40007FE0, LENGTH = 32		/* variables used by Philips ISP bootloader	*/
	ram_usb_dma			: ORIGIN = 0x7FD00000, LENGTH = 8192    /* on-chip USB DMA RAM area (not used)      */
}



/* define a global symbol _stack_end  */

_stack_end = 0x40007EDC;
_ram_low = 0x40000000;



/* now define the output sections  */

SECTIONS 
{
	. = 0x00000000;						/* set location counter to address zero  */
	
	startup : { *(.startup)} >flash		/* the startup code goes into FLASH */

	.text :								/* collect all sections that should go into FLASH after startup  */ 
	{
		*(.text)						/* all .text sections (code)  */
		*(.rodata)						/* all .rodata sections (constants, strings, etc.)  */
		*(.rodata*)						/* all .rodata* sections (constants, strings, etc.)  */
		*(.glue_7)						/* all .glue_7 sections  (no idea what these are) */
		*(.glue_7t)						/* all .glue_7t sections (no idea what these are) */
		_etext = .;						/* define a global symbol _etext just after the last code byte */
	} >flash							/* put all the above into FLASH */

	. = ALIGN(4);						/* start data section on 32-bit boundary */
	_flash_data_start = .;
	.data :								/* collect all initialized .data sections that go into RAM  */ 
	{
		_data = .;						/* create a global symbol marking the start of the .data section  */
		*(.data)						/* all .data sections  */
		_edata = .;						/* define a global symbol marking the end of the .data section  */
	} >ram AT >flash					/* put all the above into RAM (but load the LMA copy into FLASH) */

	.bss :								/* collect all uninitialized .bss sections that go into RAM  */
	{
		_bss_start = .;					/* define a global symbol marking the start of the .bss section */
		*(.bss)							/* all .bss sections  */
	} >ram								/* put all the above in RAM (it will be cleared in the startup code */

	. = ALIGN(4);						/* advance location counter to the next 32-bit boundary */
	_bss_end = . ;						/* define a global symbol marking the end of the .bss section */
}
	_end = .;							/* define a global symbol marking the end of application RAM */

main.c

#include "LPC214x.h"

static inline void feed(void)
{
	PLLFEED = 0xAA;
	PLLFEED = 0x55;
}
 
void sys_init(void)
{
	// Configure PLL0: set CCLK (processor clock) to 60Mhz. Oscillator is 12Mhz
	PLLCFG = 0x24;				// set CCLK to 60Mhz
	feed();
	PLLCON = 0x1;				// Enabled PLL. Set bit 1
	feed();
	while(!(PLLSTAT & (1 << 10)));	// wait for PLL lock (PLOCK bit is set if locked)
	PLLCON = 0x3;				// Connect and enable PLL. Set bits 1:0
	feed();
	
	MAMTIM = 3;					// set MAM-Fetch cycle to 3 cclk as recommended for >40MHz
	MAMCR = 0x02;				// enable MAM 
	
	VPBDIV = 1;					// set PCLK (peripheral clock) to CCLK

	VICProtection = 0;			// enabled user-mode code to change VIC state
	VICIntSelect = 0;			// assign all interrupts to IRQ category
	MEMMAP = 0x01;				// use user-mode flash mapping
	
	SCS = 3;					// use high speed GPIO
}

void led_blink_ISR()
{	
	FIO1PIN ^= 1 << 24;				// toggle pin
	T1IR = 0xff;					// clear all interrupts by writing ones
	VICVectAddr = 0;
}

void led_blink(unsigned int ms)
{
	static int isBlinking = 0;
	
	if(ms == 0) {
		VICIntEnClr |= (1 << 5);	// disable timer1 interrupt
		VICVectAddr9 = 0;
		VICVectCntl9 = 0;
		T1TCR = 0;					// put timer1 in reset
		FIO1SET |= 1 << 24;			// turn off LED
		isBlinking = 0;
		return;
	}
	
	if(isBlinking) {
		// just update the blink rate
		T1MR0 = ms;
		return;
	}
	
        // The LED is connected to P1.24: initialize it as a GPIO:output
        FIO1DIR |= 1 << 24;
        FIO1SET = 1 << 24;

	// Configure timer1 to generate an interrupt at ms/2
	T1TCR = 2;						// put timer2 in reset
	T1CTCR = 0;						// select timer mode
	T1PR = 30000 - 1;				// set prescale so we have a resolution of .5ms
	T1MCR = (1 << 0) | (1 << 1);	// reset and interrupt on MAT1.0
	T1MR0 = ms;						// fires an interrupt at ms/2
	
	VICVectAddr9 = (unsigned long)led_blink_ISR;
	VICVectCntl9 = 5 | (1 << 5);
	VICIntEnable |= (1 << 5);		// enable interrupt for timer1 [man47]
	
	isBlinking = 1;
	
	T1TCR = 1;						// take timer1 out of reset
}

void main (void)
{
	sys_init();
        led_blink(100);   // start the LED blinking asynchronously with a period of 100ms
        
        while(1);           // hang out forever
}