@@ -102,12 +102,16 @@ static void xosc32k_init(void)
102
102
return ;
103
103
}
104
104
105
+ /* Startup should be a valid value 0 - 6 (~63 ms to 8000 ms) see manual
106
+ * table 29-2 : 3 ^~= 1 sec
107
+ * this delay will happen only when the system is booted or the XOSC32
108
+ * is reenabled after beeing disabled for e.g.: standby*/
105
109
OSC32KCTRL -> XOSC32K .reg = OSC32KCTRL_XOSC32K_ENABLE
106
110
| OSC32KCTRL_XOSC32K_EN1K
107
111
| OSC32KCTRL_XOSC32K_EN32K
108
112
| OSC32KCTRL_XOSC32K_RUNSTDBY
109
113
| OSC32KCTRL_XOSC32K_XTALEN
110
- | OSC32KCTRL_XOSC32K_STARTUP (7 );
114
+ | OSC32KCTRL_XOSC32K_STARTUP (3 );
111
115
112
116
while (!(OSC32KCTRL -> STATUS .reg & OSC32KCTRL_STATUS_XOSC32KRDY )) {}
113
117
}
@@ -197,24 +201,34 @@ static void fdpll_init_nolock(uint8_t idx, uint32_t f_cpu, uint8_t flags)
197
201
return ;
198
202
}
199
203
200
- /* Source the DPLL from 32kHz GCLK1 ( equivalent to ((f_cpu << 5) / 32768) ) */
201
- const uint32_t LDR = (f_cpu >> 10 );
202
-
203
204
/* disable the DPLL before changing the configuration */
204
205
OSCCTRL -> Dpll [idx ].DPLLCTRLA .reg &= ~OSCCTRL_DPLLCTRLA_ENABLE ;
205
206
while (OSCCTRL -> Dpll [idx ].DPLLSYNCBUSY .reg ) {}
206
207
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 ;
208
+ if (!EXTERNAL_OSC32_SOURCE ){
209
+ /* set DPLL clock source */
210
+ GCLK -> PCHCTRL [OSCCTRL_GCLK_ID_FDPLL0 + idx ].reg = GCLK_PCHCTRL_GEN (1 ) | GCLK_PCHCTRL_CHEN ;
211
+ while (!(GCLK -> PCHCTRL [OSCCTRL_GCLK_ID_FDPLL0 + idx ].reg & GCLK_PCHCTRL_CHEN )) {}
212
+ /* Source the DPLL from 32kHz GCLK1 ( equivalent to ((f_cpu << 5) / 32768) )
213
+ * avoid the routing through gclk when XOSC32 is the source */
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
+ } else {
218
+ /* Source the DPLL from 32kHz XOSC32 ( equivalent to ((f_cpu << 5) / 32768) ) */
219
+ const uint32_t LDR = (f_cpu >> 10 );
220
+ OSCCTRL -> Dpll [idx ].DPLLRATIO .reg = OSCCTRL_DPLLRATIO_LDRFRAC (LDR & 0x1F )
221
+ | OSCCTRL_DPLLRATIO_LDR ((LDR >> 5 ) - 1 );
222
+ }
223
+ /* Without LBYPASS, startup takes very long, see errata section 2.13.
224
+ * according to the documentation several milliseconds
225
+ * (critical for some application not so much for other)*/
226
+ if (EXTERNAL_OSC32_SOURCE ){
227
+ OSCCTRL -> Dpll [idx ].DPLLCTRLB .reg = OSCCTRL_DPLLCTRLB_REFCLK_XOSC32 ;
228
+ }
229
+ else {
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