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

Timer is not accurate with softDevice.

Hi nordics!

First of all, thanks for answering my questions before.


Now, I want to generate a clock(48 pulses) with 200us width.

However, sometimes the width of pulse(clock) is not accurate.

image description

**yellow line is the clock line.

(Maybe it is because of the softDevice... I should make the pulse during BLE connection)

I read some post that I need to make the timer interrupt with GPIOTE, but I don't know how to make the timer interrupt with GPIOTE.

Can you fix my code up, or let me know some examples?

This is my code.

Thanks.


void timer2_init(void) {

uint32_t err_code;

// Configure timer
NRF_TIMER2->MODE      = TIMER_MODE_MODE_Timer;
NRF_TIMER2->BITMODE   = TIMER_BITMODE_BITMODE_16Bit;
NRF_TIMER2->PRESCALER = 4;


// Clear the timer
NRF_TIMER2->TASKS_CLEAR = 1;
NRF_TIMER2->CC[0] = 100;

NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;
NRF_TIMER2->SHORTS=(TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
//NRF_TIMER1->TASKS_START = 1;

err_code = sd_nvic_SetPriority(TIMER2_IRQn,3);
APP_ERROR_CHECK(err_code);  

}

void TIMER2_IRQHandler(void) {

if ((NRF_TIMER2->EVENTS_COMPARE[0] == 1) && 
    (NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE0_Msk))
{
    NRF_TIMER2->EVENTS_COMPARE[0] = 0;
    
    if(tick==0){
        nrf_gpio_pin_set(SCL);
        tick=1;    
    }
    else if(tick==1){
        nrf_gpio_pin_clear(SCL);
        tick=0;
        my_cnt++;  
    }  
}

//finish     
if(my_cnt==48){
  
    my_cnt=0;
    sd_nvic_DisableIRQ(TIMER2_IRQn);
    NRF_TIMER2->TASKS_STOP=1;
   
    nrf_gpio_pin_clear(SCL);   

}

}

static void my_app_timer_timeout_handler(void * p_context) {

 sd_nvic_ClearPendingIRQ(TIMER2_IRQn);
 sd_nvic_EnableIRQ(TIMER2_IRQn);  
 NRF_TIMER2->TASKS_START=1;
 nrf_gpio_pin_clear(SCL);

}

int main(void) {

// Initialize.
...
...

my_app_timer_init();
gpiote_init();
...
...
ble_stack_init();
scheduler_init();
...
...

my_app_timer_start();   //my_app_timer call the timer2 interrupt in every 20ms. 
advertising_start();
...
...
timer2_init();

// Enter main loop.
for (;;)
{
    app_sched_execute();
    power_manage();
}

}

Parents
  • Hi

    I suspect the root of this delay in clock is that the CPU is not available to process the TIMER2 interrupt. This is because the softdevice blocks the CPU up to 6 ms during a radio event. The thing you can do is to avoid using the CPU for the generation of the clock. Do that by using PPI channels instead. That way you connect the TIMER2 event directly with GPIOTE task. You can see how that is done in the gpiote_example in the nRF51 SDK.

    You would have to use sd_* function to configure and set the PPI channels after you initialize the softdevice. You can see an example of that in the PWM library on Github, namely in the nrf_pwm.c file line 57

Reply
  • Hi

    I suspect the root of this delay in clock is that the CPU is not available to process the TIMER2 interrupt. This is because the softdevice blocks the CPU up to 6 ms during a radio event. The thing you can do is to avoid using the CPU for the generation of the clock. Do that by using PPI channels instead. That way you connect the TIMER2 event directly with GPIOTE task. You can see how that is done in the gpiote_example in the nRF51 SDK.

    You would have to use sd_* function to configure and set the PPI channels after you initialize the softdevice. You can see an example of that in the PWM library on Github, namely in the nrf_pwm.c file line 57

Children
No Data
Related