The datasheet for the MKV5X has the following values in Table 17 for the PLL:
Reference Frequency Range: 8 to 16 MHz
Ipll @ 176 MHz: 2.8 mA (Note says fpll_ref = 8 MHz, VDIV = 22, 8 * 22 = 176 MHz)
Ipll @ 360 MHz: 4.7 mA (Note says fpll_ref = 8 MHz, VDIV = 45, 8 * 45 = 360 MHz)
This seems to indicate that the feedback for the PLL comes directly from the VCO output.
However, this contradicts Figure 32-1 in the reference manual. This figure shows the feedback being derived from the fixed divide-by-2 MCGPLLCLK output. I confirmed using the FlexBus clock output pin and the PIT that the PLL N-divider appears to actually be connected to MCGPLLCLK2X. Can you please confirm if the following markup is correct?
Hi, Shawn,
If above figure is correct, the VCO output frqeuency(MCGPLLCLK2X) is 8MHz*VDIV*2, MCGPLLCLK is 8MHz*VDIV.
I will test it tomorrow, can you post the PLL setting code here?
BR
Xiangjun Rong
Xiangjun,
Yes, I believe that's correct. In my application I have a 10 MHz PLL reference frequency and would like MCGPLLCLK/MCGOUTCLK to operate at 160 MHz. In the original Figure 32-1, it led me to believe VDIV should be set to 16. I actually have to set it to 32, meaning the VDIV input must actually be connected directly to the VCO output (MCGPLLCLK2X). Code is below:
// -----------------------------------------------------------------
//
// Name: InitOSC
//
// Description:
//
// Enables the external reference and sets clock dividers
// to initial low speed values for boot.
//
// Input parameters:
// None.
//
// Returned value:
// None.
//
// Algorithm:
// 1) Set low speed system clock dividers:
// Core clock: 1
// Bus clock: 6
// FlexBus clock: 6
// Flash clock: 6
// 2) Enable external oscillator
// 3) Set oscillator divider to 1 (40 MHz / 1 = 40 MHz) for
// the OSCERCLK output.
//
// Special Notes:
// None.
//
// -----------------------------------------------------------------
void initOSC(void)
{
uint32_t tmp32 = 0x00000000;
tmp32 = SIM->CLKDIV1;
tmp32 &= ~(SIM_CLKDIV1_OUTDIV1_MASK | SIM_CLKDIV1_OUTDIV2_MASK |
SIM_CLKDIV1_OUTDIV3_MASK | SIM_CLKDIV1_OUTDIV4_MASK);
tmp32 |= (SIM_CLKDIV1_OUTDIV1(0x01) | SIM_CLKDIV1_OUTDIV2(0x05) |
SIM_CLKDIV1_OUTDIV3(0x05) | SIM_CLKDIV1_OUTDIV4(0x05));
SIM->CLKDIV1 = tmp32;
OSC0->CR &= ~(OSC_CR_EREFSTEN_MASK | OSC_CR_SC2P_MASK | OSC_CR_SC4P_MASK |
OSC_CR_SC8P_MASK | OSC_CR_SC16P_MASK);
OSC0->CR |= OSC_CR_ERCLKEN_MASK;
OSC0->DIV &= ~(OSC_DIV_ERPS_MASK);
OSC0->DIV |= OSC_DIV_ERPS(0x0);
}
// -----------------------------------------------------------------
//
// Name: InitMCG
//
// Description:
//
// Initializes the clock generator module for high speed PLL operation
// based on the external reference.
//
// Input parameters:
// None.
//
// Returned value:
// None.
//
// Algorithm:
// 1) Zero out trim.
// 2) Set DCO for low speed range and 0 trim.
// 3) Select OSCCLK0 for MCG FLL external reference (Default C7 setting on KV5).
// 4) Disable loss of lock monitors.
// 5) Set the MCG range for very high frequency oscillator.
// 6) Set FLL clock source to external reference with divider of 1280. This
// results in 40 MHz / 1280 = 31.250 kHz for the FLL. This
// clock is based on OSCCLK.
// 7) Set MCGOUTCLK source to external reference.
// 8) Wait for status to indicate external reference for FLL.
// 9) Wait for status to indicate external reference for MCGOUTCLK.
// 10) Enable PLL and set reference divider to 4, so 40 MHz / 4 = 10 MHz.
// 11) Enable PLL as MCGOUTCLK. Set feedback divider to 32, so (32 * 10 MHz) / 2 = 160 MHz.
// 12) Wait for status to indicate PLL selected.
// 13) Wait for status to indicate PLL locked.
// 14) Select PLL output for MCGOUTCLK.
// 15) Wait for status to indicate PLL is active clock.
//
// Special Notes:
// None.
//
// -----------------------------------------------------------------
void initMCG(void)
{
MCG->C3 = 0x00;
MCG->C4 = 0x00;
MCG->C8 &= ~(MCG_C8_LOLRE_MASK);
MCG->C2 = MCG_C2_RANGE(2U);
MCG->C1 = (MCG_C1_CLKS(2U) | MCG_C1_FRDIV(6U));
while ((MCG->S & MCG_S_IREFST_MASK) != 0x00)
{
}
while ((MCG->S & MCG_S_CLKST_MASK) != 0x08)
{
}
MCG->C5 = (MCG_C5_PLLCLKEN0_MASK | MCG_C5_PRDIV0(3U));
MCG->C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(16U));
while ((MCG->S & MCG_S_PLLST_MASK) != 0x20)
{
}
while ((MCG->S & MCG_S_LOCK0_MASK) != 0x40)
{
}
MCG->C1 &= ~(MCG_C1_CLKS_MASK);
while ((MCG->S & MCG_S_CLKST_MASK) != 0x0C)
{
}
}
void initRUN(void)
{
uint32_t tmp32 = 0x00000000;
SMC->PMPROT &= ~(SMC_PMPROT_AHSRUN_MASK | SMC_PMPROT_AVLP_MASK | SMC_PMPROT_AVLLS_MASK);
SMC->PMCTRL &= ~(SMC_PMCTRL_RUNM_MASK);
while ((SMC->PMSTAT & SMC_PMSTAT_PMSTAT_MASK) != 0x01)
{
}
tmp32 = SIM->CLKDIV1;
tmp32 &= ~(SIM_CLKDIV1_OUTDIV1_MASK | SIM_CLKDIV1_OUTDIV2_MASK |
SIM_CLKDIV1_OUTDIV3_MASK | SIM_CLKDIV1_OUTDIV4_MASK);
tmp32 |= (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV2(0x01) |
SIM_CLKDIV1_OUTDIV3(0x07) | SIM_CLKDIV1_OUTDIV4(0x07));
SIM->CLKDIV1 = tmp32;
}
Hi, Shawn,
Okay, i see, the /2 divider is not in the feedback loop as the figure.
BR
Xiangjun Rong