Hello experts,
I am trying to understand what the oscillator fault ISR is doing. Code is below, it is exactly the same as the cs_03 demo for FR5969 except I added CSCTL0_H = 0x00 to enable CS locking. In the demo the clock system is left unlocked, and it works just as described: fault is generated, then it is cleared, and the LED blinks.
If I lock the CS registers, however (CSCTL0_H = 0x00) then the ISR is still triggered and the fault bits are cleared but the LED does not blink and the breakpoint in the ISR takes me to an assembly code block, when I step into it. Technically, the ISR instruction:
CSCTL5 &= ~LFXTOFFG; // Clear XT1 fault flag
should not even work if the CS registers are locked, but it does somehow because if I scope the ACLK with CS locked and ISR enabled, the ACLK output defaults to MODCLK, and then comes back to LFXT when the fault is removed. If I disable ISR then the ACLK does not restore when the fault is removed.
This is of course the desired behavior but I don't understand how the ISR is doing this, and why it does not move on past the CSCTL5 &= ~LFXTOFFG; instruction if the CS is locked?
Thanks!
-P
#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW | WDTHOLD;
// GPIO Setup
P1OUT = 0;
P1DIR = BIT0; // For LED
P2DIR |= BIT0;
P2SEL0 |= BIT0; // Output ACLK
P2SEL1 |= BIT0;
P3DIR |= BIT4;
P3SEL1 |= BIT4; // Output SMCLK
PJSEL0 = BIT4 | BIT5; // For XT1
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
// Clock System Setup
CSCTL0_H = CSKEY >> 8; // Unlock CS registers
CSCTL1 = DCOFSEL_0; // Set DCO to 1MHz
CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;
CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // Set all dividers
CSCTL4 &= ~LFXTOFF;
do
{
CSCTL5 &= ~LFXTOFFG; // Clear XT1 fault flag
SFRIFG1 &= ~OFIFG;
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
//CSCTL0_H = 0x00; // Lock CS module (use byte mode to upper byte)
// Now that osc is running enable fault interrupt
SFRIE1 |= OFIE;
__bis_SR_register(LPM0_bits); // Wait in LPM0 for fault flag
}
#pragma vector=UNMI_VECTOR
__interrupt void UNMI_ISR(void)
{
do
{
// set a breakpoint on the line below to observe XT1 operating from VLO
// when the breakpoint is hit during a crystal fault
CSCTL5 &= ~LFXTOFFG; // Clear XT1 fault flag
SFRIFG1 &= ~OFIFG;
P1OUT |= BIT0;
__delay_cycles(25000); // time for flag to get set again
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
P1OUT &= ~BIT0;
}