I am using NRF52832 for BLE application with softdevice 132 under SDK15.3. My application is supposed to sleep off after certain amount of time when there is no user activity and using ppi to read SAADC (pressure sensor) with 20 ms interval. So if SAADC input doesn't go over a predefined limit, it regards no user interaction and wait for 1 hour and sleep off. It did work well using SAADC and PPI with TIMER peripheral.
I upgraded my application to low power SAADC, which provided very good energy saving with good adc reading and good sleeping.
And I continued to change TIMER to RTC, which gave more energy saving but as side effect my device never falls a sleep off anymore. (but it reads SAADC well)
I am using RTC2 with two channels. Channel 0 for sleep off and channel 1 for SAADC capture interval with compare interrupt. And I noticed that the SAADC capture interval clears whole RTC2 timer and ends up disabling the sleep off time setup. I also read https://devzone.nordicsemi.com/f/nordic-q-a/23317/rtc-clear-ppi-after-compare/91668#91668 and https://devzone.nordicsemi.com/f/nordic-q-a/8772/rtc-nrf51-sdk-example-matches-compare0-only-once#post-id-49056 but they are not my case, I think.
I am a beginner in Nordic world. Please help me out with easy words. Thanks.
#define POWER_OF_PRESCALER 4 //0..12 #define PRESCALER (1<<POWER_OF_PRESCALER)-1 #define RTC_FREQ 32768/PRESCALER #define NRFX_RTC_MS_TO_TICKS(ms, rtc_freq_hz) (((ms) * (rtc_freq_hz)) / 1000U) #define NRFX_RTC_SEC_TO_TICKS(sec, rtc_freq_hz) ((sec) * (rtc_freq_hz)) #define NRFX_RTC_MIN_TO_TICKS(min, rtc_freq_hz) ((min) * (rtc_freq_hz) * 60) #define SLEEP_OFF_TIMER_MINUTES 60 //minutes to sleep off when no user activity #define SLEEP_OFF_TICKS NRFX_RTC_MIN_TO_TICKS(SLEEP_OFF_TIMER_MINUTES, RTC_FREQ) #define PS_CAPTURE_INTERVAL_MS 20 //ms for pressure seonsor capture interval #define PS_TICKS NRFX_RTC_MS_TO_TICKS(PS_CAPTURE_INTERVAL_MS, RTC_FREQ) static void rtc_handler(nrf_drv_rtc_int_type_t int_type) { uint32_t err_code; if (int_type == NRF_DRV_RTC_INT_COMPARE0) { //nrf_gpio_pin_toggle(COMPARE_EVENT_OUTPUT); sleep_mode_enter(); } if (int_type == NRFX_RTC_INT_COMPARE1) //for test ps interval only { //workaround for recurring COMPARE[x] interrupt is diabled in nrf_drv_rtc_init_handler err_code = nrf_drv_rtc_cc_set(&rtc, 1, PS_TICKS, true); APP_ERROR_CHECK(err_code); nrf_gpio_pin_toggle(LED_3); //Test only } } static void rtc_config(void) { uint32_t err_code; //Initialize RTC instance nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG; config.prescaler = PRESCALER; err_code = nrf_drv_rtc_init(&rtc, &config, rtc_handler); APP_ERROR_CHECK(err_code); //Enable tick event & interrupt - NO NEED! //nrf_drv_rtc_tick_enable(&rtc,true); //Set compare channel 0 to trigger interrupt for sleep off timer err_code = nrf_drv_rtc_cc_set(&rtc, 0, SLEEP_OFF_TICKS , true); APP_ERROR_CHECK(err_code); //Set compare channel 1 to trigger interrupt for pressure sensor interval for ppi err_code = nrf_drv_rtc_cc_set(&rtc, 1, PS_TICKS, true); APP_ERROR_CHECK(err_code); } void timer_with_ppi_init(void) { ret_code_t err_code; // a variable to hold the error code // Initialize the PPI (make sure its initialized only once in your code) err_code = nrf_drv_ppi_init(); APP_ERROR_CHECK(err_code); // check for errors rtc_config(); //Enable on RTC instance nrf_drv_rtc_enable(&rtc); // Save the address of compare event so that it can be connected to ppi module uint32_t rtc_compare_event_addr = nrf_drv_rtc_event_address_get(&rtc, NRF_RTC_EVENT_COMPARE_1); uint32_t rtc_clear_task_addr = nrf_drv_rtc_task_address_get(&rtc, NRF_RTC_TASK_CLEAR); // Save the task address to a variable so that it can be connected to ppi module for automatic triggering uint32_t saadc_sample_task_addr = nrf_drv_saadc_sample_task_get(); // Allocate the ppi channel by passing it the struct created at the start err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel); APP_ERROR_CHECK(err_code); // check for errors // attach the addresses to the allocated ppi channel so that its ready to trigger tasks on events err_code = nrf_drv_ppi_channel_assign(m_ppi_channel, rtc_compare_event_addr, saadc_sample_task_addr); APP_ERROR_CHECK(err_code); // check for errors err_code = nrf_drv_ppi_channel_fork_assign(m_ppi_channel, rtc_clear_task_addr); APP_ERROR_CHECK(err_code); }