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

Reading multiple events with GPIOTE

I'm trying to test out pin change interrupts using the PCA10028 dev board. I'm using two buttons to turn off and on an LED. The code below is only generating events from button1. I'm trying to illuminate and LED when button1 is pressed and turn it off when button2 is pressed. So far, I'm only able to illuminate the LED, not turn it off. What am I missing? I'm using the nrf51422 with no SD. Thanks for the help.

static void button_gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {

if(pin & BUTTON2)//turn off led { //app_sched_event_put(NULL,0, led_clear_event); nrf_gpio_pin_set(LED_PIN1); }

else if(pin & BUTTON1) //light up led { nrf_gpio_pin_clear(LED_PIN1); //app_sched_event_put(NULL,0, led_set_event); } }

void gpiote_handler_init() { if(!nrf_drv_gpiote_is_init()) { nrf_drv_gpiote_init(); } }

void gpiote_button_init() {

nrf_drv_gpiote_in_config_t gpiote_button1 = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); gpiote_button1.pull = NRF_GPIO_PIN_PULLUP;

nrf_drv_gpiote_in_config_t gpiote_button2 = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);

gpiote_button2.pull = NRF_GPIO_PIN_PULLUP;

nrf_drv_gpiote_in_init(BUTTON1, &gpiote_button1, button_gpiote_event_handler); nrf_drv_gpiote_in_init(BUTTON2, &gpiote_button2, button_gpiote_event_handler);

nrf_drv_gpiote_in_event_enable(BUTTON1, true);

nrf_drv_gpiote_in_event_enable(BUTTON2, true);

}

/** * @brief Function for application main entry. */

int main(void) {

pin_config();

scheduler_init();

gpiote_handler_init();

gpiote_button_init();

while (true)
{ 			
app_sched_execute();	
}}
Parents
  • You know that there is app_button library available at SDKXX\components\libraries\button. When you press a button, most likely there is debounce causing un-necessary events. App_button library takes care of this debounce. Anyways, if you do not worry about the debounce then change your button handler little like below and it should work.

    static void button_gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
    
    if((pin == BUTTON2) && (NRF_GPIOTE_POLARITY_HITOLO == action))//turn off led 
    { 
    //app_sched_event_put(NULL,0, led_clear_event); 
    nrf_gpio_pin_set(LED_PIN1); 
    }
    
    else if((pin == BUTTON1) && (NRF_GPIOTE_POLARITY_HITOLO == action)) //light up led 
    { 
    nrf_gpio_pin_clear(LED_PIN1); 
    //app_sched_event_put(NULL,0, led_set_event); 
    } }
    
    void gpiote_handler_init() { 
    if(!nrf_drv_gpiote_is_init()) 
    { nrf_drv_gpiote_init(); 
    } }
    
  • I realize there is an app_button library. I don't think this is a debounce issue since I'm turning on the LED with any change on one button and turning off the LED with any change on the other button, so it isn't level dependent. I've tried the change that you suggested as well as usign NRF_GPIOTE_POLARITY_TOGGLE in my button handler. Still I can only illuminate the LED and not turn it off. Is there something I need to do to clear a port event since I'm not using high accuracy mode? I'm really stuck on this...

    static void button_gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action{

    if(pin == BUTTON2 && action == NRF_GPIOTE_POLARITY_TOGGLE)//turn off led{

    	//app_sched_event_put(NULL,0, led_clear_event);
    	nrf_gpio_pin_set(LED_PIN1);
    }
    else if(pin == BUTTON1 && action == NRF_GPIOTE_POLARITY_TOGGLE) //light up led
    {
    	nrf_gpio_pin_clear(LED_PIN1);
    	//app_sched_event_put(NULL,0, led_set_event);
    }}
    

    void gpiote_handler_init(){

    //uint32_t err_code;
    if(!nrf_drv_gpiote_is_init())
    {
    nrf_drv_gpiote_init();
    }}
    

    void gpiote_button_init(){

    nrf_drv_gpiote_in_config_t gpiote_button1 = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
    gpiote_button1.pull = NRF_GPIO_PIN_PULLUP;
    
    nrf_drv_gpiote_in_config_t gpiote_button2 = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
    gpiote_button2.pull = NRF_GPIO_PIN_PULLUP;
    
    nrf_drv_gpiote_in_init(BUTTON1, &gpiote_button1, button_gpiote_event_handler);
    nrf_drv_gpiote_in_init(BUTTON2, &gpiote_button2, button_gpiote_event_handler);
    
    nrf_drv_gpiote_in_event_enable(BUTTON1, true);
    nrf_drv_gpiote_in_event_enable(BUTTON2, true);
    

    }

Reply
  • I realize there is an app_button library. I don't think this is a debounce issue since I'm turning on the LED with any change on one button and turning off the LED with any change on the other button, so it isn't level dependent. I've tried the change that you suggested as well as usign NRF_GPIOTE_POLARITY_TOGGLE in my button handler. Still I can only illuminate the LED and not turn it off. Is there something I need to do to clear a port event since I'm not using high accuracy mode? I'm really stuck on this...

    static void button_gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action{

    if(pin == BUTTON2 && action == NRF_GPIOTE_POLARITY_TOGGLE)//turn off led{

    	//app_sched_event_put(NULL,0, led_clear_event);
    	nrf_gpio_pin_set(LED_PIN1);
    }
    else if(pin == BUTTON1 && action == NRF_GPIOTE_POLARITY_TOGGLE) //light up led
    {
    	nrf_gpio_pin_clear(LED_PIN1);
    	//app_sched_event_put(NULL,0, led_set_event);
    }}
    

    void gpiote_handler_init(){

    //uint32_t err_code;
    if(!nrf_drv_gpiote_is_init())
    {
    nrf_drv_gpiote_init();
    }}
    

    void gpiote_button_init(){

    nrf_drv_gpiote_in_config_t gpiote_button1 = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
    gpiote_button1.pull = NRF_GPIO_PIN_PULLUP;
    
    nrf_drv_gpiote_in_config_t gpiote_button2 = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
    gpiote_button2.pull = NRF_GPIO_PIN_PULLUP;
    
    nrf_drv_gpiote_in_init(BUTTON1, &gpiote_button1, button_gpiote_event_handler);
    nrf_drv_gpiote_in_init(BUTTON2, &gpiote_button2, button_gpiote_event_handler);
    
    nrf_drv_gpiote_in_event_enable(BUTTON1, true);
    nrf_drv_gpiote_in_event_enable(BUTTON2, true);
    

    }

Children
No Data
Related