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

nrf52 timer example, over 5 minutes event handler.

When I test the timer example with nrf52832 DK, it so nice to 4 minutes.

uint32_t time_ms = 240000;

But when I set the time interval over 5 minutes, then the event handler run more rapidly.

So, what should I do for long time period?

Parents
  • Hi JW,

    By default, the timer runs at 16 MHz and the maximum bit width of the timer is 32-bit. This corresponds to a maximum timer value of:

    (2^32)-1 = 4294967295
    

    The reason why you see event handler more rapidly with 5 minutes, is that nrf_drv_timer_ms_to_ticks use the configured frequency and the time_ms parameter to generate the number of ticks, and return this in a 32 bit variable:

    5*60*16000000 = 4800000000
    

    This overflows the 32 bit variable, giving you a tick count of 505032705 = ~31.5 seconds.

    You need to change the frequency of the timer to make it run run slower. This is done by changing the timer configuration:

    timer_cfg.frequency = NRF_TIMER_FREQ_8MHz;
    

    You can set it to any of the frequencies documented here.

    Best regards,

    Jørgen

  • It should not affect other projects, as this only changes the multiplication result from 32 to 64 bits. The ASSERT in the nrf_timer_ms_to_ticks() should have fired when you called the function with time_ms = 300000, but this does not seems to have happened. I'm not sure why, but I have reported this issue internally.

    If you want to keep the ASSERT and make sure all inputs are valid, you can use this function:

    __STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms,
                                                   nrf_timer_frequency_t frequency)
    {
        // The "frequency" parameter here is actually the prescaler value, and the
        // timer runs at the following frequency: f = 16000 kHz / 2^prescaler.
        uint32_t prescaler = (uint32_t)frequency;
        uint64_t ticks = ((time_ms * 16000ULL) >> prescaler);
        ASSERT(ticks <= UINT32_MAX);
        return (uint32_t)ticks;
    }
    

    You can configure the timer frequency all the way down to 31250 Hz, which should give you a maximum of ~2290.6 minutes. If you want to run timers longer, you can use the RTC. The RTC can be configured to run for up to ~582.5 hours before overflowing. RTC is also lower power than the TIMER.

Reply
  • It should not affect other projects, as this only changes the multiplication result from 32 to 64 bits. The ASSERT in the nrf_timer_ms_to_ticks() should have fired when you called the function with time_ms = 300000, but this does not seems to have happened. I'm not sure why, but I have reported this issue internally.

    If you want to keep the ASSERT and make sure all inputs are valid, you can use this function:

    __STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms,
                                                   nrf_timer_frequency_t frequency)
    {
        // The "frequency" parameter here is actually the prescaler value, and the
        // timer runs at the following frequency: f = 16000 kHz / 2^prescaler.
        uint32_t prescaler = (uint32_t)frequency;
        uint64_t ticks = ((time_ms * 16000ULL) >> prescaler);
        ASSERT(ticks <= UINT32_MAX);
        return (uint32_t)ticks;
    }
    

    You can configure the timer frequency all the way down to 31250 Hz, which should give you a maximum of ~2290.6 minutes. If you want to run timers longer, you can use the RTC. The RTC can be configured to run for up to ~582.5 hours before overflowing. RTC is also lower power than the TIMER.

Children
No Data
Related