generating clock on GPIO

Hi team,

I am trying to generate pulses on a GPIO using timer1. The pulse need not to be very accurate.

To start with I used the below given code to generate a clock frequency of 1.6 MHz.

/* Start 16 MHz crystal oscillator */
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;

/* Wait for the external oscillator to start up */
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
{
// Do nothing.
}

NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
NRF_TIMER1->TASKS_CLEAR = 1;
NRF_TIMER1->PRESCALER = 0;
NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit;

// Timer expires 1
NRF_TIMER1->CC[0] = 5;
NRF_TIMER1->TASKS_START = 1; // Start TIMER1

while(1)
{
while(!NRF_TIMER1->EVENTS_COMPARE[0]);
NRF_TIMER1->TASKS_STOP = 1;
NRF_TIMER1->EVENTS_COMPARE[0] = 0;
NRF_TIMER1->TASKS_CLEAR = 1;
nrf_gpio_pin_toggle(SDA_PIN);
NRF_TIMER1->TASKS_START = 1; // Start TIMER1
}

Here I am observing a frequency of 347 Khz. I don't want to use PPI for now.

I know there will be some offset because peripheral is running at 16 MHz and due to the instructions inside the while loop, but I think this will be very small and should not cause this much difference. Why there is so much difference ?

  • Hi,

    Any read access to the peripheral bus will stall the processor until the transfer is completed, and I guess that is part of the reason you only get 347 KHz. The nrf_gpio_pin_toggle() is also relatively slow as it first reads the current output state before writing the new state. It would be faster if you used a GPIOTE toggle task for this (CONFIG[n]).

    I can help set up a sample with PPI if that's of interest.

    Best regards,

    Vidar

Related