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

Timer0 randomly changes time for NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK

So I am using ESB and want a very percise timer. Because the 16mhz clock is not 2^n we want it to roll over at a certain value that is a multiple of 16mhz, so we chose 4.096E9. We turn on the HF clock, init the timer0, setup some ppi for capturing interrupts (only one listed) and things work great.... sometimes.

Randomly sometimes the rollover_time changes. We don't call it anywhere in code, we only init once, but it could be 2 hours or 28 hours, but sometimes randomly it'll change it's rollover from 4.096E9 to something else. It's seems to decay over time from 4.096E9 to other but random values. This has happened on three distinct units. 

We can't find TIMER0 in use anywhere else (no softdevice), ESB has some fixes on TIMER2 and TIMER3, and a bunch of statically defined PPI's. Could this be it? Could the PPI's be doubly assigned because ESB.h does it statically?

const nrfx_timer_t TIME_HFCLK = NRFX_TIMER_INSTANCE(0);
#define TIMER0_ROLLOVER_TIME 4096000000u
static uint32_t rollover_time = TIMER0_ROLLOVER_TIME;

void clocks_start(void)
{
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;

    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
        ;
}

void hf_time_init(void)
{   
    ret_code_t err_code;
    //HFCLK TIMER
    nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG;
    err_code = nrfx_timer_init(&TIME_HFCLK, &timer_cfg, NULL);
    APP_ERROR_CHECK(err_code);
    
    //Fixes rollover by rolling over at a constant interval
    nrfx_timer_extended_compare(&TIME_HFCLK, NRF_TIMER_CC_CHANNEL0, rollover_time, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false); 
    
    //Start the timer
    nrfx_timer_enable(&TIME_HFCLK);

}

void hf_ppi_in_setup(void)
{
    uint32_t capture_evt_addr;
    uint32_t gpiote_task_addr;
    nrf_ppi_channel_t ppi_channel;
    ret_code_t err_code;

    //get an available ppi channel
    err_code = nrfx_ppi_channel_alloc(&ppi_channel);
    APP_ERROR_CHECK(err_code);

    //get the addresss for the gpiote high accuracy input based on the sensor
    gpiote_task_addr= nrfx_gpiote_in_event_addr_get(in_SENSOR);
    capture_evt_addr = nrfx_timer_event_address_get(&TIME_HFCLK, NRF_TIMER_TASK_CAPTURE1);

    //Assign a ppi channel to the "wiring"
    err_code = nrfx_ppi_channel_assign(ppi_channel, gpiote_task_addr, capture_evt_addr);
    APP_ERROR_CHECK(err_code);

    //turn on the ppi task
    err_code = nrfx_ppi_channel_enable(ppi_channel);
    APP_ERROR_CHECK(err_code);

}

We're trying on TIMER1 now and after 16 hours no bug, but one of the last times took 30 hours on TIMER0 for it to show up, but sometimes it's 5 minutes. None of the nrfx_timer_extended_compare or nrfx_timer_compare commands and timers are not touched anywhere else. Nothing was using TIMER0 (no soft device no use anywhere else) and we can't find anything that might use TIMER0 in our code. Some searching reveals LIBUART might but we're only using RTT Logging. Because it's random and can take hours to days we can't seem to find what's causing it. Is there any bugs in the TIMER0?

Parents Reply
  • Unfortunately they are in a Laird BL652-SA module we have limited hardware we can't risk removing the RF can as they don't have the right skillsets in house (it's remote from me). They are definitely of a QFN variety. 

    The switching to TIMER1 may have alleviated some of this. We've noticed tying the PPI to a capture task to more accurately get the time when we see a pulse works well but sometimes it gives stray results even when tied to ground. It

Children
No Data
Related