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

Timer event handler problem

Dear all,

I just writing a little piece of code (no softdevice, using sdk 17.00), that in theory toggle a led based on 2 compare (CC[0] and CC[1]).

/**
 * Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/** @file
 * @defgroup nrf_dev_timer_example_main main.c
 * @{
 * @ingroup nrf_dev_timer_example
 * @brief Timer Example Application main file.
 *
 * This file contains the source code for a sample application using Timer0.
 *
 */

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

// Mettendo lo 0 nella macro, sto settando il compare = 0
const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(4);
const nrf_drv_timer_t TIMER_TIMESTAMP = NRF_DRV_TIMER_INSTANCE(2);

void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
{
  switch(event_type)
  {
    case NRF_TIMER_EVENT_COMPARE0:
       TIMER_TIMESTAMP.p_reg->TASKS_CAPTURE[0] = 1; 
       printf("ON: %d\n", TIMER_TIMESTAMP.p_reg->CC[0]);
       bsp_board_led_on(BSP_BOARD_LED_0);
       break;
    case NRF_TIMER_EVENT_COMPARE1:
      TIMER_TIMESTAMP.p_reg->TASKS_CAPTURE[0] = 1; 
       printf("OFF: %d\n", TIMER_TIMESTAMP.p_reg->CC[0]);
      bsp_board_led_off(BSP_BOARD_LED_0);
      TIMER_LED.p_reg->TASKS_STOP = 1;
      break;
  }
}
void timer_timestamp_event_handler(nrf_timer_event_t event_type, void* p_context)
{

}
static void timer_init()
{
  ret_code_t err_code;

  nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
  timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_8;
  timer_cfg.frequency = NRF_TIMER_FREQ_31250Hz;

  err_code = nrf_drv_timer_init(&TIMER_LED, &timer_cfg, timer_led_event_handler);
  APP_ERROR_CHECK(err_code);
  // Setting compare
  TIMER_LED.p_reg->CC[0] = 10; // 320 us
  TIMER_LED.p_reg->INTENSET = 0x1UL << 16UL;
  TIMER_LED.p_reg->CC[1] = 40;  //1280 us
  TIMER_LED.p_reg->INTENSET = 0x1UL << 16UL+1;
  // Timer timestamp
  timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
  timer_cfg.frequency = NRF_TIMER_FREQ_1MHz;
  err_code = nrf_drv_timer_init(&TIMER_TIMESTAMP, &timer_cfg, timer_timestamp_event_handler);
  APP_ERROR_CHECK(err_code);

  // Starting timer
  TIMER_TIMESTAMP.p_reg->TASKS_START = 1;
  TIMER_LED.p_reg->TASKS_START = 1;
  
}
int main(void)
{
    bsp_board_init(BSP_INIT_LEDS);
    timer_init();
    while (1)
    {
        __WFI();
    }
}

/** @} */

The strange thing is that, if the 2 compare are pretty high (1 second or more) there is no problem, while if the values are low, something strange happened:

1) Why isn't the timer stopped instantly? (but it needs two cycles)

2) Why are the timestamps not correct? (I expected that OFF - ON = 960)

Thanks to everyone,

Elia

Parents
  • Hi Elia,

    1) Why isn't the timer stopped instantly? (but it needs two cycles)

    Since you are handling the stopping of the timer in the interrupt handler, the CPU requires some time to wakeup and call the interrupt handler when the interrupt is generated. Since you have configured the timer with only 8-bits width, it will overflow when the internal counter reaches 255. This will happen after ~8 ms, which means that the CPU should have plenty of time to handle the interrupt before this if nothing it blocking the handling of the interrupt. I tested your code on my DK, but I'm not able to reproduce any of the issues you are listing. This is the output from my run:

    <info> app: ON: 322
    
    <info> app: OFF: 1282

    I'm not sure how you have implemented the printf statements, but could these slow down the application and cause this behavior?

    2) Why are the timestamps not correct? (I expected that OFF - ON = 960)

    As you can see above, I'm seeing a delta of exactly 960 in my run. Again, I believe that something must be slowing down your code, causing this.

    I have attached my test-project. Can you have a run with this and see what values it is giving you? 4578.timer_cc.zip

    It is possible to configure PPI to trigger the STOP and CAPTURE tasks in hardware when the events are generated. This would prevent you from relaying on constant interrupt latency for giving correct results.

    Best regards,
    Jørgen

  • Dear Jorgen,

    Unfortunately nothing is print on the Debug terminal: why??

    Regards,

    Elia

Reply Children
No Data
Related