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.

CC430F6137 Watchdog Timer Stalls With Software UART P2 Interrupt Reset

Other Parts Discussed in Thread: CC430F6137

I have code running on a CC430F6137 that uses the watchdog timer as a 1.9ms timer with the following setup code:

WDTCTL = WDT_ADLY_1_9;

This works fine and I use the timer to check a housekeeping routine which among other things checks for data needed to be sent over USB serieal using the on-board hardware UCA. The housekeeping is quickly enabled by using the WDT to set a bit where other code in the main loop checks. In and out super fast.

#pragma vector=WDT_VECTOR
__interrupt void WDT_ISR(void)
{
	//Be careful! Will miss data and such if too long.
	//This is a HIGH priority interrupt, be careful even in interrupt mode.
	//check_housekeeping();
	//P3OUT ^= LED_1 + LED_2;

	//Set houskeeping bitmask general timer bit
	housekeeping_bitmask_char |= BIT0; //Must follow by running housekeeping bitmask check in MAIN!

	//__no_operation();                         // For debugger
}

however. I have a GPS communicating over a bit-banged UART implemented on P2.0 using Timer A0 and P2 interrupts.

My watchdog timer never enters its ISR once GPS lock is enabled and data starts flowing. I know this because I see a string of data over USB serial and then nothing, after that I never reset the housekeeping bit and therefore am never entering the watchdog ISR.

Problem Enabling Code

I've tracked the issue to only occur when this line of code is uncommented (thus enabling GPS software UART communications)

P2IFG &= ~GPS_UART_TX;

It's located in the Timer1 vector

//TIMER1_A1_VECTOR
#pragma vector=TIMER1_A1_VECTOR
__interrupt void TIMER1_A1_ISR(void)
{

  switch(__even_in_range(TA1IV,14))
  {
    case 0: break;
    case 2: //TA1CCR1
    	//Add UART bit-time (time duration of 1 bit) to the trigger
		TA1CCR1 += SOFTWARE_UART_BIT_TIME;

		//If currently still parsing a new UART byte "frame"
		if(software_uart_char_bit_count>0){
			--software_uart_char_bit_count;
			//If recieved bit is HIGH (1)
			if (P2IN & GPS_UART_TX){
				//Add a "1" bit to the received byte that is building at the location just above the MSB. This allows the byte to "build"
				software_uart_int_buffer_rx |= 0x400;
				//Shift the byte down to move the recieved bit into the data byte
				software_uart_int_buffer_rx = software_uart_int_buffer_rx>>1;
			}
			//If recieved bit is LOW (0)
			else{
				//Since bit above the MSB of the lower byte is already 0 by default just shift it into the building data byte
				software_uart_int_buffer_rx = software_uart_int_buffer_rx >> 1;			// otherwise just shift.
			}
		}

		//Entire byte "frame" recieved, finished parsing and reset for next byte frame
		else{
			//If recieved bit is HIGH (1)
			if (P2IN & GPS_UART_TX){
				//Add a "1" bit to the received byte that is building at the location just above the MSB. This allows the byte to "build"
				software_uart_int_buffer_rx |= 0x400;
				//Shift the byte down to move the recieved bit into the data byte
				software_uart_int_buffer_rx = software_uart_int_buffer_rx>>1;
			}
			//If recieved bit is LOW (0)
			else{
				//Since bit above the MSB of the lower byte is already 0 by default just shift it into the building data byte
				software_uart_int_buffer_rx = software_uart_int_buffer_rx >> 1;			// otherwise just shift.
			}
			//NOTE: THIS DOESN'T CHECK FOR PROPER START/STOP BITS BUT INSTEAD ASSUMES GOOD AND BLASTS AWAY!
			//Disable TimerA1 - No longer needed
			TA1CCTL1 &= ~CCIE;
			//Check start and stop bit for correctness (start -> LSB=0 stop -> MSB=1)
			//Start and Stop bits correct (not a garuentee but better than nothing)
			if((software_uart_int_buffer_rx & SOFTWARE_UART_STOPBIT_MASK) && (~software_uart_int_buffer_rx & SOFTWARE_UART_STARTBIT_MASK)){
				//Perform final shift of data to remove start bit from data byte received
				software_uart_int_buffer_rx = (software_uart_int_buffer_rx >> 1);	// extract received byte
				//Copy received byte (int) into temporary unsigned char byte
				software_uart_char_buffer_rx = software_uart_int_buffer_rx;
				//Send received byte to GPS NMEA string parsing function(s)
				gps_get_nmea_string(software_uart_char_buffer_rx);
				//software_uart_int_buffer_rx ^= BIT0; //Toggle start to 1

			}
			//Start and Stop bits incorrect
			else{
				//Ignore, data is corrupt.
				__no_operation();
			}

			//Clear P2 interrupt flags
			P2IFG &= ~GPS_UART_TX; // Should this be complete port on just this ISR case? Bug?	COMMENTING THIS OUT PREVENTS GPS FUNCTION AT THIS TIME OVER UART
			//Enable P1 interrupt to receive next byte from software UART
			//P1IE = UCB0CS1;
			P2IE |= GPS_UART_TX;
			//SFRIE1 |= WDTIE;
			__no_operation();
		}

             break;
    case 4:  //TA1CCR2 += 100;                // Add Offset to CCR2
             break;
    case 6:  break;                         // CCR3 not used
    case 8:  break;                         // CCR4 not used
    case 10: break;                         // CCR5 not used
    case 12: break;                         // Reserved not used
    case 14: //P1OUT ^= 0x01;                 // overflow
             break;
    default: break;
 }
}

Does anyone have any idea why resetting the P2 GPS pin interrupt causes the watchdog timer to stop working?

I wonder if I am at all being affected by CC430F6137 Errata WDG4: 

**Attention** This is a public forum