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

app_timer interrupt for dongle (pca10059)

Hallo,

I try to use app_timer on the dongle to raise an interrupt every 5 min.

The goal is to send the µC in power save mode and every 5 min, it shall wake up, measure a distance with an attached sensor and send the value via thread/mqttsn to my server. It is all implemented except the timer. I wanted to test it first with a simple example of a blinking LED.

When I try to recreate this tutorial (I skipped the buttons, since i want the timer to start after boot up automatically) with the DK, everything works fine. But using the code on the dongle, it doesn't work. It isn't blinking. That's my code:

#include <stdbool.h>

#include "boards.h"
#include "bsp.h"
#include "nrf_drv_clock.h"
#include "app_timer.h"
#include "nrf_log_ctrl.h"
#include "nrf_log.h"
#include "nrf_log_default_backends.h"
#include "nrf_drv_gpiote.h"

APP_TIMER_DEF(m_repeated_timer_id);     /**< Handler for repeated timer used to blink LED 1. */

/***************************************************************************************************
 * @section Initialization
 **************************************************************************************************/

/**@brief Function for initializing the Application Timer Module.
 */
static void timer_init(void)
{
    uint32_t err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing the nrf log module.
 */
static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();
}

static void gpio_init(void)
{
    nrf_drv_gpiote_init();    
    nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(true);
    nrf_drv_gpiote_out_init(BSP_LED_0, &out_config); //G
    nrf_drv_gpiote_out_init(BSP_LED_1, &out_config); //R
    nrf_drv_gpiote_out_init(BSP_LED_2, &out_config); //G
    nrf_drv_gpiote_out_init(BSP_LED_3, &out_config); //B 
}

/**@brief Function starting the internal LFCLK oscillator.
 *
 * @details This is needed by RTC1 which is used by the Application Timer
 *          (When SoftDevice is enabled the LFCLK is always running and this is not needed).
 */
static void lfclk_request(void)
{
    ret_code_t err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);
    nrf_drv_clock_lfclk_request(NULL);
}

/**@brief Timeout handler for the repeated timer.
 */
static void repeated_timer_handler(void * p_context)
{
    nrf_drv_gpiote_out_toggle(BSP_LED_2);
    nrf_drv_gpiote_out_toggle(BSP_LED_3);
}

/**@brief Create timers.
 */
static void create_timers()
{
    ret_code_t err_code;

    // Create timers
    err_code = app_timer_create(&m_repeated_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                repeated_timer_handler);
    APP_ERROR_CHECK(err_code);
    
}

/***************************************************************************************************
 * @section Main
 **************************************************************************************************/

int main(int argc, char *argv[])
{  
    lfclk_request();
    app_timer_init();
    log_init();
    gpio_init();
    
    //nrf_drv_gpiote_out_toggle(BSP_LED_2);

    create_timers();

    app_timer_start(m_repeated_timer_id, APP_TIMER_TICKS(1000), NULL);
    
    NRF_LOG_INFO("Application timer tutorial example started.");
   
    while (true)
    {
        __WFI();

    }
}

I figured out, if I switch on LED2 inside the main() first, the LED starts flickering depending on the APP_TIMER_TICKS (but timing is not correct). But LED3 does nothing. That means for me, I can't access the timer handler and therefore no interrupt is fired. But the timer seems to run, kind of, since LED2 is flickering if set in the first place.

Ps: I use Linux, SDK17, VS-Code, pca10059

Parents
  • Hi, 

    I do not see any issue in your code.

    I figured out, if I switch on LED2 inside the main() first, the LED starts flickering depending on the APP_TIMER_TICKS (but timing is not correct). But LED3 does nothing.

    What do you mean by the first LED? LD2 on the dongle is a RGB LED and not separate LEDS (So BSP_LED_1, BSP_LED_2 and BSP_LED_3 are all the same RGB LED). At which frequency do you see flickering? In your code I see you use 1000 ms so you should see it change every second.

    Perhaps you can elaborate?

Reply
  • Hi, 

    I do not see any issue in your code.

    I figured out, if I switch on LED2 inside the main() first, the LED starts flickering depending on the APP_TIMER_TICKS (but timing is not correct). But LED3 does nothing.

    What do you mean by the first LED? LD2 on the dongle is a RGB LED and not separate LEDS (So BSP_LED_1, BSP_LED_2 and BSP_LED_3 are all the same RGB LED). At which frequency do you see flickering? In your code I see you use 1000 ms so you should see it change every second.

    Perhaps you can elaborate?

Children
  • Thanks for your reply,

    sorry for the confusing LED names. What i meant was, if I switch on BSP_LED_2 inside the main() - you find it inside the code:

    ...
    gpio_init();
        
    nrf_drv_gpiote_out_toggle(BSP_LED_2);
    
    create_timers();
    ...

    then BSP_LED_2 (green) lights up and every 1000 ms it goes off for a moment and immediately on again. See the video:

    But if i comment out the BSP_LED_2 code...

    // nrf_drv_gpiote_out_toggle(BSP_LED_2);

    nothing happens, so in both cases I don't enter the IR. Inside the IR BSP_LED_2 and BSP_LED3 should be triggered/toggled.

    So another question would be: After an timer interrupt or after __WFI(), so to speak, does the µC start the program from the beginning? That would at least explain, why BSP_LED_2 inside the main is flickering?!

  • Maboo said:
    So another question would be: After an timer interrupt or after __WFI(), so to speak, does the µC start the program from the beginning?

    No, there is no reset in that case. __WFI() will return after an interrupt. If you see the device resetting then it is caused by something else. For instance, if you use a debug build an an error is detected by an APP_ERROR_CHECK(), the default error handler will reset. It is a bit difficult to debug on a dongle as it does not have an onboard debugger, but if you have an nRF52840 DK to test with that would be the first thing to check. You could verify if this is the problem by toggling a GPIO only during initial configuration before your main loop, and check with a logic analyzer if that happens when it should not.

  • Thanks for the reply,

    I have found the problem. When I started working with your tutorial, I used my "main" program as a base and stripped it down till just the code you can see in my first post was left. But the sdk_config file and the makefile stayed the same. And there was the problem: Inside the sdk_config under the APP_TIMER section, APP_TIMER_CONFIG_USE_SCHEDULER was still enabled but not implemented in the code anymore. After fixing it (using one of your tutorials as well) everything worked fine and the scheduler did its thing.

    Side note: just disabling APP_TIMER_CONFIG_USE_SCHEDULER worked as well...

Related