This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

The interrupt priority of F28035 CPU Timer1/2

Hi

I need to use F28035's CPU Timer1 and Timer2 to generate 2 interrupt routines

to demostrate that Timer1's interrupt breaks into timer2's interrupt routine.

So I set Timer1's period to 10us and Timer2's period to 100us. And I also wrote 

a while loop to delay about 35us at Timer2's interrupt routine. In this way, Timer2's

interrupt routine can be interrupted by Timer1 several times.

To my surprise, Timer1 cannot interrupt Timer2's interrupt routine, Only Timer2

can interrupt Timer1's interrupt routine.

I checked SPRUGL8C, Timer1's interrupt priority is 17, and Timer2's interrupt

priority is 18, so Timer1 has a higher priority than Timer2. I don't know if there are

some mistakes in my program.

thanks,

Jiakai

PS: The initialization program is as follows:

const volatile struct CPUTIMER_REGS* aryCpuTimer[3] = {&CpuTimer0Regs, &CpuTimer1Regs, &CpuTimer2Regs};
void PS_InitTimer(int timerNo, Uint32 interval, PINT vec)
{
    struct CPUTIMER_REGS *pTimer = (struct CPUTIMER_REGS *)aryCpuTimer[timerNo];
    pTimer->PRD.all = interval - 1;
    pTimer->TPR.bit.TDDR = 0; // make it to CPU clock
    pTimer->TPRH.bit.TDDRH = 0;

    pTimer->TCR.all = 0x4030; // reload/interrupt but not start
//  pTimer->TCR.bit.TIE = 1; // interrupt enable bit, 1: enable
//  pTimer->TCR.bit.TRB = 1; // timer reload bit.
//  pTimer->TCR.bit.SOFT = 0; // Timer free run
//  pTimer->TCR.bit.FREE = 0; // Timer Free Run
//  pTimer->TCR.bit.TSS = 1; // 0: Start Timer, 1: Stop timer
    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.TINT1 = vec;
    IER |= (timerNo == 0) ? M_INT1 : ((timerNo == 1) ? M_INT13 : M_INT14);
    EDIS; // This is needed to disable write to EALLOW protected registers
    pTimer->TCR.bit.TSS = 0; // 0: Start Timer, 1: Stop timer

}

  • Sorry the initialization function is as follows:
    const volatile struct CPUTIMER_REGS* aryCpuTimer[3] = {&CpuTimer0Regs, &CpuTimer1Regs, &CpuTimer2Regs};
    void PS_InitTimer(int timerNo, Uint32 interval, PINT vec)
    {
    struct CPUTIMER_REGS *pTimer = (struct CPUTIMER_REGS *)aryCpuTimer[timerNo];
    pTimer->PRD.all = interval - 1;
    pTimer->TPR.bit.TDDR = 0; // make it to CPU clock
    pTimer->TPRH.bit.TDDRH = 0;

    pTimer->TCR.all = 0x4030; // reload/interrupt but not start
    // pTimer->TCR.bit.TIE = 1; // interrupt enable bit, 1: enable
    // pTimer->TCR.bit.TRB = 1; // timer reload bit.
    // pTimer->TCR.bit.SOFT = 0; // Timer free run
    // pTimer->TCR.bit.FREE = 0; // Timer Free Run
    // pTimer->TCR.bit.TSS = 1; // 0: Start Timer, 1: Stop timer
    EALLOW; // This is needed to write to EALLOW protected registers
    switch (timerNo) {
    case 0:
    PieVectTable.TINT1 = vec;
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    IER |= M_INT1;
    break;
    case 1:
    PieVectTable.TINT1 = vec;
    IER |= M_INT13;
    break;
    case 2:
    PieVectTable.TINT2 = vec;
    IER |= M_INT14;
    break;
    }
    EDIS; // This is needed to disable write to EALLOW protected registers
    pTimer->TCR.bit.TSS = 0; // 0: Start Timer, 1: Stop timer
    }
  • Hello,

    By default, interrupts aren't nested. The hardware assigned priority determines which interrupt gets handled first if they're both pending. However, there are things you can do in software in the ISR to allow nesting. See this wiki page:

    processors.wiki.ti.com/.../Interrupt_Nesting_on_C28x

    - Whitney
  • Dear Whitney,

    Thank you for the reply.

    Maybe I didn't explain the things properly. I need nested interrupt in my system. In each ISR, I will set interrupt enable first
    to enable the nested interrupt. I also don't want to change interrupt priority.

    From TI's technical documents, Timer1 has higher interrupt priority than Timer2, So I suppose Timer2's ISR can be interrupted
    by Timer1. But In my project, Timer1's ISR is interrupted by Timer2.

    I want to know if there are some errors in my program or timer2's interrupt priority can be changed if it's used by TI/RTOS.
    By the way I don't use TI/RTOS in the project.

    thanks,
    Jiakai
  • Hi Jiakai,

    Do you mind sharing what your ISR code looks like? Maybe that will help me understand.

    Thanks,
    Whitney
  • The Interrupt routines for Timer1/2 are as follows:

    // ISR of Timer1
    interrupt void Task()
    {
    int i;

    PS_EnableIntr(); // asm(" clrc INTM")
    PS_ClearDigitOutBitA((Uint32) 1 << 17); // Set GPIO17 to low
    for (i = 0; i < 100; i++);
    PS_SetDigitOutBitA((Uint32) 1 << 17); // Set GPIO17 to high
    }

    // ISR of Timer2
    interrupt void Task_1()
    {
    int i;
    PS_EnableIntr(); // asm(" clrc INTM")
    PS_ClearDigitOutBitA((Uint32) 1 << 19); // Set GPIO19 to low
    for (i = 0; i < 1000; i++);
    PS_SetDigitOutBitA((Uint32) 1 << 19); // Set GPIO19 to high
    }
  • You'll need to do some additional masking before clearing INTM in the Timer1 ISR. IER &= ~M_INT14 should prevent the Timer2 ISR from being called until the Timer1 ISR completes. You don't need to save/restore IER because that's already done as part of the context save.

    Like I said, the hardware priority determines which gets serviced first if both are pending. Once you're inside the Timer1 ISR and its corresponding IFR flag has been cleared, the priority doesn't protect it from being interrupted once you've enabled interrupts. You need to use masks on the interrupt enable registers to control that.

    Whitney
  • Hi Whitney,

    Thank you very much! It is very helpful!

    I thought that C2000 MCUs remember the current interrupt priority to avoid the same or lower interrupt.

    I think I need to ask you another question: What's the simplest way to avoid the same or lower interrupt

    in the current ISR?

    Can I just change IER to do this? for example, In PWM1 periodic ISR, I need to allow INT1 and INT2

    interrupt but avoid INT3 to INT14 interrupt. 

    void PwmISR(void)

    {

        IER &= ~(MINT3 | (MINT3 - 1));

       asm(" nop");   // don't know if this is needed.

        asm(" clrc INTM");

        ...

        EPwm1Regs.ETCLR.bit.INT = 1;
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

    }

    thanks,

    Jiakai

  • Hi Jiakai,

    Glad that helped. I think the code snippet you shared though is doing the opposite of what you described. It will disable INT1 through 3. IER &= (MINT3 - 1) should disable INT3 through 14. Is that what you wanted?

    Whitney

  • Yes, you are right.
    Thank you very much.
    Jiakai