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

Understanding GPIOTE better

I'm using interrupts on nRF for the first time and have some trouble wrapping my head around / struggling with uncertainty in how to use the interrupts/GPIOTE efficiently. I'd really appreciate some input. My previous experience with using interrupts is on 8bit AVRs wich was fairly straight forward..

I am going for low power design, with a coin cell battery, I used the ble_app_uart as a starting point, and have added SPI master and now GPIOTE.

What I want to achieve is, in order of execution:

  1. Setup MCU and peripherals, advertise BLE in low power mode
  2. When paired with a central device, set up a high-to-low interrupt on a !detect pin and go back to sleep
  3. Sleeping, when I get interrupt on the !detect pin, disable interrupts on this pin and set it to tristate, start peripheral unit and set up another interrupt to the peripheral !rdy pin
  4. SPI Conversions from peripheral when !rdy pin goes low, !rpy pin is also MISO, so interrupt has to be disabled in between, ie get interrupted, read and set up interrupt again. MCU sleeps in between cycles
  5. When the peripheral is done, put it to sleep, send the info over ble_nus, disable the !rdy pin interrupt, enable the !detect pin interrupt and go to step 3.

I figured I need to use GPIOTE with hi_accuracy disabled, however I get confused by the documentation and examples out there,

Questions:

  1. Is this the right approach to do what I want?
  2. Is there a better way to check if I am paired with a central than making a flag that I set and clear in the on_ble_evt GAPP?
  3. Why does nrf_drv_gpiote_out_init(PIN_OUT, &out_config) need to be used? It doesnt seem to be nessecary? Is there only certain things that can be done inside the in_pin_handler event? Should I instead go for setting flags and do the handling in the main loop? How does this coincide with low power usage?
  4. Which call should I be using when enabling/disabling the different interrupts? Will nrf_drv_gpiote_in_event_disable(pin) be enough or do I have to use something like NRF_GPIOTE->INTENSET = 0x80000000? It seems like just using nrf_drv_gpiote_in_event_enable(pin, true); / nrf_drv_gpiote_in_event_disable(pin); just doesnt quite do the trick? I get NRF_ERROR_INVALID_STATE when I try to enable the interrupt again
  5. Do I set up one event for each pin or do I set up one event and check which pin triggered it?
Related