Hello,
For more precise clock we switched from FRO12Mhz to 32K oscillator to be the source of clock to PLL. I used your configurator to do that. But i see after sometimes i am getting random hardfaults which never happened before! And also when i wait for PLL till it's locked it takes very long time till bootup "More than 1 minute". Can you help me with that?
Hello,
In the LPC54113 user manual is stated the following instruction regarding the lock bit:
6.6.5.2.1 Lock detector
The lock detector measures the phase difference between the rising edges of the input and feedback clocks. Only when this difference is smaller than the so called “lock criterion” for more than seven consecutive input clock periods, the lock output switches from low to high. A single too large phase difference immediately resets the counter and causes the lock signal to drop (if it was high). Requiring seven phase measurements in a row to be below a certain figure ensures that the lock detector will not indicate lock until both the phase and frequency of the input and feedback clocks are very well aligned. This effectively prevents false lock indications, and thus ensures a glitch free lock signal.
The PLL lock indicator is not dependable when Fref is below 100 kHz or above 20 MHz. Instead, software should use a 6 ms time interval to insure the PLL will be stable.
In fractional mode and spread spectrum mode, the PLL will generally not lock, software should use a 6 ms time interval to insure the PLL will be stable. See Section 6.6.5.5.1.
The Clocks tool (in MCUXpresso Config Tools) provides the following code for the FRO 12MHz and RT 32kHz clock source of the PLL.
PLL initialization sequence with FRO 12MHz clock source
/*!< Set up PLL */
CLOCK_AttachClk(kFRO12M_to_SYS_PLL); /*!< Switch PLL clock source selector to FRO12M */
const pll_setup_t pllSetup = {
.syspllctrl = SYSCON_SYSPLLCTRL_BANDSEL_MASK | SYSCON_SYSPLLCTRL_SELI(26U) | SYSCON_SYSPLLCTRL_SELP(31U) | SYSCON_SYSPLLCTRL_DIRECTO_MASK,
.syspllndec = SYSCON_SYSPLLNDEC_NDEC(199U),
.syspllpdec = SYSCON_SYSPLLPDEC_PDEC(66U),
.syspllssctrl = {(SYSCON_SYSPLLSSCTRL0_MDEC(9637U) | SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK),0x0U},
.pllRate = 150000000U,
.flags = PLL_SETUPFLAG_WAITLOCK
};
CLOCK_SetPLLFreq(&pllSetup); /*!< Configure PLL to the desired values */
PLL initialization sequence with RTC 32 kHz clock source
/*!< Set up PLL */
CLOCK_AttachClk(kOSC32K_to_SYS_PLL); /*!< Switch PLL clock source selector to OSC32K */
const pll_setup_t pllSetup = {
.syspllctrl = SYSCON_SYSPLLCTRL_BANDSEL_MASK | SYSCON_SYSPLLCTRL_SELI(1U) | SYSCON_SYSPLLCTRL_SELP(6U) | SYSCON_SYSPLLCTRL_DIRECTO_MASK,
.syspllndec = SYSCON_SYSPLLNDEC_NDEC(770U),
.syspllpdec = SYSCON_SYSPLLPDEC_PDEC(66U),
.syspllssctrl = {(SYSCON_SYSPLLSSCTRL0_MDEC(3821U) | SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK),0x0U},
.pllRate = 149946368U,
.flags = PLL_SETUPFLAG_POWERUP
};
CLOCK_SetPLLFreq(&pllSetup); /*!< Configure PLL to the desired values */
The change of the flags impacts the checking of lock bit in the CLOCK_SetPLLFreq() function. See bellow the code:
pll_error_t CLOCK_SetPLLFreq(const pll_setup_t *pSetup)
{
/* Power off PLL during setup changes */
POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0);
/* Write PLL setup data */
SYSCON->SYSPLLCTRL = pSetup->syspllctrl;
SYSCON->SYSPLLNDEC = pSetup->syspllndec;
SYSCON->SYSPLLNDEC = pSetup->syspllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
SYSCON->SYSPLLPDEC = pSetup->syspllpdec;
SYSCON->SYSPLLPDEC = pSetup->syspllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0];
SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0] | (1UL << SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT); /* latch */
SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1];
SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1] | (1UL << SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT); /* latch */
/* Flags for lock or power on */
if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0UL)
{
/* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
uint32_t curSSCTRL = SYSCON->SYSPLLSSCTRL0 & ~(1UL << 17U);
/* Initialize and power up PLL */
SYSCON->SYSPLLSSCTRL0 = maxCCO;
POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
/* Set mreq to activate */
SYSCON->SYSPLLSSCTRL0 = maxCCO | (1UL << 17U);
/* Delay for 72 uSec @ 12Mhz */
SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
/* clear mreq to prepare for restoring mreq */
SYSCON->SYSPLLSSCTRL0 = curSSCTRL;
/* set original value back and activate */
SYSCON->SYSPLLSSCTRL0 = curSSCTRL | (1UL << 17U);
/* Enable peripheral states by setting low */
POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
}
if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0UL)
{
while (CLOCK_IsSystemPLLLocked() == false)
{
}
}
/* Update current programmed PLL rate var */
s_Pll_Freq = pSetup->pllRate;
return kStatus_PLL_Success;
}
So you need to fix the flags in your code because the lock bit cannot be used when the PLL use the RTC 32kHz clock source. You can also add a waiting loop (6.25ms) for the PLL stabilization as it is stated in the user manual and datasheet of the LPC54113
Best Regards,
Marek Neuzil
Hello,
Yes i am aware of it. But i am not using fractional mode in PLL. I am using Normal mode. Shall this be the same in Normal mode.
And in Fractional mode i see PLL input must be in 2 to 4 MHZ range.
Hello,
Yes, the PLL lock bit cannot be used when the RTC 32kHz clock is used as the reference clock (Fref) for the PLL in normal mode. It is also stated in the LPC54113 user manual:
6.6.5.2.1 Lock detector
. . .
The PLL lock indicator is not dependable when Fref is below 100 kHz or above 20 MHz. Instead, software should use a 6 ms time interval to insure the PLL will be stable.
In fractional mode and spread spectrum mode, the PLL will generally not lock, software should use a 6 ms time interval to insure the PLL will be stable. See Section 6.6.5.5.1.
Please, fix your code and use the 6,25 ms delay (specified in the LPC54113 datasheet) instead of the PLL lock indicator.
Best Regards,
Marek Neuzil