basil4j 1 Posted March 11, 2014 Share Posted March 11, 2014 Hi All, Im having a bit of trouble with these interrupts on TimerB2 on the MSP430FR5739. I am using 3 compare registers, TB2CCR0 = 250, TB2CCR1 = 150 & TB2CCR2 = 50 CCR0 Interrupts are easy enough, but im confused when it comes to the rest. The Family guide says: The TBIFG flag and TBxCCRn CCIFG flags (excluding TBxCCR0 CCIFG) are prioritized and combined to source a single interrupt vector. The interrupt vector register TBxIV is used to determine which flag requested an interrupt. [snip] Any access, read or write, of the TBxIV register automatically resets the highest-pending interrupt flag. If another interrupt flag is set, another interrupt is immediately generated after servicing the initial interrupt. For example, if the TBxCCR1 and TBxCCR2 CCIFG flags are set when the interrupt service routine accesses the TBxIV register, TBxCCR1 CCIFG is reset automatically. I was hoping to use the following code, using TB2IV to detemrine which CCRn caused the interrupt but if I read this correctly it will be cleared before I get a chance? Can someone help? Am I misreading or is there a trick around this? //=====Interrupt for 40Hz timer pre-sample===== #pragma vector=TIMER2_B1_VECTOR __interrupt void Interrupt_40_pre(void) { switch (TB2IV) { case 0x02: //Temp break; case 0x04: //Baro break; default: break; } } Quote Link to post Share on other sites
KatiePier 73 Posted March 13, 2014 Share Posted March 13, 2014 Hi @@basil4j, Your code is on the right track and should work - in fact this is basically the same way the interrupts are handled in the TI MSP430FR5739 code examples (www.ti.com/lit/zip/slac491 ). You can look at for example MSP430FR57xx_tb0_03.c in that zip file. You can see the ISR looks very similar to yours: // TimerB Interrupt Vector (TBIV) handler #pragma vector=TIMER0_B1_VECTOR __interrupt void TIMER0_B1_ISR(void) { switch(__even_in_range(TB0IV,14)) { case 0: break; // No interrupt case 2: break; // CCR1 not used case 4: break; // CCR2 not used case 6: break; // reserved case 8: break; // reserved case 10: break; // reserved case 12: break; // reserved case 14: P1OUT ^= 0x01; // overflow break; default: break; } } I think the confusion is about the part of the user's guide that talks about autoclearing the flags when the TBxIV register is read out. The trick is that it only clears the highest priority flag that is set and leaves the others. This means that it will only clear the one that your switch statement will service in this iteration. For example, in your ISR above, if you enter the ISR and both the interrupts for 0x02 and 0x04 are already pending, then TBxIV will read as just 0x02 (it only reads as whatever is the highest-priority pending interrupt), though an interrupt flag in the TBxCCTLx register corresponding to the 0x04 interrupt vector is still set, so it will still be pending. From the user's guide: The highest-priority enabled interrupt (excluding TBxCCR0 CCIFG) generates a number in the TBxIVregister (see register description). When TBxIV is read, only the highest priority interrupt (the value that you just read out), in this case 0x02, is cleared, and TBxIV will then update to the value of the next highest priority interrupt that is still pending. So after you exit the ISR having serviced 0x02 in your switch statement, you will re-enter your ISR again because 0x04 is still pending, and this time TBxIV will read 0x04. I hope this helps clear things up - it is pretty useful the way that it works, but can be a bit tricky to understand when you are first starting to use it. Regards, Katie Quote Link to post Share on other sites
basil4j 1 Posted March 13, 2014 Author Share Posted March 13, 2014 Thanks Katie, my confusion is more around the statment in the manual 'if the TBxCCR1 and TBxCCR2 CFIG flags are set when the interrupt servicr routine accesses the TBxIV register, TBxCCR1 CCIFG is reset automatically. ' This says to me the interrupt routine itself resets the flag once it's decided to use the vector, thus will clear before my switch case even sees it? Sent from my GT-I9300 using Tapatalk Quote Link to post Share on other sites
basil4j 1 Posted March 13, 2014 Author Share Posted March 13, 2014 Ahh I think I got it. The flags in TBxCCRn are cleared, but not nlthe flag in TBxIV, right? Sent from my GT-I9300 using Tapatalk Quote Link to post Share on other sites
KatiePier 73 Posted March 13, 2014 Share Posted March 13, 2014 Not quite - it does actually clear the single TBxCCRn flag that corresponds to the value currently in TBxIV (the highest priority interrupt), as well as clearing TBxIV and setting it to the next priority pending interrupt, but it only does this when your code actually reads out the register TBxIV, not just as soon as the ISR is entered. You can observe this happening by adding a _no_operation(); before your switch inside your ISR, and put a breakpoint there. Open the register view in your debugger and take note of the state of the CCIFG bits in the TBxCCTLn registers, and the value in TBxIV. You'll see that the CCIFG and TBxIV values are still set on entry to the ISR. Now, single step over the switch statement (where it reads TBxIV) and you'll see that this is the time when the TBxIV and the CCIFG value are cleared. But since your switch is what read TBxIV, it already has the value to jump to the correct case. I think the easiest way to understand it is probably to run it on a part and step through it and watch what the flags and registers do. Regards, Katie Rickta59 and enl 2 Quote Link to post Share on other sites
basil4j 1 Posted March 13, 2014 Author Share Posted March 13, 2014 Ahh I see, thanks for the clarification! Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.