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

NRF52 DK: LF External Crystal Clarification

Starting from this example I try to bring clock functionality to my BLE-project.

1. The external LFCLK-XTAL

I need some clarification about the use of the different clock sources on the Development Kit. I searched through the Q&A, but did not find a concrete statement about that:

(the links of this question are leading to the Q&A-start-page)

The NRF52 DK-User Guide says, that an OPTIONAL 32.768kHz Crystal X2 can be soldered to the board, which is directly connected to the GPIO Pin P0.00 and P0.01. My board has nothing soldered to this, so far so good.

In the sdk_config.h of the example projects the ClockSource for the soft device is always set to 1, which means it's clocked to some XTAL:

// <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
 
// <0=> NRF_CLOCK_LF_SRC_RC 
// <1=> NRF_CLOCK_LF_SRC_XTAL 
// <2=> NRF_CLOCK_LF_SRC_SYNTH 

#ifndef NRF_SDH_CLOCK_LF_SRC
#define NRF_SDH_CLOCK_LF_SRC 1
#endif

(1) All the examples are running on my board, so, which XTAL is used then?

I see that there are two Oscillators X1 (lose to the nrf52832 Bluetooth chip) and X2 (close to the ARM Cortex M4F chip) soldered to the board but I guess (2) these are the HF-Oscillators?

2. Starting/accessing the HFCLK from the soft device

I understand that the soft device is using the HFCLK and the LFCLK. According to this article the soft device is powering off the HFCLK if it's not needed by the BLE-stack but it can be enabled manually via a call to the sd_clock_hfclk_request()-function. So, if my soft device is working correctly (and from this I assume that a valid HFCLK has been selected by the soft device)
why does this code keeps stuck in the while loop / why is the HFCLK not starting?

NRF_LOG_DEBUG("requesting HFCLK via softdevice function");
		sd_clock_hfclk_request();
	
		NRF_LOG_DEBUG("checking in loop if HFCLK is running");
		uint32_t * nrf_clock_running_flag = 0;
		sd_clock_hfclk_is_running(nrf_clock_running_flag);
	
		int n = 0;
    while(!nrf_clock_running_flag){
			if(n % 1000000 == 0) NRF_LOG_DEBUG("clock is not running: %i, while-loop: %i", nrf_clock_running_flag, n);
			n++;
			if(n > 10000000) n= 0;
		}
		NRF_LOG_DEBUG("clock is running");

 

PS: is there a reason why the nordic-website is so slow from Germany? Pages and Insert-Code-windows are loading really slow.

  • If I understand things correctly, there are two crystals which you can connect to the nRF52 devices:

    - A 32MHz crystal

    - A 32.768KHz crystal

    The CPU clock and peripheral bus clocks are derived from the high frequency clock (HFCLK). There are two possible sources for the HFCLK: an internal RC oscillator or a 64MHz high frequency crystal oscillator (HFX) which is locked using an external 32MHz crystal.

    At power up, the CPU doesn't know if it has a crystal connected or not, and there isn't a strapping pin to tell it, so by default it will run off the internal RC oscillator. You can switch to using the HFXO instead by do the NRF_CLOCK->TASKS_HFCLKSTART register.

    The real-time clock (RTC) is derived from the low frequency clock (LFCLK). The LFCLK has three possible sources: 1) an internal RC oscillator, 2) an external 32.768KHz crystal, or 3) synthesized from the HFCLK.

    As with the HFCLK, at power-up the chip will use the internal RC oscillator for the LFCLK by default. To change the source you have to write to the NRF_CLOCK->LFCLKSRC.

    Ideally you'd like to have crystals for both clocks, in order to have the best accuracy and stability.

    I think all that sd_clock_hfclk_request() does is start the HFXO. It doesn't actually start the HFCLK, because if that clock was not running, the CPU would grind to a halt.

    I think your code is subtly wrong. You only call sd_clock_hfclk_is_running() once. The idea is that this function returns the current state of the HFXO. I think you need to keep calling it so that once the clock does start, you'll detect it. Also, you're passing it a NULL pointer. That's not how this works.

    In other words, I think you want this:

    uint32_t nrf_clock_running_flag;
    
    nrf_clock_running_flag = 0;
    
    while (1) {
            sd_clock_hfclk_is_running (&nrf_clock_running_flag);
            if (nrf_clock_running_flag == 1)
                    break;
    }
    

    -Bill

  • Hey Bill,

    Thank you very much! Indeed, the code was sloppy and wrong, my appologies!

    The only point where I still stuck is why, if in the sdk_config.h the macro NRF_SDH_CLOCK_LF_SRC is set to 1 (which means NRF_CLOCK_LF_SRC_XTAL, what references to the external 32.768KHz crystal, right?), the code is working, altough no external 32.768kHz crystal is mounted to my board at the GPIO XTAL soldering points.

    And another thing:

    The "ApplicationTimer"-Library has accually nothing to do with the timers which are derived from the HFCLK, right? It looks like the instances of timer-library depend on the RTC which is derived from the LFCLK. So that's kind of confusing too...

  • You're correct in that if you select the LFCLK source to be the crystal and you don't have one, then things wouldn't work. But I may have misunderstood something when I read your original post.

    You said: "My board has nothing soldered to this."

    One question: did you mean "my board" as in "I have a custom board of my own design" or "my board" as in "my own particular nRF52 Development Kit board?"

    I think at first glance I thought you meant the former, but I realize now you probably meant the latter.

    If so (i.e. you're talking about the nRF52 DK board), then you *do* actually have the 32.768KHz crystal mounted. It's very small so it may be hard to see it, but it's there. Hold the board face-up so that the Nordic nRF52 chip is on the right and the J-Link chip and USB plug are on the left. Look closely at the rectangle outline where the nRF52 is mounted. Immediately to the left of the chip you should see X2. To the top and right of the chip, you should see X1.

    X1 is the 32.768KHz crystal and X2 is the 32MHz crystal.

    The term "Optional" in the Nordic documentation is misleading. It's optional in the sense that depending on your custom application/board design requirements, you may be able to get away without it. (You could chose one of the other LFCLK clock source options instead.) With the DK board, the crystal is there, but you also have the option of cutting two traces on the board to disconnect it so that you can use P0.00 an P0.01 as GPIOs instead. As it is now, you can't use those pins for that purpose because the crystal is there.

    Note that for the 32MHz crystal, there are two dedicated pins which can't be used as GPIOs, so there's no need to ever physically disconnect it.

    Regarding the application timer library. I think this is just a library provided in the SDK which provides application timers which use the RTC1 timer instance as their hardware timer source. At the hardware level, the nRF52 chip provides two kinds of hardware timers:

    TIMER -- 5 instances, driven by the peripheral bus clocks (derived from HFCLK)

    RTC -- 2 instances, driven by the LFCLK

    The RTC uses less power.

    -Bill

Related