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 because the timer isn't stopping and causes erratic behavior.
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.