Counter/Timer or RTC sample using nRF52

Hi,

I have seen some samples like samples\drivers\counter\alarm or samples\drivers\counter\maxim_ds3231 both using counter API.

Driver for rtc_mcp7940n is placed in counter folder and using counter and alarm API. So we can only use the counter API if any type of RTC we want to use with nrf52 or there are other options?

Also searching on google for nrf52 TIMER samples will always results in the samples from older versions of SDK. Is there any sample for nrf52 TIMER with the latest connect sdk? If not then how somebody can use the sample from older sdk versions into connect sdk? Or can we use the nrf52 peripheral Timer same as alarm sample using Counter API?

Thank you

  • Hello,

    Not sure if this is 100% what you were after, but hopefully it will help either way. That's where I struggled, and still struggle, is basic examples of how to use certain things. DevZone has a lot if you search, but you will find that there is a lot of older SDK code or broken links. I found the samples were good and when I didn't find a good sample I looked at the unit tests (under /tests). 

    Here is a timer example. I added two timers to show you how to use a single fire timer as well as a repeating timer. They also use the same callback so you can see how to reference multiple timers in the same callback so you know which one fired.

    #include <zephyr/zephyr.h>
    #include <zephyr/sys/printk.h>
    
    struct k_timer timer_a;
    struct k_timer timer_b;
    
    static void on_timer(struct k_timer *timer);
    
    void main(void)
    {
        k_timer_init(&timer_a, on_timer, NULL);
        k_timer_init(&timer_b, on_timer, NULL);
    
        k_timer_start(&timer_a, K_MSEC(1000), K_NO_WAIT);    // Will only fire once
        k_timer_start(&timer_b, K_MSEC(1000), K_MSEC(1000)); // Will fire every second
    }
    
    static void on_timer(struct k_timer *timer)
    {
        if (timer == &timer_a)
        {
            printk("Hello from timer A!\n");
        }
        else if (timer == &timer_b)
        {
            printk("Hello from timer B!\n");
        }
    }

    I know you didn't mention this, but I thought I would bring it up regardless. You can also use work queue, which is helpful when you need a repeating task when using multithreading and need a mutex lock. The mutex lock is optional, but I added it as an example.

    #include <zephyr/zephyr.h>
    #include <zephyr/sys/printk.h>
    
    typedef struct work_info {
        struct k_work_delayable work;
        struct k_mutex lock;
    } work_info_t;
    
    static work_info_t work;
    
    static void on_work(struct k_work *item);
    
    void main(void)
    {
        k_work_init_delayable(&work.work, on_work);
        k_work_schedule(&work.work, K_MSEC(1000));
    }
    
    static void on_work(struct k_work *item)
    {
        work_info_t *context = CONTAINER_OF(item, work_info_t, work);
    
        if (k_mutex_lock(&context->lock, K_NO_WAIT) == 0)
        {
            printk("Do work here under lock, which is great for when you're multithreading\n");
            k_mutex_unlock(&context->lock);
        }
    
        // Reschedule to keep repeating the work
        k_work_reschedule(&work.work, K_MSEC(1000));
    }

    Sorry if I misunderstood you. Best of luck.

  • Would you like to use the TIMER peripheral? For that, you can use the counter Alarm Sample and set CONFIG_COUNTER_NRF_TIMER=y. It will make the counter driver use Timer peripheral through the NRF HAL.

    If you would like to use the RTC peripheral, you can use k_timer like James suggested.

    Take a look at this DevZone ticket for a more detailed explanation:

     RE: TIMERS IN NRF5340 

    Best regards,

    Simon

Related