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

Interrupts on many pins high to low

I want to detect high to low transitions on 28 GPIO independently. I've read in other posts you can configure 4 pin interrupts or a port interrupt for all pins, but I'm not sure that allows the pins to have different states and still be detected.

I'm using GPIOTE. The code below does not seem to work for all pins.

for(int i = 2; ...; i++) {
    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
    in_config.pull = NRF_GPIO_PIN_NOPULL;
    err_code = nrf_drv_gpiote_in_init(i, &in_config, in_pin_handler);
    VERIFY_SUCCESS(err_code);
    nrf_drv_gpiote_in_event_enable(i, true);
}

Is the only solution polling?

  • Hi,

    In order to use IN event, a GPIOTE channel is required. On nRF52832 there are 8 GPIOTE channels available (4 channels on nRF51 series). Using the PORT event, you can still track individual pin states, but you need to check each enabled pin on every event, to keep track of which pin changed. This is slower than IN events, and can not be used to track high-speed pin changes. 

    If you use the GPIOTE driver in the SDK, this will track the pin states for you automatically.

    Best regards,
    Jørgen

  • I am using gpiote driver with SDK 15, but it isn’t working. I only get interrupt handler called on one pin out of the 4 I am testing (pins 8 to 11 on the DK) using the code in my post but with internal pull down configuration. Can you think why?

  • Are you checking the error code returned from nrf_drv_gpiote_in_init()? Note that VERIFY_SUCCESS will check if the error code is NRF_SUCCESS, and return the error code if it is not.

  • Yes I do eventually check the error code (I originally received NRFX_ERROR_NO_MEM as NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS was set to default 4, I increased to 28), it always succeeds

  • To reproduce, copy the following code into the blinky example, replacing main(). Connect P0.8 to P0.11 to VDD as shown. Only pins 8 and 11 interrupt for me.

    #include "nrf_drv_gpiote.h"
    #include "nrf_gpiote.h"
    
    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
        NRF_LOG_INFO("Pin %d action %d", pin, action);
    }
    
    
    /**@brief Function for application main entry.
     */
    int main(void)
    {
        // Initialize.
        log_init();
        //leds_init();
        //timers_init();
        //buttons_init();
        power_management_init();
        //ble_stack_init();
        //gap_params_init();
        //gatt_init();
        //services_init();
        //advertising_init();
        //conn_params_init();
    
    
        ret_code_t err_code = NRF_SUCCESS;
        if(!nrf_drv_gpiote_is_init()) {
            err_code = nrf_drv_gpiote_init();
            APP_ERROR_CHECK(err_code);
        }
    
        for(int i = 8; i < 12; i++) {
            nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
            in_config.pull = NRF_GPIO_PIN_PULLDOWN;
            err_code = nrf_drv_gpiote_in_init(i, &in_config, in_pin_handler);
            APP_ERROR_CHECK(err_code);
            nrf_drv_gpiote_in_event_enable(i, true);
        }
    
        // Start execution.
        NRF_LOG_INFO("Blinky example started.");
        //advertising_start();
    
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
        }
    }

Related