This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

HFCLK timer issue

Hi Nordic Engineers,

I have few queries over HFCLK 16 MHz timer.

I am using nrf52840 custom board. IDE - segger embedded studio

#define TIME_IN_US  2600


/**
 * @brief Handler for timer events.
 */
void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
{
      switch (event_type)
      {
          case NRF_TIMER_EVENT_COMPARE3:
              timerenabled = 1;
              if(!cal_HR_ir_enabled)
              {
                  DisableHRMLed();       //Disabling RED and Enabling IR
                  EnableHRMLed(HR_IR_LED);
                   //printf("Timer IR\r\n");
              }
              else if(!cal_HR_red_enabled)
              {
                  DisableHRMLed();       //Disabling IR and Enabling RED
                  EnableHRMLed(HR_RED_LED);
                   //printf("Timer RED\r\n");
              }
              break;

          default:
              //Do nothing.
              break;
      }
}

void enable_HR_LED_timer(void)
{ 
      uint32_t time_ticks;
      uint32_t err_code = NRF_SUCCESS;

      //Configure TIMER_LED for generating simple light effect - leds on board will invert his state one after the other.
      nrf_drv_timer_config_t led_timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
      err_code = nrf_drv_timer_init(&TIMER_LED, &led_timer_cfg, timer_led_event_handler);
      APP_ERROR_CHECK(err_code);

      //Time(in microseconds) between consecutive compare events.
      time_ticks = nrf_drv_timer_us_to_ticks(&TIMER_LED, TIME_IN_US);

      nrf_drv_timer_extended_compare(
           &TIMER_LED, NRF_TIMER_CC_CHANNEL3, time_ticks, NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK, true);

      nrf_drv_timer_enable(&TIMER_LED);
}

I have enabled HFCLK timer and able to reach timer callback.

The problem is...If I set the Timeout as 2600 us, it seemed only timer callback was running (not even while(1) ) 

But in 2700 us or greater, each and every functionalities were working fine.

I have to generate ~250us time delay. 

I have attached my code snippet and I am using Timer 3

Looking forward for your suggestion.

Regards

Sudharsan

  • My source code contains softdevice also. We should not use Timer 0 right??? which is reserved for softdevice

  • What's the execution time of the TIMER_LED's event handler?

    And yes, TIMER0 is reserved for the SoftDevice.

  • Hi Haakonsh,

    Please confirm...Is my timer initialization function definition right or ...??

    Do I need to modify anything on timer side??

    I have changed the timer callback. Now I am just setting the flag and reading it in while(1)

    Now its fine and loop is also running...I have given 250us time-interval to switch the sensor's LED.

    Sensor which is using I2C communication and speed - 400K

    I am able to see the LED switching (RED <-> GREEN) ...Should it be possible to see in naked eye ??

    This is where I am right now

    /***************Enter main loop********************/
    for (;;)
    {   
            while (app_usbd_event_queue_process());
            process_usb_event();
             
    #if defined(CMD_MODE) || defined(BLECMD_MODE)
            APPTASK_Handler();
    #endif
    
    #ifdef BLECMD_MODE
            BLE_PROCESS();
    #endif
    
            if(timerenabled == 1)
            {
                  if(is_HF_timer_started){
                      if(!cal_HR_ir_enabled)
                      {
                          //nrf_drv_timer_pause(&TIMER_LED);
                          DisableHRMLed();       //Disabling RED and Enabling IR
                          EnableHRMLed(HR_IR_LED);
                          //nrf_drv_timer_resume(&TIMER_LED);
                      }
                      else if(!cal_HR_red_enabled)
                      {
                          //nrf_drv_timer_pause(&TIMER_LED);
                          DisableHRMLed();       //Disabling IR and Enabling RED
                          EnableHRMLed(HR_RED_LED);
                          //nrf_drv_timer_resume(&TIMER_LED);
                      }
                  }
                  timerenabled = 0;
            }
    
    
    #ifdef HRMEN
          HRM_Process();
          
    #endif
            idle_state_handle();
    }
    /****************************************************************/
    
    
    
    
    void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
    {
      switch (event_type)
      {
        case NRF_TIMER_EVENT_COMPARE3:
          timerenabled = 1;
          break;
    
        default:
        //Do nothing.
        break;
       }
    }

    Regards,

    Sudharsan

  • If it "works" now then it's an indication that the the functions DisableHRMLed() and EnableHRMLed() takes ~2600µs to execute. Can you share their implementation as well? 

    What I believe is happening is that there's a pending TIMER COMPARE interrupt when you exit the TIMER event handler, therefore you never return to your main loop.

    sudharsan said:

    Please confirm...Is my timer initialization function definition right or ...??

    Do I need to modify anything on timer side??

     Your timer initialization seems okay to me. I think the issue lies in the LED toggling. 

  • This is not LED which is connected to GPIO. It is connected to HRM sensor where the enable/disable should be I2C write.

    Please check the below

    void EnableHRMLed(enum enable_led_t led_on)
    {
         if(led_on == HR_RED_LED){
            switch_on_LED_1A_2A(&m_twi, ADPD410X_TS_A, ENABLE_HRLED_2A);
            cal_HR_red_enabled = true;
            cal_HR_ir_enabled = false;
         }
         else{
            switch_on_LED_1A_2A(&m_twi, ADPD410X_TS_B, ENABLE_HRLED_1A);
            cal_HR_red_enabled = false;
            cal_HR_ir_enabled = true;
         }
    } 
    
    void DisableHRMLed(void)
    {
         switch_off_LEDs(&m_twi, PAIR_12, ADPD410X_TS_A); 
         switch_off_LEDs(&m_twi, PAIR_12, ADPD410X_TS_B);
    }

Related