Files
IR-protocol/IrInterruptGuard.h

52 lines
1.2 KiB
C++

#pragma once
#include <Arduino.h>
#if defined(__AVR__)
#include <avr/interrupt.h>
#include <avr/io.h>
#endif
/**
* Nest-safe interrupt guard for the short ISR/main shared-state sections used
* by IR-protocol. Unlike a noInterrupts()/interrupts() pair it restores the
* previous state and therefore never enables interrupts from inside an ISR.
*/
class IrInterruptGuard final
{
public:
IrInterruptGuard()
{
#if defined(__arm__) || defined(__thumb__) || defined(ARDUINO_ARCH_STM32)
state_ = __get_PRIMASK();
__disable_irq();
#elif defined(__AVR__)
state_ = SREG;
cli();
#else
noInterrupts();
#endif
}
~IrInterruptGuard()
{
#if defined(__arm__) || defined(__thumb__) || defined(ARDUINO_ARCH_STM32)
if ((state_ & 1U) == 0U)
__enable_irq();
#elif defined(__AVR__)
SREG = static_cast<uint8_t>(state_);
#else
interrupts();
#endif
}
IrInterruptGuard(const IrInterruptGuard&) = delete;
IrInterruptGuard& operator=(const IrInterruptGuard&) = delete;
private:
#if defined(__arm__) || defined(__thumb__) || defined(ARDUINO_ARCH_STM32) || \
defined(__AVR__)
uint32_t state_ = 0U;
#endif
};