How to use internal clock for K64F

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

How to use internal clock for K64F

3,925 Views
anandmeharwade
Contributor II

Hi,

We have designed a custom board with K64FN1MOVLL12 and we have added 32.768kHz RTC crystal but not the external clock reference in the design. Could any one help me to understand and configure the micro controller to run with internal/RTC clock reference with below function for configuring the MCG.

BOARD_BootClockRUN();

For any clarification feel free to reply me

Thanks

Anand M

Labels (1)
5 Replies

1,555 Views
mjbcswitzerland
Specialist V

Hi

You can find another practical guide/discussion at

http://www.utasker.com/kinetis/MCG.html

which also highlights some pit-falls to be avoided.

uTasker K64 users configure 32kHz RTC reference to FLL using

#define RUN_FROM_RTC_FLL // use 32.76kHz crystal clock as input to the FLL

and the exact bus speeds with

#define FLL_FACTOR 2929 // use FLL (factors available are 640, 732, 1280, 1464, 1920, 2197, 2560 and 2929) for 96MHh

#define FLEX_CLOCK_DIVIDE 2 // 96/2 to give 48MHz

#define FLASH_CLOCK_DIVIDE 4 // 96/4 to give 24MHz

The resulting operation can be checked in the uTasker Kinetis simulator and in case of any invalid ranges the build will gererate an error, explaining the problem.

Regards

Mark

1,555 Views
charlesasquith
NXP Employee
NXP Employee

Hi Anand,

To configure the clocks you're going to first want to look in the clock_config.c file in your project. That is where the BOARD_BootClockRUN function is defined.

pastedImage_8.png

As you can see, it's making extensive use of the members of the structure "g_defaultClockConfigRun", which can also be found in the clock_config.c file. This structure is what is being used to configure the clocks when you call the BOARD_BootClockRUN function, so to suit the needs of your application, you're going to want to look in that structure  and adjust it (or make your own).

pastedImage_13.png

pastedImage_15.png

As you can see in the clock_config_t structure, there are 4 members (mcgConfig, simConfig, oscConfig, and coreClock - all of these except for coreClock are substructures).
I'll attach the clocking diagram for the FRDM-K64F, but of course, each substructure is being used to configure its respective clock diagram module found in the image below (e.g. .mcgConfig is setting up the MCG module, .simConfig sets up the SIM, and .oscConfig picks and sets up either the system, RTC, or IRC48M oscillator).

FRDM-K64F Clocking Diagram.PNG

Since you're question is how to use the internal clock, you're going to want to set up these modules accordingly.
Looking at the .mcgConfig substructure, you can see that is has a few members:

.mcgMode picks what mode the MCG and decides things like if you will use the FLL or PLL to alter the MCGOUTCLK frequency, if you are using an internal or external clock, and if you are in low power mode or not. You can find more detailed information about each mode under the "MCG modes of operation" in the reference manual. Since you're using an internal clock you'll pick FEI, FBI, or BLPI, as these are for internal sources. If you use an RTC oscillator you'll pick one of the others that utilize an external source.

.irclkEnable will either be kMCG_IrclkEnable or kMCG_IrclkEnableInStop

.ircs picks the internal reference clock source, which will either be the 4 MHz IRC (the "fast" one), or the 32 kHz IRC (the "slow" one). .ircs will be equal to either "kMCG_IrcFast" or "kMCG_IrcSlow".pastedImage_17.png

.fcrdiv is the fast clock internal reference divider, and enables you to divide down the 4 MHz IRC signal if you so desire. It is apart of the MCG_SC (MCG Status and Controler Register) and can be found in the reference manual.

.frdiv is the FLL External Reference Divider, is apart of the MCG_C1 (MCG Control 1 Register), and is in the manual. It allows you to divide external reference clock signals.

pastedImage_18.png


.dmx32 will be either "kMCG_Dmx32Default" or "kMCG_Dmx32Fine" and controls the MCG DCO maximum frequency with 32.768 kHZz reference.

.oscsel picks the external oscillator that will be used. It will be "kMCG_OscselOsc", "kMCG_OscselRtc", or "kMCG_OscselIrc".
To use the RTC oscillator you'll pick the second one.
pastedImage_20.png

.pll0Config is a small structure that allows you enable/disable the PLL and to pick the values you want to multiply/divide your source signal by. VDIV is a multiplication factor, and PRDIV a dividing factor. Look in their reference manual registers for numbers.

For the .simConfig structure you've got:

.pllFllSel selects if the PLL, FLL, or IRC48M (produces nominal 48MHz clocks for USB crystal-less operation and other function) will be used.

1U=PLL

2U=FLL

3U=IRC48M
U meaning unsigned

pastedImage_19.png

.er32kSrc selects the source clock of the ERCLK32K. It's basically deciding which signal will make it through its pertinent multiplexer, either OSC32KCLK, the 32.768 kHz RTC oscillator, or the PMC LPO signal. Once again, you'll right a 1U, 2U, or 3U to this.
pastedImage_22.png

.clkdiv1 is directly filling the CLKDIV1 register, and is altering the MCGOUTCLK signal for each target clock (Core, Bus, FlexBus, or Flash). For example, if MCGOUTCLOCK is 120 MHz, and writing a 1 to the OUTDIV1 value in CLKDIV1 will divide the MCGOUTCLOCK signal by two and route it to the Core/system clocks. This means that the Core/system clocks will be 120MHz/2 = 60MHz.

.oscConfig configures the external clock that you picked:

.freq is the frequency is the external clock frequency. It's defined in clock_config.h

.capLoad is situational and has to do with capacitors involved with the reference clock. You may look at the schematic and consider if you have any attached to the clock peripheral as well.


.workMode will be either kOSC_ModeExt, kOSC_ModeOscLowPower, or kOSC_ModeOscHighGain depending on what you need.

.oscerConfig enables the OSCERCLK signal if you so desire.

pastedImage_23.png

.coreClock is the frequency of the Core/system clocks. Make sure that this aligns with what is outputted by OUTDIV1.

So all in all, this just structure is a quick way to set a bunch of registers that deal with the SIM and MCG clocking modules. It might help to trace the signal of what internal reference clock/external oscillator you're using to its output to see what kind of things it goes through, and then fill out a structure according to how you want its output to look.

For more detailed information on the registers and whatnot, the reference manual can be found at: http://cache.freescale.com/files/microcontrollers/doc/ref_manual/K64P144M120SF5RM.pdf

Hopefully this will help you configure the clocks to your needs. If you have any more questions, please ask.

1,555 Views
mounir
Contributor I

Hi Charles, 

Our custom board based on K60P100M100SF2V2 is equiped with 32.768kHz RTC crystal

I 'm not able tu use  FEE mode with external 32.768kHz RTC as clock reference.

Here is my BOARD_BootClockRUN function and my g_defaultClockConfigRun structure

 

BOARD_BootClockRUN()

{

CLOCK_SetSimSafeDivs();
CLOCK_InitOsc0(&ClockConfigRun.oscConfig);
CLOCK_SetXtal32Freq(BOARD_XTAL32K_CLK_HZ);
CLOCK_BootToFeeMode(g_defaultClockConfigRun.mcgConfig.oscsel, g_defaultClockConfigRun.mcgConfig.frdiv, g_defaultClockConfigRun.mcgConfig.dmx32 , g_defaultClockConfigRun.mcgConfig.drs, CLOCK_FllStableDelay);
CLOCK_SetInternalRefClkConfig(g_defaultClockConfigRun.mcgConfig.irclkEnableMode,
g_defaultClockConfigRun.mcgConfig.ircs, g_defaultClockConfigRun.mcgConfig.fcrdiv);
CLOCK_SetSimConfig(&g_defaultClockConfigRun.simConfig);
SystemCoreClock = g_defaultClockConfigRun.coreClock;

}

/* Configuration for enter RUN mode. Core clock = 20MHz. */
const clock_config_t g_defaultClockConfigRun = {
.mcgConfig =
{
.mcgMode = kMCG_ModeFEE, /* Work in PEE mode. */
.irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enable. */
.ircs = kMCG_IrcSlow, /* Select IRC32k. */
.fcrdiv = 0U, /* FCRDIV is 0. */

.frdiv = 0U,
.drs = kMCG_DrsLow, /* Low frequency range. */
.dmx32 = kMCG_Dmx32Fine, /* DCO has a default range of 25%. */
.oscsel = kMCG_OscselRtc, /* Select OSC. */

.pll0Config =
{
.enableMode = 0U, .prdiv = 0x13U, .vdiv = 0x18U,
},
},
.simConfig =
{
.pllFllSel = 0U, /* PLLFLLSEL select PLL. */
.er32kSrc = 2U, /* ERCLK32K selection, use RTC. */
.clkdiv1 = 0x01140000U, /* SIM_CLKDIV1. */
},
.oscConfig = {.freq =BOARD_XTAL32K_CLK_HZ,//BOARD_XTAL32K_CLK_HZ,//
.capLoad = 0,
.workMode = kOSC_ModeOscLowPower,//kOSC_ModeOscLowPower,//kOSC_ModeExt
.oscerConfig =
{
.enableMode = kOSC_ErClkEnable,
#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER)
.erclkDiv = 0U,
#endif
}},
.coreClock = 20000000U, /* Core clock frequency */
};

 

CLOCK_SetFeeMode is blocked on : 

while (kMCG_ClkOutStatFll != MCG_S_CLKST_VAL)
{
}

For any clarification feel free to reply me

 

Thanks

Mounir

0 Kudos

1,555 Views
anandmeharwade
Contributor II

Dear Charles Asquith,

Thanks for the detailed description of the clock configuration, I will modify the code and revert to you if any issue encounters.

Thank

Anand M

0 Kudos

1,555 Views
charlesasquith
NXP Employee
NXP Employee

Hi Anand,

I'm glad to have helped. If it is the correct answer, then I would encourage you to mark it as so, so that others who may need this information can easily find it.

Best regards,
Charles

0 Kudos