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.

TBCCR3 and Timer overflow at the same time

Hello

According to slau144_.pdf (MSP430f2xx user guide) TBIV equals 06h when interrupt source is TBCCR3 and equals 0Eh when timer overflow (TBIFG).

But what is the TBIV value when TBCCR3 and timer overflow occur at the same time (or nearly same time: before ISR is served) ?

Best regards

Michel

  • The order of appearance (or the time in-between) is unimportant. Every unhandled interrupt sorts itself into the queue based on priority, and hte highest priority event is reported (and cleared at the same time) first.

    So on first read of TBIV you'll get 0x0e, the very next read on TBIV would return 0x06 (provided that not another overflow happened between the two reads) and the associated IFG bits are cleared.

    The IV registers are 'sorted lists' of all associated interrupts where IE and IFG bits are currently set. Reading from the IV register fetches the topmost event nr., while at the same time clearing the IFG bit. Manually clearing the IFG bit or the IE bit removes the event from the IV list, and writing something to the IV register clears all associated IFG bits (including those where the IE bit is not set).

  • Mich said:

    But what is the TBIV value when TBCCR3 and timer overflow occur at the same time (or nearly same time: before ISR is served) ?

     Hi Mich, when IRQ is served the highest priority code is on TBIV, if you need to alter then check single flag bit and write code that service in the order you need.

     Regards

  • Jens-Michael Gross said:

    So on first read of TBIV you'll get 0x0e, the very next read on TBIV would return 0x06 (provided that not another overflow happened between the two reads) and the associated IFG bits are cleared.

    Thanks for the answers.

    This issue is seen only when TBIV and TBCCR3 events occur at the same time. From my understanding of signals on the oscilloscope, the reading of TBIV (0x0E) clears both individual flags and the 2nd interrupt never occurs. And as I tested TBIV, the 0x06 value was never seen in such case. TBBCR3 and TBIV have the same priority 28.

    Roberto solution seems to work. I am still testing.

  • Mich said:
    This issue is seen only when TBIV and TBCCR3 events occur at the same time. From my understanding of signals on the oscilloscope, the reading of TBIV (0x0E) clears both individual flags and the 2nd interrupt never occurs.

    No, this shouldn't happen. Reading TBIV returns the highest priority interrutp event and only clears the event flag for exactly this event.

    However, your code yould do something that clears more than one or even all event flags (like writing to TAIV or reading TAIV more than exactly once per itnerrupt).

    If you have to handle several events that can happen at th esame time, a good idea is to put the switch into a loop:

    while(1)
     switch (__even_in_range(TAIV, 14))
    {
      case 0: return;
      case 2: ...
    }

    This way, all pending events are handled dependign on their priority, until TAIV returns 0, which means no more events.

  • Mich said:
    Roberto solution seems to work. I am still testing.

     Hi Mich, I tested many time ago on a multiple service priority due to task. After max priority check also remember TBIV check loop as suggested by Jens to avoid return then fire again same interrupt, also remember if you need again not to read TBIV on switch, copy to a variable or use Jens solution.

     Verify answer can be check on more than one answer and also to selfpost.

     Regards

     Roberto

  • You are fully right. I saw it in thte documentation now (TBIV, Timer_B Interrupt Vector Register => there is a priority column in the table). What's more I tested the following code and I never succeeded to reach the breakpoint, even with TBCCR3 value between 0xFFFE up to 0x0001.

    __interrupt void timer_B1( void )
    {

        u16 val;

        if ((TBCCTL3 & CCIFG) && (TBCTL & TBIFG))
        {
            __delay_cycles(2); // use to set the breakpoint
        }

        val = TBIV;
        if (val == 0x06)   // TBCCR3 flag
        {
             TEST14_ON;
        }
        if (val == 0x0E)   // TB flag
        {
             TEST63_ON;
        }

    TEST63_OFF;
    TEST14_OFF;

    }

     

    And both test points were seen at level one sequently at the oscilloscope.

    Thanks a lot.

**Attention** This is a public forum