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 

Parents
  • 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) ;

  • 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) ;

Reply
  • 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) ;

Children
No Data
Related