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

NRF51822 Interrupt Service Routine handling

Hello, I was using wiringPiSPI() to connect via SPI and so i was using wiringPiISR function to create an interupt handler that will do callback to the user suplied function. Now I moved to module with NRF architecture. How can I handle interuptions the way i was doing it on the Raspberry PI? I'm using spi_master.h to connect via SPI. Is there any ready to use ISR handle the way it was made on Raspberry?

Parents
  • Comment field is a little to small so I will paste it here as a new post.

    I started to use GPIOTE and managed to sucesfully get interupt from external device. Next problem I have is, that when IRQHandler kicks in, whole system freezes (with APP_IRQ_PRIORITY_HIGH) or program isn't executed correctly (with APP_IRQ_PRIORITY_LOW)

    isr() function read and write to device through SPI (And here I'm not so sure what happens with concurrent SPI transmission)

    void GPIOTE_initirq()
    {
    	
    NVIC_DisableIRQ(GPIOTE_IRQn);
    	NVIC_ClearPendingIRQ(GPIOTE_IRQn);
    	NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_LOW); //Here is the problem
    
    
    NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos)
    					   | (0x10 << GPIOTE_CONFIG_PSEL_Pos)   //
    					   | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
    NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;
    
     __NOP();
     __NOP();
     __NOP();
    
     NRF_GPIOTE->EVENTS_IN[0] = 0;
     NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_IN0_Enabled << GPIOTE_INTENSET_IN0_Pos;
     NVIC_EnableIRQ(GPIOTE_IRQn);
    
    }
    
    void GPIOTE_IRQHandler(void)
    {
    		process_irq();
    		NRF_GPIOTE->EVENTS_IN[0] = 0;
    }
    
    process_irq()
    {
    	do
    	{
    		isr();
    	}while(nrf_gpio_pin_read(IRQ) == 1)
    }
    

    On Raspberry Pi the following code was executed to handle interruptions:

        //port_EnableIRQ(); 
        //enable ScenSor IRQ before starting
    	// set Pin 24 generate an interrupt on high-to-low transitions
    	// and attach process_deca_irq() to the interrupt
    
    if ( wiringPiISR (IRQ_PIN, INT_EDGE_RISING, &process_deca_irq) < 0 ) {
      printf("Unable to setup ISR\r\n");
    }
    
Reply
  • Comment field is a little to small so I will paste it here as a new post.

    I started to use GPIOTE and managed to sucesfully get interupt from external device. Next problem I have is, that when IRQHandler kicks in, whole system freezes (with APP_IRQ_PRIORITY_HIGH) or program isn't executed correctly (with APP_IRQ_PRIORITY_LOW)

    isr() function read and write to device through SPI (And here I'm not so sure what happens with concurrent SPI transmission)

    void GPIOTE_initirq()
    {
    	
    NVIC_DisableIRQ(GPIOTE_IRQn);
    	NVIC_ClearPendingIRQ(GPIOTE_IRQn);
    	NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_LOW); //Here is the problem
    
    
    NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos)
    					   | (0x10 << GPIOTE_CONFIG_PSEL_Pos)   //
    					   | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
    NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;
    
     __NOP();
     __NOP();
     __NOP();
    
     NRF_GPIOTE->EVENTS_IN[0] = 0;
     NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_IN0_Enabled << GPIOTE_INTENSET_IN0_Pos;
     NVIC_EnableIRQ(GPIOTE_IRQn);
    
    }
    
    void GPIOTE_IRQHandler(void)
    {
    		process_irq();
    		NRF_GPIOTE->EVENTS_IN[0] = 0;
    }
    
    process_irq()
    {
    	do
    	{
    		isr();
    	}while(nrf_gpio_pin_read(IRQ) == 1)
    }
    

    On Raspberry Pi the following code was executed to handle interruptions:

        //port_EnableIRQ(); 
        //enable ScenSor IRQ before starting
    	// set Pin 24 generate an interrupt on high-to-low transitions
    	// and attach process_deca_irq() to the interrupt
    
    if ( wiringPiISR (IRQ_PIN, INT_EDGE_RISING, &process_deca_irq) < 0 ) {
      printf("Unable to setup ISR\r\n");
    }
    
Children
  • I don't think it's a good idea to handle everything in a IRQ handler and stay there until the pin is released. Don't think you gonna receive the SPI interrupt if you already in a highest level priority context.

    My suggestion for you is to set a flag when in IRQHandler, and execute the SPI transmission when you are back to the main loop.

    When you mentioned you are using APP_IRQ_PRIORITY_LOW and APP_IRQ_PRIORITY_HIGH, do you have the softdevice also running ?

Related