Configuring the clock on K10

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

Configuring the clock on K10

Jump to solution
1,024 Views
garylynch
Contributor IV

I am working on a bare metal application on a K10 processor
and must switch from reset clock configuration to using the
external oscillator with a 50 MHz crystal to clock my MCU at
100 MHz.

Are there any code samples that tackle this (or a similar)
task?

Labels (1)
0 Kudos
1 Solution
725 Views
mjbcswitzerland
Specialist V

Gary

The uTasker defines are based on the part's user's maual so you can simply check the registers in the user's manual and it should be fully interpretable.

They avoid macros since they are often unclear (the field width is not obvious and also the meaning of each value is not clear, plus reading code like REG_MACRO(6) still gives no indication about what the 6 means).

You can get the uTasker source code from http://www.utasker.com/forum/index.php?topic=1721.0 in case you need to know how anything is defined.

The ones used in the clock configuration code are:

#define MCG_C1_CLKS_PLL_FLL    0x00
#define MCG_C1_FRDIV_1024      0x28
#define MCG_C1_CLKS_EXTERN_CLK 0x80
#define MCG_C2_RANGE_8M_32M    0x20
#define MCG_C2_LOCRE0          0x80
#define MCG_C5_PLLSTEN0        0x20
#define MCG_C6_PLLS            0x40
#define MCG_S_CLKST_EXTERN_CLK 0x08
#define MCG_S_CLKST_MASK       0x0c
#define MCG_S_CLKST_PLL        0x0c
#define MCG_S_IREFST           0x10
#define MCG_S_PLLST            0x20
#define MCG_S_LOCK             0x40

Regards

Mark

View solution in original post

0 Kudos
6 Replies
725 Views
mjbcswitzerland
Specialist V

Gary

For 50MHz clock input (32 MHz is fastest crystal that can be used) the code can be taken from a K60 setup for the TWR board.

For 100MHz core/sytem clock, with 50MHz bus and 25MHz flash clocks the following (from the uTasker project) will do it:

#define CLOCK_MUL             32
#define MCG_C6_VDIV0_LOWEST   depends on the K10 type used (either 24 or 16 - consult the particular data sheet)
#define CLOCK_DIV             16
#define SYSTEM_CLOCK_DIVIDE   1
#define BUS_CLOCK_DIVIDE      2
#define FLEX_CLOCK_DIVIDE     16 (not important if no Flex Bus)
#define FLASH_CLOCK_DIVIDE    4


MCG_C2 = (MCG_C2_RANGE_8M_32M | MCG_C2_LOCRE0);                      // select external clock source (with reset on clock loss)
MCG_C1 = (MCG_C1_CLKS_EXTERN_CLK | MCG_C1_FRDIV_1024);               // switch to external input clock (the FLL input clock is set to as close to its input range as possible, although this is not absolutely necessary since the FLL will not be used)
while ((MCG_S & MCG_S_IREFST) != 0) {}                               // loop until the FLL source is no longer the internal reference clock
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST_EXTERN_CLK) {}      // loop until the external reference clock source is valid
MCG_C5 = ((CLOCK_DIV - 1) | MCG_C5_PLLSTEN0);                        // now move from state FEE to state PBE (or FBE) PLL remains enabled in normal stop modes
MCG_C6 = ((CLOCK_MUL - MCG_C6_VDIV0_LOWEST) | MCG_C6_PLLS);
while ((MCG_S & MCG_S_PLLST) == 0) {}                                // loop until the PLLS clock source becomes valid
while ((MCG_S & MCG_S_LOCK) == 0) {}                                 // loop until PLL locks
SIM_CLKDIV1 = (((SYSTEM_CLOCK_DIVIDE - 1) << 28) | ((BUS_CLOCK_DIVIDE - 1) << 24) | ((FLEX_CLOCK_DIVIDE - 1) << 20) | ((FLASH_CLOCK_DIVIDE - 1) << 16)); // prepare bus clock divides
MCG_C1 = (MCG_C1_CLKS_PLL_FLL | MCG_C1_FRDIV_1024);                  // finally move from PBE to PEE mode - switch to PLL clock
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL) {}             // loop until the PLL clock is selected

Simulation showing the obtained speeds:

pastedImage_0.png

Regards

Mark

0 Kudos
725 Views
garylynch
Contributor IV

Mark,

Thanks for the tips.

1.  We are feeding an external, 50 MHz oscillator to the
    K10. Please forgive the oversimplification.

2.  As assumed by your comments, we are not using FlexBus.

3.  I can't figure out the comment:
    >
    > depends on the K10 type used
    > (either 24 or 16 - consult the
    > particular data sheet)
    >
    We are using a 100 MHz K10, which is indicated by a '10' at
    the end of the part number. I can't find anything that maps
    to 24 or 16.

4.  After posting, I found code in file system_MK10D10.c, which
    is auto-generated by KDS and which I presume is executed
    before entry into main().  It contains 2 functions:
    - SystemInit(), &
    - SystemCoreClockUpdate();

    both of which appear to modify the MCG (I haven't figured
    out everything they do, yet).  If my observation is correct,
    I will have to disable this section manually to use your
    code in main(), correct?

0 Kudos
725 Views
mjbcswitzerland
Specialist V

Gary

You can also generate code with PE.

The KDS code needs configuring, whereby you will also need to know the register content details since it needs raw settings configured. PE will allow you to not need to understand register settings but the generated code is pretty huge.

K10 120MHz

pastedImage_0.png

K10 100MHz

pastedImage_3.png

If using KDS you will also need to know this because you have to plug in the raw details, rather than being able to work with the actual divide and multiplications that you ultimately would like.

Therefore, for your K10 100MHz, a multiplication factor of x47 is 0x17, whereby for a K10 120MHz it is 0x1f.

#define MCG_C6_VDIV0_LOWEST  24 // when using K10 100MHz

or

#define MCG_C6_VDIV0_LOWEST  16 // when using K10 120MHz

allows the user to enter the value that is really required, eg, 47, and automates the actual register content used to match the chip.

The following article may help de-mystify the MCG and its operation http://www.utasker.com/kinetis/MCG.html

Regards

Mark

0 Kudos
725 Views
garylynch
Contributor IV

Mark,

More thanks for sorting that out.

Meanwhile I started processing the code snippet you provided. It contains 15 tokens that look like macros that aren't defined in the snippet.  Of those I was able to find definitions for 4 in an MK10D10.h header inside PE:
- MCG_C2_LOCRE0()
- MCG_C5_PLLSTEN0()
- MCG_C6_PLLS()
- MCG_S()

The definitions however have parameters, while the evocations in the sample do not, so I am not sure I have the correct file and I can't find the other tokens anywhere.

Are they specific to uTasker or some other outside resource?

We don't rely much on PE because we have an internal requirement for project portability, i.e. I should be able to check a project into our version control, and another developer check it out and build it on his system without significant fine tuning.  I am able to copy projects WITHIN MY WORKSPACE inside KDS, but anything copied by any other means winds up broken in ways I find very difficult to troubleshoot.  If there is a way to use these tools to generate portable projects, I would love to hear about it.

0 Kudos
726 Views
mjbcswitzerland
Specialist V

Gary

The uTasker defines are based on the part's user's maual so you can simply check the registers in the user's manual and it should be fully interpretable.

They avoid macros since they are often unclear (the field width is not obvious and also the meaning of each value is not clear, plus reading code like REG_MACRO(6) still gives no indication about what the 6 means).

You can get the uTasker source code from http://www.utasker.com/forum/index.php?topic=1721.0 in case you need to know how anything is defined.

The ones used in the clock configuration code are:

#define MCG_C1_CLKS_PLL_FLL    0x00
#define MCG_C1_FRDIV_1024      0x28
#define MCG_C1_CLKS_EXTERN_CLK 0x80
#define MCG_C2_RANGE_8M_32M    0x20
#define MCG_C2_LOCRE0          0x80
#define MCG_C5_PLLSTEN0        0x20
#define MCG_C6_PLLS            0x40
#define MCG_S_CLKST_EXTERN_CLK 0x08
#define MCG_S_CLKST_MASK       0x0c
#define MCG_S_CLKST_PLL        0x0c
#define MCG_S_IREFST           0x10
#define MCG_S_PLLST            0x20
#define MCG_S_LOCK             0x40

Regards

Mark

0 Kudos
725 Views
garylynch
Contributor IV

Works like a hose!

Thanks, Mark!

0 Kudos