Other Parts Discussed in Thread: C2000WARE
Hello.
Please tell me about switching to an alternative clock when MISS_CLOCK is detected.
PLL_Initial(6,2) generates a 60MHz system clock using 20M_XTAL.
For a switching test, run the code below and the process will proceed to nmi_isr().
NmiIntruptRegs.NMIFLGFRC.bit.CLOCKFAIL = 1;
We understand that it is necessary to reconfigure the PLL in order to switch to internal OSC1 within this function.
Is this understanding correct?
I am thinking of generating a 60MHz system clock using internal OSC1 using PLL_Initial(12, 2).
However, when this function is executed, the CPU will stop.
Conversely, if this function is not executed, the CPU will continue to operate.
Is the XTAL->OSC1 switching successful without resetting the PLL?
Best regard.
Best regard!
__interrupt void nmi_isr(void)
{
PLL_Initial(12, 2); // CLK=10M*12/2=60M XTAL->OSC1
EALLOW;
NmiIntruptRegs.NMIFLGCLR.bit.CLOCKFAIL = 1;
NmiIntruptRegs.NMIFLGCLR.bit.NMIINT = 1;
EDIS;
}
void
PLL_Initial(Uint16 val, Uint16 divsel)
{
volatile Uint16 iVol;
//
// Make sure the PLL is not running in limp mode
//
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
{
EALLOW;
//
// OSCCLKSRC1 failure detected. PLL running in limp mode.
// Re-enable missing clock logic.
//
SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1;
EDIS;
//
// Replace this line with a call to an appropriate
// SystemShutdown(); function.
__asm(" ESTOP0"); // Uncomment for debugging purposes
}
//
// DIVSEL MUST be 0 before PLLCR can be changed from
// 0x0000. It is set to 0 by an external reset XRSn
// This puts us in 1/4
//
if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
EDIS;
}
//
// Change the PLLCR
//
if (SysCtrlRegs.PLLCR.bit.DIV != val)
{
EALLOW;
//
// Before setting PLLCR turn off missing clock detect logic
//
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
SysCtrlRegs.PLLCR.bit.DIV = val;
EDIS;
//
// Optional: Wait for PLL to lock.
//
// During this time the CPU will switch to OSCCLK/2 until
// the PLL is stable. Once the PLL is stable the CPU will
// switch to the new PLL value.
//
// This time-to-lock is monitored by a PLL lock counter.
//
// Code is not required to sit and wait for the PLL to lock.
// However, if the code does anything that is timing critical,
// and requires the correct clock be locked, then it is best to
// wait until this switching has completed.
//
//
// Wait for the PLL lock bit to be set.
//
//
// The watchdog should be disabled before this loop, or fed within
// the loop via ServiceDog().
//
//
// Uncomment to disable the watchdog
//
DisableDog();
while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
{
//
// Uncomment to service the watchdog
//
// ServiceDog();
}
EALLOW;
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
EDIS;
}
//
// If switching to 1/2
//
if((divsel == 1)||(divsel == 2))
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
EDIS;
}
//
// If switching to 1/1
// * First go to 1/2 and let the power settle
// The time required will depend on the system, this is only an example
// * Then switch to 1/1
//
if(divsel == 3)
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
DELAY_US(50L);
SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
EDIS;
}
}