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

How to redefine PPI tasks inside a TIMER interrupt ???

Dear Nordic Developer Zone,

I am working on a BLE application using nrf51822 with softDevice.

My aim is to be able to redefine which GPIOTE channel my PPI is using inside the TIMER1 interrupt under logical conditions.

Unfortunately, all softdevice calls to modify the PPI (sd_ppi_X) in the TIMER1 interrupt doesn't work and crash the app ?!

It should be trivial, but I can't figure it out by myself... I am able to redefine the PPI tasks in my app functions, but not inside interrupt.

Is there someone to help me? Here is my code.


static uint32_t                               m_counter = 0; 

void TIMER1_IRQHandler(void)
{
	uint32_t err_code;
	
  if ((NRF_TIMER1->EVENTS_COMPARE[0] != 0) && ((NRF_TIMER1->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0))
  {
	//Reinit comparator	
        NRF_TIMER1->EVENTS_COMPARE[0] = 0;
	
        m_counter = m_counter +1;

        if(m_counter == 5)
        {
	     //-->PPI call here crash the app
             //! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    	    sd_ppi_channel_assign(0, &(NRF_TIMER1->EVENTS_COMPARE[0]), &(NRF_GPIOTE->TASKS_OUT[1]));
        }

	//Toggle led to have a visual feedback that the application didn't crash
	nrf_gpio_pin_toggle(17);//Devkit
  }
}

/**
 * main function
 * \return 0. int return type required by ANSI/ISO standard.
 */
void rtc_test(void)
{
	uint32_t err_code;
	
	nrf_gpio_cfg_output(M1_A0_PIN);
	nrf_gpio_cfg_output(M1_B0_PIN);
	nrf_gpio_cfg_output(M1_C0_PIN);
	
	// Configure timer
	NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
	NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
	NRF_TIMER1->PRESCALER = 9;   // 31.25kHz ? 32us tick 
	NRF_TIMER1->TASKS_CLEAR = 1;  // Clear the timer
	NRF_TIMER1->CC[0] = 0x1E84;  // CC[0] occurs at 250ms from START
	
	// Configure the shortcut to clear and restart on Compare[0]
	NRF_TIMER1->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos); 
	
	NRF_TIMER1->INTENSET = (1UL << TIMER_INTENSET_COMPARE0_Pos);
	NVIC_EnableIRQ(TIMER1_IRQn);
	
	// Configure the GPIOTE Task to toggle the LED state. 
	nrf_gpiote_task_config(0,  // GPIOTE Channel
					M1_A0_PIN, // GPIO pin
					NRF_GPIOTE_POLARITY_TOGGLE,
					NRF_GPIOTE_INITIAL_VALUE_HIGH);

	// Configure the GPIOTE Task to toggle the LED state. 
	nrf_gpiote_task_config(1,  // GPIOTE Channel
					M1_B0_PIN, // GPIO pin
					NRF_GPIOTE_POLARITY_TOGGLE,
					NRF_GPIOTE_INITIAL_VALUE_HIGH);
											
	//Configure PPI
	err_code = sd_ppi_channel_assign(0, &(NRF_TIMER1->EVENTS_COMPARE[0]), &(NRF_GPIOTE->TASKS_OUT[0]));
	// Enable PPI channel 0
	err_code = sd_ppi_channel_enable_set(PPI_CHEN_CH0_Msk);

	NRF_TIMER1->TASKS_START = 1;
}
Related