Hi All!
I have an M0 clone from RobotDyne (M0-mini).
I have to use relatively stable system oscillator in my project.
However, the board has it`s internal 8MHz RC as a reference for a 48MHz DFLL.
I switched the divided internal clock (~12MHz) to the external pin and have a pretty big jitter on it.
// Set the clock generator 5's divisor to 4 (48Mhz / 4 = 12MHz)
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(4) | // Set the clock divisor to 4 => 12 MHz
GCLK_GENDIV_ID(5); // Set the clock generator ID to 5
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for the bus to synchronise
// Connect he 48MHz clock source to generic clock generator 5 and enable its outputs
REG_GCLK_GENCTRL = GCLK_GENCTRL_OE | // Enable the generic clock 5's outputs
GCLK_GENCTRL_IDC | // Ensure the duty cycle is about 50-50 high-low
GCLK_GENCTRL_GENEN | // Enable the clock generator 5
GCLK_GENCTRL_SRC_DFLL48M | // Set source to be 48MHz (_DFLL48M) clock Note: for 8MHz source use GCLK_GENCTRL_SRC_OSC8M
GCLK_GENCTRL_ID(5); // Set the clock generator ID to 5
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for the bus to synchronise
// Output the clock on digital pin 7 (chosen as it happens to be one of generic clock 5's outputs)
// Enable the port multiplexer (mux) on digital pin 7
PORT->Group[g_APinDescription[7].ulPort].PINCFG[g_APinDescription[7].ulPin].bit.PMUXEN = 1;
// Switch port mux to peripheral function H - generic clock I/O
// Set the port mux mask for odd processor pin numbers, D7 = PA21 = 21 is odd number, PMUXO = PMUX Odd
PORT->Group[g_APinDescription[7].ulPort].PMUX[g_APinDescription[7].ulPin >> 1].reg |= PORT_PMUX_PMUXO_H;
So, looks like I need to switch the DFLL reference to XOSC32K and divider to 1465.
I found only a way to change the conf_clocks.h (and recompile and reburn the bootloader?) in the internet.
Can somebody advise me a correct way to change the SAMD21 clock settings form the Arduino sketch?
0.01uf (or less) CAP may help.
To change the internal FLL setup???
FYI: Normally RC does not produce clean edges of the real square. But you can have quick try, its does not hurt?
After a division we don't deal with the input clock but the toggle flip-flops.
I use this code on my Arduino Zero to reference DFLL48 from the low speed external 32kHz crystal
// enable 1 wait state required at 3.3V 48 MHz
REG_NVMCTRL_CTRLB = NVMCTRL_CTRLB_MANW | NVMCTRL_CTRLB_RWS_HALF;
/*****************************************************
start external crystal XOSC32K, must disable first
*****************************************************/
REG_SYSCTRL_XOSC32K = SYSCTRL_XOSC32K_STARTUP(0x7) | SYSCTRL_XOSC32K_RUNSTDBY | SYSCTRL_XOSC32K_AAMPEN | SYSCTRL_XOSC32K_EN32K | SYSCTRL_XOSC32K_XTALEN;
REG_SYSCTRL_XOSC32K |= SYSCTRL_XOSC32K_ENABLE;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_XOSC32KRDY)) == 0);
// CLOCK GENERATOR 3, use external XOSC32K (DFLL48M reference)
REG_GCLK_GENCTRL = GCLK_GENCTRL_ID(0x3);
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | GCLK_GENDIV_ID(0x3);
REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(0x3);
while(REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY);
/*******************************************************************
Initialize CPU to run at 48MHz using the DFLL48M
Reference the XOSC32K on ClockGen3
*******************************************************************/
// change reference of DFLL48M to generator 3
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK3 | GCLK_CLKCTRL_ID_DFLL48;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_DFLLRDY)) == 0);
// enable open loop
REG_SYSCTRL_DFLLCTRL = SYSCTRL_DFLLCTRL_ENABLE;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_DFLLRDY)) == 0);
// set DFLL multipliers
REG_SYSCTRL_DFLLMUL = SYSCTRL_DFLLMUL_CSTEP(31) | SYSCTRL_DFLLMUL_FSTEP(511) | SYSCTRL_DFLLMUL_MUL(1465);
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_DFLLRDY)) == 0);
// get factory calibrated value for DFLL_COARSE/FINE from NVM Software Calibration Area
uint32_t dfllCoarse_calib = *(uint32_t*) FUSES_DFLL48M_COARSE_CAL_ADDR;
dfllCoarse_calib &= FUSES_DFLL48M_COARSE_CAL_Msk;
dfllCoarse_calib = dfllCoarse_calib >> FUSES_DFLL48M_COARSE_CAL_Pos;
uint32_t dfllFine_calib = *(uint32_t*) FUSES_DFLL48M_FINE_CAL_ADDR;
dfllFine_calib &= FUSES_DFLL48M_FINE_CAL_Msk;
dfllFine_calib = dfllFine_calib >> FUSES_DFLL48M_FINE_CAL_Pos;
REG_SYSCTRL_DFLLVAL = dfllCoarse_calib << SYSCTRL_DFLLVAL_COARSE_Pos | dfllFine_calib << SYSCTRL_DFLLVAL_FINE_Pos;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_DFLLRDY)) == 0);
// enable close loop
REG_SYSCTRL_DFLLCTRL |= SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_WAITLOCK;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_DFLLRDY)) == 0);
// change CLOCK GENERATOR 0 reference to DFLL48M
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | GCLK_GENDIV_ID(0x0);
REG_GCLK_GENCTRL = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(0x0);
while(REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY);
The first line is required if you are going to run 48MHz on the SAMD21. The basic step is
Start the XOSC32K
Start Clock Generator 3 and use XOSC32K as source
Use ClockGen3 for DFLL48M
Use DFLL48M for Clock Generator 0
Ups, the magic with open loop - close loop...
Thanks a lot, I will try tomorrow.
Dear hzrnby,
Unfortunately the code you shared here does not work "as is".
The XOSC32K initialization goes well, I checked by redirecting it`s output to the external pin.
I tried to comment it block by block and configured out that it starts to reset by WDT after
REG_SYSCTRL_DFLLVAL = dfllCoarse_calib << SYSCTRL_DFLLVAL_COARSE_Pos | dfllFine_calib << SYSCTRL_DFLLVAL_FINE_Pos;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_DFLLRDY)) == 0);
being enabled.
May be the M0 has some startup initialization differences which may be conflicting with your setup?
May be it`s necessary to use clock generator 1?
Regards!
Do you have a proper debugger like a JLINK SWD? The values that goes to here are just factory calibration determined when the chip is manufactured. You can get those values manually by reading the fuse bits
The just write it manually
REG_SYSCTRL_DFLLVAL = 0x18 << SYSCTRL_DFLLVAL_COARSE_Pos | 0x0200 << SYSCTRL_DFLLVAL_FINE_Pos;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_DFLLRDY)) == 0);
It's also possible that the manual clock configuration is conflicting with what the bootloader is configured. Considering that you already have WDT running tells me that the clock registers are already configured to some degree.
You can skip loading those calibration values and see if the performance is acceptable
This is my own clock initialization for the SAMD21. I don't have any bootloader or anything so I have total control to every configuration on the clock registers
void clock_init(void)
{
// reset everything
REG_GCLK_CTRL = GCLK_CTRL_SWRST;
while(REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY);
// enable 1 wait state required at 3.3V 48 MHz
REG_NVMCTRL_CTRLB = NVMCTRL_CTRLB_MANW | NVMCTRL_CTRLB_RWS_HALF;
// remove DIV8 from OSC8M, make it run at full 8Mhz
REG_SYSCTRL_OSC8M &= ~(1<<9 | 1<<8);
/*****************************************************
start external crystal XOSC32K, must disable first
*****************************************************/
REG_SYSCTRL_XOSC32K = SYSCTRL_XOSC32K_STARTUP(0x7) | SYSCTRL_XOSC32K_RUNSTDBY | SYSCTRL_XOSC32K_AAMPEN | SYSCTRL_XOSC32K_EN32K | SYSCTRL_XOSC32K_XTALEN;
REG_SYSCTRL_XOSC32K |= SYSCTRL_XOSC32K_ENABLE;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_XOSC32KRDY)) == 0);
/*****************************************************
start internal oscillator OSC32K, must disable first
*****************************************************/
// get factory calibrated value for OSC32K from NVM Software Calibration Area
uint32_t osc32k_calib = *(uint32_t*) FUSES_OSC32K_CAL_ADDR;
osc32k_calib &= FUSES_OSC32K_CAL_Msk;
osc32k_calib = osc32k_calib >> FUSES_OSC32K_CAL_Pos;
REG_SYSCTRL_OSC32K = osc32k_calib << SYSCTRL_OSC32K_CALIB_Pos | SYSCTRL_OSC32K_STARTUP(0x7) | SYSCTRL_OSC32K_RUNSTDBY | SYSCTRL_OSC32K_EN32K;
REG_SYSCTRL_OSC32K |= SYSCTRL_OSC32K_ENABLE;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_OSC32KRDY)) == 0);
/*****************************************************
start internal OSCULP32K -->
enabled by default and always run
*****************************************************/
/*****************************************************
Initialize clock generators:
ClockGen0 --> DFLL48M
ClockGen1 --> XOSC32K --> DIV32 --> 1024 Hz
ClockGen2 --> OSC8M --> DIV1 --> 8MHz
ClockGen3 --> XOSC32K --> DIV1 --> 32K
ClockGen4 --> OSCULP32K --> DIV32 --> 1024 Hz
*****************************************************/
// CLOCK GENERATOR 1, use external XOSC32K, pre-scaled by 32 to generate 1024 Hz
REG_GCLK_GENCTRL = GCLK_GENCTRL_ID(0x1);
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(32) | GCLK_GENDIV_ID(0x1);
REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(0x1);
while(REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY);
// CLOCK GENERATOR 2, use internal OSC8M, no pre-scaling
REG_GCLK_GENCTRL = GCLK_GENCTRL_ID(0x2);
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | GCLK_GENDIV_ID(0x2);
REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSC8M | GCLK_GENCTRL_ID(0x2);
while(REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY);
// CLOCK GENERATOR 3, use external XOSC32K (DFLL48M reference)
REG_GCLK_GENCTRL = GCLK_GENCTRL_ID(0x3);
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | GCLK_GENDIV_ID(0x3);
REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(0x3);
while(REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY);
// CLOCK GENERATOR 4, use internal OSCULP32K, pre-scaled by 32 to generate 1024 Hz
REG_GCLK_GENCTRL = GCLK_GENCTRL_ID(0x4);
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(32) | GCLK_GENDIV_ID(0x4);
REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(0x4);
while(REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY);
/*****************************************************
Initialize generic clocks for peripherals:
RTC --> ClockGen1 (1024 Hz)
WDT --> ClockGen4 (1024 Hz)
SERCOM2 --> ClockGen2
SERCOM3 --> ClockGen2
SERCOM5 --> ClockGen2
TC2/3 --> ClockGen1 (1024 Hz)
TC4/5 --> ClockGen0 (48 MHz)
DFLL48M --> ClockGen3
*****************************************************/
// use clock generator 1 for RTC
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_ID_RTC;
while(REG_GCLK_CLKCTRL & 1<<14);
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_RTC;
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_RTC;
// use clock generator 4 for WDT
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_ID_WDT;
while(REG_GCLK_CLKCTRL & 1<<14);
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_GEN_GCLK4 | GCLK_CLKCTRL_ID_WDT;
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK4 | GCLK_CLKCTRL_ID_WDT;
// use clock generator 2 for SERCOM2
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_ID_SERCOM2_CORE;
while(REG_GCLK_CLKCTRL & 1<<14);
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_GEN_GCLK2 | GCLK_CLKCTRL_ID_SERCOM2_CORE;
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | GCLK_CLKCTRL_ID_SERCOM2_CORE;
// use clock generator 2 for SERCOM3
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_ID_SERCOM3_CORE;
while(REG_GCLK_CLKCTRL & 1<<14);
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_GEN_GCLK2 | GCLK_CLKCTRL_ID_SERCOM3_CORE;
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | GCLK_CLKCTRL_ID_SERCOM3_CORE;
// use clock generator 2 for SERCOM5
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_ID_SERCOM5_CORE;
while(REG_GCLK_CLKCTRL & 1<<14);
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_GEN_GCLK2 | GCLK_CLKCTRL_ID_SERCOM5_CORE;
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | GCLK_CLKCTRL_ID_SERCOM5_CORE;
// use clock generator 1 for TIMER 2 and 3
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_ID_TCC2_TC3;
while(REG_GCLK_CLKCTRL & 1<<14);
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_TCC2_TC3;
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_TCC2_TC3;
/*******************************************************************
Initialize CPU to run at 48MHz using the DFLL48M
Reference the XOSC32K on ClockGen3
*******************************************************************/
// change reference of DFLL48M to generator 3
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK3 | GCLK_CLKCTRL_ID_DFLL48;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_DFLLRDY)) == 0);
// enable open loop
REG_SYSCTRL_DFLLCTRL = SYSCTRL_DFLLCTRL_ENABLE;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_DFLLRDY)) == 0);
// set DFLL multipliers
REG_SYSCTRL_DFLLMUL = SYSCTRL_DFLLMUL_CSTEP(31) | SYSCTRL_DFLLMUL_FSTEP(511) | SYSCTRL_DFLLMUL_MUL(1465);
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_DFLLRDY)) == 0);
// get factory calibrated value for DFLL_COARSE/FINE from NVM Software Calibration Area
uint32_t dfllCoarse_calib = *(uint32_t*) FUSES_DFLL48M_COARSE_CAL_ADDR;
dfllCoarse_calib &= FUSES_DFLL48M_COARSE_CAL_Msk;
dfllCoarse_calib = dfllCoarse_calib >> FUSES_DFLL48M_COARSE_CAL_Pos;
uint32_t dfllFine_calib = *(uint32_t*) FUSES_DFLL48M_FINE_CAL_ADDR;
dfllFine_calib &= FUSES_DFLL48M_FINE_CAL_Msk;
dfllFine_calib = dfllFine_calib >> FUSES_DFLL48M_FINE_CAL_Pos;
REG_SYSCTRL_DFLLVAL = dfllCoarse_calib << SYSCTRL_DFLLVAL_COARSE_Pos | dfllFine_calib << SYSCTRL_DFLLVAL_FINE_Pos;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_DFLLRDY)) == 0);
// enable close loop
REG_SYSCTRL_DFLLCTRL |= SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_WAITLOCK;
while((REG_SYSCTRL_PCLKSR & (SYSCTRL_PCLKSR_DFLLRDY)) == 0);
// change CLOCK GENERATOR 0 reference to DFLL48M
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | GCLK_GENDIV_ID(0x0);
REG_GCLK_GENCTRL = GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(0x0);
while(REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY);
// use clock generator 0 for TIMER 4 and 5 (48 MHz)
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_ID_TC4_TC5;
while(REG_GCLK_CLKCTRL & 1<<14);
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TC4_TC5;
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TC4_TC5;
return;
}
As you can see, what I provided was just a snippet of my own full clock initialization routine. It activates a bunch of other clocks (SERCOMs, timers, RTC, WDT, etc). Some of it is probably going to conflict with some settings loaded by your bootloader.
OK,
That means the the bootloader has the ability to rewrite manual configuration time to time.
Is it so?
Yes, I have a J-Link (pretty old, may be a clone) but Im not sure about how to install and use a proper toolchain. I
m using Arduino because it`s pretty simple for a non-FE person.
It's the opposite. The bootloader already configured the clock registers and you are modifying it from your user program. Unless you can figure out what the bootloader is doing with respect to the clocking mechanism, it's hard to modify it properly without causing some issue.
Atmel Studio is free and quite easy to start with the SAMD21.
I found this snippet on the the SAMD21 bootloader
/** * \brief system_init() configures the needed clocks and according Flash Read Wait States. * At reset: * - OSC8M clock source is enabled with a divider by 8 (1MHz). * - Generic Clock Generator 0 (GCLKMAIN) is using OSC8M as source. * We need to: * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator), will be used as DFLL48M reference. * 2) Put XOSC32K as source of Generic Clock Generator 1 * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference) * 4) Enable DFLL48M clock * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. * 6) Modify PRESCaler value of OSCM to have 8MHz * 7) Put OSC8M as source for Generic Clock Generator 3 */
Thank you for the attempt,
But my question was about how to make it from an Arduino sketch,
Not how to install the Eclipse properly.
I can see the bootloader clock init in the conf_clocks.h file:
#include <clock.h>
#ifndef CONF_CLOCKS_H_INCLUDED
# define CONF_CLOCKS_H_INCLUDED
/* System clock bus configuration */
# define CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT true
# define CONF_CLOCK_FLASH_WAIT_STATES 2
# define CONF_CLOCK_CPU_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
# define CONF_CLOCK_APBA_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
# define CONF_CLOCK_APBB_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
/* SYSTEM_CLOCK_SOURCE_OSC8M configuration - Internal 8MHz oscillator */
# define CONF_CLOCK_OSC8M_PRESCALER SYSTEM_OSC8M_DIV_1
# define CONF_CLOCK_OSC8M_ON_DEMAND true
# define CONF_CLOCK_OSC8M_RUN_IN_STANDBY false
/* SYSTEM_CLOCK_SOURCE_XOSC configuration - External clock/oscillator */
# define CONF_CLOCK_XOSC_ENABLE false
# define CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL
# define CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY 12000000UL
# define CONF_CLOCK_XOSC_STARTUP_TIME SYSTEM_XOSC_STARTUP_32768
# define CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL true
# define CONF_CLOCK_XOSC_ON_DEMAND true
# define CONF_CLOCK_XOSC_RUN_IN_STANDBY false
/* SYSTEM_CLOCK_SOURCE_XOSC32K configuration - External 32KHz crystal/clock oscillator */
# define CONF_CLOCK_XOSC32K_ENABLE false
# define CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL
# define CONF_CLOCK_XOSC32K_STARTUP_TIME SYSTEM_XOSC32K_STARTUP_65536
# define CONF_CLOCK_XOSC32K_AUTO_AMPLITUDE_CONTROL false
# define CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT false
# define CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT true
# define CONF_CLOCK_XOSC32K_ON_DEMAND true
# define CONF_CLOCK_XOSC32K_RUN_IN_STANDBY false
/* SYSTEM_CLOCK_SOURCE_OSC32K configuration - Internal 32KHz oscillator */
# define CONF_CLOCK_OSC32K_ENABLE false
# define CONF_CLOCK_OSC32K_STARTUP_TIME SYSTEM_OSC32K_STARTUP_130
# define CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT true
# define CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT true
# define CONF_CLOCK_OSC32K_ON_DEMAND true
# define CONF_CLOCK_OSC32K_RUN_IN_STANDBY false
/* SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop */
# define CONF_CLOCK_DFLL_ENABLE true
# define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_USB_RECOVERY
# define CONF_CLOCK_DFLL_ON_DEMAND true
/* DFLL open loop mode configuration */
# define CONF_CLOCK_DFLL_COARSE_VALUE (0x1f / 4)
# define CONF_CLOCK_DFLL_FINE_VALUE (0xff / 4)
/* DFLL closed loop mode configuration */
# define CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR GCLK_GENERATOR_1
# define CONF_CLOCK_DFLL_MULTIPLY_FACTOR 6
# define CONF_CLOCK_DFLL_QUICK_LOCK true
# define CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK true
# define CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP true
# define CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE true
# define CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE (0x1f / 4)
# define CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE (0xff / 4)
/* SYSTEM_CLOCK_SOURCE_DPLL configuration - Digital Phase-Locked Loop */
# define CONF_CLOCK_DPLL_ENABLE false
# define CONF_CLOCK_DPLL_ON_DEMAND true
# define CONF_CLOCK_DPLL_RUN_IN_STANDBY false
# define CONF_CLOCK_DPLL_LOCK_BYPASS false
# define CONF_CLOCK_DPLL_WAKE_UP_FAST false
# define CONF_CLOCK_DPLL_LOW_POWER_ENABLE false
# define CONF_CLOCK_DPLL_LOCK_TIME SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_NO_TIMEOUT
# define CONF_CLOCK_DPLL_REFERENCE_CLOCK SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_REF0
# define CONF_CLOCK_DPLL_FILTER SYSTEM_CLOCK_SOURCE_DPLL_FILTER_DEFAULT
# define CONF_CLOCK_DPLL_REFERENCE_FREQUENCY 32768
# define CONF_CLOCK_DPLL_REFEREMCE_DIVIDER 1
# define CONF_CLOCK_DPLL_OUTPUT_FREQUENCY 48000000
/* Set this to true to configure the GCLK when running clocks_init. If set to
* false, none of the GCLK generators will be configured in clocks_init(). */
# define CONF_CLOCK_CONFIGURE_GCLK true
/* Configure GCLK generator 0 (Main Clock) */
# define CONF_CLOCK_GCLK_0_ENABLE true
# define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY true
# define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_DFLL
# define CONF_CLOCK_GCLK_0_PRESCALER 1
# define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false
/* Configure GCLK generator 1 */
# define CONF_CLOCK_GCLK_1_ENABLE false
# define CONF_CLOCK_GCLK_1_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_1_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_1_PRESCALER 1
# define CONF_CLOCK_GCLK_1_OUTPUT_ENABLE false
/* Configure GCLK generator 2 (RTC) */
# define CONF_CLOCK_GCLK_2_ENABLE true
# define CONF_CLOCK_GCLK_2_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_2_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_ULP32K
# define CONF_CLOCK_GCLK_2_PRESCALER 32
# define CONF_CLOCK_GCLK_2_OUTPUT_ENABLE false
/* Configure GCLK generator 3 */
# define CONF_CLOCK_GCLK_3_ENABLE false
# define CONF_CLOCK_GCLK_3_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_3_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_3_PRESCALER 1
# define CONF_CLOCK_GCLK_3_OUTPUT_ENABLE false
/* Configure GCLK generator 4 */
# define CONF_CLOCK_GCLK_4_ENABLE false
# define CONF_CLOCK_GCLK_4_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_4_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_4_PRESCALER 1
# define CONF_CLOCK_GCLK_4_OUTPUT_ENABLE false
/* Configure GCLK generator 5 */
# define CONF_CLOCK_GCLK_5_ENABLE false
# define CONF_CLOCK_GCLK_5_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_5_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_5_PRESCALER 1
# define CONF_CLOCK_GCLK_5_OUTPUT_ENABLE false
/* Configure GCLK generator 6 */
# define CONF_CLOCK_GCLK_6_ENABLE false
# define CONF_CLOCK_GCLK_6_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_6_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_6_PRESCALER 1
# define CONF_CLOCK_GCLK_6_OUTPUT_ENABLE false
/* Configure GCLK generator 7 */
# define CONF_CLOCK_GCLK_7_ENABLE false
# define CONF_CLOCK_GCLK_7_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_7_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_7_PRESCALER 1
# define CONF_CLOCK_GCLK_7_OUTPUT_ENABLE false
#endif /* CONF_CLOCKS_H_INCLUDED */
But I think it is not so simple. I just changed the settings after the bootloader finished, I must have the clock output on the pin even if the sketch freezes soon. But I have another behavior - looks like something returns the original clock configuration on regular basis. May be there are the core timing functions, may be not.
Unfortunately, looks like I`ll have to find another board/architecture for my project.
system
Closed
August 24, 2021, 9:44pm
12
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.