atsamd: Add support for 25Mhz crystals
Needed for the Duet3 Mini 5+ board. Reported by @lukeslaboratory. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
6266e7c259
commit
bd65c37ed5
|
@ -89,6 +89,8 @@ choice
|
||||||
prompt "Clock Reference"
|
prompt "Clock Reference"
|
||||||
config CLOCK_REF_X32K
|
config CLOCK_REF_X32K
|
||||||
bool "32.768Khz crystal"
|
bool "32.768Khz crystal"
|
||||||
|
config CLOCK_REF_X25M
|
||||||
|
bool "25Mhz crystal" if MACH_SAMD51
|
||||||
config CLOCK_REF_INTERNAL
|
config CLOCK_REF_INTERNAL
|
||||||
bool "Internal clock"
|
bool "Internal clock"
|
||||||
endchoice
|
endchoice
|
||||||
|
|
|
@ -97,6 +97,8 @@ config_dfll(uint32_t dfllmul, uint32_t ctrlb)
|
||||||
|
|
||||||
#if CONFIG_CLOCK_REF_X32K
|
#if CONFIG_CLOCK_REF_X32K
|
||||||
DECL_CONSTANT_STR("RESERVE_PINS_crystal", "PA0,PA1");
|
DECL_CONSTANT_STR("RESERVE_PINS_crystal", "PA0,PA1");
|
||||||
|
#elif CONFIG_CLOCK_REF_X25M
|
||||||
|
DECL_CONSTANT_STR("RESERVE_PINS_crystal", "PB22,PB23");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initialize the clocks using an external 32K crystal
|
// Initialize the clocks using an external 32K crystal
|
||||||
|
@ -123,6 +125,33 @@ clock_init_32k(void)
|
||||||
gen_clock(CLKGEN_48M, GCLK_GENCTRL_SRC_DPLL1);
|
gen_clock(CLKGEN_48M, GCLK_GENCTRL_SRC_DPLL1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize the clocks using an external 25M crystal
|
||||||
|
static void
|
||||||
|
clock_init_25m(void)
|
||||||
|
{
|
||||||
|
// Enable XOSC1
|
||||||
|
uint32_t freq_xosc = 25000000;
|
||||||
|
uint32_t val = (OSCCTRL_XOSCCTRL_ENABLE | OSCCTRL_XOSCCTRL_XTALEN
|
||||||
|
| OSCCTRL_XOSCCTRL_IPTAT(3) | OSCCTRL_XOSCCTRL_IMULT(6));
|
||||||
|
OSCCTRL->XOSCCTRL[1].reg = val;
|
||||||
|
while (!(OSCCTRL->STATUS.reg & OSCCTRL_STATUS_XOSCRDY1))
|
||||||
|
;
|
||||||
|
|
||||||
|
// Generate 120Mhz clock on PLL0 (with XOSC1 as reference)
|
||||||
|
uint32_t p0div = 10, p0mul = DIV_ROUND_CLOSEST(FREQ_MAIN, freq_xosc/p0div);
|
||||||
|
uint32_t p0ctrlb = OSCCTRL_DPLLCTRLB_DIV(p0div / 2 - 1);
|
||||||
|
config_dpll(0, p0mul, p0ctrlb | OSCCTRL_DPLLCTRLB_REFCLK_XOSC1);
|
||||||
|
|
||||||
|
// Switch main clock to 120Mhz PLL0
|
||||||
|
gen_clock(CLKGEN_MAIN, GCLK_GENCTRL_SRC_DPLL0);
|
||||||
|
|
||||||
|
// Generate 48Mhz clock on PLL1 (with XOSC1 as reference)
|
||||||
|
uint32_t p1div = 50, p1mul = DIV_ROUND_CLOSEST(FREQ_48M, freq_xosc/p1div);
|
||||||
|
uint32_t p1ctrlb = OSCCTRL_DPLLCTRLB_DIV(p1div / 2 - 1);
|
||||||
|
config_dpll(1, p1mul, p1ctrlb | OSCCTRL_DPLLCTRLB_REFCLK_XOSC1);
|
||||||
|
gen_clock(CLKGEN_48M, GCLK_GENCTRL_SRC_DPLL1);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize clocks from factory calibrated internal clock
|
// Initialize clocks from factory calibrated internal clock
|
||||||
static void
|
static void
|
||||||
clock_init_internal(void)
|
clock_init_internal(void)
|
||||||
|
@ -167,6 +196,8 @@ SystemInit(void)
|
||||||
// Init clocks
|
// Init clocks
|
||||||
if (CONFIG_CLOCK_REF_X32K)
|
if (CONFIG_CLOCK_REF_X32K)
|
||||||
clock_init_32k();
|
clock_init_32k();
|
||||||
|
else if (CONFIG_CLOCK_REF_X25M)
|
||||||
|
clock_init_25m();
|
||||||
else
|
else
|
||||||
clock_init_internal();
|
clock_init_internal();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue