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