I am using the MSP430FR5994 Launchpad. My application needs to know how main was entered (i.e. WDT timeout, WDT access violation, LPM3 wakeup, etc).. Upon entering main() my test code initializes the GPIO, the clock system, and the UART (for communications). Button S2 interrupts (which causes a WDT access violation) are then enabled and the WDT is activated to generate a timeout reset every 16sec. My the test I expect a return to main either from the S2 button press (which writes WDTCTL=0 to cause an access violation) or a timeout. I use a switch statement to find the source of the interrupt.
However, there are things happening I don't understand.
It appears that any access to the WDT causes the SYSRST_WDTPW word to be set. The macro definitions for WDTPW states "/* WDTPW watchdog password violation */" which leads me to believe this reset code is generated for illegal access (any access without 0xa500 in the high order bits of the word). However, an explicit check for WDTPW violation is ignored when S2 is pressed.
From the datasheet I would expect that a WDTIFG timeout (16h) is higher priority than the WDTPW violation so a timeout should be the first interrupt found in the switch statement. But the switch reports the WDTPW violation instead. I have to explicitly check outside of the switch for the WDTIFG timeout. This doesn't make sense if WDTIFG is higher priority.
In addition, the SYSRSTIV_WDTIFG if statement (before the switch) is never executed. Reading the SYSRSTIV should clear the highest priority interrupt which should have been the WDTIFG and it should have found the WDTPW violation but doesn't when the S2 button is pressed.
Can anyone explain why WDTPW violation seems to appears when I configure the WDT (I don' think I configured illegally) and why WDTIFG is not caught first by the switch statement? And why the WDTPW isn't caught when S2 is pressed?
Below is the test code followed by ISR handler for the S2 Button.
int main(void){ __disable_interrupt(); Init_GPIO(); Init_Clock(); Init_UART(); P5IFG &= ~BIT5; //clear interrupts char tm[]={"\n\r\tBack in Main"}; Probe(tm); P5IE |= BIT5; __enable_interrupt(); WDT_A_initWatchdogTimer(WDT_A_BASE, WDT_A_CLOCKSOURCE_XCLK, WDT_A_CLOCKDIVIDER_512K); //16sec SFR_enableInterrupt(SFR_WATCHDOG_INTERVAL_TIMER_INTERRUPT); WDT_A_start(WDT_A_BASE); //WDTCTL &= ~WDTHOLD; if (SYSRSTIV == SYSRSTIV__WDTIFG){ //WD timeout char tm[]={"\n\r\tWDT Time Out"}; Probe(tm); SYSRSTIV=0; //reset P1DIR |= BIT0 | BIT1; //set as output P1OUT |= BIT0 | BIT1; //Red & Grn LED on } if (SYSRSTIV == SYSRSTIV__WDTPW){ //WD timeout char tm[]={"\n\r\tWDTPW VIOLTN"}; Probe(tm); P1DIR |= BIT0 | BIT1; //set as output P1OUT |= BIT0 | BIT1; //Red & Grn LED on } char tm0[]={"\n\r\tWDT Time Out "}; char tm1[]={"\n\r\tWDTPW violation "}; char tm2[]={"\n\r\tLPM5WU"}; switch (SYSRSTIV,SYSRSTIV__WDTPW) { case SYSRSTIV_NONE: __no_operation(); break; case SYSRSTIV_BOR: __no_operation(); break; case SYSRSTIV_LPM5WU: //LPM5WU __no_operation(); Probe(tm2); break; case SYSRSTIV_WDTTO: //timeout __no_operation(); Probe(tm0); P1DIR |= BIT0 | BIT1; //set as output P1OUT |= BIT0 | BIT1; //Red & Grn LED on break; case SYSRSTIV__WDTPW: //access violation __no_operation(); P5IFG &= ~BIT5;//clear flag Probe(tm1); SYSRSTIV=0; //reset break; default: break; }
#pragma vector=PORT5_VECTOR __interrupt void Port_5(void) { //P5IFG &= ~BIT5; // Clear P5.5 IFG //mode = '0'; char ms[]={"\n\r\tS2 ISR"};Probe(ms); RTC_C_holdClock(RTC_C_BASE); rec_calendar=calendar; WDTCTL=0; //WD PW violation, generate PUC }