How to set main core frequency of FRDM-K22F to 100MHz?

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

How to set main core frequency of FRDM-K22F to 100MHz?

9,603 Views
zoranm
Contributor III

Hello all. I am working on this ARM Cortex M4 board and as you can see the MCU runs at 120 MHz. I would like to bring that down to 100 MHz because I am trying to implement a Timer init function and interrupt handler. A basic 1ms heartbeat timer is needed for much of the testing I need to do regarding this board. I found this reference manual for the specific MCU on this board. I've been told I could alter the clock going into the systick or alter the PLL configuration but I am new to this and I am not too sure how to approach this. By the way, I am using Kinetis Design Studio and KSDK. Any and all help is greatly appreciated.

Labels (1)
55 Replies

2,063 Views
mjbcswitzerland
Specialist V

Zoran

If you use KSDK you can just as well use its HWTIMER_SYS_SystickInit() to configure the SysTick.

I see that its code uses

SysTick->LOAD

SysTick->VAL

which are the same as SYSTICK_RELOAD and SYSTICK_CURRENT in the code that I showed you. These are Cortex SYSTICK registers located at the addresses 0xe000e014 and 0xe000e018 respectively as defined by the Cortex M4: ARM Information Center

So the method is to work out what the registers and values mean and find their equivalents in other headers and use them instead.

However I didn't find where the struct pointer SysTick is defined in the KSDK. Either it is a macro or a global pointer. The KSDK code is quite complicated to follow since it is spread out in some 2'000 files, with headers including other headers.

Unfortunately I am not much help with KSDK since it is too complicated for me so you will be on your own from here on ;-)

Regards

Mark

Kinetis: µTasker Kinetis support

K22: µTasker Kinetis FRDM-K22F support  / µTasker Kinetis TWR-K22F120M support

For the complete "out-of-the-box" Kinetis experience and faster time to market

0 Kudos
Reply

2,063 Views
zoranm
Contributor III

Mark. Since you are using uTasker I decided to take a look at it here but there is nothing for free as you said a few comments above.

0 Kudos
Reply

2,063 Views
mjbcswitzerland
Specialist V

Zoran

µTasker - Simple licensing terms

Quote: "Licensing and Prices

The µTasker project and all code used in it is delivered as source code. It is completely FREE to educational establishments, individuals and other users or organisations who are not using it for commercial work. So if you wish to use it for educational purposes, for hobby or experimental work, or just want to see what it is all about then please do so. No one will charge you a Cent for it."

There is also an anonymous public download at KINETIS Project Code  that doesn't even need registration.This will in fact include the defines that you are missing (in the file kinetis.h).

This doesn't however include K22 board support and newest features, which are reserved for registered users, as is personal email, telephone and remote desktop support. Registration is free at the links I already gave.

Regards

Mark

Kinetis: µTasker Kinetis support

K22: µTasker Kinetis FRDM-K22F support  / µTasker Kinetis TWR-K22F120M support

For the complete "out-of-the-box" Kinetis experience and faster time to market

2,063 Views
zoranm
Contributor III

Mark. Can you add more comments to your code. Can you be as detailed as possible for each line of code and what is happening and why you are doing it like that. This will help me decipher your approach and then make it easier to implement the headers from Kinetis. Thank you very much.

0 Kudos
Reply

2,063 Views
mjbcswitzerland
Specialist V

Hi Zoran

With the original defines below and the information at the ARM web site the code should be easily understandable without additional comments:

// SYSTICK

//

#define SYSTICK_CSR                 *(volatile unsigned long *)(CORTEX_M4_BLOCK + 0x10) // SYSTICK Control and Status Register

  #define SYSTICK_ENABLE            0x00000001 // enable SYSTICK counter

  #define SYSTICK_TICKINT           0x00000002 // interrupt on counter reload (reaching zero)

  #define SYSTICK_CORE_CLOCK        0x00000004 // choose core clock as opposed to external reference clock

  #define SYSTICK_COUNTFLAG         0x00010000 // '1' if the timer counted to 0 since the last time this register was read

#define SYSTICK_RELOAD              *(unsigned long *)(CORTEX_M4_BLOCK + 0x14) // SYSTICK Reload value (24 bits are valid)

#define SYSTICK_CURRENT             *(volatile unsigned long *)(CORTEX_M4_BLOCK + 0x18) // SYSTICK Current value - write any value to it to clear to 0

  #define SYSTICK_COUNT_MASK        0x00ffffff // valid count width in registers

#define SYSTICK_CALIB               *(const unsigned long *)(CORTEX_M4_BLOCK + 0x1c) // SYSTICK Calibration value (read-only)

// NVIC

//

#define SYSTEM_HANDLER_12_15_PRIORITY_REGISTER *(unsigned long *)(CORTEX_M4_BLOCK + 0xd20) // System Handler Priority Register 12..15

If you were to download the uTasker project you could run it in VisualStudio (also free as Express Edition) - you don't need to run it as K22 - any Kinetis will do - and step the code, watch the registers and vaues and learn all details without losing as much time as you seem to be losing at the moment. It would also allow you to run the SysStick interrupt in real-time on your PC so you can watch how the interrupts operate too.

If you have specific technical questions about the Kinetis I can help but I think that you first need to do some learning about basic operation because the present discussion is probably too basic to be of interest to community members in general.

Regards

Mark

Kinetis: µTasker Kinetis support

K22: µTasker Kinetis FRDM-K22F support  / µTasker Kinetis TWR-K22F120M support

For the complete "out-of-the-box" Kinetis experience and faster time to market

2,063 Views
zoranm
Contributor III

Hi Mark. It is interesting after I put all those defines in the header a lot of my errors dissapear as you can see here. I am down to 11 now instead of 18. It seems that Kinetis Design Studio recognizes some of those headers you used. I will continue working to get the first use in this function errors cleared.

EDIT

Mark, so I created some defines in the header for the variables that were giving me errors as "undeclared (first use in this function)" as you can see here, but what values should I give them?

0 Kudos
Reply

2,063 Views
mjbcswitzerland
Specialist V

Zoran

The defines from kinetis.h at the link are:

#define CORTEX_M4_BLOCK 0xe000e000

#define RAM_START_ADDRESS (0x20000000 - (SIZE_OF_RAM/2)), where SIZE_OF_RAM is (128 * 1024) for the FRDM_K22

#define SYSTICK_PRIORITY 7 (mid-value - but can be chosen to be 0..15 of Cortex M4)

#define __interrupt (dummy define)

VECTOR_TABLE is

typedef struct stVECTOR_TABLE

{

    RESET_VECTOR  reset_vect;

    void  (*ptrNMI)(void);

    void  (*ptrHardFault)(void);

    void  (*ptrMemManagement)(void);

    void  (*ptrBusFault)(void);

    void  (*ptrUsageFault)(void);

    unsigned long ptrReserved0;

    unsigned long ptrReserved1;

    unsigned long ptrReserved2;

    unsigned long ptrReserved3;

    void  (*ptrSVCall)(void);

    void  (*ptrDebugMonitor)(void);

    unsigned long ptrReserved4;

    void  (*ptrPendSV)(void);

    void  (*ptrSysTick)(void);

    //PROCESSOR_IRQ processor_interrupts; // length is processor specific

} VECTOR_TABLE;

where RESET_VECTOR is

typedef struct stRESET_VECTOR

{

    void  *ptrResetSP;                                                   // initial stack pointer

    void  (*ptrResetPC)(void);                                           // initial program counter

} RESET_VECTOR;

You need to add the following line of code to allow the interrpt vector table to be in SRAM:

VECTOR_TABLE_OFFSET_REG = (unsigned long *)(RAM_START_ADDRESS);

which is defined as

#define VECTOR_TABLE_OFFSET_REG  *(unsigned long *)(CORTEX_M4_BLOCK + 0xd08) // Interrupt Control State Register
  #define TBLBASE_IN_RAM         0x20000000 // vector table base is in RAM
  #define TBLBASE_IN_CODE        0x00000000
  #define TBLOFF_MASK            0x1fffff80  // table offset from bottom of Code / RAM

You may need to globally enable interrupts with something like:

__asm__("cpsie   i"); (when using KDS)

or

__enable_irq(); (when using Keil).

Also you should put a prototype for RealTimeInterrupt() at the start of the file.

Finally you need to ensure that there are no variables located at the start of SRAM by starting the variables in the linker script file at

0x1fff01f0 rather than 0x1fff0000

eg. (for KDS)

SECTIONS

{

  __SRAM_segment_start__   = 0x1fff01f0;

  __SRAM_segment_end__     = 0x2000ffff;

...

With these mods you may get it to build and run - then you can turn your attention back to the original question about the core clock speed.

Regards

Mark

0 Kudos
Reply

2,063 Views
zoranmilosavlje
Contributor II

Mark, could you refer to my replies below and let me know what you think? Thanks very much.

0 Kudos
Reply

2,063 Views
mjbcswitzerland
Specialist V

Zoran

You are now using the Low Power Timer, which can be clocked from the LPO (1kHz), the slow interal clock (32.768kHz nominal), fast internal clock (4MHz nominal) or the external reference clock (if available).

Looking at the code

        .prescalerEnable = true,

        .prescalerClockSource = kClockLptmrSrcLpoClk,

        .prescalerValue = kLptmrPrescalerDivide2,

it looks like you have chosen the LPO divided by a prescaler of 2. This would mean the shortest interval is 2ms.

Since the LPO is not a very accurate clock (+/-10% over voltage and temperature) 2.023ms is probably what is expected.

To get 1ms you can presumably disable the prescaler and then get 1.0115ms.

If you need higher accuracy you would do better to choose a different clock source to the LPTMR.

Regards

Mark

Kinetis: µTasker Kinetis support

K22: µTasker Kinetis FRDM-K22F support  / µTasker Kinetis TWR-K22F120M support

For the complete "out-of-the-box" Kinetis experience and faster time to market

2,063 Views
zoranmilosavlje
Contributor II

Hi Mark. I just disabled the prescaler and I got 1.032ms. I am looking to get as close to 1ms as possible and as you suggested I can use another clock source to achieve this. If you look at this table I took out of the FRDM-K22F reference manual you can see all of the clock sources there. Which one would you recommend I use and how would I change my code to implement this new clock source?

0 Kudos
Reply

2,063 Views
mjbcswitzerland
Specialist V

Hello Zoran

I don't know the code that you are using but I suspect that you just need to set a different clock source for:

.prescalerClockSource = kClockLptmrSrcLpoClk,

The list of clocks in your link are not necessariyl the ones that can be used by the LPTMR - you need to check the LPTMR configuration to see them all.

Any of the others will be more accurate than the LPO.

Regards

Mark

Kinetis: µTasker Kinetis support

K22: µTasker Kinetis FRDM-K22F support  / µTasker Kinetis TWR-K22F120M support

For the complete "out-of-the-box" Kinetis experience and faster time to market

0 Kudos
Reply

2,063 Views
zoranmilosavlje
Contributor II

Hi Mark. I have been thinking about the core clock of this MCU and in your first reply you mentioned that either the 8MHz crystal can be used or the internal IRC48M reference clock. Are there any more crystals or reference clocks one could use to set the core clock of this MCU? I found this table in the reference manual. What are your thoughts?

0 Kudos
Reply

2,063 Views
dave408
Senior Contributor II

I usually just try stuff and see what happens.  In your case, you should be able to see where your currently-used clock's identifier is defined, and chances are there will be a bunch of other definitions next to it.  Pick the one for the 8MHz crystal and see what happens!

0 Kudos
Reply

2,063 Views
zoranmilosavlje
Contributor II

Hi dave408. Could you refer to my question to Mark Butcher from yesterday regarding the ADC configuration and let me know what you think?

0 Kudos
Reply

2,063 Views
dave408
Senior Contributor II

Hi Zoran, while I use Processor Expert, I also use the KSDK, so the components in my projects are different.  I don't have any experience with the components you are using.  My only observation is that it's not clear from your screenshots what sort of problem you're actually having.  For the output, there's a droplist next to Output pin, but you haven't indicated what happens when you try to change it.  And for the ADC input, it's not clear what you have done to try to select a different pin.

0 Kudos
Reply

2,063 Views
zoranmilosavlje
Contributor II

Hi dave408. Can you show me how you would do this using both Processor Expert and KSDK? I thought I could do this using only Processor Expert. After all, it is very simply what I am trying to do. All I need is to set one of the header pins to take in an analog voltage and another header pin to output the digital signal as a PWM so that I can probe it with a logic analyzer.

0 Kudos
Reply

2,063 Views
dave408
Senior Contributor II

I think you should be able to do it with or without the KSDK.  When I have time, I will put together a demo project for the FRDM-K22F, but unfortunately at the moment I have some deadlines to meet.

0 Kudos
Reply

2,063 Views
zoranmilosavlje
Contributor II

Sound good dave408. Will you upload the steps here?

0 Kudos
Reply

2,063 Views
dave408
Senior Contributor II

I'll upload the project.

0 Kudos
Reply

2,063 Views
zoranmilosavlje
Contributor II

Hi dave. Have you had the chance to take a look at this yet?

0 Kudos
Reply

2,063 Views
dave408
Senior Contributor II

Unfortunately, no.  I have several deadlines to meet and I'm currently running into issues with my Kinetis project that I need to figure out.  :smileysad:

0 Kudos
Reply