4 XOSCHF with External Crystal
To use XOSCHF with external crystal, the SELHF bit in the External High-Frequency
Oscillator Control A (CLKCTRL.XOSCHFCTRLA) register must be written to
‘0
’ and the ENABLE bit must be written to ‘1
’.
In addition, the Frequency Range (FRQRANGE) bit field must be written to a setting equal to or higher than the frequency of the connected crystal, and the Crystal Start-up Time (CSUTHF) bit field can be written to select the number of cycles to wait before the clock is considered stable.
To make sure the oscillator runs as expected before it is requested by any modules, the Run Standby (RUNSTDBY) bit can be enabled.
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.
/* Enable crystal oscillator with frequency range 16 MHz and 4K cycles start-up time */ ccp_write_io((uint8_t *) &CLKCTRL.XOSCHFCTRLA, CLKCTRL_RUNSTDBY_bm | CLKCTRL_CSUTHF_4K_gc | CLKCTRL_FRQRANGE_16M_gc | CLKCTRL_SELHF_CRYSTAL_gc | CLKCTRL_ENABLE_bm);
After enabling the XOSCHF, wait for the clock source to stabilize by polling
the External Clock Status (EXTS) bit in the Main Clock Status (CLKCTRL.MCLKSTATUS)
register until the bit is read as ‘1
’.
/* Confirm crystal oscillator start-up */ while(!(CLKCTRL.MCLKSTATUS & CLKCTRL_EXTS_bm)) { ; }
The Main Clock prescaler shall be configured to give a maximum frequency of 24 MHz.
If Main Clock will use XOSCHF with a crystal running faster than 24 MHz as the clock
source, a prescaler setting can be written to the Prescaler Division (PDIV) bit field
and ‘1
’ to the Prescaler Enable (PEN) bit in the Main Clock Control B
(CLKCTRL.MCLKCTRLB) register. The AVR128DB48 Curiosity Nano has a 16 MHz crystal which
allows disabling the prescaler by writing ‘0
’ to the PEN bit.
Main Clock Control B also has CCP.
/* Clear Main Clock Prescaler */
ccp_write_io((uint8_t *) &CLKCTRL.MCLKCTRLB, 0x00);
Change Main Clock source by writing the EXTCLK setting to the Clock Select
(CLKSEL) bit field in the Main Clock Control A (CLKCTRL.MCLKCTRLA) register. The Main
Clock Out (CLKOUT) bit can be written to ‘1
’ to output the Main Clock
on the CLKOUT pin. This register also has CCP.
/* Set the main clock to use XOSCHF as source, and enable the CLKOUT pin */ ccp_write_io((uint8_t *) &CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_EXTCLK_gc | CLKCTRL_CLKOUT_bm);
After changing the Main Clock source, wait for the switch to complete by
polling the Main Clock Oscillator Changing (SOSC) bit in the Main Clock Status
(CLKCTRL.MCLKSTATUS) register until the bit is read as ‘0
’.
/* Wait for system oscillator changing to complete */ while(CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm) { ; }
The Run Standby bit can now be cleared since the output is now is used by Main Clock and there is no need to force enable the oscillator.
/* Clear RUNSTDBY for power save during sleep */ ccp_write_io((uint8_t *) &CLKCTRL.XOSCHFCTRLA, CLKCTRL.XOSCHFCTRLA & ~CLKCTRL_RUNSTDBY_bm);
The code for this example is available in the
XOSCHF-with-external-crystal folder in these github
repositories: