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

Adding a timer to a BLE application

I am working on adding a periodic timer to an existing and running application to add some new features.

I mimic exactly what is done in the peripheral/timer_pca10028 example, except the following minor(?) changes:

  • Variable/function names and add some #define
  • Change #define TIMER0_ENABLED value from 0 to 1
  • Change handler to print out an incrementing static uint8 instead of toggling LEDs

The app stopped working after those change, and was printing out UART rubbishes instead of what it had done before that. Since I remember reading somewhere here that TIMER0 canot be used, I made some more changes:

  • Change timer instance from NRF_DRV_TIMER_INSTANCE(0) to NRF_DRV_TIMER_INSTANCE(1)
  • Change #define TIMER0_ENABLED back to 0
  • Change #define TIMER1_ENABLED value from 0 to 1

Now the timer works. However, the timer handler is called way too quickly. There must be tens of printf fired off every seconds. I could not figure out why.

Here is my timer related code for referrence

#define INTERVAL    1000            /**< Number of mili seconds between interrupts */
const nrf_drv_timer_t TIMER = NRF_DRV_TIMER_INSTANCE(1);

static void ble_stack_init(void)
{
  uint32_t err_code;

  // Initialize the SoftDevice handler module.
  SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION, NULL);
  // Other non-timer codes...
}

void timer_event_handler(nrf_timer_event_t event_type, void* p_context)
{   
  static uint8_t i;
  i++;
  printf("%x\n", i);
}

// main()
uint32_t time_ms = INTERVAL; // I tried using 500 or 5000 here, but they also don't work
uint32_t time_ticks;
uint32_t err_code;
err_code = nrf_drv_timer_init(
  &TIMER,
  NULL,
  timer_event_handler);
if (err_code == NRF_SUCCESS) {
  printf("NRF_SUCCESS\n");
} else {
  printf("%08x\n", err_code);
}
APP_ERROR_CHECK(err_code);
time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER, time_ms);
nrf_drv_timer_extended_compare(&STIMER, 
  NRF_TIMER_CC_CHANNEL0, 
  time_ticks, 
  NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, 
  true); 
nrf_drv_timer_enable(&TIMER);

So my question is:

  1. Was the reason the app failed to run with TIMER0 is that TIMER0 is used for some core functionality of a BLE app?

1.1. If yes, is it the APP_TIMER or something else?

1.2. If no, what would the cause TIMER0 not to work then?

1.3. Does this mean TIMER0 cannot be used anywhere else?

  1. Why is TIMER1 running so quickly? I suspect two places that could be the source of problem but do not understand them fully to work further on:

2.1. I understand that nrf_drv_timer_ms_to_ticks() would convert the ms time value passed to equivalent value in "ticks" for the timer parameter. Is this always dependable? The SDK documentation says that this function detects if overflow occurs, but I do not see any interruption in the application flow.

2.2. According to the this SDK documentation a "default configuration" is applied to the TIMER1 when nrf_drv_timer_init() was called with a second parameter of NULL. But what exactly is this "default configuration"?

Parents
    1. Yes

    1.1 no it's something else - its the softdevice and documented in the softdevice docs

    1.2 n/a

    1. don't know yet

    2.1 Why don't you break there and find out what value it's worked out and see if it makes sense given your timer frequency. If that's default it should be 16,000 or 0x3e80.

    2.2 NRF_DRV_TIMER_DEFAULT_CONFIG (in the same documentation) which uses the TIMER1_CONFIG_FREQUENCY etc etc defines in the same file you enabled the timer.

Reply
    1. Yes

    1.1 no it's something else - its the softdevice and documented in the softdevice docs

    1.2 n/a

    1. don't know yet

    2.1 Why don't you break there and find out what value it's worked out and see if it makes sense given your timer frequency. If that's default it should be 16,000 or 0x3e80.

    2.2 NRF_DRV_TIMER_DEFAULT_CONFIG (in the same documentation) which uses the TIMER1_CONFIG_FREQUENCY etc etc defines in the same file you enabled the timer.

Children
Related