Skip to content

Commit 06ae208

Browse files
ladyadacmaglie
authored andcommitted
fix for crystal-less startup stability
1 parent b50f475 commit 06ae208

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

cores/arduino/startup.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void SystemInit( void )
139139
/* DFLL Configuration in Closed Loop mode, cf product datasheet chapter 15.6.7.1 - Closed-Loop Operation */
140140

141141
/* Remove the OnDemand mode, Bug http://avr32.icgroup.norway.atmel.com/bugzilla/show_bug.cgi?id=9905 */
142-
SYSCTRL->DFLLCTRL.bit.ONDEMAND = 0 ;
142+
SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE;
143143

144144
while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
145145
{
@@ -158,27 +158,35 @@ void SystemInit( void )
158158
#if defined(CRYSTALLESS)
159159

160160
#define NVM_SW_CALIB_DFLL48M_COARSE_VAL 58
161-
#define NVM_SW_CALIB_DFLL48M_FINE_VAL 64
162161

163162
// Turn on DFLL
164163
uint32_t coarse =( *((uint32_t *)(NVMCTRL_OTP4) + (NVM_SW_CALIB_DFLL48M_COARSE_VAL / 32)) >> (NVM_SW_CALIB_DFLL48M_COARSE_VAL % 32) )
165164
& ((1 << 6) - 1);
166165
if (coarse == 0x3f) {
167166
coarse = 0x1f;
168167
}
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-
}
168+
// TODO(tannewt): Load this value from memory we've written previously. There
169+
// isn't a value from the Atmel factory.
170+
uint32_t fine = 0x1ff;
174171

175172
SYSCTRL->DFLLVAL.bit.COARSE = coarse;
176173
SYSCTRL->DFLLVAL.bit.FINE = fine;
177174
/* Write full configuration to DFLL control register */
178-
SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_USBCRM | /* USB correction */
175+
SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 0x1f / 4 ) | // Coarse step is 31, half of the max value
176+
SYSCTRL_DFLLMUL_FSTEP( 10 ) |
177+
SYSCTRL_DFLLMUL_MUL( (48000) ) ;
178+
179+
SYSCTRL->DFLLCTRL.reg = 0;
180+
181+
while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
182+
{
183+
/* Wait for synchronization */
184+
}
185+
186+
SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_MODE |
179187
SYSCTRL_DFLLCTRL_CCDIS |
180-
SYSCTRL_DFLLCTRL_WAITLOCK |
181-
SYSCTRL_DFLLCTRL_QLDIS ; /* Disable Quick lock */
188+
SYSCTRL_DFLLCTRL_USBCRM | /* USB correction */
189+
SYSCTRL_DFLLCTRL_BPLCKC;
182190

183191
while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
184192
{

0 commit comments

Comments
 (0)