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.

  • Thank all of you. I find the table 22 and 24 in the S110_SDS_v2.pdf that about PPI and GPIOTE.  The SD uses the channel 14-15. The APP can use channel 0-13.  I think  the SDK I used is too old.  Now I am trying the SDK 10. But find I can not use GPIOTE  interrupt directly.  If I use bsp_event_handler, the delay is about 700us, it is too long.

    I want to measure the time from a signal on one pin to another.  About 200us-50ms.  Error should less than 5us. How can I do?

  • You only use the SD that comes with the SDK. So, not really an issue of using an old one, just using the correct one. SDK's and SD's are released in pairs.  The SD's are in the components folder.  Only by using the matching SD will the libraries and API calls work out. The API's are constantly changing and being improved on. Thus each new SD gets a new SDK. When one moves a project from one SDK to a later version (only if required for features, it is not normally necessary to do this) then you need to do some extensive reading of the SD release notes to make sure you are using the correct API's as they may be different.

Reply
  • You only use the SD that comes with the SDK. So, not really an issue of using an old one, just using the correct one. SDK's and SD's are released in pairs.  The SD's are in the components folder.  Only by using the matching SD will the libraries and API calls work out. The API's are constantly changing and being improved on. Thus each new SD gets a new SDK. When one moves a project from one SDK to a later version (only if required for features, it is not normally necessary to do this) then you need to do some extensive reading of the SD release notes to make sure you are using the correct API's as they may be different.

Children
No Data
Related