I'm using the MKL27 and wanted to confirm I had programmed MCG_Lite correctly.
I am not understanding the frequencies I'm seeing on CLKOUT when I select Bus as the output,
they are not integer divisions or multiples of the selected clock sources, which makes no sense to me.
Does CLKOUT[Bus] in fact work on the MKL27 or have I done something wrong in my code below?
My board has a external 10 MHz Osc.
SIM_CLKDIV is set to divide the CPU Core by two to give Core Clock/2 on Bus.
SIM_SOPT2_CLKOUTSEL( 2U ) | /* 0:None, 2:Bus, 3:LPO-1kHz, 4:IRC8M/LIRC_CLK, 6:OSCERCLK, 7:IRC48M */
If I set:
SOPT2_CLKOUTSEL to 3 I get 1.01 kHz..
SOPT2_CLKOUTSEL to 4 I get 7.99 MHz,
SOPT2_CLKKOUTSEL to 6 I get 9.9999... MHz
SOPT2_CLKOUTSEL to 7 I get 48 MHz.
All those do exactly what I expect.
Now if I sent SOPT2_CLKOUTSEL to 2, Bus Out, with a source of:
IRC48M I get 48 MHz on CLKOUT when I expect to see 24 MHz.
OSCERCLK (10MHz) I get a frequency wondering between 13 and 16 MHz spending most of its time at 15.2 MHz. I expect 5 MHz.
IRC8M with FCRDIV set to /1 I get 11.98 MHz when I expect 4 MHz.
What is going on here?
Here is my code:
void clock_destructor_150( void ) ATTR_DTOR( 150 );
void clock_destructor_150( void )
{
LED_HEAT_GRN_ASSERT(); /* Turn on Green LED */
SIM_CLKDIV1 = (
SIM_CLKDIV1_OUTDIV1( 0U ) | /* Divide MCGOUTCLK by /1 Divide value for the core/system clock, */
SIM_CLKDIV1_OUTDIV4( 1U ) /* Divide MCGOUTCLK by /2 Bus and Flash clock divider. */
);
/*
* Maximum frequency limitations for VLPR mode is as follows :
• the core/system clocks are less than or equal to 4 MHz, and
• the bus and flash clocks are less than or equal to 1 MHz
*/
/*
* To select other clock sources, the mode must be set to HIRC
* before changing to an other mode.
*/
MCG_SC = MCG_SC_FCRDIV( 0U ); /* Select FCRDIV divided by 0:/1, 1:/2, 2:/4, 3:/8, 4:/16, 5:32, 6:64, 7:128 */
MCG_MC = (MCG_MC_HIRCEN_MASK|MCG_MC_LIRC_DIV2( 1U )); /* High-frequency IRC Enabled. LIRC divided by 0:/1, 1:/2, 2:/4, 3:/8, 4:/16, 5:32, 6:64, 7:128 To match Bus. Use MCGIRCLK for peripherals */
MCG_C1 = (
MCG_C1_CLKS( 0U ) | /* 0:HIRC, 1:LIRC2M or LIRC8M mode, 2:External Clock */
MCG_C1_IRCLKEN_MASK /* Internal Reference Clock LIRC enabled */
);
/*
* Clock Mode Status. This field does not update immediately after
* a write to MCG_C1[CLKS] due to domain synchronization.
*
* Check MCG_S[CLKST] to confirm HIRC clock source is selected
*/
delay_ms( 5UL );
while( (0U << MCG_S_CLKST_SHIFT) != MCG_S_CLKST( 0U ) )
{
nop();
}
/* Now running at 48 MHz */
OSC0_CR = 0U; /* External reference clock is inactive */
CLK_OE_DEASSERT(); /* Power down the Osc. */
SIM_SOPT2 = (
SIM_SOPT2_TPMSRC( 0U ) | /* 1:IRC48M/MCGPCLK, 2:OSCERCLK, 3:IRC8M/MCGIRCLK: Clock feeds the TPM clock */
SIM_SOPT2_LPUART0SRC( 0U ) | /* 1:IRC48M/MCGPCLK, 2:OSCERCLK, 3:IRC8M/MCGIRCLK: Clock feeds LPUART0 baud rate generator */
SIM_SOPT2_LPUART1SRC( 0U ) | /* 1:IRC48M/MCGPCLK, 2:OSCERCLK, 3:IRC8M/MCGIRCLK: Clock feeds LPUART0 baud rate generator */
SIM_SOPT2_CLKOUTSEL( 2U ) | /* 0:None, 2:Bus, 3:LPO-1kHz, 4:IRC8M/LIRC_CLK, 6:OSCERCLK, 7:IRC48M */
SIM_SOPT2_USBSRC_MASK /* 0:External bypass clock (USB_CLKIN), 1:IRC48M */
);
// CLKOUT[Bus] gives 48 MHz at this point should be 24 MHz.
/* Switch to 8MHz internal: */
MCG_C2 = MCG_C2_IRCS_MASK; /* Low-frequency Internal Reference Clock, Select LIRC 8 MHz */
MCG_C1 = (
MCG_C1_CLKS( 1U ) | /* 0:HIRC, 1:LIRC2M or LIRC8M mode, 2:External Clock */
MCG_C1_IRCLKEN_MASK /* Internal Reference Clock LIRC enabled */
);
/*
* Clock Mode Status. This field does not update immediately after
* a write to MCG_C1[CLKS] due to domain synchronization.
*
* Check MCG_S[CLKST] to confirm LIRC clock source is selected
*/
delay_ms( 5UL );
while( (1U << MCG_S_CLKST_SHIFT) != MCG_S_CLKST( 1U ) )
{
nop();
}
MCG_MC = MCG_MC_LIRC_DIV2( 1U ); /* High-frequency IRC disabled. LIRC/2 = 4MHz to match Bus. Use MCGIRCLK for peripherals */
// CLKOUT[Bus] gives 11.99 MHz at this point should be 4 MHz.
/* The SOPT1 register is only reset on POR or LVD: */
SIM_SOPT1 = 0U; /* LPO */
SIM_SOPT2 = (
SIM_SOPT2_TPMSRC( 0U ) | /* 1:IRC48M/MCGPCLK, 2:OSCERCLK, 3:IRC8M/MCGIRCLK: Clock feeds the TPM clock */
SIM_SOPT2_LPUART0SRC( 0U ) | /* 1:IRC48M/MCGPCLK, 2:OSCERCLK, 3:IRC8M/MCGIRCLK: Clock feeds LPUART0 baud rate generator */
SIM_SOPT2_LPUART1SRC( 0U ) | /* 1:IRC48M/MCGPCLK, 2:OSCERCLK, 3:IRC8M/MCGIRCLK: Clock feeds LPUART0 baud rate generator */
SIM_SOPT2_CLKOUTSEL( 0U ) | /* 0:None, 2:Bus, 3:LPO-1kHz, 4:IRC8M/LIRC_CLK, 6:OSCERCLK, 7:IRC48M */
SIM_SOPT2_USBSRC_MASK /* 0:External bypass clock (USB_CLKIN), 1:IRC48M */
);
for(;;)
{
LED_HEAT_GRN_TOGGLE();
delay_ms( 100U );
}
}