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

GPOITE interrupt not being serviced with softdevice S132, ble and SPI running.

So I've been having a problem the last few days - using the NRF52832 we have an SPI chip connected his chip requires a clock signal (1MHz) that is being generated by the NRF. 

When a conversion has occurred, and data is available to be read from the chip - the chip will assert another signal that is set up to trigger a GPIOTE interrupt on the NRF. When this is triggered, we should read the data from the chip and send it over BLE.

However, the problem is the interrupt is never getting serviced. I've stripped back the code quite a lot in order to debug - the ISR now just sets a flag (volatile don't worry) that is periodically checked in the main loop, but even this never gets serviced. 

void IRQ(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
		irq_triggered = true;
}

static void gpiote_init(void)
{
	ret_code_t err_code;
	NRF_LOG_INFO("init gpiote \n");
	NRF_LOG_FLUSH();

	err_code = nrf_drv_gpiote_init();		//Initiate the GPIO - must be called once
	APP_ERROR_CHECK(err_code);					//check this

	//WES
	nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
	//in_config.pull = NRF_GPIO_PIN_NOPULL;
	in_config.pull = NRF_GPIO_PIN_PULLUP;
	err_code = nrf_drv_gpiote_in_init(24, &in_config, IRQ);	//SETUP INTERUPT 
	APP_ERROR_CHECK(err_code);	
}


void enable_data() {
	//SPI SETUP STUFF
	
	
	NRF_LOG_INFO("enabling interrupt \n");
	
	nrf_drv_gpiote_in_event_enable(24, true);
	NRF_LOG_FLUSH();
}

//This sets the 1MHz for the SPI chip.

static void timers_init(void)
{
		nrf_gpio_cfg_output(MAIN_CLOCK_OUT);

    // Initialize timer module.
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);

    // Create timers for the ADC.
    app_timer_create(&m_adc_timer_id,APP_TIMER_MODE_REPEATED, timer_timeout_handler);
		
	
	
		// Create the 1MHz Clock
		NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
    {
        // Wait for clock to start
				__NOP();
    }
    
    // Configure GPIOTE to toggle pin 10 
    NRF_GPIOTE->CONFIG[0] = GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos |
                            GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos |
                            MAIN_CLOCK_OUT << GPIOTE_CONFIG_PSEL_Pos | 
                            GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos;
    
		// Clear TIMER1
		NRF_TIMER1->TASKS_CLEAR = 1; 
    
		// Set up timer
		
    NRF_TIMER1->PRESCALER = 0;
    NRF_TIMER1->CC[0] = (uint32_t)((1/(float)(4*hfclk_freq)) * (XTAL_FREQ >> 0)); // Adjust the output frequency by adjusting the CC.
    NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
        
    // Set up PPI to connect the timer compare event with the GPIOTE toggle task
    NRF_PPI->CH[3].EEP = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[0];
    NRF_PPI->CH[3].TEP = (uint32_t) &NRF_GPIOTE->TASKS_OUT[0];
    
    NRF_PPI->CHENSET = PPI_CHENSET_CH3_Enabled << PPI_CHENSET_CH3_Pos;
		NRF_TIMER1->TASKS_START = 1;
		
		nrf_gpiote_task_enable(0);		
}

//IN MAIN LOOP...
if(irq_triggered == true){
    NRF_LOG_INFO("IRQ_TRIGGERED");
    NRF_LOG_FLUSH();
    irq_triggered = false;
	}
					

I've redacted quite a lot of the code as you can tell!

Things I've tried:


Changing priorities in sdk_config (should I be using the nvic functions as I'm using a SD?)

Only initializing the GPIOTE when I call enable_data (gpiote_init() is currently called at the program start)

I've scoped the signals and can see the data ready signal getting assented - it lasts about 60uS, with minimum repeats every 200mS - ie 5Hz. This is really slow so should be fine?

Could it be a logging issue?

Hope someone will see my hopefully trivial mistake :)

  • Hi,

    You are configuring the CONFIG register of GPIOTE channel 0 inside timers_init() to toggle a GPIO. The GPIOTE driver will most likely also use channel 0, as it is not aware that this channel is used elsewhere. I would recommend that you do not mix configuration using registers and drivers on the same peripheral within the same application. Our drivers typically implement checks towards double initialization, but this only works if the driver is used in both places.

    Best regards,
    Jørgen

Related