Skip to content

Commit 11386ce

Browse files
committed
add DFLL closed loop support in addition to crystalless configuration options
1 parent 26c39c0 commit 11386ce

1 file changed

Lines changed: 49 additions & 10 deletions

File tree

cores/arduino/startup.c

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,42 +109,81 @@ void SystemInit( void )
109109
/* Wait for synchronization */
110110
}
111111

112-
/* DFLL Configuration in Open Loop mode */
113-
112+
#ifdef CRYSTALLESS
113+
/* DFLL Configuration in Open Loop mode with USB clock recovery */
114+
114115
OSCCTRL->DFLLCTRLA.reg = 0;
115-
//GCLK->PCHCTRL[OSCCTRL_GCLK_ID_DFLL48].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK3_Val);
116-
116+
117117
OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_CSTEP( 0x1 ) |
118118
OSCCTRL_DFLLMUL_FSTEP( 0x1 ) |
119119
OSCCTRL_DFLLMUL_MUL( 0 );
120-
120+
121121
while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLMUL )
122122
{
123123
/* Wait for synchronization */
124124
}
125-
125+
126126
OSCCTRL->DFLLCTRLB.reg = 0;
127127
while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLCTRLB )
128128
{
129129
/* Wait for synchronization */
130130
}
131-
131+
132132
OSCCTRL->DFLLCTRLA.reg |= OSCCTRL_DFLLCTRLA_ENABLE;
133133
while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_ENABLE )
134134
{
135135
/* Wait for synchronization */
136136
}
137-
137+
138138
OSCCTRL->DFLLVAL.reg = OSCCTRL->DFLLVAL.reg;
139139
while( OSCCTRL->DFLLSYNC.bit.DFLLVAL );
140-
140+
141141
OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_WAITLOCK |
142142
OSCCTRL_DFLLCTRLB_CCDIS | OSCCTRL_DFLLCTRLB_USBCRM ;
143-
143+
144144
while ( !OSCCTRL->STATUS.bit.DFLLRDY )
145145
{
146146
/* Wait for synchronization */
147147
}
148+
#else
149+
/* DFLL Configuration in Closed Loop mode against XOSC32K (via GCLK3) */
150+
151+
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_DFLL48].reg = GCLK_PCHCTRL_CHEN |
152+
GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK3_Val);
153+
154+
OSCCTRL->DFLLCTRLA.reg = 0;
155+
156+
// MUL = round(48000000 / 32768) = 1465 -> DFLL targets 48,005,120 Hz
157+
OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_CSTEP( 1 ) |
158+
OSCCTRL_DFLLMUL_FSTEP( 1 ) |
159+
OSCCTRL_DFLLMUL_MUL( (48000000UL + 16384UL) / 32768UL );
160+
161+
while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLMUL )
162+
{
163+
/* Wait for synchronization */
164+
}
165+
166+
OSCCTRL->DFLLCTRLB.reg = 0;
167+
while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLCTRLB )
168+
{
169+
/* Wait for synchronization */
170+
}
171+
172+
OSCCTRL->DFLLCTRLA.reg |= OSCCTRL_DFLLCTRLA_ENABLE;
173+
while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_ENABLE )
174+
{
175+
/* Wait for synchronization */
176+
}
177+
178+
OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_MODE |
179+
OSCCTRL_DFLLCTRLB_WAITLOCK;
180+
181+
while ( (OSCCTRL->STATUS.reg & (OSCCTRL_STATUS_DFLLRDY | OSCCTRL_STATUS_DFLLLCKC))
182+
!= (OSCCTRL_STATUS_DFLLRDY | OSCCTRL_STATUS_DFLLLCKC) )
183+
{
184+
/* Wait for synchronization and coarse lock */
185+
}
186+
#endif
148187

149188
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_1M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_DIV(48u);
150189

0 commit comments

Comments
 (0)