Issue using 32K OSC as input source to pll in LPC54113

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Issue using 32K OSC as input source to pll in LPC54113

1,474 Views
AD11
Contributor I

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?

Tags (1)
0 Kudos
Reply
4 Replies

1,453 Views
AD11
Contributor I
Please find below the code i am using to enable clock with RTC Oscillator   

/*!< Set up the clock sources */
    /*!< Set up FRO */
    POWER_DisablePD(kPDRUNCFG_PD_FRO_EN);                   /*!< Ensure FRO is on  */
    CLOCK_SetupFROClocking(12000000U);                    /*!< Set up FRO to the 12 MHz, just for sure */
    CLOCK_AttachClk(kFRO12M_to_MAIN_CLK);                  /*!< Switch to FRO 12MHz first to ensure we can change voltage without accidentally
                                                                being below the voltage for current speed */
    POWER_SetVoltageForFreq(100007936U);             /*!< Set voltage for the one of the fastest clock outputs: System clock output */
    CLOCK_SetFLASHAccessCyclesForFreq(100007936U);   /*!< Set FLASH wait states for core */

    /*!< Set up RTC OSC */
    CLOCK_EnableClock(kCLOCK_Rtc);                          /*!< Enable the RTC peripheral clock */
   
 
        RTC->CTRL &= ~(RTC_CTRL_RTC_OSC_PD_MASK | RTC_CTRL_RTC_OSC_BYPASS_MASK); /*!< Enable RTC oscillator */
        SYSCON->RTCOSCCTRL = SYSCON_RTCOSCCTRL_EN_MASK;                          /*!< RTC oscillator 32kHz output is available to the other modules */
    

    /*!< Set up PLL */
    CLOCK_AttachClk(kOSC32K_to_SYS_PLL);                  /*!< Switch PLL clock source selector to OSC32K */
    pll_setup_t pllSetup = {
        .syspllctrl = SYSCON_SYSPLLCTRL_BANDSEL_MASK | SYSCON_SYSPLLCTRL_SELI(1U) | SYSCON_SYSPLLCTRL_SELP(6U) | SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK | SYSCON_SYSPLLCTRL_DIRECTO_MASK,
        .syspllndec = SYSCON_SYSPLLNDEC_NDEC(770U),
        .syspllpdec = SYSCON_SYSPLLPDEC_PDEC(98U),
        .syspllssctrl = {(SYSCON_SYSPLLSSCTRL0_MDEC(9602U) | SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK),0x0U},
        .pllRate = 100007936U,
        .flags =  PLL_SETUPFLAG_WAITLOCK
    };
    pll_config_t pllConfig =
        {
            .desiredRate = HIGH_FREQ_CLOCK,
            .inputRate = RTC_OSC_CLOCK,
            .flags = PLL_CONFIGFLAG_USEINRATE | PLL_CONFIGFLAG_FORCENOFRACT};

    CLOCK_SetPLLFreq(&pllSetup); /*!< Configure PLL to the desired values */
    _ASSERT(kStatus_PLL_Success == CLOCK_SetupPLLData(&pllConfig, &pllSetup)); /*Used For PLL Stabilization*/
    /*!< Set up dividers */
    CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false);                  /*!< Set AHBCLKDIV divider to value 1 */

    /*!< Set up clock selectors - Attach clocks to the peripheries */
    CLOCK_AttachClk(kSYS_PLL_to_MAIN_CLK);                  /*!< Switch MAIN_CLK to SYS_PLL */
    SYSCON->MAINCLKSELA = ((SYSCON->MAINCLKSELA & ~SYSCON_MAINCLKSELA_SEL_MASK) | SYSCON_MAINCLKSELA_SEL(0U)); /*!< Switch MAINCLKSELA to FRO12M even it is not used for MAINCLKSELB */
    /*!< Set SystemCoreClock variable. */
    SystemCoreClock = 100007936U;
0 Kudos
Reply

1,421 Views
marek_neuzil
NXP Employee
NXP Employee

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

 

1,412 Views
AD11
Contributor I

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.

0 Kudos
Reply

1,396 Views
marek_neuzil
NXP Employee
NXP Employee

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