Pages: [1]   Go Down
Author Topic: Slow Clock External Crystal is Not Used - BUG  (Read 2018 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It seems that even though it is present on the board as Y2 and fully connected, the slow clock is driven by the internal RC oscillator and not the external crystal. Y1 seems to be a pretty high-quality part, why is it not used? Power reasons?

To turn it on, put the code below into the init() function in <arduino directory>/hardware/arduino/sam/variants/arduino_due_x/variant.cpp. I would put it somewhere after the first two commands that set the frequency.

Code:
pmc_switch_sclk_to_32kxtal(0);

while (!pmc_osc_is_ready_32kxtal()) {}


« Last Edit: September 25, 2013, 01:08:21 pm by m3741 » Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It would be more useful if you make a pull request in Github for a piece of code that fixes this bug or just open an issue to let the team know about it  smiley-wink
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

PS:
it seems that this mod doesn't work.. Not only the source for Slow Clock remains set to the internal RC (I can see it through the SUPC_SR register via the OSCSEL bit) but also the RTC doesn't run any more.
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I followed a simpler way.
Before to use the RTC, I switch to the 32 kHz with this code:
Code:
SUPC->SUPC_CR = ((((uint32_t)(0xA5)) << 24) | (SUPC_CR_XTALSEL));
This sets the source clock of the Slow Clock Generator to the external clock (0xA5 is the password that MUST be written into the SUPC_CR register otherwhise the chip won't execute the switch).

The datasheet suggests to wait for the chip changes the source clock by monitoring the change of the OSCSEL bit in SUPC_SR register. when that bit will be set to 1, the chip has done the change. This can be done with this code after the preivous code
Code:
while ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL);
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

PS:
the 32 kHz crystal is labeled Y2, not Y1.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

PS:
the 32 kHz crystal is labeled Y2, not Y1.

Good catch; post edited. Thanks!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I followed a simpler way.
Before to use the RTC, I switch to the 32 kHz with this code:
Code:
SUPC->SUPC_CR = ((((uint32_t)(0xA5)) << 24) | (SUPC_CR_XTALSEL));
This sets the source clock of the Slow Clock Generator to the external clock (0xA5 is the password that MUST be written into the SUPC_CR register otherwhise the chip won't execute the switch).

The datasheet suggests to wait for the chip changes the source clock by monitoring the change of the OSCSEL bit in SUPC_SR register. when that bit will be set to 1, the chip has done the change. This can be done with this code after the preivous code
Code:
while ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL);


Just to be clear, I'm now looking at the 1.5.4 tag from github.

Actually, if you look at the function pmc_switch_sclk_to_32kxtal() in hardware/arduino/sam/system/libsam/source/pmc.c it does the exact same thing as the code you listed above. Since your answer is duplicating work, I fail to see how it is simpler.

You are very correct that I was not waiting for the chip to complete the change. It did work fine for me without waiting for that bit, but I can see why it may not work. There is a function for this too in pmc.c, pmc_osc_is_ready_32kxtal(void). I've amended my post to fix this oversight.

I agree that I need to submit a pull request. I'm just not at a computer where that's possible at the moment. I'll get off my lazy butt here shortly and do so.

Thanks!

Code:
/**
* \brief Switch slow clock source selection to external 32k (Xtal or Bypass).
*
* \note This function disables the PLLs.
*
* \note Switching SCLK back to 32krc is only possible by shutting down the VDDIO
* power supply.
*
* \param ul_bypass 0 for Xtal, 1 for bypass.
*/
void pmc_switch_sclk_to_32kxtal(uint32_t ul_bypass)
{
  /* Set Bypass mode if required */
  if (ul_bypass == 1) {
    SUPC->SUPC_MR |= SUPC_MR_KEY(SUPC_KEY_VALUE) |
    SUPC_MR_OSCBYPASS;
  }

  SUPC->SUPC_CR |= SUPC_CR_KEY(SUPC_KEY_VALUE) | SUPC_CR_XTALSEL;
}

/**
* \brief Check if the external 32k Xtal is ready.
*
* \retval 1 External 32k Xtal is ready.
* \retval 0 External 32k Xtal is not ready.
*/
uint32_t pmc_osc_is_ready_32kxtal(void)
{
  return ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) && (PMC->PMC_SR & PMC_SR_OSCSELS));
}
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Actually, if you look at the function pmc_switch_sclk_to_32kxtal() in hardware/arduino/sam/system/libsam/source/pmc.c it does the exact same thing as the code you listed above. Since your answer is duplicating work, I fail to see how it is simpler.
When I first tried your suggestion, I put the function in the point you suggested in your first post, and it didn't work. So, I read the datasheet and found the register & bit that enabled the external clock and used it. It was "simpler" for me instead of looking the whole core trying to find what that piece of code did  smiley-wink

Quote
You are very correct that I was not waiting for the chip to complete the change. It did work fine for me without waiting for that bit
I agree. It can work (it worked fine for me too) but the datasheet "suggests" to wait the change so I think it's better if we "follow" that suggestion  smiley-sweat

Quote
Thanks!
You're welcome  smiley-surprise
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When I first tried your suggestion, I put the function in the point you suggested in your first post, and it didn't work.

Out of curiosity, where did you put it so it worked for you?
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

To be honest, I tried a couple of points. After the line that disables the watchdog, and before the initialization of the analog controller.
I didn't remember the exact points.

Logged


Pages: [1]   Go Up
Jump to: