NRF Timer doesn't start

Hi,

In my application I need an interrupt every 8us that I use as basetime, so I add a nrf timer to my code in the following way:

in the prj.conf

CONFIG_NRFX_TIMER1=y
CONFIG_NRFX_TIMER2=y

In the application:

#include <nrfx_timer.h>
#include <irq.h>

static const nrfx_timer_t mIrTimer = NRFX_TIMER_INSTANCE(2);
static volatile uint64_t mIrTimerCounter = 0;

static void irTimerHandler (nrf_timer_event_t event_type, void *p_context) 
{
    mIrTimerCounter += 8;
}

static bool startIrTimer (void) 
{
    nrfx_err_t errCode;

    nrfx_timer_config_t tmrConfig = NRFX_TIMER_DEFAULT_CONFIG;
    tmrConfig.frequency           = NRF_TIMER_FREQ_125kHz;
    tmrConfig.mode                = NRF_TIMER_MODE_TIMER;
    tmrConfig.bit_width           = NRF_TIMER_BIT_WIDTH_32;
    //tmrConfig.interrupt_priority  = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY;

    errCode = nrfx_timer_init(&mIrTimer,&tmrConfig,irTimerHandler);
    if (errCode != NRFX_SUCCESS) 
    {
		return false;
	}

    // Interrupt every 10us
    //nrfx_timer_extended_compare(&mIrTimer,NRF_TIMER_CC_CHANNEL1,10,NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK, true);

	IRQ_CONNECT(TIMER2_IRQn,2,nrfx_timer_2_irq_handler, NULL,0);

    nrfx_timer_clear(&mIrTimer);
    nrfx_timer_enable(&mIrTimer);

    return true;
}

I call the function startIrTimer() and the function return without any error, but the callback is never called. Where is it the problem?

Best

Marco

Parents
  • you seems to have commented out the nrfx_timer_extended_compare which actually sets the CC register needed to trigger the event and the interrupt. Have you tried uncommenting the nrfx_timer_extended_compare part? 

    Also you seem to be using 10 ticks hardcoded into the cc_value parameter in the nrfx_timer_extended_compare  function. 

    In my application I need an interrupt every 8us that I use as basetime,

    Setting 10 in CC of Timer running at 125KHz speed will give you a timeout of 80uS not 8uS (or maybe 8uS is a typo?)

  • Hi Susheel,

    thanks for the reply. Yes, you are right, 8us is a typo.

    In the application I need an interrupt every 10us, so I changed the code in this way:

    static bool startIrTimer (void) 
    {
        nrfx_err_t errCode;
    
        nrfx_timer_config_t tmrConfig = NRFX_TIMER_DEFAULT_CONFIG;
        tmrConfig.frequency           = NRF_TIMER_FREQ_1MHz;
        tmrConfig.mode                = NRF_TIMER_MODE_TIMER;
        tmrConfig.bit_width           = NRF_TIMER_BIT_WIDTH_8;
        //tmrConfig.interrupt_priority  = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY;
    
        errCode = nrfx_timer_init(&mIrTimer,&tmrConfig,irTimerHandler);
        if (errCode != NRFX_SUCCESS) 
        {
    		return false;
    	}
    
        // Interrupt every 10us
        nrfx_timer_extended_compare(&mIrTimer, NRF_TIMER_CC_CHANNEL0, 10, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
    
    	IRQ_CONNECT(TIMER2_IRQn,5,nrfx_timer_2_irq_handler, NULL,0);
    
        //nrfx_timer_clear(&mIrTimer);
        nrfx_timer_enable(&mIrTimer);
    
        return true;
    }

    Now the interrupt was triggered, but it seems to be ten times faster. How is it possible?

    Best

    Marco

  • instead of using 10 as hardcoded value in the nrfx_timer_extended_compare I suggest you use this code to get correct conversion.

    uint32_t desired_ticks = nrfx_timer_us_to_ticks(&mIrTimer, 10);
    
    // Interrupt every 10us
    nrfx_timer_extended_compare(&mIrTimer, NRF_TIMER_CC_CHANNEL0, desired_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
    

  • Hi Susheel,

    thank, with your suggestion the base-time works but not perfecty: I mean that the interrupt some time was triggered after 6us and other times after 29us. What is it wrong?

    Best

    Marco

Reply Children
  • Hi Susheel,

    I am using a pin to toggle its output just to show when the interrupt was trigger.

    The output is the yellow line.

    Thanks

    Marco

  • It seems like something else is masking your interrupt sometimes for a small period of time. It would be better if you enable tracing and use the systemview to get the overall timings of all contexts traced.

    Other than some other higher interrupt masking your timer interrupt sometimes, I do not see a valid explanation for this behavior. Once you understand which interrupt is doing this you will have better control on your timer. If you have BLE or any other RADIO protocol activity in parallel, then it makes sense that the protocol high priority activity is masking your application interrupt. Are you using BLE or any other radio protocol in parallel with your timer? If so, test the behavior of timer latencies without any other protocols to double confirm on the cause of this behavior.

Related