leo72:
I followed a simpler way.
Before to use the RTC, I switch to the 32 kHz with this 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
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!
/**
* \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));
}