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

HFCLKSTART blocks changes to LFCLKSRC

Using a nRF51822-QFAC-A1 on the nRF51-DK I noticed unexpected behavior when starting the HFCLK and LFCLK in rapid succession. This variant reproduces the problem at startup:

NRF_CLOCK->TASKS_HFCLKSTART = 1;
NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_Xtal;
while (! NRF_CLOCK->EVENTS_HFCLKSTARTED) {
}
NRF_CLOCK->TASKS_LFCLKSTART = 1;

With this configuration both clocks start but NRF_CLOCK->LFCLKSTAT shows the clock source to be RC, not Xtal, and it never changes to Xtal. In fact, LFCLKSRC reads back 0 instead of 1 as it was assigned.

If I move the wait-for-started before the assignment to LFCLKSRC then the expected behavior is observed: LFCLKSTAT shows RC immediately, but switches to Xtal after the crystal has stabilized. Delays up to 500 us are not a substitute for waiting for EVENTS_HFCLKSTARTED.

Without trying more variations, it appears that writes to some clock registers are ignored between TASKS_HFCLKSTART and EVENTS_HFCLKSTARTED. I don't see a dependency of this sort documented in the nRF51 SRM v3.0 or in PAN v3.0; is this a known anomaly, or documented somewhere else?

  • Hi pabigot, Very nice description of the problem. I will try this today

  • I have tested this now. And I see that only selecting the the LFCLKSRC is ignored and trying to set some other register just works fine if done in between HFCLKSTART and EVENTS_HFCLKSTARTED.

    It is not a big thing as you mentioned but I agree that this needs to be documented. I will create a internal ticket for the team to document this. It will be handled for sure (internal tickets get solved at some point), but cannot give you any time line.

    Thanks for pointing this out.

  • You're welcome. I confirm that if LCFLKSRC is assigned before HFCLKSTART the wait is not necessary and the two startups can proceed in parallel, which shaves 800 us off the clock configuration sequence. I don't have a pre-V3 chip to hand to test; if you can verify this anomaly also exists in V2 chips I'd like to know.

  • That is not a good idea to completely skip waiting for one. There are different types of external clocks and the stable time is different for different crystal oscillators.

    Instead, we can make use of your observation and do this

    NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_Xtal;
    NRF_CLOCK->TASKS_LFCLKSTART = 1;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    while (! NRF_CLOCK->EVENTS_HFCLKSTARTED) {}
    while (! NRF_CLOCK->EVENTS_LFCLKSTARTED) {}
    

    With the above code, you can still start the clocks in parallel and do not have to wait if LFCLK already started along with HFCLK, but we also now handled the cases where in some cases it wont.

  • Didn't mean to imply I wasn't going to wait before counting on clock stability, just that I was looking for a way to run the start sequence in parallel without waiting between the two starts. In the framework I'm developing the wait-for-stability is delayed until the point stability is actually needed (e.g., TIMER or RTC startup); there's a lot of other non-timing-critical initialization that can occur while the clocks stabilize, and the RC sources are fine for that work.

Related