Timer accuracy with softdevice

I have a scenario where the timer needs to be strictly 250us timed and repeated,  aligned with GPS 1pps.

To achieve this goal, I use the rising edge event of GPS 1PPS to capture the value of the timer, so as to evaluate the error of the timer for correction. GPIOTE is used for the rising edge of GPS 1PPS, and PPI is used for capturing.

Now the problem is that if I enable the softdevice, the CC value captured by each 1pps will vary greatly, at the 100us level; If softdevice is not enabled, the difference of CC value captured by each 1pps is very small, about 0.25us.

does the protocol stack affect TIMER accuracy?   The following is the core code:

static void mcu_ad_timer_init( void )
{

    NRF_TIMER1->BITMODE = 0;    
    NRF_TIMER2->PRESCALER = 2;   
    NRF_TIMER2->MODE = 0;         


    NRF_TIMER1->CC[0] = 1000;  

    NRF_TIMER1->SHORTS = (1<<0);

    NRF_TIMER1->INTENSET = (1<<16);

    NVIC_ClearPendingIRQ(TIMER1_IRQn);
    NVIC_SetPriority(TIMER1_IRQn, 2);
    NVIC_EnableIRQ(TIMER1_IRQn);

}

static void sync_1pps_port_init( void )
{
    nrf_gpio_cfg_input(SYNC_1PPS_PIN,NRF_GPIO_PIN_PULLUP);
   
    NRF_GPIOTE->CONFIG[0] &= ~(GPIOTE_CONFIG_PORT_PIN_Msk | GPIOTE_CONFIG_POLARITY_Msk);
    NRF_GPIOTE->CONFIG[0] |= ((SYNC_1PPS_PIN  << GPIOTE_CONFIG_PSEL_Pos)&GPIOTE_CONFIG_PORT_PIN_Msk ) |    
                              ((NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_Pos)&GPIOTE_CONFIG_POLARITY_Msk );  
    NRF_GPIOTE->CONFIG[0] |= GPIOTE_CONFIG_MODE_Event;

    NRF_GPIOTE->INTENSET  = 1;
    
    NVIC_ClearPendingIRQ(GPIOTE_IRQn);
    NVIC_SetPriority(GPIOTE_IRQn, 2);
    NVIC_EnableIRQ(GPIOTE_IRQn);
}

static void sync_1pps_event_bond( void )
{
    NRF_PPI->CH[0].EEP     = (uint32_t)(&NRF_GPIOTE->EVENTS_IN[0]);
    NRF_PPI->CH[0].TEP     = (uint32_t)(&NRF_TIMER1->TASKS_CAPTURE[1]) ;

    NRF_PPI->CHEN = 0;
}

Parents
  • Hi,

    The timer peripheral itself is not affected by the SoftDevice, and is completely independent. There is one thing to remember though, and that is that for the timer to be accurate, you need to request the HFXO so that it does not use the HFINT as clock source. If you don't, you will be using the (inaccurate) HFINT for the most part, except when there is radio activity, as the SoftDevice will enable the HFXO for those times.

    As the SoftDevice does not impact the timer, there must be another issue. I do not see enough of you r code to get a full overview, but I see that you use shorts and PPI, which is independent of the CPU when configured, and thus also independent of the SoftDevice. However, I also see that you enable interrupt but I don't know what you are doing in the interrupt handler. A key point here is that the interrupt may be delayed if a higher priority SoftDevice interrupt is being processed at that time, so you should make sure to not depend on the timing of the interrupt (so don't do things like restarting timers etc. in an interrupt, instead this must be done with shorts or PPI in order to avoid such issues).

    Lastly, I notice a few things worth mentioning. You write to both TIMER1 and TIMER2 registers, but I assume all should have been TIMER1? Also, you set the CC to 1000, and while that could be right, it seems wrong, as the counter counts from 0, and the clearing of the counter via a short also takes a clock cycle. This would give a consistent bias though, so it should not be related to the issue you are seeing.

Reply
  • Hi,

    The timer peripheral itself is not affected by the SoftDevice, and is completely independent. There is one thing to remember though, and that is that for the timer to be accurate, you need to request the HFXO so that it does not use the HFINT as clock source. If you don't, you will be using the (inaccurate) HFINT for the most part, except when there is radio activity, as the SoftDevice will enable the HFXO for those times.

    As the SoftDevice does not impact the timer, there must be another issue. I do not see enough of you r code to get a full overview, but I see that you use shorts and PPI, which is independent of the CPU when configured, and thus also independent of the SoftDevice. However, I also see that you enable interrupt but I don't know what you are doing in the interrupt handler. A key point here is that the interrupt may be delayed if a higher priority SoftDevice interrupt is being processed at that time, so you should make sure to not depend on the timing of the interrupt (so don't do things like restarting timers etc. in an interrupt, instead this must be done with shorts or PPI in order to avoid such issues).

    Lastly, I notice a few things worth mentioning. You write to both TIMER1 and TIMER2 registers, but I assume all should have been TIMER1? Also, you set the CC to 1000, and while that could be right, it seems wrong, as the counter counts from 0, and the clearing of the counter via a short also takes a clock cycle. This would give a consistent bias though, so it should not be related to the issue you are seeing.

Children
No Data
Related