Go Down

Topic: Interrupt handling question - optimised digitalWrite (Read 422 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;\
      cli();\
   }\
\
   if (value == LOW) {\
      *reg &= ~bit;\
   } else {\
      *reg |= bit;\
   }\
\
   if (!__builtin_constant_p(pin) || registerWriteNeedsLocking(reg)) {\
      SREG = oldSREG;\
   }\
} while(0)

Coding Badly

Quote
Does the return re-enable interrupts?


No.

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!

Arduino
via Egeo 16
Torino, 10131
Italy