Using app timer in sdk13

Tostikoning gravatar image

asked 2017-04-21 09:58:42 +0100

Hi all,

I am using a nRF52832 with SD S132 V4.0.2 ion SDK13.

My application currently uses TWI, SPI and BLE and also 1 wire (which is based on delays). Everything works fine. The 1 wire is used before the SD is enabled and after it is done it will not be used anymore, so it wouldn't interfere with the SD.

On my custom board I have an ADC conected through SPI. I want to take a sample every 100ms based on a app timer timeout. However the timeout interrupt is not fired.

I use the following code in main start:

NRF_LOG_INIT(NULL); // Initialize the logging module

err_code = app_timer_init();

/* Initialize peripherals */

/* Initialize bluetooth */

/* Start advertising on start-up */
err_code = ble_advertising_start(BLE_ADV_MODE_FAST);


The timer is started in measurement_start and created in measurement_create:


void measurement_init(void)
    uint32_t time_base;
    ret_code_t err_code;

    /* Define a timer id used for 10Hz sample rate */
    err_code = app_timer_create(&m_pt100_timer_id, APP_TIMER_MODE_REPEATED, measurement_handler);

void measurement_start(void)
    /* Start timer */
    app_timer_start(&m_pt100_timer_id, MEAS_TIMER_INTERVAL, NULL);

    /* Clear previous measurement in flash */


void measurement_handler(void * p_context) // this code is not fired
    float   temperature = 0, pressure = 0;

    // do measurement, code currently not included

I have the following questions:

  1. Does app_timer module enable RTC1 or do I need to enable it?
  2. Do I need to initialize the LF clk?
  3. Should I first enable the softdevice and then the timer, or the other way around?
  4. Do you guys know why my timeout is not fired?
edit retag flag offensive close delete report spam

2 answers

Sort by ยป oldest newest most voted
Tostikoning gravatar image

answered 2017-04-21 12:19:03 +0100

updated 2017-04-21 12:19:34 +0100

With help from @Sigurd I managed to find the problem. It was a problem all programmers will experience in their careers and one of my finest "d'oh" moments.

You should create the timer with the following function:

ret_code_t app_timer_create(app_timer_id_t const *      p_timer_id,
                            app_timer_mode_t            mode,
                            app_timer_timeout_handler_t timeout_handler)

And start the timer with the following function:

ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context)

Notice the difference in the first argument. The init requires an address of your timer id, and when you start a timer it only needs a copy. So when I changed my call from:

err_code = app_timer_start(&m_pt100_timer_id, APP_TIMER_TICKS(1000), NULL);


err_code = app_timer_start(m_pt100_timer_id, APP_TIMER_TICKS(1000), NULL);

It worked like a charm! Oh and btw, do not try to debug after the softdevice was enabled, it can get quirky.

edit flag offensive delete publish link more
sigurdon gravatar image

answered 2017-04-21 11:13:30 +0100


Q1: Does app_timer module enable RTC1 or do I need to enable it?

A1: The app_timer module enable RTC1 in the function app_timer_init()

Q2:Do I need to initialize the LF clk?

A2:If you are using the SoftDevice, the LFCLCK gets initialized and enabled when you enable the SoftDevice.

Q3:Should I first enable the softdevice and then the timer, or the other way around?

A3: You can do both, but you won't get any timeout before the LFCLK is started.

Q4:Do you guys know why my timeout is not fired?

A4: Try to change app_timer_start(&m_pt100_timer_id, MEAS_TIMER_INTERVAL, NULL); with app_timer_start(m_pt100_timer_id, APP_TIMER_TICKS(100), NULL);

edit flag offensive delete publish link more


Hi Sigurd,

I tried the change you suggested in A4. Unfortunately it did not work. The following snippet is from the sdk_config.h:

    // <e> APP_TIMER_ENABLED - app_timer - Application timer functionality
// <o> APP_TIMER_CONFIG_RTC_FREQUENCY  - Configure RTC prescaler.

// <0=> 32768 Hz
// <1=> 16384 Hz
// <3=> 8192 Hz
// <7=> 4096 Hz
// <15=> 2048 Hz
// <31=> 1024 Hz


// <o> APP_TIMER_CONFIG_IRQ_PRIORITY  - Interrupt priority

// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest)
// <1=> 1
// <2=> 2
// <3=> 3
// <4=> 4
// <5=> 5
// <6=> 6
// <7=> 7


// <o> APP_TIMER_CONFIG_OP_QUEUE_SIZE - Capacity of timer requests queue.
// <i> Size of the queue depends on how many timers are used
// <i> in the system, how often timers are started and overall
// <i> system latency. If queue size is too small app_timer calls
// <i ...
Tostikoning ( 2017-04-21 11:20:10 +0100 )editconvert to answer

The rest of the application is working fine? The only problem is that the timeout is not fired?

Have you tried debugging the application? Are you running into the error handler somewhere? See this post on how to debug.

Sigurd ( 2017-04-21 11:25:53 +0100 )editconvert to answer

Yeah, I mean I can connect to my application and read all my data. I use a LED blinking from main, just to detect if no error has occured or if it is stuck. It keeps blinking. A different LED is toggled in the handler, which does not blink, even when I set it to 1s instead of 100ms. In the debugger I do not enter the handler. Should I use the wait for event functions? Are those mandatory for the intterupt to fire? Also I do not use the scheduler.

Tostikoning ( 2017-04-21 11:34:18 +0100 )editconvert to answer

What does app_timer_start(m_pt100_timer_id, APP_TIMER_TICKS(100), NULL); return? Try do send the err_code to the error handler:

void measurement_start(void)
    ret_code_t err_code;
    /* Start timer */
    err_code = app_timer_start(&m_pt100_timer_id, MEAS_TIMER_INTERVAL, NULL);

    /* Clear previous measurement in flash */

Sigurd ( 2017-04-21 11:39:03 +0100 )editconvert to answer

Okay, this helped me. Not in an expected way. I missed a reset. i put a breakpoint in the measurement start function. No error code is returned but i can see it resetting. I'll try to investigate this further.

EDIT 1: Strange things are happening. I also placed a breakpoint in the RTC1_IRQHandler in app_timer.c . Another breakpoint is in measurement_start() just after

err_code = app_timer_start(m_pt100_timer_id, APP_TIMER_TICKS(5000), NULL);

btw app_timer_start does not like to get a address of the timer id, but would rather like a copy.

ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context);

This change allows me to enter the RTC1_IRQHandler() however I still do not enter my own handler and it still resets.

Also it only enters the RTC1_IRQhandler if I wait a a few seconds, if I just continue it resets without entering the RTC1_IRQHandler(). I will continue..

EDIT 2: If I change the ...(more)

Tostikoning ( 2017-04-21 11:42:34 +0100 )editconvert to answer

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer. Do not ask a new question or reply to an answer here.

[hide preview]

Question Tools

1 follower


Asked: 2017-04-21 09:58:42 +0100

Seen: 498 times

Last updated: april 21