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

BLE makes CPU skip a clock cycle on nRF52-DK

Dear all,

I am expanding the eddystone example for my nRF52832 (nRF52-DK) with some extra functionality. I wanted to create a periodic impulse with a timer (timer 1), all hardware driven via PPI, toggling a GPIO, still via PPI. The timer is configured so it will clear via a short at the count of 256 (16 bit timer). Then I have a PPI channel toggling a gpio every time the timer resets. Here is my code:

	
	// initializing timer
	
	timer_ = NRF_DRV_TIMER_INSTANCE(1);
	nrf_drv_timer_config_t timer_config = NRF_DRV_TIMER_DEFAULT_CONFIG;
	timer_config.bit_width = NRF_TIMER_BIT_WIDTH_16;
	timer_config.frequency = NRF_TIMER_FREQ_16MHz;
	nrf_drv_timer_init(&timer_, &timer_config, drv_dac::timer_evt_handler);
	
	// initializing GPIOTE
	
	nrf_drv_gpiote_out_config_t ss_pin_config;
	ss_pin_config.init_state = NRF_GPIOTE_INITIAL_VALUE_HIGH;
	ss_pin_config.task_pin = true;
	ss_pin_config.action = NRF_GPIOTE_POLARITY_TOGGLE;
	
	nrf_drv_gpiote_out_init(SPI_DAC_SS_PIN, &ss_pin_config);
	
	// setting up timer compare and short
	
	unsigned int ss_period = 256;
	nrf_drv_timer_extended_compare(
		&timer_,
		NRF_TIMER_CC_CHANNEL2,
		ss_period,
		NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK,
		false
	);
	
	// configuring the PPI channel for toggling the GPIO
	
	nrf_drv_ppi_channel_alloc(&ppi_channel_count_);
	nrf_drv_ppi_channel_assign(
		ppi_channel_count_,
		nrfx_timer_event_address_get(&timer_, NRF_TIMER_EVENT_COMPARE2),
		nrfx_gpiote_out_task_addr_get(SPI_DAC_SS_PIN)
	);
	nrf_drv_ppi_channel_enable(ppi_channel_count_);

	nrf_drv_gpiote_out_task_enable(SPI_DAC_SS_PIN);
	
	// clearing and starting the timer
	
	nrf_drv_timer_clear(&timer_);
	nrf_drv_timer_enable(&timer_);
	

However, when the softdevice is running and I have beacon transmission, I can see the timer occasionally "skipping a beat" meaning that the on time is 257 cycles instead of 256 as expected, I measured it quite clearly with the scope, it is exactly an extra 16MHz clock cycle, and this happens exactly in correspondence of the eddystone beacon transmission.

I could deduce that the problem is the timer "strectching its period" and not the GPIO being delayed because I can see that these delays accumulate over consecutive cycles.

EDIT:

I actually made an additional test, I wanted to see problem was happening when the timer was resetting (PPI issue) or if the whole system was actually skipping a clock cycle. So instead of toggling the gpio I set up two compares, one with counter = 2 to set the pin and the next one with counter = 253 to clear the pin, so an impulse is generated for every timer cycle.

If the problem only happens when the timer is resetting I would expect to see this clock glitch on the first rising edge after the trigger but not on the falling edge of the impulse. However I can see the glitch on the falling edge, and between rising edge and falling edge of the GPIO there is no TIMER_CLEAR. So this hints to the fact that the whole system might be skipping a cycle.

I wonder is this is due to interference of the bluetooth antenna with the clock oscillator on the nRF52-DK board. Is there any way to keep the softdevice running but disable sources of potential interference like the antenna?

Thank you very much

Parents
  • Hi

    it could be that you're seeing the NRF52832 switching from the internal HFCLK source to the external high frequency crystal oscillator.

    could you try to request the HFCLK by calling sd_clock_hfclk_request() in main() after you have called ble_stack_init(). The  external high frequency crystal oscillator should now be running all the time. Can you test and check if you observe the same behavior as before or if this resolves the issue?

    Best regards

    Bjørn

Reply
  • Hi

    it could be that you're seeing the NRF52832 switching from the internal HFCLK source to the external high frequency crystal oscillator.

    could you try to request the HFCLK by calling sd_clock_hfclk_request() in main() after you have called ble_stack_init(). The  external high frequency crystal oscillator should now be running all the time. Can you test and check if you observe the same behavior as before or if this resolves the issue?

    Best regards

    Bjørn

Children
Related