|
59 | 59 | # endif
|
60 | 60 |
|
61 | 61 | # if (CLOCK_CORECLOCK > SAM0_XOSC_FREQ_HZ)
|
62 |
| -# error When using an external oscillator for the main clock, the CPU frequency can't exceed it's frequency. |
| 62 | +# error When using an external oscillator for the main clock,\ |
| 63 | +the CPU frequency can't exceed it's frequency. |
63 | 64 | # endif
|
64 | 65 |
|
65 | 66 | # define USE_DPLL 0
|
@@ -102,12 +103,16 @@ static void xosc32k_init(void)
|
102 | 103 | return;
|
103 | 104 | }
|
104 | 105 |
|
| 106 | + /* Startup should be a valid value 0 - 6 (~63 ms to ~8000 ms) see manual 7 is reserved |
| 107 | + * table 29-2 : time_for_startup_val[] = {63ms, 125ms, 500ms, 1sec, 2sec, 4sec, 8sec} |
| 108 | + * this delay will happen only when the system is powered on or the XOSC32 |
| 109 | + * is re-enabled after being disabled for e.g.: standby*/ |
105 | 110 | OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE
|
106 | 111 | | OSC32KCTRL_XOSC32K_EN1K
|
107 | 112 | | OSC32KCTRL_XOSC32K_EN32K
|
108 | 113 | | OSC32KCTRL_XOSC32K_RUNSTDBY
|
109 | 114 | | OSC32KCTRL_XOSC32K_XTALEN
|
110 |
| - | OSC32KCTRL_XOSC32K_STARTUP(7); |
| 115 | + | OSC32KCTRL_XOSC32K_STARTUP(3); /* 3 ^= ~1sec see above or manual*/ |
111 | 116 |
|
112 | 117 | while (!(OSC32KCTRL->STATUS.reg & OSC32KCTRL_STATUS_XOSC32KRDY)) {}
|
113 | 118 | }
|
@@ -197,24 +202,33 @@ static void fdpll_init_nolock(uint8_t idx, uint32_t f_cpu, uint8_t flags)
|
197 | 202 | return;
|
198 | 203 | }
|
199 | 204 |
|
200 |
| - /* Source the DPLL from 32kHz GCLK1 ( equivalent to ((f_cpu << 5) / 32768) ) */ |
201 |
| - const uint32_t LDR = (f_cpu >> 10); |
202 |
| - |
203 | 205 | /* disable the DPLL before changing the configuration */
|
204 | 206 | OSCCTRL->Dpll[idx].DPLLCTRLA.reg &= ~OSCCTRL_DPLLCTRLA_ENABLE;
|
205 | 207 | while (OSCCTRL->Dpll[idx].DPLLSYNCBUSY.reg) {}
|
206 | 208 |
|
207 |
| - /* set DPLL clock source */ |
208 |
| - GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + idx].reg = GCLK_PCHCTRL_GEN(1) | GCLK_PCHCTRL_CHEN; |
209 |
| - while (!(GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + idx].reg & GCLK_PCHCTRL_CHEN)) {} |
210 |
| - |
211 |
| - OSCCTRL->Dpll[idx].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(LDR & 0x1F) |
212 |
| - | OSCCTRL_DPLLRATIO_LDR((LDR >> 5) - 1); |
213 |
| - |
214 |
| - /* Without LBYPASS, startup takes very long, see errata section 2.13. */ |
215 |
| - OSCCTRL->Dpll[idx].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK |
216 |
| - | OSCCTRL_DPLLCTRLB_WUF |
217 |
| - | OSCCTRL_DPLLCTRLB_LBYPASS; |
| 209 | + /* Without LBYPASS, startup takes very long, see errata section 2.13. |
| 210 | + * according to the documentation several milliseconds |
| 211 | + * (critical for some application not so much for other)*/ |
| 212 | + if (EXTERNAL_OSC32_SOURCE) { |
| 213 | + /* Source the DPLL from 32kHz XOSC32 ( equivalent to ((f_cpu << 5) / 32768) ) */ |
| 214 | + const uint32_t LDR = (f_cpu >> 10); |
| 215 | + OSCCTRL->Dpll[idx].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(LDR & 0x1F) |
| 216 | + | OSCCTRL_DPLLRATIO_LDR((LDR >> 5) - 1); |
| 217 | + OSCCTRL->Dpll[idx].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_XOSC32; |
| 218 | + } |
| 219 | + else { |
| 220 | + /* TODO find a better fallback source (eg 48MCLK routed though gclk divided down to 1MHz) |
| 221 | + * until then the frequency might not be defined if source is low power internal 32kHz*/ |
| 222 | + /* set DPLL clock source */ |
| 223 | + GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + idx].reg = GCLK_PCHCTRL_GEN(1) | GCLK_PCHCTRL_CHEN; |
| 224 | + while (!(GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + idx].reg & GCLK_PCHCTRL_CHEN)) {} |
| 225 | + /* Source the DPLL from 32kHz GCLK1 ( equivalent to ((f_cpu << 5) / 32768) ) |
| 226 | + * avoid the routing through gclk when XOSC32 is the source */ |
| 227 | + const uint32_t LDR = (f_cpu >> 10); |
| 228 | + OSCCTRL->Dpll[idx].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(LDR & 0x1F) |
| 229 | + | OSCCTRL_DPLLRATIO_LDR((LDR >> 5) - 1); |
| 230 | + OSCCTRL->Dpll[idx].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK; |
| 231 | + } |
218 | 232 |
|
219 | 233 | OSCCTRL->Dpll[idx].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE | flags;
|
220 | 234 |
|
|
0 commit comments