Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Timer can't generate a <10 μs clock, what did I do wrong?

Hi Nordic community,

I'm trying to generate a 1 MHz base clock with one of the peripheral timer, and in the timer ISR does some GPIO toggling. 

I followed the nRF5 SDK example and just toggle one GPIO in the ISR to test the clock frequency. I notice, for some reason, the fastest clock I can get here is ~100 kHz (10.6 μs period).

Would you help me check what I did wrong?

Here is the relevant code snippet in main function:

    nrf_gpio_cfg_output(BSP_LED_1);
    nrf_gpio_pin_set(BSP_LED_1);
    timer_init(&TIMER1, 1);
    timer_enable(&TIMER1);
    while(1)
    {
        __WFI();
    }

Here is the timer_init definition:

void timer_init(nrfx_timer_t const * const p_instance, uint32_t time_us)
{
    uint32_t time_ticks;
    nrfx_timer_config_t timer_config = NRFX_TIMER_DEFAULT_CONFIG;               // Start with default settings for the timer instance
    timer_config.bit_width = NRF_TIMER_BIT_WIDTH_16;
    timer_config.frequency = NRF_TIMER_FREQ_1MHz;

    APP_ERROR_CHECK(nrfx_timer_init(p_instance, &timer_config, timer_irq_handler)); // Initialize the timer
    time_ticks = nrfx_timer_us_to_ticks(p_instance, time_us);                   // Calculate time tick needed for the initialized timer based on its clock config
    
    switch(p_instance->instance_id)
    {
      // case NRFX_CONCAT_3(NRFX_TIMER, 0, _INST_IDX):
      //   nrfx_timer_extended_compare(p_instance, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);                                 // Setting the timer channe0 in the extended compare mode
      //   break;      
      case NRFX_CONCAT_3(NRFX_TIMER, 1, _INST_IDX):
        nrfx_timer_extended_compare(p_instance, NRF_TIMER_CC_CHANNEL1, time_ticks, NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK, true);                                 // Setting the timer channel in the extended compare mode
        break;
      // case NRFX_CONCAT_3(NRFX_TIMER, 2, _INST_IDX):
      //   nrfx_timer_extended_compare(p_instance, NRF_TIMER_CC_CHANNEL2, time_ticks, NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK, true);                                 // Setting the timer channel in the extended compare mode
      //   break;
      // case NRFX_CONCAT_3(NRFX_TIMER, 3, _INST_IDX):
      //   nrfx_timer_extended_compare(p_instance, NRF_TIMER_CC_CHANNEL3, time_ticks, NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK, true);                                 // Setting the timer channel in the extended compare mode
      //   break;
      default:
        break;
    }
}

And here is the timer irq handler

static void timer_irq_handler(nrf_timer_event_t event_type, void *p_context)    // Timer handler is only used in timer mode not counter mode
{
  switch(event_type)
  {
    // case NRF_TIMER_EVENT_COMPARE0:
    //   nrf_gpio_pin_toggle(BSP_LED_1);
    //   break;
    case NRF_TIMER_EVENT_COMPARE1:                                              // The event type is based on the timer setting
      nrf_gpio_pin_toggle(BSP_LED_1);
      //NRF_LOG_INFO("TIMER");
      break;
    // case NRF_TIMER_EVENT_COMPARE2:
    //   nrf_gpio_pin_set(BSP_LED_0);
    //   break;
    // case NRF_TIMER_EVENT_COMPARE3:
    //   break;
    default:
      break;
  }
}

Lastly, the timer_enable function just calls 

nrfx_timer_enable
 .

Really appreciate your help.

Thanks.

Richard

Related