Cannot change SAMD21 to closed-loop

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I wanted to use SAM D21 with DFLL48 clock configured in closed-loop mode. I decided to use the following scheme:

 

XOSC (24MHz in my case) -> GCLK1 (divider set to output 32kHz) -> DFLL48 -> GCLK0 -> CPU

 

To understand how to properly use SAM D21 clock system i used tutorial provided by microchip on their developer help and run the code provided by them on the SAMDA1 Xplained dev board since the clock system is the same as in the SAMD21 mcu.

 

So using that example I've came up with the following code:

uint32_t tempDfllCalibration;
//Set GCLK1 as DFLL reference
GCLK_CLKCTRL_Type gclk_clkctrl =
{
    .bit.WRTLOCK = 0,
    .bit.CLKEN = 1,
    .bit.GEN = 3,
    .bit.ID = GCLK_CLKCTRL_ID_DFLL48
};

GCLK->CLKCTRL.reg = gclk_clkctrl.reg;
while(GCLK->STATUS.bit.SYNCBUSY);

//Enable DFLL48 in open-loop
while(!SYSCTRL->PCLKSR.bit.DFLLRDY);
SYSCTRL->DFLLCTRL.reg = (uint16_t)(SYSCTRL_DFLLCTRL_ENABLE);
while(!SYSCTRL->PCLKSR.bit.DFLLRDY);

//Set DFLL48 multiplayer and max steps
      SYSCTRL->DFLLMUL.reg =
         (uint32_t) (SYSCTRL_DFLLMUL_CSTEP(31) |
         SYSCTRL_DFLLMUL_FSTEP(511) |
         SYSCTRL_DFLLMUL_MUL(1500));

while(!SYSCTRL->PCLKSR.bit.DFLLRDY);

//Load calibration from NVM
tempDfllCalibration = *(uint32_t*)FUSES_DFLL48M_COARSE_CAL_ADDR;
tempDfllCalibration &= FUSES_DFLL48M_COARSE_CAL_Msk;
tempDfllCalibration = tempDfllCalibration >> FUSES_DFLL48M_COARSE_CAL_Pos;

SYSCTRL->DFLLVAL.bit.COARSE = tempDfllCalibration;
while(!SYSCTRL->PCLKSR.bit.DFLLRDY);

//Switch DFLL48 to close-loop and enable waitlock
SYSCTRL->DFLLCTRL.reg =
    (uint16_t)SYSCTRL_DFLLCTRL_MODE |
    SYSCTRL_DFLLCTRL_ENABLE |
    SYSCTRL_DFLLCTRL_WAITLOCK;

The problem is that it seems like it does not goes into the closed-loop mode. I suspect that because I observed generated signals under oscilloscope and with SAM D21 the frequency is around 47MHz similarly to SAMDA1 board put in the open-loop mode.

What is more, I had to remove setting WAITLOCK bit in the DFLLCTRL register, because it was crashing my debug session everytime I ran it.

 

I think that both GCLK1 and XOSC are configured properly, because when I redirected GCLK1 directly into GCLK0 and observed the signal on the oscilloscope, which gave me clear, pretty 32kHz. I've also changed NVM wait states to 1, based on table from datasheet so that is not the case neither.

 

How can I solve this?

Last Edited: Mon. Oct 11, 2021 - 10:25 AM