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

Disable SD stops ALL RTCs and/or LFCLK?

Hi all,

I got strange behavior: when I disable the SoftDevice (nRF52832, S132 V3.0, SDK 12.2) seem that ALL the RTCs, not just the one used by the SD, are stopped, and also the LFCLK are stopped.

This behavior, of course (why?) do not occours when I'm debugging.

Here my code:

void Ble_DeInit(void)
{
uint8_t sd_enabled;
uint32_t err_code;
sd_softdevice_is_enabled(&sd_enabled);

if(ble_state != Ble_State_SD_Disabled){

    Ble_Set_Connectability(OFF);

    do{
        Ble_Task();
    }while(Ble_Flags.set_connectability != 0 && Ble_Flags.reset_connectability != 0 && ble_state != Ble_State_Idle);
    }

    if(sd_enabled)
    {
    err_code = softdevice_handler_sd_disable(); // ~ -125uA
    APP_ERROR_CHECK(err_code);
    Ble_Flags.is_sd_active = 0;
    }

    /* softdevice_handler_sd_disable disables the lfclk (?): re-enable */
    nrf_drv_clock_uninit();     // to avoid the error
    err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);
    nrf_drv_clock_lfclk_request(NULL); // ~ +60uA

    ble_state = Ble_State_NOT_INITIALIZED;
}

Any idea? Thanks!

  • Solved!

    I changed my code as follow:

     void Ble_DeInit(void)
     {
     uint8_t sd_enabled;
     uint32_t err_code;
     sd_softdevice_is_enabled(&sd_enabled);
    
        if(ble_state != Ble_State_SD_Disabled){
    
             Ble_Set_Connectability(OFF);
    
            do{
                Ble_Task();
            }while(Ble_Flags.set_connectability != 0 && Ble_Flags.reset_connectability != 0 && ble_state != Ble_State_Idle);
        }
    
        if(sd_enabled)
        {
            err_code = softdevice_handler_sd_disable(); // ~ -125uA
            APP_ERROR_CHECK(err_code);
            Ble_Flags.is_sd_active = 0;
        }
    
        if(!nrf_drv_clock_lfclk_is_running()){
             nrf_drv_clock_lfclk_request(NULL);
    
             // de-init and re-init RTC
             DateTime_Init_RTC();
        }
    
         ble_state = Ble_State_NOT_INITIALIZED;
     }
    

    This is the body of DateTime_Init_RTC function:

        void DateTime_Init_RTC(void){
    
        if(DateTime_Flags.initialized){
            nrf_drv_rtc_tick_disable(DATETIME_RTC);
            nrf_drv_rtc_disable(DATETIME_RTC);
            nrf_drv_rtc_uninit(DATETIME_RTC);
        }
    
        // Setup RTC
        nrf_drv_rtc_config_t config;
        config.prescaler            = RTC_FREQ_TO_PRESCALER(DATETIME_RTC_FREQ_HZ);
        config.interrupt_priority   = DATETIME_RTC_IRQ_Priority;
        config.reliable             = RTC_DEFAULT_CONFIG_RELIABLE;
        config.tick_latency         = RTC_US_TO_TICKS(NRF_MAXIMUM_LATENCY_US, RTC_DEFAULT_CONFIG_FREQUENCY);
        uint32_t err_code           = nrf_drv_rtc_init(DATETIME_RTC, &config, DateTime_RTC_Handler);
        APP_ERROR_CHECK(err_code);
    
        //Enable tick event & interrupt
        nrf_drv_rtc_tick_enable(DATETIME_RTC, true);
    
        //Power on RTC instance
        nrf_drv_rtc_enable(DATETIME_RTC);
    
        datetime_tick_counter = 0;
    }
    
  • Thanks. I have the same issue with SDK14.2. I am trying multiprotocol, and did not expect disabling SD to stop the LF clock, and thus in my case, app_timer. (I think that is what is happening.)

    It would be nice if Nordic commented on whether this is documented behaviour. My opinion is that the SD should not own the LF clock, and should not be stopping it. For use cases: 1) LF clock used for a calendar clock (your case) 2) LF clock used for multiprotocol app_timer

    In my case, when the LF clock is stopped by disabling SD, it has serious consequences for the other protocol. In your case, isn't your calendar clock wrong now because the LF clock stopped?

    Also, if SD disable stops the LF clock, then the Nordic multiprotocol example is flawed, because it also uses app_timer, which would be stopped when LF clock is stopped.

  • Now I am reading other posts and the code in nrf_drv_clock.c. See sd_state_evt_handler(). The clock driver is notified when the sd is disabled, and "releases" the LF clock. That means it decrements a count of users of the clock, and stops the clock if there are no more users. The question now is, doesn't app_timer qualify as a user of the LF clock? For you, the question is similar. Maybe "nrf_drv_clock_lfclk_request(NULL);" with a NULL handler does not increment the count of users/requesters?

Related