Electronic – AVR SEI instruction

assemblyavrinterrupts

The AVR SEI instruction (http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_SEI.html)
waits for the next instruction to finish before enabling interrupts.

If I use another instruction to set the I flag in SREG, will this also wait 1 instruction?

In other words: Is the wait a feature of the SEI instruction or the status register?

If it is a feature of the SEI instruction, then at what point does the flag actually get set, in the cycle that executes SEI or with the next instruction?

Best Answer

Empirical results!

While the other answers are thoughtful and well reasoned, they are all incomplete or just conjecture. Where the documentation is ambiguous, we must experiment and we must test every case.

This question deserves a conclusive answer, so let's pull out an AVR and start setting some bits!

Procedure

To test, I made a little Arduino (ATMEGA328P) program that would...

  1. setup an ISR that would never return (while (1))
  2. assigned the ISR to a source I could trigger in software (INT0 going low)
  3. disabled interrupts
  4. enabled and triggered the interrupt so it would be pending

I used a test bed that would turn on an LED in the single instruction after interrupts were enabled. By trying different ways of enabling interrupts in the test bed and checking the LED, I could tell if the instruction after the enabling instruction was executed or not.

If the LED did not come on, then I know that the ISR executed (and locked) immediately after interrupts were enabled.

If the LED did come on, then I know that the next instruction was allowed to execute before the ISR was called.

Results

SEI instruction (base case)

Code:

sei

Result: LED on. Following instruction executed.

OUT instruction

Code:

in  r16,0x3f   // Get SREG
ori r16,128    // Set I bit 
out 0x3f,r16   // Save back to SREG

Result:

LED on. Following instruction executed.

ST instruction

Code:

   clr r29        // Clear Y high byte
   ldi r28,0x5f   // Set Y low byte to point to SREG
   ld r16, Y      // Get SREG
   ori r16,128    // Set I bit 
   st Y,r16       // Put SREG

Result:

LED on. Following instruction executed.

Conclusion!

Q: Is the wait a feature of the SEI instruction or the status register?

A: It appears that changing the I bit in SREG is from a 0 to a 1 will allow the following instruction to execute next even if there is a pending interrupt, regardless of what instruction is used to set the bit.

Notes

This actually turned into a very interesting question with lots of complications. If you are interested int he details, check out...

http://wp.josh.com/2016/01/05/different-ways-to-set-i-bit-in-avr-sreg-besides-sei/