Go Down

Topic: Interrupt handling question - optimised digitalWrite (Read 596 times) previous topic - next topic


A question for the interrupt handling experts. 

I'm using the optimised digitalWrite library here: http://code.google.com/p/arduino/issues/detail?id=140#c10 to speed things up (see extract below), and I understand why it is necessary to disable interrupts (cli()) when updating registers above 32 or when using variables. 

However, what I don't understand is when the interrupts get re-enabled after the function call.  I don't see a call to sei() or similar, but without that then surely the main program will then be running with interrupts disabled.  But I know that can't be true because my program works and does things that need interrupts enabled.

Does the return re-enable interrupts?  Any help much appreciated (and as a by-the-way, why the "while(0)" loop, which will only ever execute once?).


#define digitalWrite_implementation(pin, value)\
do {\
   uint8_t oldSREG;\
   uint8_t bit = digitalPinToBitMask(pin);\
   uint8_t port = digitalPinToPort(pin);\
   volatile uint8_t *reg = portOutputRegister(port);\
   if (!__builtin_constant_p(pin) || registerWriteNeedsLocking(reg)) {\
      oldSREG = SREG;\
   if (value == LOW) {\
      *reg &= ~bit;\
   } else {\
      *reg |= bit;\
   if (!__builtin_constant_p(pin) || registerWriteNeedsLocking(reg)) {\
      SREG = oldSREG;\
} while(0)

Coding Badly

Does the return re-enable interrupts?


The global interrupt enable state is determined by a bit in a register; specifically, the I (eye) bit in the Status Register (SREG).  If the I bit is set, interrupts are enabled.  If the I bit is clear, interrupts are disabled.

As you've discovered, the CLI instruction (aka cli()) disables interrupts.  It does that by clearing the I bit in the SREG register.

The "oldSREG = SREG;" assignment saves the current value of the SREG register, including the I bit, in a local variable named oldSREG.

The "SREG = oldSREG;" assignment restores the previously saved value of the SREG register, including the I bit.

So, the code does not re-enable interrupts.  It restores the interrupt state to what it was when digitalWrite was called.


Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131