@@ -51,6 +51,7 @@ void SystemInit( void )
51
51
/* Turn on the digital interface clock */
52
52
PM -> APBAMASK .reg |= PM_APBAMASK_GCLK ;
53
53
54
+ #if !defined(CRYSTALLESS )
54
55
/* ----------------------------------------------------------------------------------------------
55
56
* 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator)
56
57
*/
@@ -193,6 +194,118 @@ void SystemInit( void )
193
194
// GCLK_GENCTRL_OE | // Output clock to a pin for tests
194
195
GCLK_GENCTRL_GENEN ;
195
196
197
+ #else
198
+
199
+
200
+ /* Set OSC8M prescalar to divide by 1, now gclk0 is @ 8mhz */
201
+ SYSCTRL -> OSC8M .bit .PRESC = 0 ;
202
+
203
+ /* ----------------------------------------------------------------------------------------------
204
+ * 1) Enable OSC32K clock (Internal 32.768Hz oscillator)
205
+ */
206
+
207
+ uint32_t calib = (* ((uint32_t * ) SYSCTRL_FUSES_OSC32K_ADDR ) & SYSCTRL_FUSES_OSC32K_Msk ) >> SYSCTRL_FUSES_OSC32K_Pos ;
208
+
209
+ SYSCTRL -> OSC32K .reg = SYSCTRL_OSC32K_CALIB (calib ) | SYSCTRL_OSC32K_STARTUP ( 0x6u ) | // cf table 15.10 of product datasheet in chapter 15.8.6
210
+ SYSCTRL_OSC32K_EN32K | SYSCTRL_OSC32K_ENABLE ;
211
+
212
+ while ( (SYSCTRL -> PCLKSR .reg & SYSCTRL_PCLKSR_OSC32KRDY ) == 0 ); // Wait for oscillator stabilization
213
+
214
+ /* ----------------------------------------------------------------------------------------------
215
+ * 2) Put OSC32K as source of Generic Clock Generator 1
216
+ */
217
+
218
+ GCLK_GENCTRL_Type genctrl = {0 };
219
+ uint32_t temp_genctrl ;
220
+
221
+ GCLK -> GENCTRL .bit .ID = 1 ; // Read GENERATOR_ID - GCLK_GEN_1
222
+
223
+ while (GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY ); // wait for data to be ready
224
+
225
+ temp_genctrl = GCLK -> GENCTRL .reg ;
226
+ genctrl .bit .SRC = GCLK_GENCTRL_SRC_OSC32K_Val ; // gclk 1 is now = osc32k
227
+ genctrl .bit .GENEN = 1 ;
228
+ genctrl .bit .RUNSTDBY = 0 ;
229
+ genctrl .bit .OE = 1 ; // output on GCLK_IO[1] pin for debugging
230
+
231
+ GCLK -> GENCTRL .reg = (genctrl .reg | temp_genctrl ); // set it!
232
+
233
+ while (GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY );
234
+
235
+
236
+ /* Configure OSC8M as source for GCLK_GEN 2 */
237
+ GCLK -> GENCTRL .bit .ID = 2 ; // Read GENERATOR_ID - GCLK_GEN_2
238
+
239
+ while (GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY ); // wait for data to be ready
240
+
241
+ temp_genctrl = GCLK -> GENCTRL .reg ;
242
+ genctrl .bit .SRC = GCLK_GENCTRL_SRC_OSC8M_Val ; // gclk 2 is now = osc8m
243
+ genctrl .bit .GENEN = 1 ;
244
+ genctrl .bit .RUNSTDBY = 0 ;
245
+ genctrl .bit .OE = 1 ; // output on GCLK_IO[2] pin for debugging
246
+ GCLK -> GENCTRL .reg = (genctrl .reg | temp_genctrl ); // set it!
247
+
248
+ while (GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY );
249
+
250
+
251
+ #define NVM_SW_CALIB_DFLL48M_COARSE_VAL 58
252
+ #define NVM_SW_CALIB_DFLL48M_FINE_VAL 64
253
+
254
+ // Turn on DFLL
255
+ SYSCTRL_DFLLCTRL_Type dfllctrl_conf = {0 };
256
+ SYSCTRL_DFLLVAL_Type dfllval_conf = {0 };
257
+ uint32_t coarse = ( * ((uint32_t * )(NVMCTRL_OTP4 )
258
+ + (NVM_SW_CALIB_DFLL48M_COARSE_VAL / 32 ))
259
+ >> (NVM_SW_CALIB_DFLL48M_COARSE_VAL % 32 ))
260
+ & ((1 << 6 ) - 1 );
261
+ if (coarse == 0x3f ) {
262
+ coarse = 0x1f ;
263
+ }
264
+ uint32_t fine = ( * ((uint32_t * )(NVMCTRL_OTP4 )
265
+ + (NVM_SW_CALIB_DFLL48M_FINE_VAL / 32 ))
266
+ >> (NVM_SW_CALIB_DFLL48M_FINE_VAL % 32 ))
267
+ & ((1 << 10 ) - 1 );
268
+ if (fine == 0x3ff ) {
269
+ fine = 0x1ff ;
270
+ }
271
+ dfllval_conf .bit .COARSE = coarse ;
272
+ dfllval_conf .bit .FINE = fine ;
273
+ dfllctrl_conf .bit .USBCRM = 1 ; // usb correction
274
+ dfllctrl_conf .bit .BPLCKC = 0 ;
275
+ dfllctrl_conf .bit .QLDIS = 0 ;
276
+ dfllctrl_conf .bit .CCDIS = 1 ;
277
+ dfllctrl_conf .bit .ENABLE = 1 ;
278
+
279
+ SYSCTRL -> DFLLCTRL .bit .ONDEMAND = 0 ;
280
+ while (!(SYSCTRL -> PCLKSR .reg & SYSCTRL_PCLKSR_DFLLRDY ));
281
+ SYSCTRL -> DFLLMUL .reg = 48000 ;
282
+ SYSCTRL -> DFLLVAL .reg = dfllval_conf .reg ;
283
+ SYSCTRL -> DFLLCTRL .reg = dfllctrl_conf .reg ;
284
+
285
+ //
286
+ GCLK_CLKCTRL_Type clkctrl = {0 };
287
+ uint16_t temp ;
288
+ GCLK -> CLKCTRL .bit .ID = 2 ; // GCLK_ID - DFLL48M Reference
289
+ temp = GCLK -> CLKCTRL .reg ;
290
+ clkctrl .bit .CLKEN = 1 ;
291
+ clkctrl .bit .WRTLOCK = 0 ;
292
+ clkctrl .bit .GEN = GCLK_CLKCTRL_GEN_GCLK0_Val ;
293
+ GCLK -> CLKCTRL .reg = (clkctrl .reg | temp );
294
+
295
+ // Configure DFLL48M as source for GCLK_GEN 0
296
+ GCLK -> GENCTRL .bit .ID = 0 ; // GENERATOR_ID - GCLK_GEN_0
297
+ while (GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY );
298
+ temp_genctrl = GCLK -> GENCTRL .reg ;
299
+ genctrl .bit .SRC = GCLK_GENCTRL_SRC_DFLL48M_Val ;
300
+ genctrl .bit .GENEN = 1 ;
301
+ genctrl .bit .RUNSTDBY = 0 ;
302
+ genctrl .bit .OE = 1 ;
303
+ GCLK -> GENCTRL .reg = (genctrl .reg | temp_genctrl );
304
+ while (GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY );
305
+
306
+
307
+ #endif
308
+
196
309
while ( GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY )
197
310
{
198
311
/* Wait for synchronization */
0 commit comments