This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RM48L952: Recovery from main oscillator failure

Part Number: RM48L952

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

  • Hello Vitality,

    Did you clear the RFSLIP and FBSLIP status flags in GLBSTAT? The PLL slip bits may be set on the OSCIN failure.

  • Hello.
    Yes, I tried to write 0x301 to GLBSTAT. It does no matter, bit 0 is not cleared.
  • Hello Vitaliy,

    I run your code, and bit 0 of GLBSTAT is cleared.

    1. load program, and run to main

    2. Add a breakpoint at switchToHfLpo();

    2. short the OSC to generate OSC failure

    3. run the code, it should enter the if() loop, and stop at switchToHfLpo()

    4. restore OSC (remove the short wire)

    5. run the code to the end

    6. check the register of GLBSTAT, it should be 0x00

    By the way,  clear the PFF slip error bits in clearOSCFail():

    static void clearOscfail()

    {

       /* Clear Global Status Register */

       systemREG1->GBLSTAT = 0x301U;

    }

  • Hello, QJ Wang!

    My project is still not working.

    Do you use my version of function switchToHfLpo()?

    I did some research and find something usefull. Look at code:

    static void switchToHfLpo()
    {
        systemREG1->GHVSRC = (uint32)((uint32)SYS_LPO_HIGH << 24U)
                           | (uint32)((uint32)SYS_LPO_HIGH << 16U)
                           | (uint32)((uint32)SYS_LPO_HIGH << 0U);
    #if 1 /* disable from compilation to reset GLBSTAT.0; else if compiled then GLBSTAT.0 is not cleared */
        systemREG1->VCLKASRC = (uint32)((uint32)SYS_LPO_HIGH << 0U);
    #endif
    }

    If I disable change of VCLKASRC register then GLBSTAT.0 is cleared. If I change VCLKASRC to HF LPO then GLBSTAT.0 is not cleared.

    Here is my project. It is based on GCC, but this does no matter. Code runs from RAM, so in debug session you need to set PC to 0x08000000 after code download (before start program).

    7242.civl6.zip