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,6 +52,24 @@ void SystemInit( void )
51
52
/* Turn on the digital interface clock */
52
53
PM -> APBAMASK .reg |= PM_APBAMASK_GCLK ;
53
54
55
+
56
+ #if defined(CRYSTALLESS )
57
+
58
+ /* ----------------------------------------------------------------------------------------------
59
+ * 1) Enable OSC32K clock (Internal 32.768Hz oscillator)
60
+ */
61
+
62
+ uint32_t calib = (* ((uint32_t * ) FUSES_OSC32K_CAL_ADDR ) & FUSES_OSC32K_CAL_Msk ) >> FUSES_OSC32K_CAL_Pos ;
63
+
64
+ SYSCTRL -> OSC32K .reg = SYSCTRL_OSC32K_CALIB (calib ) |
65
+ SYSCTRL_OSC32K_STARTUP ( 0x6u ) | // cf table 15.10 of product datasheet in chapter 15.8.6
66
+ SYSCTRL_OSC32K_EN32K |
67
+ SYSCTRL_OSC32K_ENABLE ;
68
+
69
+ while ( (SYSCTRL -> PCLKSR .reg & SYSCTRL_PCLKSR_OSC32KRDY ) == 0 ); // Wait for oscillator stabilization
70
+
71
+ #else // has crystal
72
+
54
73
/* ----------------------------------------------------------------------------------------------
55
74
* 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator)
56
75
*/
@@ -63,6 +82,8 @@ void SystemInit( void )
63
82
/* Wait for oscillator stabilization */
64
83
}
65
84
85
+ #endif
86
+
66
87
/* Software reset the module to ensure it is re-initialized correctly */
67
88
/* Note: Due to synchronization, there is a delay from writing CTRL.SWRST until the reset is complete.
68
89
* CTRL.SWRST and STATUS.SYNCBUSY will both be cleared when the reset is complete, as described in chapter 13.8.1
@@ -85,8 +106,12 @@ void SystemInit( void )
85
106
}
86
107
87
108
/* Write Generic Clock Generator 1 configuration */
88
- GCLK -> GENCTRL .reg = GCLK_GENCTRL_ID ( GENERIC_CLOCK_GENERATOR_XOSC32K ) | // Generic Clock Generator 1
109
+ GCLK -> GENCTRL .reg = GCLK_GENCTRL_ID ( GENERIC_CLOCK_GENERATOR_OSC32K ) | // Generic Clock Generator 1
110
+ #if defined(CRYSTALLESS )
111
+ GCLK_GENCTRL_SRC_OSC32K | // Selected source is Internal 32KHz Oscillator
112
+ #else
89
113
GCLK_GENCTRL_SRC_XOSC32K | // Selected source is External 32KHz Oscillator
114
+ #endif
90
115
// GCLK_GENCTRL_OE | // Output clock to a pin for tests
91
116
GCLK_GENCTRL_GENEN ;
92
117
@@ -130,6 +155,41 @@ void SystemInit( void )
130
155
/* Wait for synchronization */
131
156
}
132
157
158
+ #if defined(CRYSTALLESS )
159
+
160
+ #define NVM_SW_CALIB_DFLL48M_COARSE_VAL 58
161
+ #define NVM_SW_CALIB_DFLL48M_FINE_VAL 64
162
+
163
+ // Turn on DFLL
164
+ uint32_t coarse = ( * ((uint32_t * )(NVMCTRL_OTP4 ) + (NVM_SW_CALIB_DFLL48M_COARSE_VAL / 32 )) >> (NVM_SW_CALIB_DFLL48M_COARSE_VAL % 32 ) )
165
+ & ((1 << 6 ) - 1 );
166
+ if (coarse == 0x3f ) {
167
+ coarse = 0x1f ;
168
+ }
169
+ uint32_t fine = ( * ((uint32_t * )(NVMCTRL_OTP4 ) + (NVM_SW_CALIB_DFLL48M_FINE_VAL / 32 )) >> (NVM_SW_CALIB_DFLL48M_FINE_VAL % 32 ) )
170
+ & ((1 << 10 ) - 1 );
171
+ if (fine == 0x3ff ) {
172
+ fine = 0x1ff ;
173
+ }
174
+
175
+ SYSCTRL -> DFLLVAL .bit .COARSE = coarse ;
176
+ SYSCTRL -> DFLLVAL .bit .FINE = fine ;
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
+
133
193
/* Write full configuration to DFLL control register */
134
194
SYSCTRL -> DFLLCTRL .reg |= SYSCTRL_DFLLCTRL_MODE | /* Enable the closed loop mode */
135
195
SYSCTRL_DFLLCTRL_WAITLOCK |
@@ -149,6 +209,8 @@ void SystemInit( void )
149
209
/* Wait for locks flags */
150
210
}
151
211
212
+ #endif
213
+
152
214
while ( (SYSCTRL -> PCLKSR .reg & SYSCTRL_PCLKSR_DFLLRDY ) == 0 )
153
215
{
154
216
/* Wait for synchronization */
0 commit comments