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

How do I use an external interrupt?

Have tried to use an external interrupt coding.

/*------------------------------------------------------------------------------------------------------------*/
#define Record 28
#define Play 26

static void gpio_init(void)
{
nrf_gpio_cfg_input(Record, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(Play, NRF_GPIO_PIN_PULLUP);

 NVIC_DisableIRQ(GPIOTE_IRQn);
NVIC_ClearPendingIRQ(GPIOTE_IRQn);

// Enable interrupt:
  NVIC_SetPriority(GPIOTE_IRQn, 3); //optional: set priority of interrupt
NVIC_EnableIRQ(GPIOTE_IRQn);
NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos)
                       | (0x1C << GPIOTE_CONFIG_PSEL_Pos)   //  핀번호 설정
                       | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;
  


NRF_GPIO->PIN_CNF[Record] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
                                                      | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) 
                                                            | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos)   
                                                 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) 
                                                           | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);

NRF_GPIO->PIN_CNF[Play] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) 
                                                      | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) 
                                                            | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) 
                                                 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) 
                                                          | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
		    // Configure GPIOTE channel 0 to generate event on input pin low-to-high transition.
nrf_gpiote_event_config(0, Record, GPIOTE_CONFIG_POLARITY_Toggle);																								  			
}


/** @brief Function for handling the GPIOTE interrupt which is triggered on pin 0 change.
 */
void GPIOTE_IRQHandler(void)
{
	
/*
// Event causing the interrupt must be cleared.
if ((NRF_GPIOTE->EVENTS_IN[0] == 1) && 
    (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN0_Msk))
{
		  
    NRF_GPIOTE->EVENTS_IN[0] = 0;
}
*/
	 if(NRF_GPIOTE->EVENTS_IN[0] == 1)
	{
     
			NRF_GPIOTE->EVENTS_IN[0] = 0;  //this is where you should set breakpoint to make sure CC[0] and cc[1] don't change while you are in breakpoint
	}

	if(NRF_GPIOTE->EVENTS_IN[1] == 1) //will run only if you intenset event 1
	{

			NRF_GPIOTE->EVENTS_IN[1] = 0;  //this is where you should set breakpoint to make sure CC[0] and cc[1] don't change while you are in breakpoint
	}
	
	 if (nrf_gpio_pin_read(Record) == 0) {Record_Start = (!Record_Start);} //do something }

 if (nrf_gpio_pin_read(Play) == 0) { Record_Play = (!Record_Play);}//do something }
	

	
}

Press the Record button is changed to 1 if the variable is 0 Record_Start

if 1, to be changed to zero.

However, pressing the button once 0-> 1-> 0 just changed in this way.

What is the source of the problem?

Parents
  • This line,

    NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos)
    

    will cause the interrupt to trigger both when you push the button and when you release it. In order to only trigger the interrupt when you push the button, change it to:

    NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_HiToLo<< GPIOTE_CONFIG_POLARITY_Pos)
    

    Also, you can not read the pin state when the GPIOTE module is configured to operate on it, as you do in the interrupt handler:

    if (nrf_gpio_pin_read(Record) == 0) {Record_Start = (!Record_Start);}
    

    But, since the GPIOTE channel is now configured to only trigger on a hi to low transition, the pin will of course be low, and you can just write:

    Record_Start = (!Record_Start);
    
Reply
  • This line,

    NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos)
    

    will cause the interrupt to trigger both when you push the button and when you release it. In order to only trigger the interrupt when you push the button, change it to:

    NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_HiToLo<< GPIOTE_CONFIG_POLARITY_Pos)
    

    Also, you can not read the pin state when the GPIOTE module is configured to operate on it, as you do in the interrupt handler:

    if (nrf_gpio_pin_read(Record) == 0) {Record_Start = (!Record_Start);}
    

    But, since the GPIOTE channel is now configured to only trigger on a hi to low transition, the pin will of course be low, and you can just write:

    Record_Start = (!Record_Start);
    
Children
  • I'm doing this? Is that right?

    static void gpio_init(void)

    {

      nrf_gpio_cfg_input(Record, NRF_GPIO_PIN_PULLUP);
          nrf_gpio_cfg_input(Play, NRF_GPIO_PIN_PULLUP);
      nrf_gpio_cfg_input(Menu_Dw, NRF_GPIO_PIN_PULLUP);
    
          NVIC_DisableIRQ(GPIOTE_IRQn);
          NVIC_ClearPendingIRQ(GPIOTE_IRQn);
    
           NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                       | (0x1C << GPIOTE_CONFIG_PSEL_Pos)   
                       | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
                         NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;
    
           NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_HiToLo <<                          
                               GPIOTE_CONFIG_POLARITY_Pos)
                       | (0x1D << GPIOTE_CONFIG_PSEL_Pos)   
                       | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
                         NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN1_Set << GPIOTE_INTENSET_IN1_Pos;
    
      	  __NOP();
          __NOP();
          __NOP();
     
    				/* Clear the event that appears in some cases */
    				NRF_GPIOTE->EVENTS_IN[0] = 0; 
    				NRF_GPIOTE->EVENTS_IN[1] = 0; 
    
          NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_IN0_Enabled << GPIOTE_INTENSET_IN0_Pos;
    	NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_IN1_Enabled << GPIOTE_INTENSET_IN1_Pos;
            NVIC_EnableIRQ(GPIOTE_IRQn);
    														  			
    

    }

    void GPIOTE_IRQHandler(void)

    {

    if ((NRF_GPIOTE->EVENTS_IN[0] != 0))

    {

         Record_Start = (!Record_Start) ;
         NRF_GPIOTE->EVENTS_IN[0] = 0;
     }
    

    if ((NRF_GPIOTE->EVENTS_IN[1] != 0))

    {

        Record_Play = (!Record_Play) ;
        NRF_GPIOTE->EVENTS_IN[1] = 0;
    }	
    

    }

Related