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?
Parents
  • Hi Erltot,

    Please be noted that you can always use the register directly if needed. The driver we provided in the SDK is just for your convenience, covering board use cases.

    But I don't see any reason the driver is not suitable for your need.

    I'm not sure I fully understand your description. Why do you have to set an interrupt when the device is paired ? Is paired meaning connected ? What exactly is "going to sleep" ? It's deep sleep mode or simply put CPU to sleep and keep the connection

    nrf_drv_gpiote_out_init() is to configured a pin as OUTPUT and if there is a task configured for the pin. This is not related to input pin.

    I don't understand this " 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?"

    You can do what ever you want in the interrupt handler, but you will block other activity with same priority level when you are inside the interrupt handler.

    If you are using the driver, you don't have to access the register directly, simply call nrf_drv_gpiote_in_event_disable(pin) will disable that pin's interrupt.

    nrf_drv_gpiote_in_event_enable() won't return anything, how could you get NRF_ERROR_INVALID_STATE ?

    You can use same interrupt handler for different pin (then you would need to check which pin causing the interrupt in the argument), or you can use different handler for each pin interrupt.

Reply
  • Hi Erltot,

    Please be noted that you can always use the register directly if needed. The driver we provided in the SDK is just for your convenience, covering board use cases.

    But I don't see any reason the driver is not suitable for your need.

    I'm not sure I fully understand your description. Why do you have to set an interrupt when the device is paired ? Is paired meaning connected ? What exactly is "going to sleep" ? It's deep sleep mode or simply put CPU to sleep and keep the connection

    nrf_drv_gpiote_out_init() is to configured a pin as OUTPUT and if there is a task configured for the pin. This is not related to input pin.

    I don't understand this " 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?"

    You can do what ever you want in the interrupt handler, but you will block other activity with same priority level when you are inside the interrupt handler.

    If you are using the driver, you don't have to access the register directly, simply call nrf_drv_gpiote_in_event_disable(pin) will disable that pin's interrupt.

    nrf_drv_gpiote_in_event_enable() won't return anything, how could you get NRF_ERROR_INVALID_STATE ?

    You can use same interrupt handler for different pin (then you would need to check which pin causing the interrupt in the argument), or you can use different handler for each pin interrupt.

Children
Related