AnsweredAssumed Answered

K22 - can't change from FEE to FEI in case of Loss Of Clock

Question asked by alessandro morniroli on Dec 4, 2015
Latest reply on Apr 11, 2016 by alessandro morniroli

Hello,

 

I'm not able to change MCG mode from FEE to FEI in case of Loss Of Clock.

I'm using a custom board mounting MK22FX512VLK12 or MK22FX512V12 (mask 3N03G). On the custom board is also mounted an external I2C RTC, which 32-kHz output is used as reference clock for the RTC oscillator.

 

At startup, MCU starts by default in FEI mode (using the internal 32-kHz clock). In the main, I change then the MCG mode from FEI to FEE, using the external 32-kHz as reference clock.

I also enable the external clock monitor for generating an interrupt in case of loss of clock (CME1 = 1, LOCRE1= 0).

In case of loss of lock then (removing a jumper on the board that cuts off the 32-kHz signal), within the MCG ISR I change the MCG mode from FEE to FEI, but the bit IREFST remains 0, meaning that the source of the FLL reference clock is still the external one.

 

Is it possible to change MCGmode from FEE to FEI in case of loss of clock without resetting the MCU? I have found no documentation about that.

 

Here is my very simple example code

 

void setFEE (void)
{
    MCG_C7 |= MCG_C7_OSCSEL_MASK;
    MCG_C1  = 0;
    MCG_C4 |= (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03));


    while ((MCG_S & MCG_S_IREFST_MASK) != 0x00U)
    {
        ;
    }


    while ((MCG_S & 0x0CU) != 0x00U)
    {
        ;
    }


    MCG_C8 = MCG_C8_CME1_MASK;


    NVICIP57   = NVIC_IP_PRI57(0x80);
    NVICISER1 |= NVIC_ISER_SETENA(0x2000000);
}


void setFEI (void)
{
    MCG_C7 |= MCG_C7_OSCSEL_MASK;
    MCG_C1 |= MCG_C1_IREFS_MASK;
    MCG_C4 |= (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03));
    MCG_C8 &= ~(MCG_C8_CME1_MASK);


    while((MCG_S & MCG_S_IREFST_MASK) == 0x00U)
    {
        /* I'm stucking here when configuring from FEE to FEI within ISR. */
        ;
    }


    while((MCG_S & 0x0CU) != 0x00U)
    {
        ;
    }
}


void lossOfLockIsr ()
{
    MCG_S = (MCG_S_LOLS_MASK | MCG_S_CLKST(0x00));


    Cpu_SetFEIMode ();


    NVICIP57 &= ~NVIC_IP_PRI57(0x80);
    NVICICER1 = NVIC_ICER_CLRENA(0x2000000);
}


void main (void)
{
    setFEE ();


    while (1)
        ;
}

 

If a reset request is generated instead of interrupt (LOCRE1 = 1), everything is working correctly (MCU resets and it starts in FEI mode by default, with IREFST bit set to 1).

Outcomes