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

Possible bug in nrf52832 LFCLK

[Bug Report] Possible bug in nRF52832 engineering release B. When LF XTAL oscillator is started, no event is generated.

NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_Xtal;
NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)   { };      // STUCK HERE FOREVER!!

The oscillator is actually started but no event is generated.

  • updated with code that worked (29.01.2016)

    Maybe it needs one clk cycle or two between selection of the clock source and starting the lfclk, try this below

    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
    __DSB();     //<-- This will wait until write buffers are emptied.
    NRF_CLOCK->TASKS_LFCLKSTART = 1;
    while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
    {
    }
    

    i do not have engineering sample B to test it with. If the above code works, then i should ask someone here to test out why the event missed.

  • This sounds a little bit like the write buffer scenario mentioned in the porting notes. I wonder if the write to LFCLKSRC isn't completing before the write to LFCLKSTART, or basically they end up completing together and so the source isn't really set and the clock event doesn't get sent.

    You could try reading NRF_CLOCK->LFCLKSRC after writing it to force the write buffer to clear.

    I think we're going to see this write-may-need-read scenario catching people out, it caught me out last week!

  • RK, but he said that it is stuck in the while loop for ever, that is the part that confused me. If it is the write buffer then it should have exited the while loop in few cycles.

  • agreed - however I wondered if the two writes, the one to the LFCLKSRC and LFCLKSTART end up getting committed at the same time because they get buffered and flushed together. I don't know what the LF clock would do if it gets both registers written at exactly the same time, possibly something a bit indeterminate.

    I'm just guessing at possibilities, I know the write buffer exists but I still don't quite have a good handle on exactly when it may or may not need a flush.

  • Yes, It is possible. In that case inserting _DSB() in between setting the clock source and starting the clock should handle that. Do you think the below code fits?

    NRF_CLOCK->LFCLKSRC            = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; 
    __DSB();
    NRF_CLOCK->TASKS_LFCLKSTART    = 1;
    
    while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
    {
        // Do nothing.
    }
    
Related