Hello, I'll try to go in steps - what I want to do, what is happening, and what I know and have tried.
I've built a state machine using function pointers, and I want one of the state transitions to be when a timer counts up to a value. Sounds simple enough right? I then want to reset the timer, wait a little bit, then turn it on again and use it for another state transition.
I've verified that I am correctly setting up Timer_A, turning it on, and entering my interrupt when the Timer_A register counts to the Timer_A compare register. I've meticulously stepped through the code in DEBUG mode of CCS and watched the registers change, so I know it's at least partially working. I've also o-scoped much of the code to get more information. However, when I try to turn off the counter in my ISR or disable the interrupt capability so I don't generate a Timer_A interrupt while still in my ISR, the register I write to either doesn't change, or i get strange errors. I'll post the (relevant) code below with some comments and hopefully someone can help me solve this. I can post full source code if someone wants to see everything in detail. Hopefully I've described the operation well enough.
//---- Timer A Setup (16 Bit Timer) ----//
void set_TimerA(void){
TACCR0 = 20; //num of cycles to count to
TACTL |= TASSEL_2; //set Timer_A clock source to SMCLK
}
// A button is pressed, and then goes to this state
void goto_PULSE1(void){
state = PULSE1; //Not important - set the state
P1IE &= ~BIT3; //Not important - disable button interrupt in case it gets pressed again
TACCTL0 |= CCIE; //Enabled the compare interrupt
P2OUT = PULSE1_OUTPUT_BITS; //Not important - set Port2 outputs
TACTL |= MC_1; //Set counter to up mode and start counting
}
//Timer A interrupt, gets to here correctly
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A_ISR(void){
// TACTL &= ~MC_0;
// TACCR0 = 0x00;
// TACTL |= TACLR;
TACCTL0 &= ~CCIE;
TACTL |= TACLR;
// TACTL &= ~TAIFG;
^^^^^^^^^^^^^^^^^^^^^^
I've tried different combinations of the above, but it doesn't do what I want it to. All i want to do is stop and clear the timer so that I can enable it again in another state. The above "works" in that it runs, but it runs the ISR multiple times until it eventually leaves for some reason.
if (state == PULSE1){
event = TIME1;
}
else if (state == PULSE2_POSV){
event = TIME2;
}
else if (state == PULSE2_NEGV){
CACTL1 &= ~CAIE;
state = PULSE2_POSV;
event = TIME2;
}
}
I've meticulously combed through the User Guide and can't seem to get a solution, no matter how hard or how many combinations I try. Any suggestions are welcome, thanks for your time.