Timer1 automatic clear with short issue

Hi,

I want to configure Timer1 (32 bit ) to run up to 1 sec and then reset. I want this to be done continuously with the help of Short but without using the event handler. 

void msecTimer_init(void)
{
  uint32_t err_code = NRF_SUCCESS;
  uint32_t time_ms = 1000;
  uint32_t time_ticks = 0; 

  // configure Timer
  nrf_drv_timer_config_t timer_cfg = {//NRF_DRV_TIMER_DEFAULT_CONFIG; // configure timer instance with default settings}
  .frequency = NRF_TIMER_FREQ_16MHz, 
  .bit_width = NRF_TIMER_BIT_WIDTH_32,
  .mode = NRF_TIMER_MODE_TIMER,
  .interrupt_priority = 2,
  };

  // initialize timer with settings 
  err_code = nrf_drv_timer_init(&msecTimer, &timer_cfg, msecTimer_handler); 
  APP_ERROR_CHECK(err_code);

  time_ticks = nrf_drv_timer_ms_to_ticks(&msecTimer, time_ms); // convert ms to ticks
  
  nrf_drv_timer_extended_compare(&msecTimer, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);  // With this I dont enter intr handler
}

but Timer1 does not reset at 1000msec (16M ticks) and keeps increasing until it reaches 0xFF FF FF FF

What am I doing wrong here?
Are shorts only used in conjunction with event handlers?

  • Hi,

    Just want to let you know that I have received your question. However, I am out of office today, so my follow-up will be delayed to latest next week Tuesday.

    Best regards,

    Hieu

  • Hi, I thought to create a simple test timer in the peripherals/timer example, to eliminate the chance of me doing something strange in my other code. 

    So, in the timer example, I added a new timer instance (TIMER_TEST)  with nrf_drv_timer_extended_compare() and I continuously capture and display its internal counter register  inside a while loop to see if the internal counter register is cleared or not after a specified interval.

    #include <stdbool.h>
    #include <stdint.h>
    #include "nrf.h"
    #include "nrf_drv_timer.h"
    #include "bsp.h"
    #include "app_error.h"
    
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(0);
    const nrf_drv_timer_t TIMER_TEST = NRF_DRV_TIMER_INSTANCE(1);
    
    /**
     * @brief Handler for timer events.
     */
    void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
    {
        static uint32_t i;
        uint32_t led_to_invert = ((i++) % LEDS_NUMBER);
    
        switch (event_type)
        {
            case NRF_TIMER_EVENT_COMPARE0:
                bsp_board_led_invert(led_to_invert);
                break;
    
            default:
                //Do nothing.
                break;
        }
    }
    
    void timerTest_handler(nrf_timer_event_t event_type, void* p_context)
    {
    
        switch (event_type)
        {
            case NRF_TIMER_EVENT_COMPARE0:
                NRF_LOG_INFO("TIMER TEST EVENT");
                break;
    
            default:
                //Do nothing.
                break;
        }
    }
    
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
    
    log_init();             // this is for NRF_LOG den douleuei
    //-----------------
        uint32_t time_ms = 2000; //Time(in miliseconds) between consecutive compare events.
        uint32_t time_ticks;
        uint32_t err_code = NRF_SUCCESS;
        
        //Configure all leds on board.
        bsp_board_init(BSP_INIT_LEDS);
    
        //Configure TIMER_LED for generating simple light effect - leds on board will invert his state one after the other.
        nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
        err_code = nrf_drv_timer_init(&TIMER_LED, &timer_cfg, timer_led_event_handler);
        APP_ERROR_CHECK(err_code);
    
        time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_LED, time_ms);
    
        nrf_drv_timer_extended_compare(&TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
    
        nrf_drv_timer_enable(&TIMER_LED);
        
    //--------------------------------------------------------
        uint32_t timeA_ms = 100; //Time(in miliseconds) between consecutive compare events.
        uint32_t timeA_ticks = 0;
       
    
        nrf_drv_timer_config_t timerA_cfg = 
        {
          .frequency = NRF_TIMER_FREQ_16MHz, 
          .bit_width = NRF_TIMER_BIT_WIDTH_32,
          .mode = NRF_TIMER_MODE_TIMER,
          .interrupt_priority = 2,
        };
    
        err_code = nrf_drv_timer_init(&TIMER_TEST, &timerA_cfg, timerTest_handler);
        APP_ERROR_CHECK(err_code);
    
        timeA_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_TEST, timeA_ms);
    
        //nrf_drv_timer_extended_compare(&TIMER_TEST, NRF_TIMER_CC_CHANNEL0, timeA_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
        nrf_drv_timer_extended_compare(&TIMER_TEST, NRF_TIMER_CC_CHANNEL0, timeA_ticks, NRF_TIMER_SHORT_COMPARE0_STOP_MASK, true);
        nrf_drv_timer_enable(&TIMER_TEST);
    //---------------------------------------------------
        while (1)
        {     
                NRF_TIMER1->TASKS_CAPTURE[0] = 1;  
                NRF_LOG_INFO("%d", NRF_TIMER1->CC[0]);
            //__WFI();
        }
    }
    
    /** @} */
    

    The result is the same. The internal counter register value is not cleared after the 100msec (1600000 ticks) interval I have set and the internal register keeps increasing until it overflows. I expect that after 1600000 ticks the value would reset to zero..

    I would expect that the Timer's internal register would be cleared every 1,6M ticks since the interval I have set is 100msec.

    I checked the TIMER1->SHORTS register in the debugger and the corresponding bit seems to be activated.

    I must be doing something wrong here but I don;t know what it is...

  • Hi,

    Regarding your initial question, with what setup did you use to see that the counter runs all the way to 0xFFFF FFF?
    If the setup is the same as your follow-up comment, please see that you are using the same Capture Compare channel to monitor the counter value as the one you use to reset/stop the timer.
    Please change your Capture Compare channel either for the monitoring or for the shortcut, and you should see the timer behaves as you would expect.

    Best regards,

    Hieu

    By the way, fun profile pic you have there :D

  • Hi Hieu,

    yes you are absolutely right.  Now I get it!
    Thank you for your help! 

Related