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);
    		}
    }
    
  • By constantly adding your interval time to the compare register and have it overflow when at the top, you can have the rtc event trigger eternally with the same exact interval. The timer will also overflow but your new compare value will be ahead all the time. Other compare registers on the rtc timer can be used in the same manner without disturbing each other.

    Before the event nrf library code permanently disables the event requiring it to be enabled again.

    This code fragment is from inside the compare interrupt of the nRF52840:

    //Add a time portion to rtc counter compare	
    rtc.p_reg->CC[0] += COMPARE_COUNTERTIME * 8;
    
    //Re -enable COMPARE0 event & interrupt
    nrf_drv_rtc_int_enable(&rtc, NRF_RTC_INT_COMPARE0_MASK);
    

    The nrf_drv_rtc library only offers a nrf_drv_rtc_cc_set function so direct increment of the CC[0] compare register was used in the test.

Reply
  • By constantly adding your interval time to the compare register and have it overflow when at the top, you can have the rtc event trigger eternally with the same exact interval. The timer will also overflow but your new compare value will be ahead all the time. Other compare registers on the rtc timer can be used in the same manner without disturbing each other.

    Before the event nrf library code permanently disables the event requiring it to be enabled again.

    This code fragment is from inside the compare interrupt of the nRF52840:

    //Add a time portion to rtc counter compare	
    rtc.p_reg->CC[0] += COMPARE_COUNTERTIME * 8;
    
    //Re -enable COMPARE0 event & interrupt
    nrf_drv_rtc_int_enable(&rtc, NRF_RTC_INT_COMPARE0_MASK);
    

    The nrf_drv_rtc library only offers a nrf_drv_rtc_cc_set function so direct increment of the CC[0] compare register was used in the test.

Children
No Data
Related