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

rtc nrf51 SDK example matches COMPARE0 only once

In order to learn how to use the RTC0 to handle an event every second, I am debugging the rtc SDK example.

Expectation: The rtc example sets the time to check the counter time at 3 seconds. I expect every 3 seconds. the int_type in rtc_handler() will equal NRF_DRV_RTC_INT_COMPARE0.

What I am seeing: the int_type in rtc_handler() equals NRF_DRV_RTC_INT_COMPARE0 after the first three seconds. Then int_type equals only NRF_DRV_RTC_INT_TICK.

Question: is my assumption correct the COMPARE0 should keep repeating such that there is a match every 3 seconds (in this example)

Question: If not, what is the example missing to do so?

thank you.

Parents
  • Hi

    The internal event handler of the rtc driver, i.e. the nrf_drv_rtc_int_handler, handles the RTC0 peripheral interupt and then calls the registered event handler of the application. If you look into the nrf_drv_rtc_int_handler, you see that interrupts for any COMPARE[x] events are disabled, while TICK and OVERFLOW interrupts are not disabled. If you avoid disabling the COMPARE[x] interrupts, then the COMPARE[0] interrupt will be recurrent after you clear the RTC0 counter. The following code shows the modified nrf_drv_rtc_int_handler where two lines are commented out to enable recurrent COMPARE[x] interrupt:

    __STATIC_INLINE void nrf_drv_rtc_int_handler(NRF_RTC_Type * p_reg, uint32_t instance_id)
    {
    		uint32_t i;
    		uint32_t int_mask = (uint32_t)NRF_RTC_INT_COMPARE0_MASK;
    		nrf_rtc_event_t event = NRF_RTC_EVENT_COMPARE_0;
    
    		for (i = 0; i < RTC_CHANNEL_NUM; i++)
    		{
    				if (nrf_rtc_int_is_enabled(p_reg,int_mask) && nrf_rtc_event_pending(p_reg,event))
    				{
    						//nrf_rtc_event_disable(p_reg,int_mask);
    						//nrf_rtc_int_disable(p_reg,int_mask);
    						nrf_rtc_event_clear(p_reg,event);
    						m_handlers[instance_id]((nrf_drv_rtc_int_type_t)i);
    				}
    				int_mask <<= 1;
    				event    = (nrf_rtc_event_t)((uint32_t)event + sizeof(uint32_t));
    		}
    		event = NRF_RTC_EVENT_TICK;
    		if (nrf_rtc_int_is_enabled(p_reg,NRF_RTC_INT_TICK_MASK) &&
    				nrf_rtc_event_pending(p_reg, event))
    		{
    				nrf_rtc_event_clear(p_reg, event);
    				m_handlers[instance_id](NRF_DRV_RTC_INT_TICK);
    		}
    
    		event = NRF_RTC_EVENT_OVERFLOW;
    		if (nrf_rtc_int_is_enabled(p_reg,NRF_RTC_INT_OVERFLOW_MASK) &&
    				nrf_rtc_event_pending(p_reg, event))
    		{
    				nrf_rtc_event_clear(p_reg,event);
    				m_handlers[instance_id](NRF_DRV_RTC_INT_OVERFLOW);
    		}
    }
    

    so with the above change to the nrf_drv_rtc and your proposed code of clearing the counter (as below code), it should work

    static void rtc_handler(nrf_drv_rtc_int_type_t int_type)
    {
    		if (int_type == NRF_DRV_RTC_INT_COMPARE0)
    		{
    				nrf_gpio_pin_toggle(COMPARE_EVENT_OUTPUT);
    				nrf_drv_rtc_counter_clear(&rtc);
    		}
    		else if (int_type == NRF_DRV_RTC_INT_TICK)
    		{
    				nrf_gpio_pin_toggle(TICK_EVENT_OUTPUT);
    		}
    }
    
  • in rtc_handler, after handling COMPARE0 interrupt and clear counter, you may also have to re-enable compare event by calling nrf_drv_rtc_cc_set(&rtc, 0, val, true);. Otherwise it may not be able to interrupt after the first time.

Reply Children
No Data
Related