1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Can't get LPC2148 timer match interrupts to work

Discussion in 'Microcontrollers' started by futz, Jan 17, 2009.

  1. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    I wrote this little test program and can't get the interrupt to fire. I've been over it and over it. Looks right to me (not that that means anything ;) ).

    I'm using Eclipse/yagarto (GCC).

    Can anyone spot what I'm doing wrong here?

    Code (text):
    #include "LPC214x.h"
    #define PLOCK 0x400
    void init(void);
    void IRQ_Routine (void)   __attribute__ ((interrupt("IRQ")));
    void FIQ_Routine (void)   __attribute__ ((interrupt("FIQ")));
    void SWI_Routine (void)   __attribute__ ((interrupt("SWI")));
    void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF")));

    int main(void)
    {
        int i;
        IODIR0 = 0x30600000;
        IOCLR0 = 0x30600000;                    //LEDs off
        init();
        T0MCR = 0x0003;                         //interrupt and reset on MR0
        T0MR0 = 0x00ffffff;                     //compare-hit count
        T0TCR = 0x02;                           //reset counter
        T0TCR = 0x01;                           //enable Timer0

        VICVectCntl0 = 0x00000024;              //use it for Timer 0 Interrupt:
        VICVectAddr0 = (unsigned)IRQ_Routine;   //set interrupt vector in 0
        VICIntEnable = 0x00000010;              //enable TIMER0 interrupt

        while(1);
    }

    void IRQ_Routine(void)
    {
        int i;
        IOSET0 = 0x30600000;        //4 LEDs blink
        for(i=0;i<0x0000ffff;i++);
        IOCLR0 = 0x30600000;
        T0IR = 0x01;                //clear interrupt
        VICVectAddr0 = 0;           //end of interrupt - dummy write
    }

    void init(void)
    {
        PLLCFG=0x24;                //set multiplier/divider values
        PLLFEED=0xaa;
        PLLFEED=0x55;
        PLLCON=0x01;                //enable PLL
        PLLFEED=0xaa;
        PLLFEED=0x55;
        while(!(PLLSTAT & PLOCK));  //wait for the PLL to lock to set frequency
        PLLCON=0x3;                 //connect the PLL as the clock source
        PLLFEED=0xaa;
        PLLFEED=0x55;
        MAMCR=0x02;                 //enable MAM
        MAMTIM=0x04;                //set number of clocks for flash memory fetch
        VPBDIV=0x01;                //set peripheral clock(pclk) to system clock(cclk)
    }

    void FIQ_Routine(void){
        while (1) ;
    }
    void SWI_Routine(void){
        while (1) ;
    }
    void UNDEF_Routine(void) {
        while (1) ;
    }
     
     
    Last edited: Jan 17, 2009
  2. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    just woundering if you can try this: change
    T0MR0 = 0x00ffffff; //16777215 is large number to count to
    to
    T0MR0 = 0x000000ff; //try a lower number to test it.

    Futz i know i dont know alot or anything but:

    void IRQ_Routine(void)

    does this have to be like in c18 where you set the address to it?

    or is that what this is for:
    VICVectAddr0 = (unsigned)IRQ_Routine;

    but then you have to make sure its providing the correct address to the register.

    I looked the the datasheet(manual) and can see you are enabling and setting the timer0 correctly In My Own Opinion.
    This is correct: (read bold)
    Code (text):

        T0MCR = 0x0003;                         //interrupt and reset on MR0
        T0MR0 = 0x00ffffff;                     //compare-hit count
        T0TCR = 0x02;                           //reset counter
        T0TCR = 0x01;                           //enable Timer0

        VICVectCntl0 = 0x00000024;              //use it for Timer 0 Interrupt:
        VICVectAddr0 = (unsigned)IRQ_Routine;   //set interrupt vector in 0 [b](not sure how this works in c but in asm you have to supply a address to the fuction)[/b]
        VICIntEnable = 0x00000010;              //enable TIMER0 interrupt

     
     
    Last edited: Jan 17, 2009
  3. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    PCLK is running at 60MHz, so that's not a terribly long count. In the ISR I'm turning a LED on, waiting a bit and turning it off. Wanted the count to be longer than the LED delay. Basically this code should blink the LED every few seconds, I think.

    Yes.

    That's what that's for. I think there's some stuff in crt.s that sets that up.

    I've been over that a hundred times. I'm fairly sure it's correct.

    That's not a function. VICIntEnable just selects which which interrupts are enabled for FIQ or vectored IRQ use.

    I'm a bit lost. I suspect crt.s may be at fault, but I'm not clear enough about what's going on in there to know. The code is cobbled together from a mix of a bunch of different source files found online, mixed with my own stuff.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US

    Futz i know how the enable works lol (i read it too)

    That comment was for that line:

    Code (text):

       //set interrupt vector in 0 (not sure how this works in c but in asm you have to supply a address to the fuction)
      VICVectAddr0 = (unsigned)IRQ_Routine;
     
    By function i mean the process of it getting the address from IRQ_Routine and placing it in "VICVectAddr0 " register. This register holds the location on where to go for the interrupt now are you sure this is getting set up correctly?

    crt.s? Sorry i dont know what this is.
     
  6. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Startup code. Your compiler almost certainly does the same kind of thing, but hides it from you unless you go looking for it.
    Code (text):
    /* ***************************************************************************************************************

        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) */


    .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, [PC,#-0xFF0]    /* see page 71 of "Insiders Guide to the Philips ARM7-Based Microcontrollers" by Trevor Martin  */
            #ldr     PC, IRQ_Addr       /*Original line from DCarne implementation*/
                    ldr     PC, FIQ_Addr

    Reset_Addr:     .word   Reset_Handler       /* defined in this module below  */
    Undef_Addr:     .word   UNDEF_Routine       /* defined in main.c  */
    SWI_Addr:       .word   SWI_Routine         /* defined in main.c  */
    PAbt_Addr:      .word   UNDEF_Routine       /* defined in main.c  */
    DAbt_Addr:      .word   UNDEF_Routine       /* defined in main.c  */
    IRQ_Addr:       .word   IRQ_Routine         /* defined in main.c  */
    FIQ_Addr:       .word   FIQ_Routine         /* defined in main.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, =_etext
                    ldr     R2, =_data
                    ldr     R3, =_edata
    1:              cmp     R2, R3
                    ldrlo   R0, [R1], #4
                    strlo   R0, [R2], #4
                    blo     1b

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

                    /* Enter the C code  */
                    b       main

    .endfunc
    .end
     
     
  7. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Try this plz:
    Code (text):

    #include "LPC214x.h"
    #define PLOCK 0x400
    void init(void);
    void IRQ_Routine (void)   __attribute__ ((interrupt("IRQ")));
    void FIQ_Routine (void)   __attribute__ ((interrupt("FIQ")));
    void SWI_Routine (void)   __attribute__ ((interrupt("SWI")));
    void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF")));

    int main(void)
    {
        int i;
        IODIR0 = 0x30600000;
        IOCLR0 = 0x30600000;                    //LEDs off
        init();
        T0MCR = 0x0003;                         //interrupt and reset on MR0
        T0MR0 = 0x00ffffff;                     //compare-hit count
        T0TCR = 0x01;                           //enable Timer0    [b]enable then reset[/b]
        T0TCR = 0x02;                           //reset counter

        VICVectCntl0 = 0x00000024;              //use it for Timer 0 Interrupt:
        VICVectAddr0 = (unsigned)&IRQ_Routine;   //set interrupt vector in 0   [b]use the & (address)[/b]
        VICIntEnable = 0x00000010;              //enable TIMER0 interrupt

        while(1);
    }

    void IRQ_Routine(void)
    {
        int i;
        IOSET0 = 0x30600000;        //4 LEDs blink
        for(i=0;i<0x0000ffff;i++);
        IOCLR0 = 0x30600000;
        T0IR = 0x01;                //clear interrupt
        VICVectAddr0 = 0;           //end of interrupt - dummy write
    }

    void init(void)
    {
        PLLCFG=0x24;                //set multiplier/divider values
        PLLFEED=0xaa;
        PLLFEED=0x55;
        PLLCON=0x01;                //enable PLL
        PLLFEED=0xaa;
        PLLFEED=0x55;
        while(!(PLLSTAT & PLOCK));  //wait for the PLL to lock to set frequency
        PLLCON=0x3;                 //connect the PLL as the clock source
        PLLFEED=0xaa;
        PLLFEED=0x55;
        MAMCR=0x02;                 //enable MAM
        MAMTIM=0x04;                //set number of clocks for flash memory fetch
        VPBDIV=0x01;                //set peripheral clock(pclk) to system clock(cclk)
    }

    void FIQ_Routine(void){
        while (1) ;
    }
    void SWI_Routine(void){
        while (1) ;
    }
    void UNDEF_Routine(void) {
        while (1) ;
    }
     
     
  8. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Doesn't work. I put a breakpoint in the ISR, set it running and went away for a while. Nothing. Still spinning in the while(1); loop when I came back.

    I'm going to grind at it some more today. I have another version of crt.s that I'll try. It's just slightly different in a few spots.
     
    Last edited: Jan 17, 2009
  9. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
  10. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Ya I read that last night. Not sure what they mean though.
    EDIT: Look close at the crt.s and you'll find that stuff IS in there.

    The crt.s I'm using came with the interrupt parts of the source code I'm using.

    This part
    Code (text):
    void IRQ_Routine (void)   __attribute__ ((interrupt("IRQ")));
    void FIQ_Routine (void)   __attribute__ ((interrupt("FIQ")));
    void SWI_Routine (void)   __attribute__ ((interrupt("SWI")));
    void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF")));
     
    and this part
    Code (text):
    void FIQ_Routine(void){
        while (1) ;
    }
    void IRQ_Routine(void)
    {
        while(1);
    }
    void SWI_Routine(void){
        while (1) ;
    }
    void UNDEF_Routine(void) {
        while (1) ;
    }
    came in the same, supposedly working, archive of files. I just changed the IRQ_Routine section from a stub to a working ISR.

    It should work. I've looked at other crt.s files and they aren't very different from mine. Mostly the same except small details.

    I'm missing some small but important detail. :p
     
    Last edited: Jan 17, 2009
  11. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    can you try this:
    Code (text):

    #include "LPC214x.h"
    #define PLOCK 0x400
    void init(void);

    static IRQ_Routine(void)  __attribute__ ((interrupt ("IRQ")));
    void FIQ_Routine (void)   __attribute__ ((interrupt("FIQ")));
    void SWI_Routine (void)   __attribute__ ((interrupt("SWI")));
    void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF")));

    int main(void)
    {
        int i;
        IODIR0 = 0x30600000;
        IOCLR0 = 0x30600000;                    //LEDs off
        init();
        T0MCR = 0x0003;                         //interrupt and reset on MR0
        T0MR0 = 0x00ffffff;                     //compare-hit count
        T0TCR = 0x02;                           //reset counter
        T0TCR = 0x01;                           //enable Timer0

        VICVectAddr0 = (unsigned long)IRQ_Routine;   //set interrupt vector in 0
        VICVectCntl0 = 0x00000024;                   //use it for Timer 0 Interrupt
        VICIntEnable = 0x00000010;                   //enable TIMER0 interrupt

        while(1);
    }

    void IRQ_Routine(void)
    {
        int i;
        IOSET0 = 0x30600000;        //4 LEDs blink
        for(i=0;i<0x0000ffff;i++);
        IOCLR0 = 0x30600000;
        T0IR = 0x01;                //clear interrupt
        VICVectAddr0 = 0;           //end of interrupt - dummy write
    }

    void init(void)
    {
        PLLCFG=0x24;                //set multiplier/divider values
        PLLFEED=0xaa;
        PLLFEED=0x55;
        PLLCON=0x01;                //enable PLL
        PLLFEED=0xaa;
        PLLFEED=0x55;
        while(!(PLLSTAT & PLOCK));  //wait for the PLL to lock to set frequency
        PLLCON=0x3;                 //connect the PLL as the clock source
        PLLFEED=0xaa;
        PLLFEED=0x55;
        MAMCR=0x02;                 //enable MAM
        MAMTIM=0x04;                //set number of clocks for flash memory fetch
        VPBDIV=0x01;                //set peripheral clock(pclk) to system clock(cclk)
    }

    void FIQ_Routine(void){
        while (1) ;
    }
    void SWI_Routine(void){
        while (1) ;
    }
    void UNDEF_Routine(void) {
        while (1) ;
    }
     
     
  12. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    **** Build of configuration Default for project debounce ****

    make all
    arm-elf-gcc -mcpu=arm7tdmi -Ic:/gccfd/yagarto/arm-elf/include -c -fno-common -O0 -g debounce.c
    debounce.c:29: error: conflicting types for 'IRQ_Routine'
    debounce.c:5: error: previous declaration of 'IRQ_Routine' was here
    debounce.c:63:2: warning: no newline at end of file
    make: *** [debounce.o] Error 1
     
  13. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    take that static out and replace with a "void" (no quotes)

    if that fails try this:

    Code (text):

    #include "LPC214x.h"
    #define PLOCK 0x400
    void init(void);

    __irq void IRQ_Routine(void)  __attribute__ ((interrupt ("IRQ")));
    void FIQ_Routine (void)   __attribute__ ((interrupt("FIQ")));
    void SWI_Routine (void)   __attribute__ ((interrupt("SWI")));
    void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF")));

    int main(void)
    {
        int i;
        IODIR0 = 0x30600000;
        IOCLR0 = 0x30600000;                    //LEDs off
        init();
        T0MCR = 0x0003;                         //interrupt and reset on MR0
        T0MR0 = 0x00ffffff;                     //compare-hit count
        T0TCR = 0x02;                           //reset counter
        T0TCR = 0x01;                           //enable Timer0

        VICVectAddr0 = (unsigned long)IRQ_Routine;   //set interrupt vector in 0
        VICVectCntl0 = 0x00000024;                   //use it for Timer 0 Interrupt
        VICIntEnable = 0x00000010;                   //enable TIMER0 interrupt

        while(1);
    }

    __irq void IRQ_Routine(void)
    {
        int i;
        IOSET0 = 0x30600000;        //4 LEDs blink
        for(i=0;i<0x0000ffff;i++);
        IOCLR0 = 0x30600000;
        T0IR = 0x01;                //clear interrupt
        VICVectAddr0 = 0;           //end of interrupt - dummy write
    }

    void init(void)
    {
        PLLCFG=0x24;                //set multiplier/divider values
        PLLFEED=0xaa;
        PLLFEED=0x55;
        PLLCON=0x01;                //enable PLL
        PLLFEED=0xaa;
        PLLFEED=0x55;
        while(!(PLLSTAT & PLOCK));  //wait for the PLL to lock to set frequency
        PLLCON=0x3;                 //connect the PLL as the clock source
        PLLFEED=0xaa;
        PLLFEED=0x55;
        MAMCR=0x02;                 //enable MAM
        MAMTIM=0x04;                //set number of clocks for flash memory fetch
        VPBDIV=0x01;                //set peripheral clock(pclk) to system clock(cclk)
    }

    void FIQ_Routine(void){
        while (1) ;
    }
    void SWI_Routine(void){
        while (1) ;
    }
    void UNDEF_Routine(void) {
        while (1) ;
    }

     
    Edited bases from:
    http://www.electro-tech-online.com/custompdfs/2009/01/an10254.pdf
     
  14. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Did that. Even more errors. I didn't make note of what. Just changed it back.

    Right after breakfast (lunch). :p
     
  15. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    yeah lunch time 4 me too :D
     
  16. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    make all
    arm-elf-as -ahls -mapcs-32 -o crt.o crt.s > crt.lst
    arm-elf-gcc -mcpu=arm7tdmi -Ic:/gccfd/yagarto/arm-elf/include -c -fno-common -O0 -g debounce.c
    debounce.c:5: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void'
    debounce.c: In function 'main':
    debounce.c:21: error: 'IRQ_Routine' undeclared (first use in this function)
    debounce.c:21: error: (Each undeclared identifier is reported only once
    debounce.c:21: error: for each function it appears in.)
    debounce.c: At top level:
    debounce.c:28: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void'
    make: *** [debounce.o] Error 1
     
    Last edited: Jan 17, 2009
  17. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    hey futz when you pause and check where the code is at can you check if the "T0IR" register instead of checking to see if it went to the location.

    Like check if the flag is even set at all. If its not then it doesnt have to do with the location on calling your function it would have to do with setting the timer right and interrupt.
     
  18. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Well duh! :p Good thinking! I should have thought of that (but I didn't :eek:). :D Just checked and the MR0 interrupt flag is set. So now I need to find out why that's not tripping the interrupt.

    EDIT: I put in a T0IR = 0xff; line to clear the flag right at init. Now the flag is clear and stays clear. I can see the timer counter changing and left it long enough to match MR0 many times. Flag still clear. Hmm...

    Oops, ran it some more and now the flag is set.
     
    Last edited: Jan 17, 2009
  19. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    I'm getting some unexpected results when debugging. Looks to me like both Timer0 and Timer1 are running on startup. The interrupt flag is set by the time my code inits things.

    I have to very carefully step thru things and see exactly what's going on and maybe mod the code to fix it. I don't know enough to say yet.
     
  20. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    can you try this:
    Code (text):

    #include "LPC214x.h"
    #define PLOCK 0x400
    void init(void);

    void IRQ_Routine(void)  __attribute__ ((interrupt ("IRQ")));
    void FIQ_Routine (void)   __attribute__ ((interrupt("FIQ")));
    void SWI_Routine (void)   __attribute__ ((interrupt("SWI")));
    void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF")));

    int main(void)
    {
        int i;
        IODIR0 = 0x30600000;
        IOCLR0 = 0x30600000;                    //LEDs off
        init();
        T0MCR = 0x0003;                         //interrupt and reset on MR0
        T0MR0 = 0x00ffffff;                     //compare-hit count
        T0TCR |= 0x01;                           //enable Timer0
        T0TCR |= 0x02;                           //reset counter

        VICVectAddr0 = (unsigned long)&IRQ_Routine;   //set interrupt vector in 0
        //[b]or[/b]
        //VICVectAddr0 = (unsigned long)IRQ_Routine;   //set interrupt vector in 0
        VICVectCntl0 = 0x00000024;                   //use it for Timer 0 Interrupt
        VICIntSelect = 0x00000000;                   //[b]Configure for IRQ[/b]
        VICIntEnable = 0x00000010;                   //enable TIMER0 interrupt

        while(1);
    }

    void IRQ_Routine(void)
    {
        int i;
        IOSET0 = 0x30600000;        //4 LEDs blink
        for(i=0;i<0x0000ffff;i++);
        IOCLR0 = 0x30600000;
        T0IR = 0x01;                //clear interrupt
        VICVectAddr0 = 0;           //end of interrupt - dummy write
    }

    void init(void)
    {
        PLLCFG=0x24;                //set multiplier/divider values
        PLLFEED=0xaa;
        PLLFEED=0x55;
        PLLCON=0x01;                //enable PLL
        PLLFEED=0xaa;
        PLLFEED=0x55;
        while(!(PLLSTAT & PLOCK));  //wait for the PLL to lock to set frequency
        PLLCON=0x3;                 //connect the PLL as the clock source
        PLLFEED=0xaa;
        PLLFEED=0x55;
        MAMCR=0x02;                 //enable MAM
        MAMTIM=0x04;                //set number of clocks for flash memory fetch
        VPBDIV=0x01;                //set peripheral clock(pclk) to system clock(cclk)
    }

    void FIQ_Routine(void){
        while (1) ;
    }
    void SWI_Routine(void){
        while (1) ;
    }
    void UNDEF_Routine(void) {
        while (1) ;
    }

     
    if anything i hope this can help:
    SparkFun Electronics :: View topic - LPC2294 Uart interrupt problem
     
    Last edited: Jan 17, 2009
  21. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    All you're changing is the VICIntSelect line, right? It shouldn't be necessary, as they're all set to IRQ on reset, but never hurts to be sure. :p

    I'll add it to my code rather than go through the misery of switching to yours and back.

    EDIT: Ran it. No change. The timer works right. The timer interrupt flag gets set. No interrupt occurs. Just so we're on the same page, here's my current code:
    Code (text):
    #include "LPC214x.h"
    #define PLOCK 0x400
    void init(void);
    void IRQ_Routine (void)   __attribute__ ((interrupt("IRQ")));
    void FIQ_Routine (void)   __attribute__ ((interrupt("FIQ")));
    void SWI_Routine (void)   __attribute__ ((interrupt("SWI")));
    void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF")));

    int main(void)
    {
        int i;
        IODIR0 = 0x30600000;
        IOCLR0 = 0x30600000;                    //LEDs off
        init();
        T0TCR = 0x02;                           //reset counter
        T0IR = 0xff;
        T0MCR = 0x0003;                         //interrupt and reset on MR0
        T0MR0 = 0x0000ffff;                     //compare-hit count

        VICVectCntl0 = 0x00000024;              //use it for Timer 0 Interrupt:
        VICIntSelect = 0;
        VICVectAddr0 = (unsigned)IRQ_Routine;   //set interrupt vector in 0
        VICIntEnable = 0x00000010;              //enable TIMER0 interrupt

        T0TCR = 0x01;                           //enable Timer0

        while(1){
            i=0;
            for(i=0;i<1000;i++);
            i=1;
        }
    }

    void IRQ_Routine(void)
    {
        int i;
        IOSET0 = 0x30600000;        //4 LEDs blink
        for(i=0;i<0x0000ffff;i++);
        IOCLR0 = 0x30600000;
        T0IR = 0x01;                //clear interrupt
        VICVectAddr0 = 0;           //end of interrupt - dummy write
    }

    void init(void)
    {
        PLLCFG=0x24;                //set multiplier/divider values
        PLLFEED=0xaa;
        PLLFEED=0x55;
        PLLCON=0x01;                //enable PLL
        PLLFEED=0xaa;
        PLLFEED=0x55;
        while(!(PLLSTAT & PLOCK));  //wait for the PLL to lock to set frequency
        PLLCON=0x3;                 //connect the PLL as the clock source
        PLLFEED=0xaa;
        PLLFEED=0x55;
        MAMCR=0x02;                 //enable MAM
        MAMTIM=0x04;                //set number of clocks for flash memory fetch
        VPBDIV=0x01;                //set peripheral clock(pclk) to system clock(cclk)
    }

    void FIQ_Routine(void){
        while (1) ;
    }
    void SWI_Routine(void){
        while (1) ;
    }
    void UNDEF_Routine(void) {
        while (1) ;
    }
     
     
    Last edited: Jan 17, 2009

Share This Page