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