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: