This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How can I use Zephyr's API to set clock source to external 32MHz crystal for NRF52840-DK

Hi there, 

I have a question about using zephyr on my nrf52840-DK board: I want to set the system to run at 64MHz for Zephyr. However, I can't find an option to do that. And if I run the following code block to measure the cycles of a second: 

```

u32_t then = k_cycle_get_32();

k_sleep(1000);

u32_t now = k_cycle_get_32();

printk("then: %d, now: %d, diff = %d\n", then, now, now - then);

```

It always return a diff number around 32768. Does the MCU run at only 32KHz by default?  How can I force it to run at 64MHz given that the board has the external 32MHz crystal? 

Thank you! 

Jun 

Parents
  • Does the MCU run at only 32KHz by default?

    Not really.

    The LF clock (either RC or crystal OSC) is the only clock source that is kept running continously. The 64MHz HF clock (sourced either internally or from the 32MHz crystal) is only enabled when necessary. This allows significant power saving: Chip uses single digit µA instead of a few 100µA in idle.

    That is also why k_cycle_get_xxx() uses the 32.768Hz RTC counter for time keeping, even though it is rather coarse.

    You can verify that the Cortex-M4 core runs at full 64MHz when executing instructions by running a benchmark of some sorts.

  • thanks for the reply! Really appreciate it!

    I’m running an application that uses the crypto cell but doesn’t use the radio. So, power consumption is not a big concern. How can I set the system always runs at 64MHz by using Zwphyr API, clock control? Should the cycles per second be changed to match the clock change as well?

  • Hi,

    The CPU always runs off the 64 MHz clock. It only needs the RC oscillator, and the clock is only running when needed. The xtal oscillator is used for a more accurate clock. If you don't care about current consumption and always want the high accuracy 64 MHz clock running (of the 32 MHz xtal), then you can enable the crystal oscillator at startup and just leave it running. You can use the Clock Control API for this.

    This clock will not be used by the k_cycle_get functions though, but you could use a TIMER peripheral to count clock cycles if that is what you want.

Reply
  • Hi,

    The CPU always runs off the 64 MHz clock. It only needs the RC oscillator, and the clock is only running when needed. The xtal oscillator is used for a more accurate clock. If you don't care about current consumption and always want the high accuracy 64 MHz clock running (of the 32 MHz xtal), then you can enable the crystal oscillator at startup and just leave it running. You can use the Clock Control API for this.

    This clock will not be used by the k_cycle_get functions though, but you could use a TIMER peripheral to count clock cycles if that is what you want.

Children
  • Einar, 

    Thanks for your clarification! 

    I have more questions: 

    1. The default clock source of a Zephyr application is LFCLK, i.e., 32K xtal, right? 

    2. If so, does it mean the zephyr application runs only at 32KHz clock by default? Or the clock changes based on the load? 

    3. In what way can I verify the MCU runs at 64MHz after calling the `clock control API`? 

    Thank you! 

    Jun

  • Read the PS. Most of your points are plainly wrong.

    In what way can I verify the MCU runs at 64MHz after calling the `clock control API`? 

    Run a benchmark, count the instructions, measure the time it took to execute all those instructions.

    Or just maybe read over on infocenter.arm.com about the DWT Cycle counter register...

  • Thanks for the reply! I read the PS. So my understanding is 

    1. The MCU always works at 64MHz once waking up no matter if the external crystal is used or not. 

    2. The reason to use the external 32MHz crystal is just to provide higher accuracy  HCLK.

    3. Likewise, the reason to enable the external 32KHz is to give more accuracy clock to RTC when the system goes to sleep. 

    right? 

    So, my last question, why is the default setting for CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC set to 32768 in Zephyr given that the hw clock is actually 64MHz? Any special considerations behind that? 

  • Hi Jun,

    jli157@intel said:
    1. The default clock source of a Zephyr application is LFCLK, i.e., 32K xtal, right? 

    No. The CPU always runs of the 64 MHz clock, either RC or xtal (using 32 MHz xtal as reference). The 32.768 kHz clock is very low power and typically always running, and used for keeping track of time (for instance to wake up the device for BLE connection events etc.)

    jli157@intel said:
    3. In what way can I verify the MCU runs at 64MHz after calling the `clock control API`? 

    There is no point in verifying this, since 64 MHz is the only possibility.

    Einar

  • Hi,

    jli157@intel said:
    1. The MCU always works at 64MHz once waking up no matter if the external crystal is used or not. 

    Yes.

    jli157@intel said:
    2. The reason to use the external 32MHz crystal is just to provide higher accuracy  HCLK.

    Yes.

    jli157@intel said:
    3. Likewise, the reason to enable the external 32KHz is to give more accuracy clock to RTC when the system goes to sleep. 

    Yes, though not only when the system is going to sleep. The 32 kHz clock is typically always running.

    jli157@intel said:
    So, my last question, why is the default setting for CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC set to 32768 in Zephyr given that the hw clock is actually 64MHz? Any special considerations behind that? 

    That is because this is the clock that is used to keep track of time, and is always running. Most nRF applications are low power, and it makes no sense to use the high-frequency clock always in a low power application (it would make the average current consumption very high).

Related