Best practise to disable external interrupt within ISR

Go To Last Post
17 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi freaks

 

I am designing a nrf24l01+ based security system where there will be a 3.3v coin cell powered door sensor which will detect the door opening and report to the main unit.I have configured the INT0 of the avr at rising edge(I am using Normally opened magnetic reed switch based door sensor).

Now I have configured the program in a way that within it's ISR,the atmega will disable it's interrupt.I am testing my code with a LED indicator and by far,it does what it is intended to do.Now my query is,if the interrupt disabling method is all right or should i change it?Please take a look at the code below.

 

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

void enable_intr0(void)
{
	EICRA |= ((1<<ISC01)|(1<<ISC00));//On rising edge
	EIMSK |= (1<<INT0);//On INT0
}

void disable_intr0(void)
{
	EICRA = 0x00;
	EIMSK = 0x00;
}

uint8_t door_open(void)//This check is to avoid the debounce during the closing of the door
{
	if(bit_is_set(PIND,2))
	{
	_delay_ms(20);
	if(bit_is_set(PIND,2))
	{
	return 1;
	}
	else
	{
	return 0;
	}
	}
	else
	{
	return 0;
	}
}

ISR (INT0_vect)
{
	disable_intr0();
}

void gotosleep(void)
{
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);
	sleep_enable();

	EIFR = (1<<INTF0);//Clear any pending interrupts
	enable_intr0();//Enable INT0 on falling edge and sleep

	sleep_cpu();
	sleep_disable();
}

int main(void)
{
    /* Replace with your application code */

	DDRD &= ~(1<<2);//Input for sensor
	PORTD |= (1<<2);//Pullup enable

	DDRB |= (1<<0);//Output for LED
	PORTB &= ~(1<<0);//Shut down at first start
	sei();//global enable

    while (1)
    {
    gotosleep();

	if(door_open())//Check if the door actually got open or the interrupt is triggered due to the debounce during closing of the door
	{
	PORTB |= (1<<0);
	_delay_ms(1000);
	PORTB &= ~(1<<0);
	}

	}
}

 

Last Edited: Thu. Nov 9, 2017 - 05:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does avr-gcc disable interrupts when an ISR is invoked? If it does, your idea  might be redundant...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As far as i am concerned,the interrupt flag register bit(in my case INTF0) is cleared whenever the ISR is serviced.

 

But i am manually disabling the interrupt after entering into the ISR so that no other interrupt occurs within the desired operation.

 

My query was,to be more precise,should I clear only the EIMSK register(Which determines which Interrupt to work on for say INT0/1) or should I also clear the EICRA register(Which one decides the edge/level priority)??

 

I am clearing both in the above mentioned code.

Last Edited: Tue. Nov 7, 2017 - 08:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

dbrion0606 wrote:
Does avr-gcc disable interrupts when an ISR is invoked?

Come on dbrion! ;-)

 

Interrupt are disabled by hardware when an interrupt vector is "taken".

 

In any AVR data sheet I would expect to find this, or a similar, text:

 

When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts are disabled.

Unless you explicitly enable interrupts they will be disabled for the duration of the execution of the ISR. The return of the ISR is done using the RETI instruction which enables interrupts:

 

 The I-bit is automatically set when a Return from Interrupt instruction – RETI – is executed.

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Tue. Nov 7, 2017 - 08:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your debounce is rather rudimentary.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, for ISRs, there is nothing that "disables an interrupt". 

 

On entry, ALL interrupts are disabled by the hardware (e.g. globally). For Tiny and Mega devices, there can be no interrupt while any ISR is executing (without "special" specific action). When the ISR is exited, the global interrupt enable is turned back on. 

 

Thus, all interrupt enables remain unchanged through the execution of any ISR. And when the code execution leaves the ISR, interrupt enable status for all interrupts remains the same as it was just before entry into the interrupt. This is all done automatically and anything you do in code along these lines is redundant.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Wed. Nov 8, 2017 - 03:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If hardware (instead of gcc) disables interrupts when an interrupts occurs, my conclusion/rhetorical question  is much more valid :  a black box (whether it soft or hard is a pico detail; important point the job is already done)  makes that explicitely disabling interrupts in an ISR is redundant -and cycle eating-  (and it cannot solve the issue of an interrupt being activated before all the necessay stuffs are put into a stack -hidden part of ISR "call"- and code begins to be executed).....

 

OTOH : interrupts should be disabled in the main when one accesses shared, global variables/structures (I can remember these portions of code are called atomic blocks in avr libc ) to avoid terrible inconsistencies.

 

Edited : if OP wants "only" to poll sensors, maybe -s-he does need many interrupt: and Arduino-like software structure, with "only" a timer interrupt -every 10 ms, say : arduino timer is every 1 ms- which increases the number of ticks (simpler than Arduino timer interrupt, then) would be enough... and main program should read and copy this number of ticks in an atomic block, to elaborate delays if needed...

Last Edited: Wed. Nov 8, 2017 - 08:48 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SHARANYADAS wrote:
My query was,to be more precise,should I clear only the EIMSK register(Which determines which Interrupt to work on for say INT0/1) or should I also clear the EICRA register(Which one decides the edge/level priority)??

 

I think it is enough to clear EIMSK.

INT0 will remain disabled after returning from the interrupt.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dbrion0606 wrote:
If hardware (instead of gcc) disables interrupts when an interrupts occurs, my conclusion/rhetorical question
Have you ever used an AVR? Why on earth is there an "If" in this??

 

But the question here was not really about I anyway. It's about disabling a single interrupt source (INT0 in EIMSK). It might be a valid thing to do IF you were planning to sei() within an ISR() but did not want the same trigger to cause re-entrancy. But there's no sign of that in this code - so it all seems pointless.

 

This whole code has the look of something that has "grown organically" (bits tagged on as you think of the next scenario you need to cater for) rather than code that has been designed. Before you write C code you should think about the entire solution, what you want to achieve and how, consider all those "scenarios" that might occur that you need to cater for and include them as part of the design. Then create a solution and finally code it in C. Don't just sit in a C editor writing code as you think of things or (as appears to be happening here) you will tie yourself in knots.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you ever used an AVR? Why on earth is there an "If" in this??

 

I did; as my Arduini are full (or have a too slow ADC for my needs and no  DMA), I am switching to ARMs  (and interrupts remain enabled on ARM, with priorities and some optimisations w/r context saving/restoring) ; therefore, I forget about some femto details, processor specific .

An Arduino like -and simplified : no serial line-  software architecture  might be more than enough for OP's needs, IMO (one timer interrupt), from what I read from his code. I have no crystal balls nor telepatic skills to decide how this code was designed -if it was designed-: these are pure speculation questions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dbrion0606 wrote:
If hardware (instead of gcc) disables interrupts when an interrupts occurs,

There is no "if" about it. 

dbrion0606 wrote:
(and interrupts remain enabled on ARM, ...

What does the way ARM does it have to do with AVR8?  You have been doing AVR8 for some years.  I guess it is certainly possible that doing straightforward apps, and say a high-level language, that you have never had the need/desire to explore the Interrupts chapter?  OTOH, as you are now comparing architectures I'd think you'd be curious.

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, knowing exactly which mecanism disables and reenables interrupts for avr is not relevant . Main point being they are disabled and reenabled, without need to add code/cycles. (and nitpicking , again and again, is redundant and unconvincig, too but it makes people feel great).....

does the way ARM does it have to do with AVR8

Nothing, I agree, except I found out arms are better suited for my needs  -ADC is 10-100 times faster- -and, if it were not with Arduino, presoldered cards might be cheaper-

 

For OPs issue -sorry for remaining in topic-, I maintain, from the code OP posted,  software architecture "à la" Arduino -in a simplified way- is more than enough (a simpler timer ISR, and polling inputs). Do you object with this point? (this is/was  not a femto nitpicking topic, AFAIK).

 

For my skills -sorry for being OT : but this was your redundent "idea", was not it?-  : I never needed AvrFreaks help (my brain optical nerve, sheets of paper, pens , google  and application notes were more than  enough).

 

Knowing there is a mecanism which makes that avr-8 bits have "only" at most 2 threads-unless explicitely adding confusion-  is enough and very satisfying (no RAM enough).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Having a bad day?

 

I re-read my snarky response.  Where did I say you asked for help?  Ever?  After re-reading, my summary is "??? that is what every datasheet says -- how could you not have run into that in the several years?"

 

Redundant?  You can say that again.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What new ideas do you bring

a) in this topic? I am very sorry to remind it....

b)w/r Jekdahl and Clawson?

Oh, sorry, you go down to telepsychology..... (old trick, when one does not have any idea)...

and I wrote I used avrs for years ... whitout help (Clawson and J Ekdahl seem clever enough to realize that, once a minor detail -and 8 bits avr implementation/use is not eternal ; makes some difference w/r blasphemy- is corrected, the topic was dead (answer to OP question  is no, whatever the reason).

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Let me get this straight -- you made a response here that some/many thought was simply outrageous -- no factual basis; misleading at best.

 

Then someone cries "The Emperor has no clothes!", and I'm getting lambasted as being redundant and some indirect reference to you asking for help?!?

 

Well, as to being "redundant" -- I am indeed of the certain age where people are often labeled as redundant and put to pasture.  You are at an age where this pasture seems to be very far on the horizon.

 

[I just hope that there is indeed the verdant pasture, and that those of your generation do'nt implement the forced euthanasia of Soylent Green.  After all, "Soylent Green is people!"]

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dbrion0606 wrote:

What new ideas do you bring

a) in this topic? I am very sorry to remind it....

b)w/r Jekdahl and Clawson?

Oh, sorry, you go down to telepsychology..... (old trick, when one does not have any idea)...

and I wrote I used avrs for years ... whitout help (Clawson and J Ekdahl seem clever enough to realize that, once a minor detail -and 8 bits avr implementation/use is not eternal ; makes some difference w/r blasphemy- is corrected, the topic was dead (answer to OP question  is no, whatever the reason).

 

 

Maybe I'm lacking some minor/pico/nano/femto detail of the english language dbrion is used to, but basically i don't make any sense of it at all. (S?)he could have named me an idiot and i fear I wouldn't have recognized it in her/his creative style of writing english. But maybe mine isn't much better? Who knows... Who cares...

Einstein was right: "Two things are unlimited: the universe and the human stupidity. But i'm not quite sure about the former..."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Original topic was complete. Enough is enough here I think.

Topic locked