@@ -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 7 is reserved
106
+ * table 29-2 : time_for_startup_val[] = { 63ms, 125ms, 500ms, 1sec, 2sec, 4sec, 8 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 ); /* 3 ^~= 1sec see above or manual*/
111
115
112
116
while (!(OSC32KCTRL -> STATUS .reg & OSC32KCTRL_STATUS_XOSC32KRDY )) {}
113
117
}
@@ -197,24 +201,32 @@ 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
+ /* Without LBYPASS, startup takes very long, see errata section 2.13.
209
+ * according to the documentation several milliseconds
210
+ * (critical for some application not so much for other)*/
211
+ if (EXTERNAL_OSC32_SOURCE ) {
212
+ /* Source the DPLL from 32kHz XOSC32 ( equivalent to ((f_cpu << 5) / 32768) ) */
213
+ const uint32_t LDR = (f_cpu >> 10 );
214
+ OSCCTRL -> Dpll [idx ].DPLLRATIO .reg = OSCCTRL_DPLLRATIO_LDRFRAC (LDR & 0x1F )
215
+ | OSCCTRL_DPLLRATIO_LDR ((LDR >> 5 ) - 1 );
216
+ OSCCTRL -> Dpll [idx ].DPLLCTRLB .reg = OSCCTRL_DPLLCTRLB_REFCLK_XOSC32 ;
217
+ }
218
+ else {
219
+ /* TODO find a good source (eg 48MCLK routed though gclk devided down to 1MHz) that should be used as a fall back*/
220
+ /* set DPLL clock source */
221
+ GCLK -> PCHCTRL [OSCCTRL_GCLK_ID_FDPLL0 + idx ].reg = GCLK_PCHCTRL_GEN (1 ) | GCLK_PCHCTRL_CHEN ;
222
+ while (!(GCLK -> PCHCTRL [OSCCTRL_GCLK_ID_FDPLL0 + idx ].reg & GCLK_PCHCTRL_CHEN )) {}
223
+ /* Source the DPLL from 32kHz GCLK1 ( equivalent to ((f_cpu << 5) / 32768) )
224
+ * avoid the routing through gclk when XOSC32 is the source */
225
+ const uint32_t LDR = (f_cpu >> 10 );
226
+ OSCCTRL -> Dpll [idx ].DPLLRATIO .reg = OSCCTRL_DPLLRATIO_LDRFRAC (LDR & 0x1F )
227
+ | OSCCTRL_DPLLRATIO_LDR ((LDR >> 5 ) - 1 );
228
+ OSCCTRL -> Dpll [idx ].DPLLCTRLB .reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK ;
229
+ }
218
230
219
231
OSCCTRL -> Dpll [idx ].DPLLCTRLA .reg = OSCCTRL_DPLLCTRLA_ENABLE | flags ;
220
232
0 commit comments