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.

MSP430FR5739: Timer A0 Interrupt Issue

Part Number: MSP430FR5739

Tool/software:

Hello,

I misinterpreted the meaning of Timer0_A0/A1 and have adjusted my question apropriately.

I would like some help figuring out why Timer0_A1 ISR is triggering indefinitely when using P1.2 as TA0CLK input supplied from external hardware. Despite this, Timer0_A0 and the Timer0_A0 ISR appear to be functioning correctly.

The main project code has been simplified, all macros and definitions removed as it's not relevant to the question:

#include "cs.h"
#include "msp430fr5739.h"

void delay_ms(uint16_t _value){ //basic delay function
	for (int i = _value; i >= 0; i--){
		__delay_cycles(((double)1000000.0 / (double)1000.0));
	}
}

volatile uint8_t counter_A0 = 0;
volatile uint8_t counter_A1 = 0;

float test(uint16_t sample_time){
	P4OUT |= (BIT0); //turn oscillations on (external circuit, connected to P1.2)
	delay_ms(5); //let settle

	__bis_SR_register(GIE);

	TA0CTL = (TASSEL__TACLK | MC__CONTINUOUS | TACLR | TAIE | CNTL__16);
	delay_ms(sample_time);
	TA0CTL = (TASSEL__TACLK | MC__STOP); //this line is never reached

	__bic_SR_register(GIE);

	P4OUT &= ~ (BIT0);//turn oscillations off

	uint32_t pulses = (65536 * counter_A1) + TA0R;

	return(pulses * (1000.0 / (float)sample_time));
}

void main(void){
	WDTCTL = WDTPW | WDTHOLD;   //stop watchdog timer
	__bic_SR_register(GIE);
	
	P4DIR |= (BIT0); //initiate extrnal control pin
	P1DIR &= ~(BIT2); //initiate P1.2 as TA0CLK
	P1SEL0 &= ~(BIT2);
	P1SEL1 |= (BIT2);

	float count_out = test(100);
	//do something with count_out

	__bis_SR_register(LPM0_bits + GIE); //enable global interrupts and enter LPM0
}

#pragma vector = TIMER0_A0_VECTOR
__interrupt void timerA0_ISR(void){
	counter_A0++; //incriment counter (working as intended)
}

#pragma vector = TIMER0_A1_VECTOR
__interrupt void timerA1_ISR(void){
	counter_A1++; //shouldn't be called? (never clears)
}

Can someone explain why both Timer0 (TA0) vectors are being triggered?

  • Okay, so there has been an unhealthy amount of editing done to this post, but talking to myself helped me figure it out. Never used the overflow or TA0CCR1/2/3/etc registers for timer interrupts before this.

    Adding the following line to my ISR has fixed all my issues. 

    uint16_t aaaa = TA0IV;

    However, what was causing Timer0_A0 to increment when Timer0_A1 was not being handled properly?

    Additionally, is there a way to use the full 16 bit timer with TA0CCR0 interrupt to allow the ISR to not to manually read/clear the IV register?

  • However, what was causing Timer0_A0 to increment when Timer0_A1 was not being handled properly?

    Priority.

    The ISR for CCRx didn't clear the interrupt source so when it exited, it caused another immediate interrupt. Tying up the CPU and preventing it from doing anything else.

    Meanwhile, the timer keeps counting and eventually triggers the CCR0 interrupt. Which has a higher priority. So it gets serviced. That one gets cleared automatically.

  • I don't see counter_A0 being incremented when I run this code. [I added a clock generator via TB2 and patch-wired it to P1.2.] I don't see how that would happen without setting TA0CCTL0:CCIE.

    I do see the counter_A1 runaway. This can be fixed by (as you have done) reading TA0IV, knowing what the result will be,  or by:

    > TA0CTL &= ~TAIFG; // Clear overflow IFG

  • Thank you for taking the time to test, reply, and provide an alternative option.

**Attention** This is a public forum