Hanging on peripheral channel during sync, datasheet error?

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

Hi all,

 

I've just been debugging an odd issue with a USART init routine for a SAMC21J18A.

 

Page 151 of the datasheet, ref 16.8.4 Peripheral Channel Control - says about Bit 6:

"This bit is used to enable and disable a Peripheral Channel.
This bit is synchronized with the GCLK domain. It will continue to read its previous state until the synchronization is
complete."

 

So, I'm setting the CHEN bit in PCHCTRL[23] equal to 1, from it's previous state of 0. I thus read the datasheet to say "CHEN will read 0 until sync is complete". But - the below code hangs on the while loop.

 

	GCLK->PCHCTRL[23].bit.CHEN = 1;		        // Enable the clock
	while (GCLK->PCHCTRL[23].bit.CHEN == 0){};	// Wait for CHEN bit to sync with GCLK domain

To be sure I'm not mad, and to prove CHEN was not already == 1, I have:

 

	volatile uint32_t previous_chen = GCLK->PCHCTRL[23].bit.CHEN;
	GCLK->PCHCTRL[23].bit.CHEN = 1;		                // Enable the clock
	while (GCLK->PCHCTRL[23].bit.CHEN == previous_chen){};	// Wait for CHEN bit to sync with GCLK domain

 

But this hangs too... and if I single step through in a debug session, previous_chen gets set to 0, as expected because the device has only just powered up.

 

So, I thought the datasheet sheet may be wrong? - because this executes just fine:

 

GCLK->PCHCTRL[23].bit.CHEN = 1;		        // Enable the clock
while (GCLK->PCHCTRL[23].bit.CHEN == 1){};	// Wait for CHEN to sync	// todo - why is this 1? previous state will be 0, so surely this should be while == 0???

 

But if I check the value of CHEN after the while, it is still 0 (which it would have to be for the above to pass...). So, rather than a datasheet error - I've just seen these registers are PAC protected. Too late in the UK now tonight, but has anybody else been bitten by PAC protected registers?

Last Edited: Thu. Nov 4, 2021 - 02:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've just noticed if I don't set GEN beforehand, I can then set CHEN.

 

	//GCLK->PCHCTRL[23].bit.GEN = 1;		        // Generic clock generator 1
	GCLK->PCHCTRL[23].bit.CHEN = 1;		            // Enable the clock
	while(GCLK->PCHCTRL[23].bit.CHEN == 0){};	    // Wait for CHEN to sync	// todo - why is this 1? previous state will be 0, so surely this should be while == 0???
	volatile chen_now = GCLK->PCHCTRL[23].bit.CHEN; // chen_now, now set to 1

 

Further datasheet digging tomorrow I think...