Topics

Determining source of GPIO Interrupt on NRF52832 #nrf52832 #gpio


bbradley@...
 

Hello, 

I hope I am posting this question in the correct place.

I have an interrupt handler which can be configured to trigger on either edge. This is working perfectly, but I want to perform a different action on a rising edge vs a falling edge in some cases. Is there any way to do this? (i.e., perhaps I can determine in the interrupt context that a rising edge and not a falling edge was triggered?)

I am configuring the interrupts and registering the handler using the gpio API (gpio_pin_configure, gpio_init_callback, gpio_add_callback, gpio_pin_enable_callback), but the interrupt handler will act differently on a rising edge vs falling edge, for instance, so it is helpful to know which specific flags were raised that triggered the interrupt. I am currently using the gpio_pin_read API to work around this, but I am not sure if this is the best solution.

In other MCU's there is often an API to read the status register containing the interrupt flags that have been raised, and then an API for clearing the status register after reading. Is there anything similar with Zephyr? Or perhaps there is a way to have two different handlers for rising edge/falling edge?

I am using Zephyr v2.0.99 right now.

Thanks for any help, 
Brian


Lawrence King
 

Hi Brian:

 

You can always test the value of the GPIO with gpio_pin_read() in the callback, if it is 1, then the cause is a rising edge, and if it is 0 the cause was a falling edge. Unfortunately if the input is a very short pulse you could get a rising edge interrupt, but by the time you get around to reading the GPIO, it could be back to low giving you the wrong information, and the short pulse should also trigger a second interrupt. If your transitions are relatively slow the testing the GPIO is good enough.

 

I agree there should be a way to separate the rising and falling events. Did you try creating two call backs, one for rising, and one for falling?

 

gpio_pin_configure – with flags for rising edge

gpio_init_callback,  - rising

gpio_add_callback, - rising

gpio_pin_enable_callback – for rising edges

 

gpio_pin_configure – with flags for falling edge

gpio_init_callback,  - falling

gpio_add_callback, - falling

gpio_pin_enable_callback – for falling edges

 

Lawrence King

Principal Developer

+1(416)627-7302

 

From: users@... <users@...> On Behalf Of bbradley@...
Sent: Thursday, December 5, 2019 11:16 AM
To: users@...
Subject: [Zephyr-users] Determining source of GPIO Interrupt on NRF52832 #gpio #nrf52832

 

Hello, 

I hope I am posting this question in the correct place.

I have an interrupt handler which can be configured to trigger on either edge. This is working perfectly, but I want to perform a different action on a rising edge vs a falling edge in some cases. Is there any way to do this? (i.e., perhaps I can determine in the interrupt context that a rising edge and not a falling edge was triggered?)

I am configuring the interrupts and registering the handler using the gpio API (gpio_pin_configure, gpio_init_callback, gpio_add_callback, gpio_pin_enable_callback), but the interrupt handler will act differently on a rising edge vs falling edge, for instance, so it is helpful to know which specific flags were raised that triggered the interrupt. I am currently using the gpio_pin_read API to work around this, but I am not sure if this is the best solution.

In other MCU's there is often an API to read the status register containing the interrupt flags that have been raised, and then an API for clearing the status register after reading. Is there anything similar with Zephyr? Or perhaps there is a way to have two different handlers for rising edge/falling edge?

I am using Zephyr v2.0.99 right now.

Thanks for any help, 
Brian


bbradley@...
 

I just realized I responded to you privately by accident, Lawrence. Sorry about that. I will copy the message I sent to you to the group so that the discussion is up to date.

The suggestion regarding testing the gpio with gpio_pin_read is exactly what I am currently doing, and it does indeed work well, but I had the same thought about spurious pulses potentially causing issues here. I haven't observed issues with this yet, but it certainly was a concern of mine.

As for your second suggestion, I have not tried that! My understanding was that calling gpio_pin_configure a second time would (re)configure the gpio, not append additional configurations. So I have been configuring the gpio with interrupt flags which are bitwise OR'd. If the API can in fact allow me to have multiple pin configurations with different callbacks then it should work perfectly. This will require a bit of refactor for my current project, but I can at least test this concept fairly quickly. 

Thanks for the suggestions! I will let you know if it works.
Brian