This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Unable to hit ISR Handler

Team,

Please suggest me what is missing/wrong?
I'm unable to hit ISR even though the timer is reset and interrupt flag is set.

I'm not using real hardware but running in simulation mode only and for LPC23xx:

My startup code:
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, IRQ_Addr LDR PC, [PC, #-0x0120]

LDR PC, FIQ_Addr

void InitTimer1() {

/* Timer1 and Preset disabled */ T1TCR = 0x00; /* Timer Counter register, after PR is reset, this inc by 1 */ T1TC = 0x00; /* Prescalar register! Max value for prescalar counter */ T1PR = 0xFFFF; /* Prescale Counter register */ T1PC = 0x0; /* End user has to fill in the match value */ T1MR0 = 0x222; /* Reset TC and interrupt on match */ T1MCR = 0x03; /* 0000 0000 0000 0011 */
}

void InitVIC() {

VICIntSelect &= (~(1 << 5)); /* Timer 1 selected as IRQ */ /* Address of the ISR */
VICVectAddr5 = (unsigned long )Timer1_IRQ_Handler;

VICVectCntl5 = 0x20 | 5;
VICIntEnable |= (1 << 5);/* Timer 1: (bit 5) interrupt enabled */

}

void Timer1_IRQ_Handler (void) __irq
{ unsigned static int i = 0; T0IR = 0x01; /* Clear Timer1 MR0 interrupt */ IOSET0 = ~ (1 << (i+1)); if ( i == 32) i = 1; i++; VICVectAddr = 0x00;/* Dummy write to ACK the VIC */

}

int main() { InitPLL(); EnableMAM(); SetPeripheralClock(); InitGPIO(); InitTimer1(); InitVIC();

/* Timer1 and Preset Enabled */ T1TCR = 0x01;

/* Rest of the code */ while (1);

}

Parents Reply Children
  • void InitVIC() {
    
    /* Timer 1 selected as IRQ */
    VICIntSelect &= (~(1 << 5));
    
    /* Address of the ISR */
    VICVectAddr5 = (unsigned long )Timer1_IRQ_Handler;
    
    VICVectCntl5 = 0x20 | 5;
    
    /* Timer 1: (bit 5) interrupt enabled */
    VICIntEnable |= (1 << 5);
    
    }
    

    What is this for? => VICVectCntl5 = 0x20 | 5; <=

  • Looks like code copied from a LPC21xx chip. They had a VICVectCntXX register that mapped what peripherial that was connected to each of the positions on the VIC. Expected value was 0x20 + the interrupt channel, where the 0x20 was to enable the slot. You controlled the priority of the different devices by selecting slot 0..15 and then you had to configure what device that used the slot.

    The LPC23xx has hard-coded indexing, so this register is now actually renamed to VICVectPriorityXX (but not renamed by Keil...) and instead of selecting a VIC slot to control priority, you now use the hard-coded slot for the device but configures the priority for the slot (interrupt source). Expected value is the priority as a value 0..31.

    On one hand, it is bad to copy/paste code without comparing with the user manual/datasheet.

    On the other hand, it is bad of Keil to reuse the old (and now incorrect) register name when they added support for LPC23xx chips. The compiler shouldn't even have known about the VICVectCntlXX register name.

    The LPC23xx.h file contains the text:

    /* The name convention below is from previous LPC2000 family MCUs, in LPC23xx/24xx,
    these registers are known as "VICVectPriority(x)". */
    


    The term "name convention" somehow gives the indication that Keil originally thought it was the same register, but with a changed name when it is actually something completely different.

  • Hi,

    Since keil LPC23xx.h file does not have VICVectPriority defined, I'm using VICVectCntxx

    Also the if you see the code, I've referred UM10211
    LPC23XX User manual and coded the initialization of PLL, timer...etc though I've not posted the complete code. If you wish I can post the same....

    I'm not able to make out why the ISR is not hit though the simulated timer shows interrupt is set and counter is reset as per the timer init routine.

    Appreciate your help.

    Regards,
    Javeed

  • I heard VICVectCntXX before (from some other posts), and tried to find it in the LPC23xx.h. And according to KEIL's comments in LPC23xx.h, I thought VICVectCntXX is the same as VICVectPriorityXX. No I learn that I was wrong.

    I think the OP should also check the Power Control for Peripherals register (PCONP - 0xE01F C0C4).

  • -> Since keil LPC23xx.h file does not have VICVectPriority defined <-

    It is defined in the LPC23xx.h, I think.

    <LPC23xx.h>

    /* LPC23xx/24xx VICVectPriority(x)". */
    #define VICVectPriority0   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x200))
    #define VICVectPriority1   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x204))
    #define VICVectPriority2   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x208))
    #define VICVectPriority3   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x20C))
    #define VICVectPriority4   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x210))
    #define VICVectPriority5   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x214))
    #define VICVectPriority6   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x218))
    

  • The correct name VICVectPriorityXX was added from version 1.02 of the LPC23xx.h file (2007-09-05).

    I started with the LPC23xx chips before it was added.

  • I've included this in my header file LPC23XX.H but still no luck of interrupt being hit.

    Snapshot of the VIC init code is as below:

    void InitVIC() {
    
            /* No PIN BLOCK HERE as we're using timer interrupt and no external interrupt */
    
            VICIntSelect = 0x00;    /* Timer 1 selected as IRQ */
            /* Address of the ISR */
            VICVectAddr5 = (unsigned long )Timer1_IRQ_Handler;
    
            VICVectPriority5 = 0x20 | 0x05;
    
            VICIntEnable |= 0x20;   /* Timer 1: (bit 5) interrupt enabled */
    
    }
    
    
    

    .

  • The datasheet for the LPC23xx claims:

    Bit 0:3 VICVectPriority Selects one of 16 priority
    levels for the corresponding vectored interrupt.
    
    31:4 - Reserved, user software should not write ones
    to reserved bits. The value read from a reserved bit
    is not defined.
    

    So maybe you shouldn't do your 0x20 | 0x05 since that is clearly writing values to reserved bits.

    Just write your priority (0..15) into the register. Nothing else. There is no "enable" bit for the priority register. That "enable" bit only existed for the LPC21xx processor in the VICVectCntlXX register.

  • Setting the priority as 0x05 does not solve the issue.

  • "Setting the priority as 0x05 does not solve the issue."
    No, but that doesn't mean you shouldn't fix it, and continue making sure that your code matches the user manual - or reference code. You are spending time on your code, or relying 100% on the forum?

    VICIntEnable |= 0x20;   /* Timer 1: (bit 5) interrupt enabled */
    


    Bettery write:

    VICIntEnable |= 1<<5;
    


    And even better to do:

    enum {
        INT_TIMER1 = 5,
    };
    ...
    VICIntEnable |= 1 << INT_TIMER1;
    

    By the way - is there a reason why your timer1 interrupt handler is writing to T0IR instead of T1IR?

    Another thing. When you finally did use the pre tags to repost your code, it seems like you copied the code from the previous post, instead of copying from the editor - it has the same strange indentation making it hard to read. Note that tab doesn't work well when posting code.

  • Please find code post again from editor.

    T0IR = 0x01;    /* Clear Timer1 MR0 interrupt */
    

    It was my mistake, I should have cleared T1IR instead of T0IR, though the comment is clearly referring to T1IR.

    Thanks for catching this bug.

    I've coded based on the manual but no luck so far. I'm not relying 100% on the forum responses but seeking inputs for techies.

    #include <LPC23xx.H>     /* LPC23xx definitions */
    void Timer1_IRQ_Handler(void) __irq;
    void InitVIC() {
    
            /* No PIN BLOCK HERE as we're using timer interrupt and no external interrupt */
    
            VICIntSelect &= ~(1L<<5);     /* Timer 1 selected as IRQ */
            /* Address of the ISR */
            VICVectAddr5 = (unsigned long )Timer1_IRQ_Handler;
    
            VICVectPriority5 = 0x05;
    
            VICIntEnable |= 0x20;   /* Timer 1: (bit 5) interrupt enabled */
    
    }
    
    /* Timer 1 IRQ
    
            T0IR: 4bits for MRn and 4bit for CRn
            0 - MR0 int
            1 - MR1 int
    
            3 - MR3 int
            4 - CR0 int
            5 - CR1 int
    
            7 - CR3 int
    */
    __irq void Timer1_IRQ_Handler (void)
    {
            unsigned static int i = 0;
    
            T1IR = 0x01;    /* Clear Timer1 MR0 interrupt */
    
    
            IOSET0 = ~ (1 << (i+1));
            if ( i == 32)
                    i = 1;
            i++;
    
            VICVectAddr = 0xFF;      /* Dummy write to ACK the VIC */
    
    }
    void InitTimer1() {
    
            /* Timer1 and Preset disabled */
            T1TCR = 0x00;
            /* Timer Counter register, after PR is reset, this inc by 1 */
            T1TC = 0x00;
            /* Prescalar register! Max value for prescalar counter */
            T1PR = 0xFFFF;
            /* Prescale Counter register */
            T1PC = 0x0;
            /* End user has to fill in the match value */
            T1MR0 = 0x222;
            /* Reset TC and interrupt on match */
            T1MCR = 0x03;             /* 0000 0000 0000 0011 */
    }
    int main() {
            InitPLL();
            EnableMAM();
            SetPeripheralClock();
            InitGPIO();
            InitTimer1();
            InitVIC();
    
            /* Timer1 and Preset Enabled */
            T1TCR = 0x01;
    
            /* Rest of the code */
            while (1);
    
    }
    
    

    Regards,