38
38
// Constants for Clock generators
39
39
#define GENERIC_CLOCK_GENERATOR_MAIN (0u)
40
40
#define GENERIC_CLOCK_GENERATOR_XOSC32K (1u)
41
+ #define GENERIC_CLOCK_GENERATOR_OSC32K (1u)
41
42
#define GENERIC_CLOCK_GENERATOR_OSCULP32K (2u) /* Initialized at reset for WDT */
42
43
#define GENERIC_CLOCK_GENERATOR_OSC8M (3u)
43
44
// Constants for Clock multiplexers
@@ -51,7 +52,21 @@ void SystemInit( void )
51
52
/* Turn on the digital interface clock */
52
53
PM -> APBAMASK .reg |= PM_APBAMASK_GCLK ;
53
54
54
- #if !defined(CRYSTALLESS )
55
+ #if defined(CRYSTALLESS )
56
+
57
+ /* ----------------------------------------------------------------------------------------------
58
+ * 1) Enable OSC32K clock (Internal 32.768Hz oscillator)
59
+ */
60
+
61
+ uint32_t calib = (* ((uint32_t * ) SYSCTRL_FUSES_OSC32K_ADDR ) & SYSCTRL_FUSES_OSC32K_Msk ) >> SYSCTRL_FUSES_OSC32K_Pos ;
62
+
63
+ SYSCTRL -> OSC32K .reg = SYSCTRL_OSC32K_CALIB (calib ) | SYSCTRL_OSC32K_STARTUP ( 0x6u ) | // cf table 15.10 of product datasheet in chapter 15.8.6
64
+ SYSCTRL_OSC32K_EN32K | SYSCTRL_OSC32K_ENABLE ;
65
+
66
+ while ( (SYSCTRL -> PCLKSR .reg & SYSCTRL_PCLKSR_OSC32KRDY ) == 0 ); // Wait for oscillator stabilization
67
+
68
+ #else // has crystal
69
+
55
70
/* ----------------------------------------------------------------------------------------------
56
71
* 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator)
57
72
*/
@@ -64,6 +79,8 @@ void SystemInit( void )
64
79
/* Wait for oscillator stabilization */
65
80
}
66
81
82
+ #endif
83
+
67
84
/* Software reset the module to ensure it is re-initialized correctly */
68
85
/* Note: Due to synchronization, there is a delay from writing CTRL.SWRST until the reset is complete.
69
86
* CTRL.SWRST and STATUS.SYNCBUSY will both be cleared when the reset is complete, as described in chapter 13.8.1
@@ -76,19 +93,23 @@ void SystemInit( void )
76
93
}
77
94
78
95
/* ----------------------------------------------------------------------------------------------
79
- * 2) Put XOSC32K as source of Generic Clock Generator 1
96
+ * 2) Put XOSC32K or OSC32K as source of Generic Clock Generator 1
80
97
*/
81
- GCLK -> GENDIV .reg = GCLK_GENDIV_ID ( GENERIC_CLOCK_GENERATOR_XOSC32K ) ; // Generic Clock Generator 1
98
+ GCLK -> GENDIV .reg = GCLK_GENDIV_ID ( GENERIC_CLOCK_GENERATOR_OSC32K ) ; // Generic Clock Generator 1
82
99
83
100
while ( GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY )
84
101
{
85
102
/* Wait for synchronization */
86
103
}
87
104
88
105
/* Write Generic Clock Generator 1 configuration */
89
- GCLK -> GENCTRL .reg = GCLK_GENCTRL_ID ( GENERIC_CLOCK_GENERATOR_XOSC32K ) | // Generic Clock Generator 1
106
+ GCLK -> GENCTRL .reg = GCLK_GENCTRL_ID ( GENERIC_CLOCK_GENERATOR_OSC32K ) | // Generic Clock Generator 1
107
+ #if defined(CRYSTALLESS )
108
+ GCLK_GENCTRL_SRC_OSC32K | // Selected source is Internal 32KHz Oscillator
109
+ #else
90
110
GCLK_GENCTRL_SRC_XOSC32K | // Selected source is External 32KHz Oscillator
91
- // GCLK_GENCTRL_OE | // Output clock to a pin for tests
111
+ #endif
112
+ GCLK_GENCTRL_OE | // Output clock to a pin for tests
92
113
GCLK_GENCTRL_GENEN ;
93
114
94
115
while ( GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY )
@@ -112,8 +133,6 @@ void SystemInit( void )
112
133
* 4) Enable DFLL48M clock
113
134
*/
114
135
115
- /* DFLL Configuration in Closed Loop mode, cf product datasheet chapter 15.6.7.1 - Closed-Loop Operation */
116
-
117
136
/* Remove the OnDemand mode, Bug http://avr32.icgroup.norway.atmel.com/bugzilla/show_bug.cgi?id=9905 */
118
137
SYSCTRL -> DFLLCTRL .bit .ONDEMAND = 0 ;
119
138
@@ -131,6 +150,46 @@ void SystemInit( void )
131
150
/* Wait for synchronization */
132
151
}
133
152
153
+ #if defined(CRYSTALLESS )
154
+ #define NVM_SW_CALIB_DFLL48M_COARSE_VAL 58
155
+ #define NVM_SW_CALIB_DFLL48M_FINE_VAL 64
156
+
157
+ // Turn on DFLL
158
+ SYSCTRL_DFLLVAL_Type dfllval_conf = {0 };
159
+ uint32_t coarse = ( * ((uint32_t * )(NVMCTRL_OTP4 )
160
+ + (NVM_SW_CALIB_DFLL48M_COARSE_VAL / 32 ))
161
+ >> (NVM_SW_CALIB_DFLL48M_COARSE_VAL % 32 ))
162
+ & ((1 << 6 ) - 1 );
163
+ if (coarse == 0x3f ) {
164
+ coarse = 0x1f ;
165
+ }
166
+ uint32_t fine = ( * ((uint32_t * )(NVMCTRL_OTP4 )
167
+ + (NVM_SW_CALIB_DFLL48M_FINE_VAL / 32 ))
168
+ >> (NVM_SW_CALIB_DFLL48M_FINE_VAL % 32 ))
169
+ & ((1 << 10 ) - 1 );
170
+ if (fine == 0x3ff ) {
171
+ fine = 0x1ff ;
172
+ }
173
+ dfllval_conf .bit .COARSE = coarse ;
174
+ dfllval_conf .bit .FINE = fine ;
175
+
176
+ SYSCTRL -> DFLLVAL .reg = dfllval_conf .reg ;
177
+ /* Write full configuration to DFLL control register */
178
+ SYSCTRL -> DFLLCTRL .reg = SYSCTRL_DFLLCTRL_USBCRM | /* USB correction */
179
+ SYSCTRL_DFLLCTRL_CCDIS |
180
+ SYSCTRL_DFLLCTRL_WAITLOCK |
181
+ SYSCTRL_DFLLCTRL_QLDIS ; /* Disable Quick lock */
182
+
183
+ while ( (SYSCTRL -> PCLKSR .reg & SYSCTRL_PCLKSR_DFLLRDY ) == 0 )
184
+ {
185
+ /* Wait for synchronization */
186
+ }
187
+
188
+ /* Enable the DFLL */
189
+ SYSCTRL -> DFLLCTRL .reg |= SYSCTRL_DFLLCTRL_ENABLE ;
190
+
191
+ #else // has crystal
192
+
134
193
/* Write full configuration to DFLL control register */
135
194
SYSCTRL -> DFLLCTRL .reg |= SYSCTRL_DFLLCTRL_MODE | /* Enable the closed loop mode */
136
195
SYSCTRL_DFLLCTRL_WAITLOCK |
@@ -149,6 +208,8 @@ void SystemInit( void )
149
208
{
150
209
/* Wait for locks flags */
151
210
}
211
+
212
+ #endif
152
213
153
214
while ( (SYSCTRL -> PCLKSR .reg & SYSCTRL_PCLKSR_DFLLRDY ) == 0 )
154
215
{
@@ -168,7 +229,7 @@ void SystemInit( void )
168
229
/* Write Generic Clock Generator 0 configuration */
169
230
GCLK -> GENCTRL .reg = GCLK_GENCTRL_ID ( GENERIC_CLOCK_GENERATOR_MAIN ) | // Generic Clock Generator 0
170
231
GCLK_GENCTRL_SRC_DFLL48M | // Selected source is DFLL 48MHz
171
- // GCLK_GENCTRL_OE | // Output clock to a pin for tests
232
+ GCLK_GENCTRL_OE | // Output clock to a pin for tests
172
233
GCLK_GENCTRL_IDC | // Set 50/50 duty cycle
173
234
GCLK_GENCTRL_GENEN ;
174
235
@@ -191,121 +252,9 @@ void SystemInit( void )
191
252
/* Write Generic Clock Generator 3 configuration */
192
253
GCLK -> GENCTRL .reg = GCLK_GENCTRL_ID ( GENERIC_CLOCK_GENERATOR_OSC8M ) | // Generic Clock Generator 3
193
254
GCLK_GENCTRL_SRC_OSC8M | // Selected source is RC OSC 8MHz (already enabled at reset)
194
- // GCLK_GENCTRL_OE | // Output clock to a pin for tests
255
+ GCLK_GENCTRL_OE | // Output clock to a pin for tests
195
256
GCLK_GENCTRL_GENEN ;
196
257
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
-
309
258
while ( GCLK -> STATUS .reg & GCLK_STATUS_SYNCBUSY )
310
259
{
311
260
/* Wait for synchronization */
0 commit comments