When to use sei() when you have multiple interrupts?

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

Hi,

 

Hopefully this is the correct place to ask this, but if not, please move to correct location it should be in.

 

Anyhow, let's say I have an interrupt generated by analog comparator, this interrupt sets a flag of bool type to true. In main(), if flag is true, then I set up a RTC interrupt to interrupt every second in order to do something else.

 

Question: when should I be enabling global interrupts? (the sei() thing) so that both the AC interrupt and the RTC interrupt will work properly?

 

Thanks

Last Edited: Sun. Mar 11, 2018 - 07:04 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is the use of using an interrupt just to set a flag? Especially considering there is a hardware flag that can be used without enabling an interrupt.
Back to your question - when to sei()? As soon as everything is initialised.

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

Hi, Kartman

 

thanks for the information. so far, never used hardware flag before. Am using an attiny817/816 at the moment. If could provide where I can look up hardware flag so i can read up on how exactly it's properly used, i'd appreciate it

 

 

Last Edited: Sun. Mar 11, 2018 - 07:56 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There’s not too many registers for the analog comparator. The flag is in AC.STATUS bit 0. You need to maunally clear it by writing a ‘1’ to it. Refer section 29.5.4

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

There are no "hardware flags" (the venerable 8051 is about the only one I know with this feature). There are probably at least one general purpose IO register that you can use as a "flag" register. Have not checked up on the Tiny816/7 to see if that is the case.

 

Normally, you would simply use a code variable of type bool (though it is quite wasteful) and simply test whether that variable is true or false. If you access that variable in an ISR, be careful to make it volatile.

 

Personally, I simply set up a variable (sometimes just named flags as in:

uint8_t flags;

Then I define one or more flags. I prefer to define them as masks rather than bit positions so I might have:

#define RTC_FLAG 1
#define MOTOR_ON 2
#define LED_RED_ON  4
#define LED_GREEN_ON  8

Then I set the flag with:

flags |= RTC_FLAG;

and clear it with:

flags &= ~RTCFLAG;

Finally, to test whether or not the flag is set/true:


if (flags & RTC_RTC_FLAG) {
   //your code here
   }

 

Hope this helps,

 

Jim

 

 

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

Last Edited: Sun. Mar 11, 2018 - 08:18 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jim. I think you've picked up on the wrong use of 'flags'. There is and have always been hardware flags for the interrupt sources on the AVR - we're not talking about 'bit' operations.

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

You normally set up all your initialisation code and call sei() just before your main while(1) loop.
.
Regular AVRs are simple. Interrupts are disabled during an ISR().
You can modify any xxxIE bits safely in the ISR() e.g, start your RTC.
.
Since you might be using Xmega/Xtiny you might need to make a modification ATOMIC but this is only a few cycles to save and restore the SREG.
.
The often quoted advice to set a software flag in the ISR applies to SLOW software operations. Not applicable to simple hardware SFR changes like starting a Timer or ADC. Just do not sit in a wait loop.
.
David.

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

What is the use of using an interrupt just to set a flag? Especially considering there is a hardware flag that can be used without enabling an interrupt.

PEDANT: When sleeping.  If there is more than one enabled interrupt source which can wake the device from a given sleep mode, a software flag set in the ISR is the only way you can differentiate one wake-up source from another. /PEDANT

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

The important fact is that sei() MUST have been executed in order for the AC interrupt to work. There is no choice if it is really to be handled in an ISR. Without that sei(), the interrupt service will NEVER be executed. So, there is no question about WHEN interrupts have to be enabled. 

 

Once the global interrupt enable is on, the RTC interrupt will happen just as soon as that individual enable is set (and the interrupt event occurs). In this case, I would do a preventive "clear" of the RTC interrupt so that it does not trigger on some left over condition from earlier in the program. And, the proper time to do this is the instruction immediately before the enable occurs. I usually make a point of having the interrupt enable as the very last initialization instruction so that everything is running exactly as it should be and no false triggers will occur. And the next to the last initialization instruction clears the interrupt register.

 

Jim

 

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

Last Edited: Sun. Mar 11, 2018 - 10:27 PM