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

Can I use Timer1 and RTC on the same app?

Hi all,

I would like someone give me a suggestion about timers.

in my current approvement I am using an RTC timer with 32k crystal to control my sleep times it is power efficient and accurate, but limited if I want to use micro seconds interruptions.

I need to generate delays for 5us for a custom protocol to transfer data, I could use nrf_delay_us function, but it will keep the CPU running. it worth implement a TIMER for such delay? 

I also tried to port the code from Timer example to my code (it uses softdevice) I am using the TIMER1 as far I see. but it is not working properly

#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_drv_timer.h"
#include "bsp.h"
#include "app_error.h"

const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(1);

void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
{
    static uint32_t i;
    uint32_t led_to_invert = ((i++) % LEDS_NUMBER);

    switch (event_type)
    {
        case NRF_TIMER_EVENT_COMPARE0:
            bsp_board_led_invert(led_to_invert);
            break;

        default:
            //Do nothing.
            break;
    }
}

void Start_timer(void)
{
    uint32_t time_ms = 500; //Time(in miliseconds) between consecutive compare events.
    uint32_t time_ticks;
    uint32_t err_code = NRF_SUCCESS;

    //Configure all leds on board.
    bsp_board_leds_init();

    //Configure TIMER_LED for generating simple light effect - leds on board will invert his state one after the other.
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    err_code = nrf_drv_timer_init(&TIMER_LED, &timer_cfg, timer_led_event_handler);
    APP_ERROR_CHECK(err_code);

    time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_LED, time_ms);

    nrf_drv_timer_extended_compare(
         &TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);

    nrf_drv_timer_enable(&TIMER_LED);

}

talking in efficiency what is better nrf_delay_us(5) vs use TIMER1 for 5us delay

I also was wondering if is possible set a value to the RTC counter to control when it overflow, for example if it is working at 8 bit, set 250, ant it will overflow every 5 ticks

Thanks

  • Hello,

    Is this case related to your other case?

    I will assume that it is, but let me know if this is a separate issue, and I will look into it.

    Best regards,

    Edvin

  • Hi Ed,

    Yes, it is. I am trying to have alternatives, But it is a little confusing on the documentation the term Timer could be use for app timer for RTC and the Timer0,1, etc. 

    For example using this code I am unable to change the prescaler or bit width chaning the values on timer_cfg

  • Have you tried to configure the timer_cfg?

    In addition you can use the nrf_drv_timer_us_to_ticks();

    const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(3);
    
    void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
    {
        switch (event_type)
        {
            case NRF_TIMER_EVENT_COMPARE0:
                bsp_board_led_invert(3);
                break;
        
            default:
                // Do nothing.
                break;
        }
    }
    
    int main(void)
    {
        uint32_t time_us = 1000000; //Time(in microseconds) between consecutive compare events.
        uint32_t time_ticks;
        uint32_t err_code = NRF_SUCCESS;
    
        //Configure all leds on board.
        bsp_board_leds_init();
    
        //Configure TIMER_LED for generating simple light effect - leds on board will invert his state one after the other.
        nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
        timer_cfg.frequency = NRF_TIMER_FREQ_1MHz;
        timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_24;
        err_code = nrf_drv_timer_init(&TIMER_LED, &timer_cfg, timer_led_event_handler);
        APP_ERROR_CHECK(err_code);
    
        time_ticks = nrf_drv_timer_us_to_ticks(&TIMER_LED, time_us);
    
        nrf_drv_timer_extended_compare(
             &TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
    
        nrf_drv_timer_enable(&TIMER_LED);
    
        while (1)
        {
            __WFI();
        }
    }

    If you look into the functions that are being used, such as the nrf_drv_timer_init(), you can see that it essentially uses the PPI functionality that we discussed in your other case.

    If you use the timer with the softdevice, you can't use timer instance(0), because the softdevice uses timer instance 0. Therefore I changed it to 3.

    I also changed the timeout handler, because the normal SDK ble examples uses LED1 and (sometimes 2) to display connection status.

    Best regards,

    Edvin

Related