Hello!
How to recover from main oscillator failure?
Actions from TRM (chapter "Recovery from Oscillator Failure") are not working: GLBSTAT.0 is set at one after oscillator fail and not resetted to zero after remove fail condition.
Some code:
static bool isMainOscillatorFailed()
{
const uint32_t* GLBSSTAT_address = reinterpret_cast<const uint32_t* >(0xFFFFFFECUL);
return (*GLBSSTAT_address) & 1;
}
static void switchToHfLpo()
{
systemREG1->GHVSRC = (uint32)((uint32)SYS_LPO_HIGH << 24U)
| (uint32)((uint32)SYS_LPO_HIGH << 16U)
| (uint32)((uint32)SYS_LPO_HIGH << 0U);
systemREG1->VCLKASRC = (uint32)((uint32)SYS_LPO_HIGH << 0U);
systemREG1->RCLKSRC &= ~0x0F;
systemREG1->RCLKSRC |= SYS_LPO_HIGH;
}
static void disableMainOscillator()
{
systemREG1->CSDISSET = 0x00000001U;
while((systemREG1->CSDIS & 0x01U) != 0x01U) {
;
}
}
static void enableMainOscillator()
{
systemREG1->CSDISCLR = 0x00000001U;
}
static void clearOscfail()
{
/* Clear Global Status Register */
systemREG1->GBLSTAT = 0x1U;
}
static void switchToMainOscillator()
{
systemREG1->GHVSRC = (uint32)((uint32)SYS_OSC << 24U)
| (uint32)((uint32)SYS_OSC << 16U)
| (uint32)((uint32)SYS_OSC << 0U);
}
void check()
{
if (isMainOscillatorFailed()) {
switchToHfLpo();
disableMainOscillator();
enableMainOscillator();
clearOscfail();
switchToMainOscillator();
}
}
I not use PLL1 or PLL2. Main oscillator frequency is 12 MHz.
Function clearOscfail() is not reset GLBSTAT.0 even if main oscillator is working after removing fail condition (oscillator short-circuit, in my example). How can I reset GLBSTAT.0?
What I did wrong?
Regards,
Vitaliy