I'll post my code below.
The problem is that the MSP's ISR_TRAP function (a function that handles ISRs that are not otherwise handled) is triggering and trapping me in its endless loop. This happens after P2.1's ISR has successfully triggered, and before the Timer B ISR does anything.
The problems is that TB0CCR4 (Timer B's Capture and Compare Register #4) should trigger an ISR when TB0R counts up to the value contained in it. That value is TB0R+delay, where delay is currently just a global variable at the top of the code. According to the debugger in CCS, the timer is counting up to and past the value stored in CCR4, but not triggering the interrupt.
If the program worked as intended, the MSP's onboard red led would turn on when the button is pressed for P2.1, and then off when the timer reaches the value stored in CCR4.
I can't figure out what's going on here, and any help would be much appreciated. Especially if the explanation can shed some light on what the timer is doing/not doing.
#include <msp430.h>
//GLOBALS
unsigned int delay = 0x00ff;
//Main
int main(void)
{
WDTCTL = WDTPW | WDTHOLD;
P8OUT &= ~0xff;
P2OUT &= ~0xff;
P1OUT &= ~BIT0;
P2DIR &= ~BIT1;//input
P2REN |= BIT1;//pullup
P2OUT |= BIT1;//sit high
P8DIR |= BIT4;//output
P8OUT &= ~BIT4;//output low
TB0CTL = TBSSEL__ACLK | ID__1 | MC__CONTINUOUS | TBCLR;//enable TB0R and choose its options
TB0CCR4 = 0x0000;//Initialize TB0CCR4, just in case there's garbage in the register
PM5CTL0 &= ~LOCKLPM5;
__enable_interrupt();//enable interrupts
P2IES |= BIT1;//falling edge interrupt on P2.1
P2IFG &= ~0xff;//clear flags
P2IE |= BIT1;//interrupts enabled on P2.1
while(1){}//go forever
return 0;
}
//INTERRUPTS
#pragma vector = PORT2_VECTOR //interrupt vector for port 2
__interrupt void Port_2(void) //interrupt function names can be anything
{
switch(__even_in_range(P2IV,P2IV_P2IFG7))
{
case P2IV_NONE: break;
case P2IV_P2IFG0: break;
case P2IV_P2IFG1: //P2.1 vector
P2IE &= ~BIT1; //disable interrupts
P2IFG &= ~0xff;
TB0CCTL4 |= CCIE; //enable timer interrupts
TB0CCR4 = TB0R + delay; //set next event
P1DIR ^= BIT0; //enable output
P1OUT ^= BIT0; //turn on onboard led
break;
case P2IV_P2IFG2: break;
case P2IV_P2IFG3: break;
case P2IV_P2IFG4: break;
case P2IV_P2IFG5: break;
case P2IV_P2IFG6: break;
case P2IV_P2IFG7: break;
default: break;
}
}
#pragma vector = TIMER0_B0_VECTOR //interrupt vector for timer B
__interrupt void T0B7_ISR(void)
{
switch(__even_in_range(TB0IV,14))
{
case 0: break;
case 2: break;
case 4: break;
case 6: break;
case 8: // ccr4
P1OUT ^= BIT0; //toggle onboard LED
P2IE |= BIT1; //re-enable interrupts after delay
TB0CCTL4 &= ~CCIE; //disable interrupts on CCR4
break;
case 10: break;
case 12: break;
case 14: break;
default: break;
}
}