9 CFD on XOSCHF

To use Clock Failure Detection (CFD) on the External High-Frequency Oscillator (XOSCHF), write the XOSCHF setting to the Clock Failure Detection Source (CFDSRC) bit field and ‘1’ to the Clock Failure Detection Enable (CFDEN) bit in the Main Clock Control C (CLKCTRL.MCLKCTRLC) register.

This register has Configuration Change Protection (CCP), so the ccp_write_io function in cpufunc.h should be used to ensure correct timing for the unlock of the register.

Figure 9-1. CLKCTRL.MCLKCTRLC – Enable CFD on XOSCHF

	/* Enable Clock Failure Detection on XOSCHF */
	ccp_write_io((uint8_t *) &CLKCTRL.MCLKCTRLC,
	             CLKCTRL_CFDSRC_XOSCHF_gc | CLKCTRL_CFDEN_bm);

To enable the regular CFD interrupt, write ‘0’ to the Interrupt Type (INTTYPE) bit and ‘1’ to the Clock Failure Detection (CFD) bit in the Main Clock Interrupt Control (CLKCTRL.MCLKINTCTRL) register. This register also has CCP.

Figure 9-2. CLKCTRL.MCLKINTCTRL – Enable regular CFD interrupt

	/* Enable regular interrupt for CFD */
	ccp_write_io((uint8_t *) &CLKCTRL.MCLKINTCTRL, CLKCTRL_CFD_bm);

The CFD vector will be called when the interrupt is triggered. Before returning from the Interrupt Service Routine (ISR), the Clock Failure Detection (CFD) interrupt flag in the Main Clock Interrupt Flags (CLKCTRL.MCLKINTFLAGS) register must be cleared. This is done by writing a ‘1’ to the flag.

Figure 9-3. CLKCTRL.MCLKINTFLAGS – Clear CFD interrupt flag

ISR(CLKCTRL_CFD_vect)
{
	/* This interrupt will trigger every time the CFD detects XOSCHF has stopped
	 * The Main Clock source is OSCHF so the CPU is not affected
	 */
	LED0_toggle();

	/* Clear the CFD interrupt flag */
	CLKCTRL.MCLKINTFLAGS = CLKCTRL_CFD_bm;
}

The code for this example is available in the CFD-on-XOSCHF folder in these github repositories: