Our device uses an nRF52840 and we are using SDK v15.3.0 and soft device v140.
In order to optimize power consumption, I want to make a delay function using the RTC (with external oscillator) that will put the device to sleep while it waits.
The delay using the RTC works, as indicated via the LED, but it doesn't go to sleep.
Elsewhere in the code I can successfully enter sleep.
Following is edited and condensed code for how I am trying to implement this delay.
const nrf_drv_rtc_t _realTimClock = NRF_DRV_RTC_INSTANCE(2); ///< Declaring an instance of nrf_drv_rtc for RTC2. rtc_callback_t _callbacks[RTC_NUM_CHANNELS]; ///< RTC has 4 timer compare registers. void rtcInit(void) { uint32_t errorCode; /// Initialize RTC instance nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG; config.prescaler = 32; errorCode = nrf_drv_rtc_init(&_realTimClock, &config, rtc_handler); APP_ERROR_CHECK(errorCode); /// Disable tick event & interrupt nrf_drv_rtc_tick_enable(&_realTimClock, false); /// Power on RTC instance nrf_drv_rtc_enable(&_realTimClock); } void runCallback(uint8_t rtc_compare_channel_id) { /// Run the requested callback function. _callbacks[rtc_compare_channel_id](); } /** * @brief: Function for handling the RTC0 interrupts. * Triggered on TICK and COMPARE0 match. */ static void rtc_handler(nrf_drv_rtc_int_type_t int_type) { switch(int_type) { /// Intentional fall throughs. case NRF_DRV_RTC_INT_COMPARE0: case NRF_DRV_RTC_INT_COMPARE1: case NRF_DRV_RTC_INT_COMPARE2: case NRF_DRV_RTC_INT_COMPARE3: /// Run the requested callback function. runCallback(int_type); break; case NRF_DRV_RTC_INT_OVERFLOW: /// RTC overflow event. break; case NRF_DRV_RTC_INT_TICK: /// RTC tick event. break; default: /// Unknown RTC event. Added for completeness. break; } } bool setMsCallback(uint8_t id, uint64_t milliSeconds, rtc_callback_t handler) { uint32_t errorCode; uint32_t delayTimeMs = milliSeconds*RTC_TICKS_PER_SECOND/1000; _callbacks[id] = handler; errorCode = nrf_drv_rtc_cc_set(&_realTimClock, id, (delayTimeMs + nrf_drv_rtc_counter_get(&_realTimClock)), true); APP_ERROR_CHECK(errorCode); if (errorCode == 0) { return true; } else { return false; } } static void ledToggle(void) { nrf_gpio_pin_toggle(PIN_RED_LED); } void rtc_delayMs(uint32_t period) { /// Trigger the RTC to restart and toggle the LED in 'period' number of milliseconds. Using setMsCallback(NRF_DRV_RTC_INT_COMPARE2, period, ledToggle); NVIC_ClearPendingIRQ(RTC2_IRQn); /// Make sure the RTC IRQ is enabled. NVIC_EnableIRQ(RTC2_IRQn); /// Go to sleep. sd_app_evt_wait(); } int main(void) { ///setup systick timer SysTick_Config( SystemCoreClock / 1000 ); rtcInit(); BLEInit(); /// BLE will start interrupts and LFClk ... /// Test the newly implemented RTC delay with sleep. nrf_gpio_cfg_output(PIN_RED_LED); nrf_gpio_pin_set(PIN_RED_LED); while(1) { rtc_delayMs(5000); } }