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

understanding nrfx_rtc_cc_set timing

Hi

I am setting an interrupt off the RTC to cause wakeup from nrf_pwr_mgmt_run(); This is to conserve power. My code is working but the times are out by an order of magnitude. I am wanting to sleep a max of about 20ms. I have the following three functions - 

/* @brief Function for handling the idle state (main loop).
 *
 *  @details If there is no pending log operation, then sleep until next the next event occurs.
 * 
 */
void sched_idle_state_handle(void)
{
    /// @todo need to disable all peripherals - otherwise they will run and chew power
    app_sched_execute();

    /// @todo need to set RTC to generate a wakeup interrupt
    if (NRF_LOG_PROCESS() == false)
    {
NRF_LOG_DEBUG("IDLE - GOING TO SLEEP: %d", nrfx_rtc_counter_get(&rtc));
        /// if we fail on the set wakeup it means that we were preempted and already gone over the time
        if (set_wakeup(SLEEP_TIME_MS))
           nrf_pwr_mgmt_run(); // equivalent of going to sleep until next event - ie hard event
    }
NRF_LOG_DEBUG("IDLE - WOKEN: %d", nrfx_rtc_counter_get(&rtc));
    /// @todo need to enable all peripherals
}

/** @brief configure the RTC for wakeup duties
*
*/
void rtc_config_wake(void)
{
    uint32_t err_code;

    if (!is_uninit) {
       nrfx_rtc_disable(&rtc);
       nrfx_rtc_uninit(&rtc);
    }

    // get the crystal buzzing
    /// The clock is also used by the softdevice. Depending on what else is started we may or may not have to start it
    if (!nrfx_clock_lfclk_is_running())
       lfclk_config();

    //Initialize RTC instance
    nrfx_rtc_config_t config = NRFX_RTC_DEFAULT_CONFIG;
    config.prescaler = RTC_FREQ_TO_PRESCALER(RTC_FREQ_WAKE);
    err_code = nrfx_rtc_init(&rtc, &config, rtc_handler);
    APP_ERROR_CHECK(err_code);
    is_uninit = false;

    //set the counter to 0
    nrfx_rtc_counter_clear(&rtc);

    //Power on RTC instance
    nrfx_rtc_enable(&rtc);
}

/** @brief set an interrupt to wake us up
**  @param[in] sleep_ms the time to sleep in millisecs
*/
bool set_wakeup(uint32_t sleep_ms) {
uint32_t err_code;

    rtc_config_wake();

    err_code = nrfx_rtc_cc_set(&rtc,  0, NRFX_RTC_US_TO_TICKS(sleep_ms * 1000, RTC_FREQ_WAKE),true);
    if (err_code == NRFX_ERROR_TIMEOUT) {
       NRF_LOG_DEBUG("set wakeup benign timeout");
       return false;
    } else APP_ERROR_CHECK(err_code);
    return true;
}

The first is called in the main loop so that when the machine is idle it will sleep. It calls the set_ wakeup to set an interrupt that will wake us up. Of course all sorts of other things may wake us up but this is the max time to sleep so that non interrupt events are checked every now and then. 

The RTC prescaler frequency is 640 (RTC_FREQ_WAKE) and the goal time is 20ms. This should give a tick count of about 128 ticks. But obviously I have a wrong understanding because it gives about 12 ticks. 6400 gives the desired 128 ticks. 

Can someone please explain?

Cheers Paul

Parents Reply Children
No Data
Related