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

GPIOTE handler module or GPIOTE driver for PORT interrupt

On dev kit nRF52 PCA10040, rev 0.9.0, Keil uVision 5.21.1.0, SDK nRF5_SDK_12.1.0_0d23e2a - I need to monitor 9 input signals for a transition (hi to lo) on any of the pins. This would generate an interrupt and then I need to capture the state of these pins at high speed for a period of time, and once that time period is expired, return to sleep and wait for another transition on any of the 9 pins. Questions:

  1. In the "low power" mode monitoring the pins using the DETECT output and the PORT event, what is the latency between the GPIO pin changing state and the invocation of the ISR?
  2. Should I be using the GPIOTE handler module (documented here - nRF5 SDK > nRF5 SDK v12.1.0 > API Reference > SDK common libraries) or not? I've seen conflicting comments regarding its obsolescence.
  3. If I should be using the GPIOTE driver, it isn't clear if the nrf_drv_gpiote_in_init will do the job pursuant to the following comment in the infocenter: "In this case only one active pin can be detected at a time. It can be worked around by setting all of the used low accuracy pins to toggle mode." This is about as clear as mud. This in_init method only works on one pin, so is configuring each of the 9 pins using the "GPIOTE_CONFIG_IN_SENSE_HITOLO" macro sufficient to ensure that a change in state of any one of the 9 causes the DETECT signal and the PORT interrupt?
  4. The GPIOTE handler module seems more geared to what I'm trying to do, but in that module there are a number of ways to register actions: ...end_irq_event_handler_register, ...input_event_handler_register, app_gpiote_user_register. what is the salient difference between these methods given the context of my desired functionality?

Please see the code block for my stab at initializing the GPIOTE using the driver for this scenario. Will this produce the expected result? It doesn't seem correct to specify (using in_init) the same function pointer (for the handler) for every one of the 9 pins - with the SENSE config does it just magically know to connect these all to the PORT event?

	// Disable interrupts
NRF_GPIOTE->INTENCLR = 0xFFFFFFFF;

// Use the built-in macro to define the input pin config struct
// Elements of this struct are defined in nrf_drv_gpiote.h
nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
// Macro does not set the pullup or pulldown
config.pull = NRF_GPIO_PIN_PULLUP;
// Initialize the specific pin (P0.xx) #defines are in pca10040.h
// This also allocates a channel (hardware resource) that needs to be returned to the pool when finished
err_code = nrf_drv_gpiote_in_init(HESA0_TOP_PIN_NUMBER, &config, hesa_pin_event_handler);
    err_code = nrf_drv_gpiote_in_init(HESA1_TOP_PIN_NUMBER, &config, hesa_pin_event_handler);
    // ...do this for 7 more pins
APP_ERROR_CHECK(err_code);
// Enable event for this pin, no interrupt
nrf_drv_gpiote_in_event_enable(HESA0_TOP_PIN_NUMBER, false);
    nrf_drv_gpiote_in_event_enable(HESA1_TOP_PIN_NUMBER, false);
    // ...do this for 7 more pins
// Enable PORT interrupt
NRF_GPIOTE->INTENSET = 0x80000000;
Related