@@ -102,12 +102,17 @@ 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 7 is reserved
106
+ * table 29-2 : time_for_startup_val[] = { 63ms, 125ms, 500ms, 1sec, 2sec, 4sec, 8 sec}
107
+ * 3 ^~= 1 sec
108
+ * this delay will happen only when the system is booted or the XOSC32
109
+ * is reenabled after beeing 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 );
111
116
112
117
while (!(OSC32KCTRL -> STATUS .reg & OSC32KCTRL_STATUS_XOSC32KRDY )) {}
113
118
}
@@ -197,24 +202,32 @@ 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 good source (eg 48MCLK routed though gclk devided down to 1MHz) that should be used as a fall back*/
221
+ /* set DPLL clock source */
222
+ GCLK -> PCHCTRL [OSCCTRL_GCLK_ID_FDPLL0 + idx ].reg = GCLK_PCHCTRL_GEN (1 ) | GCLK_PCHCTRL_CHEN ;
223
+ while (!(GCLK -> PCHCTRL [OSCCTRL_GCLK_ID_FDPLL0 + idx ].reg & GCLK_PCHCTRL_CHEN )) {}
224
+ /* Source the DPLL from 32kHz GCLK1 ( equivalent to ((f_cpu << 5) / 32768) )
225
+ * avoid the routing through gclk when XOSC32 is the source */
226
+ const uint32_t LDR = (f_cpu >> 10 );
227
+ OSCCTRL -> Dpll [idx ].DPLLRATIO .reg = OSCCTRL_DPLLRATIO_LDRFRAC (LDR & 0x1F )
228
+ | OSCCTRL_DPLLRATIO_LDR ((LDR >> 5 ) - 1 );
229
+ OSCCTRL -> Dpll [idx ].DPLLCTRLB .reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK ;
230
+ }
218
231
219
232
OSCCTRL -> Dpll [idx ].DPLLCTRLA .reg = OSCCTRL_DPLLCTRLA_ENABLE | flags ;
220
233
0 commit comments