Below is a function I am using to start an external crystal on an MSP430F2272. The intention of the function is to ensure that the crystal has started before continuing. If the crystal fails to start a certain amount of times (indicated by the OscFaults variable), the calling function will revert back to the DCO. Before calling this function, the DCO is setup to run at 8MHz. I am noticing that the line where I check if the OFIFG flag is set is occasionally returning true (as in it is not set). If I put a break point on the break statement and watch IFG1, I notice that OFIFG is still set in IFG1 even though the conditional just before apparently says otherwise.
I am disabling OFIE before calling this function. I need to use the crystal for accurate timing for algorithms elsewhere in the code. It cannot stay on all the time because this is a low power application and I use a low power mode when nothing needs to be done. What is causing the OFIFG flag to occasionally slip through, or should I take a completely different approach?
I should add that I have a special circuit with a switch for the crystal in order to verify that this function is working properly and appropriately handles an XT2 failure.
void StartXT2( void ) { unsigned int i,j; BCSCTL1 |= XTS; BCSCTL3 |= LFXT1S1; BCSCTL1 &= ~XT2OFF; for(i=0; i<500; i++){ IFG1 &= ~OFIFG; for(j=0xff; j>0; j--) _NOP(); if(!(IFG1 & OFIFG)) break; } if(i < 500){ BCSCTL2 |= SELS + SELM_3; IE1 |= OFIE; } else{ BCSCTL1 |= XT2OFF; OscFaults++; } }