App timer in repeated mode always runs with the same delay

Hello,

I am starting a new ticket as per the suggestion from a previous ticket.

I have RTC configured to trigger every 1 ms and that keeps track on milliseconds since startup. I use that variable to log(using RTT) when the timer is triggered.

There is only one app timer which refreshes watchdog. The timer does various tasks. I log the ticks since startup at various points in the timer and it takes about 2 ms to complete.

Here is some source code that show rtc and app timer. using RTT logger for some debug messages. The source is based is based on the nrf ble uart example and the soft device is running and advertising. The timer is configurted to run every 1000 ms but it is always triggered at 1024 ms. This means that every 40 triggers, the tasks in timer would have run one less time which is not acceptable.

/** @brief: Function for handling the RTC0 interrupts.
 * Triggered on TICK and COMPARE0 match.
 */
static void rtc_handler(nrf_drv_rtc_int_type_t int_type)
{    
    (void) int_type;
    
    //increment 1m tick ctr
    g_ticks_since_startup++;    
}

/**
 * @brief Handler for timer events.
 * 
 * @param p_context 
 */
static void timer_handler(void * p_context)
{
    (void) p_context;
    NRF_LOG_RAW_INFO("Timer %d\n", g_ticks_since_startup);
    
    //feed the watchdog
    nrf_drv_wdt_channel_feed(m_channel_id);    
    
    
    //do more stuff
    
    //get uart sensor data 
    sensor_poll(&m_nus);
    NRF_LOG_RAW_INFO("Timer end %d,", g_ticks_since_startup);
   
    
    //set flush logs flag
    flush_pending_logs = true;
}


/**@brief Function for initializing the timer module.
 */
static void timers_init(void)
{
    ret_code_t err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

    err_code = app_timer_create(&m_timer, APP_TIMER_MODE_REPEATED, timer_handler);
    APP_ERROR_CHECK(err_code);

    err_code = app_timer_start(m_timer, APP_TIMER_TICKS(1000), NULL);
    APP_ERROR_CHECK(err_code);
}


/**
 * @brief WDT events handler.
 */
void wdt_event_handler(void)
{
    NRF_LOG_RAW_INFO("WDT trig\r\n");
    //NOTE: The max amount of time we can spend in WDT interrupt is two cycles of 32768[Hz] clock - after that, reset occurs
}

int main(void)
{
    /* Init systick driver */
    nrf_drv_systick_init();

    
    log_init();
    
    
    timers_init();
    power_management_init();
    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();   

    //RTC Init
    lfclk_config();
    rtc_config();
    
    //feed the watchdog
    nrf_drv_wdt_channel_feed(m_channel_id);
      
    gpio_init();      
    
    //uart sensor init
    sensor_init();

    err_code = nrf_pwr_mgmt_init();
    APP_ERROR_CHECK(err_code);
    
    //set the ble tx power
    sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_SCAN_INIT, BLE_CONN_HANDLE_INVALID, BLE_TX_POWER); 
    APP_ERROR_CHECK(err_code);
    
    // Start advertising.        
    advertising_start();

    //initalise the local adc for battery voltage monitoring   
    saadc_init();
    
    //init the temperature sensor
    g_mc_termperature = 0;
        
    // Enter main loop.
    for (;;)
    {
        // Clear the event register.
        __SEV();
        __WFE();
        // Wait for an event.
        __WFE();
        
        if(flush_pending_logs)
        {
            //flush logs
            flush_pending_logs = false;
        }

        idle_state_handle();    
    }
}

How can I figure out what is causing this and ensure the timer runs every 1000 ms.

Regards

Parents Reply Children
Related