Lonewolff
Posts: 170
Joined: Fri Dec 28, 2012 11:13 pm

Problems with interrupt

Thu Jun 17, 2021 3:23 am

Hi Guys,

I am trying interrupts for the first time in C and am running in to some problems.

This is my callback code;

Code: Select all

void gpio_callback(uint gpio, uint32_t events)
{
     gpio_put(25, 1);		// LED On
     sleep_us(1000000);
     gpio_put(25, 0);		// LED Off
     sleep_us(1000000);
}
Any my interrupt setup code;

Code: Select all

gpio_set_irq_enabled_with_callback(DIN0, GPIO_IRQ_EDGE_RISE, true, &gpio_callback);
DIN0 is defined as GPIO pin 15.

When I go from logic 0 to 1 on pin 15, the LED comes on and the rest of the program pauses (as I'd expect). But from the callback, the LED should stay on of one second then turn off for one second. But the LED stays on solid and never goes out. Doesn't matter if I return the connection to pin 15 to a logic LOW or not.

Just wondering if I am missing a step somewhere here? In theory it seemed like a simple task.

Many thanks in advance!

Lonewolff
Posts: 170
Joined: Fri Dec 28, 2012 11:13 pm

Re: Problems with interrupt

Thu Jun 17, 2021 3:37 am

I just checked with an oscilloscope (there's a little bit going on in my circuit) and verified 0v on pin 15 when it's intended to be low and 3.3v (going through a 74LVC245) when it's intended to be high. So, from a circuit standpoint, the signals are verified to be ok.

So I don't know if the Pi is stuck in a repeated IRQ trigger or something (which would explain the LED staying on).

I don't really know, to be honest.

(Edit) tested on GPIO 16 also, just incase there is a quirk about 15 that I don't know about. Same symptoms on either.

dshadoff
Posts: 76
Joined: Wed Apr 28, 2021 3:12 am

Re: Problems with interrupt

Thu Jun 17, 2021 3:49 am

Try it without using sleep() in your interrupt service routine.
Rather, in your main loop, watch for when the interrupt is set and reset it after a delay from that.

Lonewolff
Posts: 170
Joined: Fri Dec 28, 2012 11:13 pm

Re: Problems with interrupt

Thu Jun 17, 2021 3:54 am

I've now isolated it to the sleep_us() function. If I remove those, the interrupt seems to fire properly.

Are you not allowed to call sleep during an interrupt? Not that I really need to, I just wanted to produce a delay so I could see the LED firing on and off to verify I had it working ok.

Lonewolff
Posts: 170
Joined: Fri Dec 28, 2012 11:13 pm

Re: Problems with interrupt

Thu Jun 17, 2021 3:55 am

dshadoff wrote:
Thu Jun 17, 2021 3:49 am
Try it without using sleep() in your interrupt service routine.
Rather, in your main loop, watch for when the interrupt is set and reset it after a delay from that.
You beat me to it. Removing the sleep did seem to make it work. Sleep a 'no go' in an interrupt?

dshadoff
Posts: 76
Joined: Wed Apr 28, 2021 3:12 am

Re: Problems with interrupt

Thu Jun 17, 2021 4:03 am

sleep() actually sets a timer and waits for an interrupt... which it shouldn't be doing if it's already inside an interrupt service routine.

In general, you want your interrupt service routines to be as short as absolutely possible, so that you can service as high as possible a frequency of interrupts, and so that you won't accidentally miss one because you were working on another.

Lonewolff
Posts: 170
Joined: Fri Dec 28, 2012 11:13 pm

Re: Problems with interrupt

Thu Jun 17, 2021 4:25 am

Awesome! Thanks!

It seems my circuit is triggering the interrupt multiple times too (possibly a bit of noise) and it is possibly running over itself or something - LOL

Code: Select all

gpio_set_irq_enabled_with_callback(DIN1, GPIO_IRQ_EDGE_FALL, false, &gpio_callback);
    
gpio_set_irq_enabled_with_callback(DIN1, GPIO_IRQ_EDGE_FALL, true, &gpio_callback);
I have added this to the start and end of my interrupt routine, which seems to have helped it. Is this the correct way to temp disable an interrupt? Or is there a better suited way?

Many thanks for your help so far too, you are awesome!

dshadoff
Posts: 76
Joined: Wed Apr 28, 2021 3:12 am

Re: Problems with interrupt

Thu Jun 17, 2021 4:31 am

I haven't used this part of the API, so I can't comment on exact usage - but again, it is not good practice to set the parameters (or callbacks) of interrupts from within an interrupt service function (only to acknowledge the interrupt).

Probably somebody else would have more experience with using the callbacks the way you intend to.

Lonewolff
Posts: 170
Joined: Fri Dec 28, 2012 11:13 pm

Re: Problems with interrupt

Thu Jun 17, 2021 5:01 am

No worries, fully understand where you are coming from there.

How do you go about acknowledging the interrupt though? I can't see anything hello_gpio_irq example that seems to do that (https://github.com/raspberrypi/pico-exa ... gpio_irq.c)

Lonewolff
Posts: 170
Joined: Fri Dec 28, 2012 11:13 pm

Re: Problems with interrupt

Thu Jun 17, 2021 6:19 am

This is what I've got going on, if anyone is interested.

I've been building my own VGA card over the past year and it's pretty close to being done.

Image

The Pico is feeding the cards RAM during the vertical blanking period (thanks to the newly implemented interrupt routine). The garbled mess at the bottom is more or less intentional as I haven't hooked up the blanking circuit so I can see the CPU time.

Now to optimise some code! 8-)

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 752
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Problems with interrupt

Thu Jun 17, 2021 2:18 pm

Code: Select all

/*!
 * \defgroup sleep sleep
 * \ingroup pico_time
 * \brief Sleep functions for delaying execution in a lower power state.
 *
 * These functions allow the calling core to sleep. This is a lower powered sleep; waking and re-checking time on every processor
 * event (WFE)
 *
 * \note  These functions should not be called from an IRQ handler.
 
Perhaps should be documented on the functions themselves rather than the group of functions.

you can use "busy_wait_us" if you must delay, but yes you are better off doing so outside of an IRQ handler

Lonewolff
Posts: 170
Joined: Fri Dec 28, 2012 11:13 pm

Re: Problems with interrupt

Thu Jun 17, 2021 10:05 pm

Ah cool! At least there isn't too many that you can't use. But I agree, a note in the manual on the function itself would make much more sense.

dthacher
Posts: 44
Joined: Sun Jun 06, 2021 12:07 am

Re: Problems with interrupt

Fri Jun 18, 2021 2:38 am

I would want to know the interrupt priority used. It is POSIX not C, so I guess that kind of makes sense.

Lonewolff
Posts: 170
Joined: Fri Dec 28, 2012 11:13 pm

Re: Problems with interrupt

Fri Jun 18, 2021 4:34 am

dthacher wrote: I would want to know the interrupt priority used. It is POSIX not C, so I guess that kind of makes sense.
Sorry I’m not understanding the question, or if there was one there.

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 752
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Problems with interrupt

Fri Jun 18, 2021 12:42 pm

dthacher wrote:
Fri Jun 18, 2021 2:38 am
I would want to know the interrupt priority used. It is POSIX not C, so I guess that kind of makes sense.
You can go look... yes it is possible to use it from an IRQ handler if you set the priorities correctly, but why would you vs. either using busy_wait or setting a timer to re-interrupt you later. Since there is no obvious need for these to work and you are likely to shoot yourself in the foot trying, we decided it was less confusing (than getting into the weeds of when you might or might not deadlock yourself) and more correct anyway to was to discourage/disallow use.

dthacher
Posts: 44
Joined: Sun Jun 06, 2021 12:07 am

Re: Problems with interrupt

Fri Jun 18, 2021 2:06 pm

Lonewolff wrote: Sorry I’m not understanding the question, or if there was one there.
It was a remark for possible documentation.
kilograham wrote:
Fri Jun 18, 2021 12:42 pm
dthacher wrote:
Fri Jun 18, 2021 2:38 am
I would want to know the interrupt priority used. It is POSIX not C, so I guess that kind of makes sense.
You can go look... yes it is possible to use it from an IRQ handler if you set the priorities correctly, but why would you vs. either using busy_wait or setting a timer to re-interrupt you later. Since there is no obvious need for these to work and you are likely to shoot yourself in the foot trying, we decided it was less confusing (than getting into the weeds of when you might or might not deadlock yourself) and more correct anyway to was to discourage/disallow use.
There are a couple rare cases were this kind of thing may be valid. If I wanted to block in my interrupt, I would intentionally put it at the lowest priority. Which I am guessing is where this interrupt is. Which causes a lock out for that interrupt level. I can create a makeshift thread out of it if I do my memory correctly.

I know its not the best approach and has many pitfalls. However my context will likely determine if it would work or not. I would know how many interrupts are possible. I would know what activates them and roughly the worst case combination. The worst case stack growth I could manually compute also.

Return to “General”