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

How to check nRF52840 external low frequency crystal (32kHz) is connected or not?

Hi,

Using SDK 15.2.0 and SD S140_6_1_1.

I have two hardware of nRF52840, one has external LF crystal(32kHz) and another does not.

Want to run same firmware file in both hardware so Is there any way to detect external crystal is connected or not by firmware?

In our firmware I am using USB also.

Thanks,

Nirav Patel 

  • Hi Nirav

    You can not dynamically switch between clocks during operation. By default, all our SDK examples are set to use the external LF crystal, but you can easily switch to the internal RC or synthesized LF clock by editing the following parameters in your sdk_config.h file: NRFX_CLOCK_CONFIG_LF_SRC, CLOCK_CONFIG_LF_SRC, and NRF_SDH_CLOCK_LF_SRC(if you use the SoftDevice).

    Best regards,

    Simon

  • Hi,

    if you want to use a single firmware for both boards, you can write some flag to UICR that will indicate whether LFXO is installed. If this way is inconvenient for your case, just start LFXO and wait for 0.25 sec, then check if it's not started, switch to RC:

    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
    NRF_CLOCK->TASKS_LFCLKSTART = 1;
    for (int cnt=0; cnt<LFXO_TIMEOUT; cnt++)
        if (NRF_CLOCK->EVENTS_LFCLKSTARTED) break;
    if (! NRF_CLOCK->EVENTS_LFCLKSTARTED) {
        NRF_CLOCK->TASKS_LFCLKSTOP = 1;
        // maybe wait some time here
        NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
        NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
        NRF_CLOCK->TASKS_LFCLKSTART = 1;
    }
    while (! NRF_CLOCK->EVENTS_LFCLKSTARTED) ;

  • Great suggestion Dmitry! I've updated my previous reply to better reflect what's possible and not.

    Best regards,

    Simon

  • Good idea!
    Adding some lines that are needed in some toolchains:

    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    
    */  Synchronize register writes to 16MHz AHB clock by reading the same register. *
    *   Protect against out of order execution by explicitly casting to volatile.    */
    (volatile void)NRF_CLOCK->EVENTS_LFCLKSTARTED; 
    
    NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
    NRF_CLOCK->TASKS_LFCLKSTART = 1;
    for (int cnt=0; cnt<LFXO_TIMEOUT; cnt++)
        if (NRF_CLOCK->EVENTS_LFCLKSTARTED) break;
    if (! NRF_CLOCK->EVENTS_LFCLKSTARTED) {
        NRF_CLOCK->TASKS_LFCLKSTOP = 1;
        // maybe wait some time here
        NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
        
        */  Synchronize register writes to 16MHz AHB clock by reading the same register. *
        *   Protect against out of order execution by explicitly casting to volatile.    */
        (volatile void)NRF_CLOCK->EVENTS_LFCLKSTARTED; 
    
        NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
        NRF_CLOCK->TASKS_LFCLKSTART = 1;
    }
    while (! NRF_CLOCK->EVENTS_LFCLKSTARTED) ;

Related