AnsweredAssumed Answered

MKL27 CLKOUT has wrong Bus frequencies?

Question asked by Bob Paddock on Oct 14, 2015
Latest reply on Oct 16, 2015 by Bob Paddock

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 );

    }

}

Outcomes