Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

GPIOET interrupt and PPI in S110

Hi,

I want to measure the time of two signals to calculate the speed and sent the data with BLE.  I find the SD effect the GPIOTE_interrupt sometimes, when I try to use GPIOTE and timer to calcluate the time . So I use the PPI function, connect the NRF_GPIOTE->EVENTS_IN[ ] to the NRF_TIMER2->TASKS.  But the program can not boot up with PPI and  GPIOTE_interrupt and SD.  I debugged the program. Looks it go to the "System Reset".   

If I use PPI and GPIOTE interrupt without BLE SD, it works well. I can measure the time accurately.   If I use PPI with SD and disable the interrupt, it works well. If I use the GPIOTE interrupt with SD and disable the PPI, it works well too.  

void time1_init(void)  
{

    NRF_TIMER2->MODE        = TIMER_MODE_MODE_Timer;	
    NRF_TIMER2->PRESCALER   = 4;  
    NRF_TIMER2->CC[2]       = (50000U);  
    NRF_TIMER2->INTENSET    = TIMER_INTENSET_COMPARE2_Enabled << TIMER_INTENSET_COMPARE2_Pos;		
    NRF_TIMER2->SHORTS      = (TIMER_SHORTS_COMPARE2_CLEAR_Enabled << TIMER_SHORTS_COMPARE2_CLEAR_Pos);
		NVIC_ClearPendingIRQ(TIMER2_IRQn);			
    NVIC_SetPriority(TIMER2_IRQn,3);				
		NVIC_EnableIRQ(TIMER2_IRQn);  					
	//  NRF_TIMER2->TASKS_START = 1; 
}

 void ppi_init(void)
{
    // Configure PPI channel 0 to start Timer 2 
    NRF_PPI->CH[0].EEP = (uint32_t)(&NRF_GPIOTE->EVENTS_IN[0]);
		NRF_PPI->CH[0].TEP = (uint32_t)(&NRF_TIMER2->TASKS_START);

    // Configure PPI channel 1 to capture Timer2
    NRF_PPI->CH[1].EEP = (uint32_t)(&NRF_GPIOTE->EVENTS_IN[1]);
    NRF_PPI->CH[1].TEP = (uint32_t)(&NRF_TIMER2->TASKS_CAPTURE[0]);

    // Enable only PPI channels 0 and 1.
    NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos) | (PPI_CHEN_CH1_Enabled << PPI_CHEN_CH1_Pos);
}

void EXIT_KEYS_Init(void)
{

		nrf_gpio_cfg_input(S1,GPIO_PIN_CNF_PULL_Pullup);
		nrf_gpio_cfg_input(S2,GPIO_PIN_CNF_PULL_Pullup);
//		NVIC_SetPriority(GPIOTE_IRQn,1);

	
    NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)	
                           | (S1 << GPIOTE_CONFIG_PSEL_Pos)  																
                           | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);					
		NRF_GPIOTE->CONFIG[1] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                           | (S2 << GPIOTE_CONFIG_PSEL_Pos)  
                           | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);

         NVIC_EnableIRQ(GPIOTE_IRQn);   //must disable GPIOTE interrupt or PPI
		NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;
		NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN1_Set << GPIOTE_INTENSET_IN1_Pos;
}

int main(void)
{
	
	uint16_t speeds;

	time1_init(); 
	EXIT_KEYS_Init(); 
	ppi_init();
    // Initialize
    leds_init();
    timers_init();
    buttons_init();
    uart_init();
	
    ble_stack_init();
    gap_params_init();
    services_init();
    advertising_init();
    conn_params_init();
    sec_params_init();
    
    simple_uart_putstring(START_STRING);	
    
    advertising_start();
	  LED_Init();
		capture_state=1;

    for (;;)
    {........}
}

I use the example  S110 \experimental\ble_app_uart. 

SofeDevices: S110  6.0.0

Board: PCA10001

IC: nRF51822 xxaa

Any idea about it? 

Parents
  • As Turbo said, you have to use the API's to assign and enable/disable PPI channels.  The SD uses PPI and thus will write over your settings.  You can set gpiote directly through the register if you wish.

    These are some of the API's.  You would find them all listed in the SD reference docs.

     sd_ppi_channel_assign
     sd_ppi_channel_enable_set
           

    You will find the PPI reserved channels on page 169 of the product spec.

  • I can use PPI with the SDK 10.0. The errors of  the time datas were less than 10us, although they were a bit of volatility. But I can not use GPIOTE interrupt with SD. If I set the interrupt of GPIOTE, it can run at first time. After that, it looks the SD clear the interrupt of GPIOTE, I can see the GPIOTE events be on, but it doesn't respond to the interrupt of GPIOTE events.  

Reply
  • I can use PPI with the SDK 10.0. The errors of  the time datas were less than 10us, although they were a bit of volatility. But I can not use GPIOTE interrupt with SD. If I set the interrupt of GPIOTE, it can run at first time. After that, it looks the SD clear the interrupt of GPIOTE, I can see the GPIOTE events be on, but it doesn't respond to the interrupt of GPIOTE events.  

Children
No Data
Related