Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 46 additions & 8 deletions cpu/samd5x/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
# endif

# if (CLOCK_CORECLOCK > SAM0_XOSC_FREQ_HZ)
# error When using an external oscillator for the main clock,\

Check warning on line 60 in cpu/samd5x/cpu.c

View workflow job for this annotation

GitHub Actions / static-tests

keyword 'for' not followed by a single space
the CPU frequency can't exceed it's frequency.
# endif

Expand All @@ -72,9 +72,11 @@
#else /* !USE_XOSC_ONLY */

/* Main clock > 48 MHz -> use DPLL, otherwise use DFLL */
# define USE_DPLL (CLOCK_CORECLOCK > SAM0_DFLL_FREQ_HZ)

Check warning on line 75 in cpu/samd5x/cpu.c

View workflow job for this annotation

GitHub Actions / static-tests

full block {} expected in the control structure
# define USE_DFLL 1
#ifndef USE_XOSC
# define USE_XOSC 0
#endif

# ifndef GCLK_TIMER_HZ
# define GCLK_TIMER_HZ MHZ(8)
Expand Down Expand Up @@ -115,9 +117,18 @@
while (!(OSC32KCTRL->STATUS.reg & OSC32KCTRL_STATUS_XOSC32KRDY)) {}
}

#ifndef XOSC0_EXT_OSC
# define XOSC0_EXT_OSC (0)
#endif

#ifndef XOSC1_EXT_OSC
# define XOSC1_EXT_OSC (0)
#endif

static void xosc_init(uint8_t idx)
{
uint32_t freq;
bool xtal;

if (!USE_XOSC ||
(idx == 0 && XOSC0_FREQUENCY == 0) ||
Expand All @@ -130,9 +141,17 @@

if (idx == 0) {
freq = XOSC0_FREQUENCY;
xtal = !XOSC0_EXT_OSC;
}
else if (idx == 1) {
freq = XOSC1_FREQUENCY;
xtal = !XOSC1_EXT_OSC;
}

if (xtal) {
OSCCTRL->XOSCCTRL[idx].reg = OSCCTRL_XOSCCTRL_ENABLE;
while (!(OSCCTRL->STATUS.vec.XOSCRDY & (idx + 1))) {}
return;
}

uint32_t reg = OSCCTRL_XOSCCTRL_XTALEN
Expand Down Expand Up @@ -177,7 +196,7 @@
#ifdef OSCCTRL_DFLLCTRLB_WAITLOCK
| OSCCTRL_DFLLCTRLB_WAITLOCK
#endif
;

Check warning on line 199 in cpu/samd5x/cpu.c

View workflow job for this annotation

GitHub Actions / static-tests

semicolon is isolated from other tokens

/* workaround for Errata 2.8.3 DFLLVAL.FINE Value When DFLL48M Re-enabled */
OSCCTRL->DFLLMUL.reg = 0; /* Write new DFLLMULL configuration */
Expand All @@ -204,6 +223,10 @@
OSCCTRL->Dpll[idx].DPLLCTRLA.reg = 0;
while (OSCCTRL->Dpll[idx].DPLLSYNCBUSY.reg) {}

/* holds LDR 13 bit integer and 5 bit fractional part:
* - integer part: ldr13_5 >> 5
* - fractional part: ldr13_5 & 0x1f */
uint32_t ldr13_5;
uint32_t ctrlb = 0;

/* HW revision before F (A and D) might false unlock -> LBYPASS and WUF */
Expand All @@ -217,12 +240,25 @@
* (critical for some application not so much for other)*/
if (EXTERNAL_OSC32_SOURCE) {
/* Source the DPLL from 32kHz XOSC32 ( equivalent to ((f_cpu << 5) / 32768) ) */
const uint32_t LDR = (f_cpu >> 10);
OSCCTRL->Dpll[idx].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(LDR & 0x1F)
| OSCCTRL_DPLLRATIO_LDR((LDR >> 5) - 1);

ldr13_5 = (f_cpu >> 10);
ctrlb |= OSCCTRL_DPLLCTRLB_REFCLK_XOSC32;
OSCCTRL->Dpll[idx].DPLLCTRLB.reg = ctrlb;
}
else if (XOSC1_FREQUENCY) {
/* Source the DPLL from XOSC1 equivalent to ((f_cpu << 5) / 32768) ) */
/* fCLK_DPLLn = fCKR × (LDR + 1 + LDRFRAC/32)*/
/* fDIV = fXOSC / 2 * ( DIV + 1) */
/* divide to 1 MHz then multiply to fcpu */
const uint32_t div = (XOSC1_FREQUENCY / MHZ(1) / 2) -1;
ldr13_5 = (f_cpu / MHZ(1)) << 5;
ctrlb |= OSCCTRL_DPLLCTRLB_DIV(DIV) | OSCCTRL_DPLLCTRLB_REFCLK_XOSC1;
}
else if (XOSC0_FREQUENCY) {
/* Source the DPLL from XOSC0 /* divide to 1 MHz then multiply to fcpu */
/* fCLK_DPLLn = fCKR × (LDR + 1 + LDRFRAC/32)*/
/* fDIV = fXOSC / 2 * ( DIV + 1) */
const uint32_t div = (XOSC0_FREQUENCY / MHZ(1) / 2) -1;
ldr13_5 = (f_cpu / MHZ(1)) << 5;
ctrlb |= OSCCTRL_DPLLCTRLB_DIV(div) | OSCCTRL_DPLLCTRLB_REFCLK_XOSC0;
}
else {
/* TODO find a better fallback source (eg 48MCLK routed though gclk divided down to 1MHz)
Expand All @@ -232,11 +268,13 @@
while (!(GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + idx].reg & GCLK_PCHCTRL_CHEN)) {}
/* Source the DPLL from 32kHz GCLK1 ( equivalent to ((f_cpu << 5) / 32768) )
* avoid the routing through gclk when XOSC32 is the source */
const uint32_t LDR = (f_cpu >> 10);
OSCCTRL->Dpll[idx].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(LDR & 0x1F)
| OSCCTRL_DPLLRATIO_LDR((LDR >> 5) - 1);
ldr13_5 = (f_cpu >> 10);
ctrlb |= OSCCTRL_DPLLCTRLB_REFCLK_GCLK;
}

OSCCTRL->Dpll[idx].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(ldr13_5 & 0x1F)
| OSCCTRL_DPLLRATIO_LDR((ldr13_5 >> 5) - 1);

OSCCTRL->Dpll[idx].DPLLCTRLB.reg = ctrlb;
OSCCTRL->Dpll[idx].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE | flags;

Expand Down Expand Up @@ -375,7 +413,7 @@
#ifdef MODULE_PERIPH_GPIO_IRQ
| MCLK_APBAMASK_EIC
#endif
;

Check warning on line 416 in cpu/samd5x/cpu.c

View workflow job for this annotation

GitHub Actions / static-tests

semicolon is isolated from other tokens

MCLK->APBBMASK.reg = 0
#ifdef MODULE_PERIPH_FLASHPAGE
Expand All @@ -384,7 +422,7 @@
#ifdef MODULE_PERIPH_GPIO
| MCLK_APBBMASK_PORT
#endif
;

Check warning on line 425 in cpu/samd5x/cpu.c

View workflow job for this annotation

GitHub Actions / static-tests

semicolon is isolated from other tokens

MCLK->APBCMASK.reg = 0;
MCLK->APBDMASK.reg = 0;
Expand Down