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

nrf_drv_timer interrupt handler get called instantly

I have been developing an application using PCA10028 board which needs to use timer. From the SDK8.0.0 pack, I found an example "timer_pca10028". It works fine when the SD is not at present.

Then I used part of the code inside my own application to try the timer. In my case, I used the SD. Thus the #define TIMER1_ENABLED 1 is applied in the "nrf_drv_config.h". Below is my code snippet:

const nrf_drv_timer_t STREAM_PAC = NRF_DRV_TIMER_INSTANCE(1);

void  timer_stream_event_handler (nrf_timer_events_t event_type)
{
    uint8_t   i;
    uint32_t   err_code;

    switch(event_type)
    {
        case NRF_TIMER_EVENTS_COMPARE1:
		AppTask(); //my staff to work here
        break;
        default:
        //Do nothing.
        break;
    }
}

int main (void)
{
    uint32_t time_ms = 50; //Time(in miliseconds) between consecutive compare events.
    uint32_t time_ticks;
    uint32_t err_code;
    err_code = nrf_drv_timer_init(&STREAM_PAC, NULL, timer_stream_event_handler);
    APP_ERROR_CHECK(err_code);

    time_ticks = nrf_drv_timer_ms_to_ticks(&STREAM_PAC, time_ms);

    nrf_drv_timer_extended_compare(&STREAM_PAC, NRF_TIMER_CC_CHANNEL1, time_ticks, NRF_TIMER_SHORTS_COMPARE1_CLEAR_MASK, true);

    nrf_drv_timer_enable(&STREAM_PAC);
    while (1)
    {
            power_manage();
    }
}

This is part of my main function. In real case, it also contains app_timer used by bsp.h to control LED. But this part is the last function I called before entering the main loop. Generally, the differences compared to timer_pca10028 examples are SD at present and timer1 is enabled. But when I did this, the stream_event_handler is getting called constantly instead of after the timer interval I setup inside the main function. When I change the time_ms, the time interval did not change any.

Could anyone give some suggestions on this issue? Thanks in advance!

Parents
  • The problem is with your PRESCALER and time_ms. With PRESCALER = 0 in the timer you generate 0X3E80 (16000) ticks per millisecond. So for your 50ms number of ticks required is C3500. This does not fit in 16-bit TIMER1. Change the prescaler so that your time_ticks will be able to fit in 16-bit TIMER1 CC register.

    changed the prescaler to 4 instead of 0 using

    nrf_timer_frequency_set(STREAM_PAC.p_reg, NRF_TIMER_FREQ_1MHz);
    

    after initializing the timer and it will work with the precision you need, which I verified by copying your timer code into ble_app_beacon_s110 example.

  • Questchin,

    I missed to see your comment, i would strongly recommend you not to directly write to timer registers when using nrf drivers. Nrf drivers had internal state machine, your code will not necessarily be compatible with future SDKs where they might store the value of prescaler inside the driver and then it would create a conflict.

Reply Children
No Data
Related