SAMD 48 MHz Clock

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

  1. Start the XOSC32K

  2. Start Clock Generator 3 and use XOSC32K as source

  3. Use ClockGen3 for DFLL48M

  4. Use DFLL48M for Clock Generator 0

Ups, the magic with open loop - close loop... :slightly_smiling_face:
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. Im 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

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. :slightly_smiling_face:
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.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.