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

Demand: nRF52 Timer operate in 400ns. nRF52 Timer Interrupt response time is too slow!

Hello everyone

 I am using nRF52 DK PCA10040.

 I try to generate puls by Timer 0.

 The puls width is 400ns.

 This goal was failed.

-----------------------------------------------------

I find out  enter timer0 interrupt until leave.

It cost around  730ns~1us .

I traced through disassembly code, the instruction is not too much to over 400ns.

How can I meet the goal? 

It's very important! Thanks.

The code reference as below

================================

void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
{
nrf_gpio_pin_write (TEST_OUT1, 1);

}

int main(void)
{

//High Speed//

NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);

// IO SETUP//

nrf_gpio_cfg_output (TEST_OUT1); //SETUP TEST P1 = OUTPUT

//TIMER SETUP//
NRF_TIMER0->TASKS_STOP = 1;      // Stop timer
NRF_TIMER0->MODE = TIMER_MODE_MODE_Timer; // taken from Nordic dev zone
NRF_TIMER0->BITMODE = (TIMER_BITMODE_BITMODE_08Bit << TIMER_BITMODE_BITMODE_Pos);
NRF_TIMER0->PRESCALER = 0; 
NRF_TIMER0->TASKS_CLEAR = 1;      // Clear timer
NRF_TIMER0->CC[0] = 6; //375ns 
NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos; // taken from Nordic dev zone
NRF_TIMER0->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
_NRFX_IRQ_PRIORITY_SET(TIMER0_IRQn,1);
NVIC_EnableIRQ(TIMER0_IRQn);
NRF_TIMER0->TASKS_START = 1; // Start TIMER



while (1)
{
nrf_gpio_pin_write (TEST_OUT1, 0);
};


}

  • #include <stdbool.h>
    #include <stdint.h>
    #include "nrf.h"
    #include "nrf_drv_timer.h"
    #include "bsp.h"
    #include "app_error.h"
    
    const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(0);
    
    #define TEST_OUT1	12
    
    /**
     * @brief Handler for timer events.
     */
    void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
    {
    		nrf_gpio_pin_write (TEST_OUT1, 1);
    		NRF_TIMER0->EVENTS_COMPARE[0] = 0;	
    }
    
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_HFCLKSTART = 1;
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
    	
    	nrf_gpio_cfg_output (TEST_OUT1);									//SETUP TEST P1 = OUTPUT	
    	
      NRF_TIMER0->TASKS_STOP = 1;	// Stop timer
      NRF_TIMER0->MODE = TIMER_MODE_MODE_Timer;  // taken from Nordic dev zone
      NRF_TIMER0->BITMODE = (TIMER_BITMODE_BITMODE_08Bit << TIMER_BITMODE_BITMODE_Pos);
      NRF_TIMER0->PRESCALER = 0;	// 1us resolution
      NRF_TIMER0->TASKS_CLEAR = 1; // Clear timer
      NRF_TIMER0->CC[0] = 200;					//375ns 
      NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;  // taken from Nordic dev zone
      NRF_TIMER0->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
    	_NRFX_IRQ_PRIORITY_SET(TIMER0_IRQn,1);
    	NVIC_EnableIRQ(TIMER0_IRQn);
      NRF_TIMER0->TASKS_START = 1;	// Start TIMER
    
        while (1)
        {
    		nrf_gpio_pin_write (TEST_OUT1, 0);
        }
    }
    
    /** @} */
    
    void timer_led_event_handler(void);
    
    #if NRFX_CHECK(NRFX_TIMER0_ENABLED)
    void nrfx_timer_0_irq_handler(void)
    {
    	timer_led_event_handler();
    //    irq_handler(NRF_TIMER0, &m_cb[NRFX_TIMER0_INST_IDX],
    //        NRF_TIMER_CC_CHANNEL_COUNT(0));
    }
    #endif
    

    Modify SDK16 example Timer

  • Hello,

    I don't understand. You set up the timer, but you toggle the pin both from your main loop and in your timeout interrupt?

    If the timer is too fast, you should look into the PPI (programmable peripheral interface). Check out the example found in SDK\examples\peripheral\ppi

    This example doesn't toggle a pin, but writes some information in the log. Monitor the UART log.

    But you can change this example to set the PPI task to toggle the pin. It is a bit complex. You need to use nrf_drv_gpiote_set_task_addr_get instead of nrf_drv_timer_task_address_get in nrf_drv_timer_task_address_get().

    BR,

    Edvin

  • Hi Edvin

      Thanks you reply.

      I try to make timer as fast as possible, but it's failed.

      I toggle the pin to check the interrupt timing cost. I found interrupt timing cost is around 730ns ~ 1us.

    --------------------------------------

    I will try your suggestion, the PPI and GPIOTE.

    Could you tell me how to use PPI to setup a pin to be input mode?

    Austin

Related