@@ -86,16 +86,13 @@ void SystemInit( void )
86
86
temp .bit .RUNSTDBY = 0 ;
87
87
// commit changes
88
88
OSC32KCTRL -> XOSC32K .reg = temp .reg ;
89
-
90
89
// enable xosc32k clock
91
90
OSC32KCTRL -> XOSC32K .reg |= OSC32KCTRL_XOSC32K_ENABLE ;
92
91
// wait for clock to become ready
93
92
while ( (OSC32KCTRL -> STATUS .reg & OSC32KCTRL_STATUS_XOSC32KRDY ) == 0 );
94
-
93
+
94
+
95
95
// init DFLL
96
- // wait for dfll register to be ready before we write to it
97
- while ( ( OSCCTRL -> STATUS .reg & OSCCTRL_STATUS_DFLLRDY ) == 0 );
98
-
99
96
/* Using DFLL48M COARSE CAL value from NVM Software Calibration Area Mapping
100
97
in DFLL.COARSE helps to output a frequency close to 48 MHz.*/
101
98
#define NVM_DFLL_COARSE_POS 26 /* DFLL48M Coarse calibration value bit position.*/
@@ -110,48 +107,7 @@ void SystemInit( void )
110
107
coarse = 0x1f ;
111
108
}
112
109
113
-
114
- // system_clock_source_dfll_set_config_errata_9905;
115
- /* Disable ONDEMAND mode while writing configurations */
116
-
117
-
118
-
119
- OSCCTRL -> DFLLCTRL .bit .ONDEMAND = 0 ;
120
- OSCCTRL -> DFLLCTRL .bit .ENABLE = 1 ;
121
- // wait for dfll register to be ready before we write to it
122
- while ( ( OSCCTRL -> STATUS .reg & OSCCTRL_STATUS_DFLLRDY ) == 0 );
123
-
124
- OSCCTRL_DFLLMUL_Type dfllMul = OSCCTRL -> DFLLMUL ;
125
- dfllMul .bit .CSTEP = (0x1f / 4 ); //MAX_COARSE_STEP_SIZE
126
- dfllMul .bit .FSTEP = (0xff / 4 ); //MAX_FINE_STEP_SIZE
127
- dfllMul .bit .MUL = (48000000 / 32768 ); // MULTIPLY_FACTOR
128
- // OSCCTRL->DFLLMUL.reg = dfllMul.reg;
129
-
130
- // wait for dfll register to be ready before we write to it
131
- // while ((OSCCTRL->STATUS.reg & OSCCTRL_STATUS_DFLLRDY) == 0);
132
-
133
- OSCCTRL_DFLLCTRL_Type dfllCtrl = OSCCTRL -> DFLLCTRL ;
134
- dfllCtrl .bit .MODE = 1 ; // closed loop mode
135
- dfllCtrl .bit .LLAW = 0 ; /** Keep DFLL lock when the device wakes from sleep */
136
- dfllCtrl .bit .STABLE = 0 ;/** Keep tracking after the DFLL has gotten a fine lock */
137
- dfllCtrl .bit .QLDIS = 0 ;/** Enable the QuickLock feature for looser lock requirements on the DFLL */
138
- dfllCtrl .bit .CCDIS = 0 ;/** Enable a chill cycle, where the DFLL output frequency is not measured */
139
- dfllCtrl .bit .ONDEMAND = 0 ; /** disable on demand mode*/
140
- dfllCtrl .bit .RUNSTDBY = 0 ; /** Do not run in standby */
141
- // OSCCTRL->DFLLCTRL.reg = dfllCtrl.reg;
142
-
143
- // wait for dfll register to be ready before we write to it
144
- // while ( ( OSCCTRL->STATUS.reg & OSCCTRL_STATUS_DFLLRDY) == 0 );
145
-
146
- OSCCTRL_DFLLVAL_Type dfllval = OSCCTRL -> DFLLVAL ;
147
- dfllval .bit .COARSE = coarse ; /** Coarse calibration value (closed loop mode) */
148
- dfllval .bit .FINE = 0xff / 4 ; /* Midpoint fine calibration value (closed loop mode) */
149
- // OSCCTRL->DFLLVAL= dfllval;
150
-
151
- // clock not enabled yet
152
- //
153
-
154
- // init GCLK (0,1,2,3)
110
+ // init GCLK (0,1)
155
111
/* Turn on the digital interface clock */
156
112
MCLK -> APBAMASK .reg |= MCLK_APBAMASK_GCLK ;
157
113
/* Software reset the module to ensure it is re-initialized correctly */
@@ -164,67 +120,27 @@ void SystemInit( void )
164
120
165
121
GCLK_GENCTRL_Type gclkConfig ;
166
122
/* Configure GCLK generator 1 ( hw timer )
167
- * run in standby : 1
168
- * source : GCLK_SOURCE_XOSC32K
123
+ * run in standby : 0
124
+ * source : GCLK_GENCTRL_SRC_XOSC32K - more stable then ULP32k
169
125
* prescaler ( division factor ) : 1
170
126
* output enable : 0
171
127
*/
172
128
gclkConfig .reg = 0 ;
173
129
gclkConfig .reg = GCLK -> GENCTRL [1 ].reg ;
174
130
gclkConfig .bit .DIV = 1 ;
175
- gclkConfig .bit .SRC = GCLK_GENCTRL_SRC_XOSC32K_Val ;
131
+ gclkConfig .bit .SRC = GCLK_GENCTRL_SRC_XOSC32K_Val ; // apparently more stable than ULP32k ( for the DFLL48 )
176
132
gclkConfig .bit .OE = 0 ;
177
133
gclkConfig .bit .RUNSTDBY = 0 ;
178
-
179
134
GCLK -> GENCTRL [1 ].reg = gclkConfig .reg ;
180
135
/* Enable generator */
181
136
gclk_gen_sync (1 );
182
137
GCLK -> GENCTRL [1 ].reg |= GCLK_GENCTRL_GENEN ;
183
138
184
- /* Configure GCLK generator 2 ( adc )
185
- * run in standby : 0
186
- * source : GCLK_SOURCE_OSC16M
187
- * prescaler ( division factor ) : 5 ( use improved dutycycle mode )
188
- * output enable : 0
189
- */
190
- gclkConfig .reg = 0 ;
191
- gclkConfig .reg = GCLK -> GENCTRL [2 ].reg ;
192
- gclkConfig .bit .DIV = 5 ;
193
- gclkConfig .bit .IDC = 1 ;
194
- gclkConfig .bit .SRC = GCLK_GENCTRL_SRC_OSC16M_Val ;
195
- gclkConfig .bit .OE = 0 ;
196
- gclkConfig .bit .RUNSTDBY = 0 ;
197
-
198
- GCLK -> GENCTRL [2 ].reg = gclkConfig .reg ;
199
- /* Enable generator */
200
- gclk_gen_sync (2 );
201
- GCLK -> GENCTRL [2 ].reg |= GCLK_GENCTRL_GENEN ;
202
-
203
- /* Configure GCLK generator 3
204
- * run in standby : 0
205
- * source : GCLK_SOURCE_DFLL48M
206
- * prescaler : 1
207
- * output enable : 0
208
- */
209
- gclkConfig .reg = 0 ;
210
- gclkConfig .reg = GCLK -> GENCTRL [3 ].reg ;
211
- gclkConfig .bit .DIV = 1 ;
212
- gclkConfig .bit .SRC = GCLK_GENCTRL_SRC_DFLL48M_Val ;
213
- gclkConfig .bit .OE = 0 ;
214
- gclkConfig .bit .RUNSTDBY = 0 ;
215
-
216
- GCLK -> GENCTRL [3 ].reg = gclkConfig .reg ;
217
- /* Enable generator */
218
- gclk_gen_sync (3 );
219
- GCLK -> GENCTRL [3 ].reg |= GCLK_GENCTRL_GENEN ;
220
-
221
-
222
-
223
139
/* Enable DFLL reference clock in closed loop mode */
224
140
/* Disable the peripheral channel */
225
141
GCLK -> PCHCTRL [OSCCTRL_GCLK_ID_DFLL48 ].reg &= ~GCLK_PCHCTRL_CHEN ;
226
142
/* Configure the peripheral channel */
227
- GCLK -> PCHCTRL [OSCCTRL_GCLK_ID_DFLL48 ].reg = GCLK_PCHCTRL_GEN (1 ); // Generator 1 is the source ( xosc32k )
143
+ GCLK -> PCHCTRL [OSCCTRL_GCLK_ID_DFLL48 ].reg = GCLK_PCHCTRL_GEN (1 ); // Generator 1 is the source ( 32k )
228
144
/* Enable the peripheral channel */
229
145
GCLK -> PCHCTRL [OSCCTRL_GCLK_ID_DFLL48 ].reg |= GCLK_PCHCTRL_CHEN ;
230
146
@@ -235,15 +151,39 @@ void SystemInit( void )
235
151
/* DFLL Enable (Open and Closed Loop) */
236
152
// system_clock_source_dfll_set_config_errata_9905;
237
153
/* Disable ONDEMAND mode while writing configurations */
154
+ while ( ( OSCCTRL -> STATUS .reg & OSCCTRL_STATUS_DFLLRDY ) == 0 );
155
+ OSCCTRL -> DFLLCTRL .bit .ONDEMAND = 0 ;
156
+ OSCCTRL -> DFLLCTRL .bit .ENABLE = 0 ;
157
+ // wait for dfll register to be ready before we write to it
158
+ while ( ( OSCCTRL -> STATUS .reg & OSCCTRL_STATUS_DFLLRDY ) == 0 );
159
+
160
+ OSCCTRL_DFLLMUL_Type dfllMul = OSCCTRL -> DFLLMUL ;
161
+ dfllMul .bit .CSTEP = (0x1f / 4 ); //MAX_COARSE_STEP_SIZE
162
+ dfllMul .bit .FSTEP = (0xff / 4 ); //MAX_FINE_STEP_SIZE
163
+ dfllMul .bit .MUL = (VARIANT_MCK / 32768 ); // MULTIPLY_FACTOR
164
+
165
+ OSCCTRL_DFLLCTRL_Type dfllCtrl = OSCCTRL -> DFLLCTRL ;
166
+ dfllCtrl .bit .MODE = 1 ; // closed loop mode
167
+ dfllCtrl .bit .LLAW = 0 ; /** low power, we re-aquire lock after wake */ // low power, we re-aquire lock after wake
168
+ dfllCtrl .bit .STABLE = 0 ;/** Keep tracking after the DFLL has gotten a fine lock */
169
+ dfllCtrl .bit .QLDIS = 0 ;/** Enable the QuickLock feature for looser lock requirements on the DFLL */
170
+ dfllCtrl .bit .CCDIS = 0 ;/** Enable a chill cycle, where the DFLL output frequency is not measured */
171
+ dfllCtrl .bit .ONDEMAND = 0 ; /** disable on demand mode*/
172
+ dfllCtrl .bit .RUNSTDBY = 0 ; /** Do not run in standby */
173
+ dfllCtrl .bit .ENABLE = 1 ; // set enable bit
174
+
175
+ OSCCTRL_DFLLVAL_Type dfllval = OSCCTRL -> DFLLVAL ;
176
+ dfllval .bit .COARSE = coarse ; /** Coarse calibration value (closed loop mode) */
177
+ dfllval .bit .FINE = 0xff / 4 ; /* Midpoint fine calibration value (closed loop mode) */
178
+ // clock not enabled yet
179
+ //
238
180
239
181
// wait for dfll register to be ready before we write to it
240
182
while ( ( OSCCTRL -> STATUS .reg & OSCCTRL_STATUS_DFLLRDY ) == 0 );
241
183
242
184
OSCCTRL -> DFLLCTRL .bit .ONDEMAND = 0 ;
243
185
OSCCTRL -> DFLLCTRL .bit .ENABLE = 1 ;
244
- dfllCtrl .bit .ENABLE = 1 ; // set enable bit
245
- //
246
-
186
+
247
187
OSCCTRL -> DFLLMUL .reg = 0 ;
248
188
OSCCTRL -> DFLLVAL .reg = 0 ;
249
189
// wait for dfll register to be ready before we write to it
@@ -268,7 +208,6 @@ void SystemInit( void )
268
208
/* Wait for DFLL sync */
269
209
}
270
210
271
- OSCCTRL -> DFLLCTRL .bit .ONDEMAND = 1 ;
272
211
/* Enable generator 0 as it depends on other generators*/
273
212
/* Configure GCLK generator 0 (Main Clock)
274
213
* run in standby : false
@@ -285,6 +224,19 @@ gclkConfig.bit.RUNSTDBY = 0;
285
224
GCLK -> GENCTRL [0 ].reg = gclkConfig .reg ;
286
225
gclk_gen_sync (0 );
287
226
GCLK -> GENCTRL [0 ].reg |= GCLK_GENCTRL_GENEN ;
227
+
228
+ //OSC32KCTRL->XOSC32K.bit.ONDEMAND = 1; // enable xosc32k to be ondemand
229
+ //
230
+ //prepare OSC16M to always run in 4MHz mode
231
+ // going to use it when we go to sleep
232
+
233
+ OSCCTRL -> OSC16MCTRL .bit .ENABLE = 0 ;
234
+ OSCCTRL -> OSC16MCTRL .bit .FSEL = OSCCTRL_OSC16MCTRL_FSEL_4_Val ;
235
+ OSCCTRL -> OSC16MCTRL .bit .RUNSTDBY = 1 ;
236
+ OSCCTRL -> OSC16MCTRL .bit .ONDEMAND = 0 ;
237
+
238
+ OSCCTRL -> OSC16MCTRL .reg |= OSCCTRL_OSC16MCTRL_ENABLE ;
239
+
288
240
/* CPU and BUS clocks */
289
241
MCLK -> BUPDIV .reg = MCLK_BUPDIV_BUPDIV_DIV1 ;/** Divide Main clock by one */
290
242
MCLK -> LPDIV .reg = MCLK_LPDIV_LPDIV_DIV1 ; /** Divide low power clock by 1*/
0 commit comments