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

doubt with saadc example from SDK

Hello!

I'm learning how to use properly the saadc for knowing muy battery state of discharge. First of all I'm testing the saadc example which is included in the SDK, changing paramenters, understaning the functions...etc.

In this function in particular is where I have troubles:

/* setup m_timer for compare event every 400ms */
uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 400);

I understand that this function is for convert the ms which I want the timer interrupt to occur to ticks of the timer.

And in the function definition:

__STATIC_INLINE uint32_t nrf_drv_timer_ms_to_ticks(
                                   nrf_drv_timer_t const * const p_instance,
                                   uint32_t timer_ms)

I can see that the number of ticks is a variable uint32, so it could have a value from 0 to 4294967295.

In my aplication i would like to have a saadc conversion every 5 minutes, so, my timer_ms should be:

5min * 60sec/min * 1000ms/sec = 300000ms And this number doesn't exceed the uint32_t range.

But when I run the program, I can see a converted value (yes, only one, I changed the following define: #define SAMPLES_IN_BUFFER 1, before was 5) every 30sec aprox, not every 5min.

What is the problem? I have noticed that if my variable timer_ms is 60000:

uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 60000);

I have a value from the saadc every minute, and if it's 5*60000:

uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 5*60000);

the error still hapens... Thank you all, here is my code (is a txt file, I can't put the code well on the web with the text editor): main.c And a screen capture of the values showed: image description

  • Hi,

    The default frequency of TIMER0 is 16 MHz. If you have not changed this, the return value of nrf_drv_timer_ms_to_ticks() will overflow the uint32_t return variable.

    The function calculates the number of ticks using the formula:

    (time_ms * 16000 kHz) / (2^prescaler)
    

    where prescaler is related to frequency like this:

    f = 16000 kHz / 2^prescaler
    

    With the timer frequency set to 16 MHz, this will give a prescaler value of 0. For 5 minutes, the formula then return:

    4800000000 > 4294967295
    

    This overflow of the uint32_t variable will give a return value from nrf_drv_timer_ms_to_ticks() of 505032704. There is a ASSERT check within the function to avoid this overflow, but this does not seem to fire. I will check this out.

    To run timers for longer time than ~4.48 minutes, you will have to set a lower frequency of the timer. You can do this when configuring your timer with the following lines:

    nrf_drv_timer_config_t m_timer_config= NRF_DRV_TIMER_DEFAULT_CONFIG(0);
    m_timer_config.frequency = NRF_TIMER_FREQ_8MHz;
    err_code = nrf_drv_timer_init(&m_timer, &m_timer_config, timer_handler);
    

    Or you can set the prescaler value directly:

    NRF_TIMER0->PRESCALER = 1;
    

    Notice that you cannot use the nrf_drv_timer_ms_to_ticks() function for values above (2^32)/16000 ~= 268435ms. You can still do the calculation yourself, or create your own function to do this calculation for larger values.

    Best regards,

    Jørgen

Related