Interrupt handling question - optimised digitalWrite

A question for the interrupt handling experts.

I'm using the optimised digitalWrite library here: Google Code Archive - Long-term storage for Google Code Project Hosting. 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)

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.

Ah, I'd missed that. Thank you