44
44
45
45
void board_init (void )
46
46
{
47
+
48
+
49
+ #if !defined(CRYSTALLESS )
50
+
47
51
/* Set 1 Flash Wait State for 48MHz, cf tables 20.9 and 35.27 in SAMD21 Datasheet */
48
52
NVMCTRL -> CTRLB .bit .RWS = NVMCTRL_CTRLB_RWS_HALF_Val ;
49
53
50
54
/* Turn on the digital interface clock */
51
55
PM -> APBAMASK .reg |= PM_APBAMASK_GCLK ;
52
56
57
+
53
58
/* ----------------------------------------------------------------------------------------------
54
59
* 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator)
55
60
*/
@@ -86,7 +91,7 @@ void board_init(void)
86
91
/* Write Generic Clock Generator 1 configuration */
87
92
GCLK -> GENCTRL .reg = GCLK_GENCTRL_ID ( GENERIC_CLOCK_GENERATOR_XOSC32K ) | // Generic Clock Generator 1
88
93
GCLK_GENCTRL_SRC_XOSC32K | // Selected source is External 32KHz Oscillator
89
- // GCLK_GENCTRL_OE | // Output clock to a pin for tests
94
+ // GCLK_GENCTRL_OE | // Output clock to a pin for tests
90
95
GCLK_GENCTRL_GENEN ;
91
96
92
97
while ( GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY )
@@ -175,29 +180,6 @@ void board_init(void)
175
180
/* Wait for synchronization */
176
181
}
177
182
178
- #if 0
179
- /* ----------------------------------------------------------------------------------------------
180
- * 6) Modify PRESCaler value of OSC8M to have 8MHz
181
- */
182
- SYSCTRL -> OSC8M .bit .PRESC = SYSCTRL_OSC8M_PRESC_1_Val ;
183
- SYSCTRL -> OSC8M .bit .ONDEMAND = 0 ;
184
-
185
- /* ----------------------------------------------------------------------------------------------
186
- * 7) Put OSC8M as source for Generic Clock Generator 3
187
- */
188
- GCLK -> GENDIV .reg = GCLK_GENDIV_ID ( GENERIC_CLOCK_GENERATOR_OSC8M ); // Generic Clock Generator 3
189
-
190
- /* Write Generic Clock Generator 3 configuration */
191
- GCLK -> GENCTRL .reg = GCLK_GENCTRL_ID ( GENERIC_CLOCK_GENERATOR_OSC8M ) | // Generic Clock Generator 3
192
- GCLK_GENCTRL_SRC_OSC8M | // Selected source is RC OSC 8MHz (already enabled at reset)
193
- // GCLK_GENCTRL_OE | // Output clock to a pin for tests
194
- GCLK_GENCTRL_GENEN ;
195
-
196
- while ( GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY )
197
- {
198
- /* Wait for synchronization */
199
- }
200
- #endif //0
201
183
202
184
/*
203
185
* Now that all system clocks are configured, we can set CPU and APBx BUS clocks.
@@ -207,4 +189,140 @@ void board_init(void)
207
189
PM -> APBASEL .reg = PM_APBASEL_APBADIV_DIV1_Val ;
208
190
PM -> APBBSEL .reg = PM_APBBSEL_APBBDIV_DIV1_Val ;
209
191
PM -> APBCSEL .reg = PM_APBCSEL_APBCDIV_DIV1_Val ;
192
+ #else
193
+
194
+ /////////////////////////////////////////
195
+
196
+ /* Set 1 Flash Wait State for 48MHz, cf tables 20.9 and 35.27 in SAMD21 Datasheet */
197
+ NVMCTRL -> CTRLB .bit .RWS = NVMCTRL_CTRLB_RWS_HALF_Val ;
198
+
199
+ ////////////////////////////////////////
200
+ uint32_t temp_genctrl_config = 0 ;
201
+
202
+ // ENABLE OUTPUT OF GENCLK 0 on D2 (PA14)
203
+ // Write to the PINCFG register to enable the peripheral multiplexer
204
+ PORT -> Group [0 ].PINCFG [14 ].reg = 1 ;
205
+ // Enable peripheral function H for PA14, refer chapter I/O Multiplexing in the device datasheet
206
+ PORT -> Group [0 ].PMUX [7 ].bit .PMUXE = 7 ;
207
+
208
+ // ENABLE OUTPUT OF GENCLK 1 on D5 (PA15)
209
+ // Write to the PINCFG register to enable the peripheral multiplexer
210
+ PORT -> Group [0 ].PINCFG [15 ].reg = 1 ;
211
+ // Enable peripheral function H for PA15, refer chapter I/O Multiplexing in the device datasheet
212
+ PORT -> Group [0 ].PMUX [7 ].bit .PMUXO = 7 ;
213
+
214
+ // ENABLE OUTPUT OF GENCLK 2 on D11 (PA16) - should be OSC8M @ 8MHz
215
+ // Write to the PINCFG register to enable the peripheral multiplexer
216
+ PORT -> Group [0 ].PINCFG [16 ].reg = 1 ;
217
+ // Enable peripheral function H for PA16, refer chapter I/O Multiplexing in the device datasheet
218
+ PORT -> Group [0 ].PMUX [8 ].bit .PMUXE = 7 ;
219
+
220
+
221
+ /////////////////////////////////////////////////
222
+
223
+ /* Set OSC8M prescalar to divide by 1, now gclk0 is @ 8mhz */
224
+ SYSCTRL -> OSC8M .bit .PRESC = 0 ;
225
+
226
+
227
+ /* ----------------------------------------------------------------------------------------------
228
+ * 1) Enable OSC32K clock (Internal 32.768Hz oscillator)
229
+ */
230
+
231
+ uint32_t calib = (* ((uint32_t * ) SYSCTRL_FUSES_OSC32K_ADDR ) & SYSCTRL_FUSES_OSC32K_Msk ) >> SYSCTRL_FUSES_OSC32K_Pos ;
232
+
233
+ SYSCTRL -> OSC32K .reg = SYSCTRL_OSC32K_CALIB (calib ) | SYSCTRL_OSC32K_STARTUP ( 0x6u ) | // cf table 15.10 of product datasheet in chapter 15.8.6
234
+ SYSCTRL_OSC32K_EN32K | SYSCTRL_OSC32K_ENABLE ;
235
+
236
+ while ( (SYSCTRL -> PCLKSR .reg & SYSCTRL_PCLKSR_OSC32KRDY ) == 0 ); // Wait for oscillator stabilization
237
+
238
+ /* ----------------------------------------------------------------------------------------------
239
+ * 2) Put OSC32K as source of Generic Clock Generator 1
240
+ */
241
+
242
+ GCLK_GENCTRL_Type genctrl = {0 };
243
+ uint32_t temp_genctrl ;
244
+
245
+ GCLK -> GENCTRL .bit .ID = 1 ; // Read GENERATOR_ID - GCLK_GEN_1
246
+
247
+ while (GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY ); // wait for data to be ready
248
+
249
+ temp_genctrl = GCLK -> GENCTRL .reg ;
250
+ genctrl .bit .SRC = GCLK_GENCTRL_SRC_OSC32K_Val ; // gclk 1 is now = osc32k
251
+ genctrl .bit .GENEN = 1 ;
252
+ genctrl .bit .RUNSTDBY = 0 ;
253
+ genctrl .bit .OE = 1 ; // output on GCLK_IO[1] pin for debugging
254
+
255
+ GCLK -> GENCTRL .reg = (genctrl .reg | temp_genctrl ); // set it!
256
+
257
+ while (GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY );
258
+
259
+
260
+ /* Configure OSC8M as source for GCLK_GEN 2 */
261
+ GCLK -> GENCTRL .bit .ID = 2 ; // Read GENERATOR_ID - GCLK_GEN_2
262
+
263
+ while (GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY ); // wait for data to be ready
264
+
265
+ temp_genctrl = GCLK -> GENCTRL .reg ;
266
+ genctrl .bit .SRC = GCLK_GENCTRL_SRC_OSC8M_Val ; // gclk 2 is now = osc8m
267
+ genctrl .bit .GENEN = 1 ;
268
+ genctrl .bit .RUNSTDBY = 0 ;
269
+ genctrl .bit .OE = 1 ; // output on GCLK_IO[2] pin for debugging
270
+ GCLK -> GENCTRL .reg = (genctrl .reg | temp_genctrl ); // set it!
271
+
272
+ while (GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY );
273
+
274
+ // Turn on DFLL
275
+ SYSCTRL_DFLLCTRL_Type dfllctrl_conf = {0 };
276
+ SYSCTRL_DFLLVAL_Type dfllval_conf = {0 };
277
+ uint32_t coarse = ( * ((uint32_t * )(NVMCTRL_OTP4 )
278
+ + (NVM_SW_CALIB_DFLL48M_COARSE_VAL / 32 ))
279
+ >> (NVM_SW_CALIB_DFLL48M_COARSE_VAL % 32 ))
280
+ & ((1 << 6 ) - 1 );
281
+ if (coarse == 0x3f ) {
282
+ coarse = 0x1f ;
283
+ }
284
+ uint32_t fine = ( * ((uint32_t * )(NVMCTRL_OTP4 )
285
+ + (NVM_SW_CALIB_DFLL48M_FINE_VAL / 32 ))
286
+ >> (NVM_SW_CALIB_DFLL48M_FINE_VAL % 32 ))
287
+ & ((1 << 10 ) - 1 );
288
+ if (fine == 0x3ff ) {
289
+ fine = 0x1ff ;
290
+ }
291
+ dfllval_conf .bit .COARSE = coarse ;
292
+ dfllval_conf .bit .FINE = fine ;
293
+ dfllctrl_conf .bit .USBCRM = 1 ; // usb correction
294
+ dfllctrl_conf .bit .BPLCKC = 0 ;
295
+ dfllctrl_conf .bit .QLDIS = 0 ;
296
+ dfllctrl_conf .bit .CCDIS = 1 ;
297
+ dfllctrl_conf .bit .ENABLE = 1 ;
298
+
299
+ SYSCTRL -> DFLLCTRL .bit .ONDEMAND = 0 ;
300
+ while (!(SYSCTRL -> PCLKSR .reg & SYSCTRL_PCLKSR_DFLLRDY ));
301
+ SYSCTRL -> DFLLMUL .reg = 48000 ;
302
+ SYSCTRL -> DFLLVAL .reg = dfllval_conf .reg ;
303
+ SYSCTRL -> DFLLCTRL .reg = dfllctrl_conf .reg ;
304
+
305
+ //
306
+ GCLK_CLKCTRL_Type clkctrl = {0 };
307
+ uint16_t temp ;
308
+ GCLK -> CLKCTRL .bit .ID = 2 ; // GCLK_ID - DFLL48M Reference
309
+ temp = GCLK -> CLKCTRL .reg ;
310
+ clkctrl .bit .CLKEN = 1 ;
311
+ clkctrl .bit .WRTLOCK = 0 ;
312
+ clkctrl .bit .GEN = GCLK_CLKCTRL_GEN_GCLK0_Val ;
313
+ GCLK -> CLKCTRL .reg = (clkctrl .reg | temp );
314
+
315
+ // Configure DFLL48M as source for GCLK_GEN 0
316
+ GCLK -> GENCTRL .bit .ID = 0 ; // GENERATOR_ID - GCLK_GEN_0
317
+ while (GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY );
318
+ temp_genctrl = GCLK -> GENCTRL .reg ;
319
+ genctrl .bit .SRC = GCLK_GENCTRL_SRC_DFLL48M_Val ;
320
+ genctrl .bit .GENEN = 1 ;
321
+ genctrl .bit .RUNSTDBY = 0 ;
322
+ genctrl .bit .OE = 1 ;
323
+ GCLK -> GENCTRL .reg = (genctrl .reg | temp_genctrl );
324
+ while (GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY );
325
+
326
+ #endif
327
+
210
328
}
0 commit comments