SAMD21 GCLK->CLKCTRL.CLKEN not getting set

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I reported a similar problem some time ago, but never got an answer which made it work

The device is a SAMD21G21A in a Sparkfun breakout board

GCLK2 GENDIV and GENCTRL is set up and enabled, but no peripherals have been changed from the default settings yet

The code is:

  GCLK_CLKCTRL_Type gclk_clkctrl;

  gclk_clkctrl.bit.ID     = GCLK_CLKCTRL_ID_TCC0_TCC1_Val;
  gclk_clkctrl.bit.CLKEN  = 1;
  gclk_clkctrl.bit.GEN    = GCLK_CLKCTRL_GEN_GCLK2_Val;
  GCLK->CLKCTRL.reg       = gclk_clkctrl.reg; // 16-bit write */

After execution GCLK->CLKCTRL.CLKEN is not set.

A surprising finding:

If I change the generic clock ID from GCLK_CLKCTRL_ID_TCC0_TCC1_Val to GCLK_CLKCTRL_ID_TCC2_TC3_Val then CLKEN is set!

There's nothing in the Errata document about this

It works OK for SERCOM0 and SERCOM4 as well

What now?

Jerry

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do the following (Ignore the C21 related stuff):

	system_interrupt_enter_critical_section();
	#if (SAMC21)
	if (serc_offset == 5) {
		serc_offset = 6;	//skip 24. its not a real position
	}
	GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE+serc_offset].reg |= GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN;	//SAMC21, 	//clk gen 0
	
	#elif (SAMD21)
	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SERCOM0_GCLK_ID_CORE + serc_offset) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);	//SAMD21, 	//clk gen 0
	#endif // (SAMC21)
	system_interrupt_leave_critical_section();

 

Note that i use the in-built system interrupts for atomic access.

---------

And I also set everything in a single operation. Many of the inbuilt registers I had issues writing to the individual bits, some of the registers even go as far to say (sometimes) bit 1 must be written within 2 clock cycles of bit 2. Now while the compiler might jump in there and put it into a single operation, it doesn't always.

 

Though now that I reread how you set your register, you do it in a single operation. Perhaps just try using the macros for something different?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Unfortunately this doesn't fix the problem. I also checked that the register values used were as expected

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  GCLK_CLKCTRL_Type gclk_clkctrl;
  gclk_clkctrl.reg = 0;    //** Perhaps ***
  gclk_clkctrl.bit.ID     = GCLK_CLKCTRL_ID_TCC0_TCC1_Val;
  gclk_clkctrl.bit.CLKEN  = 1;
  gclk_clkctrl.bit.GEN    = GCLK_CLKCTRL_GEN_GCLK2_Val;
  GCLK->CLKCTRL.reg       = gclk_clkctrl.reg; // 16-bit write */

If gclk_clkctrl is a local variable, then declaring it does not initialize it to any known value.

Possibly resulting in random values and random behavior.   Now, you set nearly ever field that is defined, but I'd still feel better if you initialized the whole contents...

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:
If gclk_clkctrl is a local variable, then declaring it does not initialize it to any known value.

Thanks for the suggestion, but GCLK->CLKCTRL.CLKEN still didn't get set. As noted above, CLKEN did get set if ID was equal to GCLK_CLKCTRL_ID_TCC2_TC3_Val, as well as other for peripherals.

Very puzzled!

Jerry

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

REG_GCLK_CLKCTRL =    GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC0_TCC1 | GCLK_CLKCTRL_CLKEN;

 

That is working on my SAMD, change GCLK_CLKCTRL_GEN_GCLK0 to your clock domain: GCLK_CLKCTRL_GEN_GCLK2

 

Flo1991

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Flo1991 wrote:

REG_GCLK_CLKCTRL =    GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC0_TCC1 | GCLK_CLKCTRL_CLKEN;

That is working on my SAMD, change GCLK_CLKCTRL_GEN_GCLK0 to your clock domain: GCLK_CLKCTRL_GEN_GCLK2

 

Flo1991

Thanks for the suggestion, but on my SAMD21G18A it didn't work, very odd! I'll investigate it further

Jerry

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have never polled to have CLKEN set, nor does the ASF 3 gclk driver (it polls it when disabling but not when enabling). Atmel Start code is also not polling for CLKEN. Fact is when I debug a start project it looks like CLKEN reads 0 (in the debugger IO window) until the TCC is enabled. 

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lajon wrote:
Fact is when I debug a start project it looks like CLKEN reads 0 (in the debugger IO window) until the TCC is enabled. 

Hello Lars,

     That fixed it! Your encyclopedic knowledge of the processor has saved lots of users

I wrote a little test program, no other peripherals than TCC0 needed to be enabled so that the corresponding GCLK->CLKCTRL.CLKEN was read as 1

Thanks very much for your help,

Jerry