diff --git a/RCSwitch.cpp b/RCSwitch.cpp index 3ff7374..59f3e1d 100644 --- a/RCSwitch.cpp +++ b/RCSwitch.cpp @@ -96,6 +96,13 @@ const unsigned int RCSwitch::nSeparationLimit = 4600; // according to discussion on issue #14 it might be more suitable to set the separation // limit to the same time as the 'low' part of the sync signal for the current protocol. unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES]; + +#if defined( RCSwitchEnableBlockingReceive ) +unsigned long RCSwitch::events[RCSWITCH_MAX_EVENTS]; +int RCSwitch::eventsHead = 0; +int RCSwitch::eventsTail = 0; +sem_t RCSwitch::eventSem; +#endif #endif RCSwitch::RCSwitch() { @@ -106,6 +113,10 @@ RCSwitch::RCSwitch() { this->nReceiverInterrupt = -1; this->setReceiveTolerance(60); RCSwitch::nReceivedValue = 0; + + #if defined( RCSwitchEnableBlockingReceive ) + ::sem_init(&eventSem, 0, 0); + #endif #endif } @@ -647,6 +658,10 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun RCSwitch::nReceivedBitlength = (changeCount - 1) / 2; RCSwitch::nReceivedDelay = delay; RCSwitch::nReceivedProtocol = p; + + #if defined( RCSwitchEnableBlockingReceive ) + RCSwitch::pushEvent(code); + #endif } return true; @@ -693,4 +708,30 @@ void RECEIVE_ATTR RCSwitch::handleInterrupt() { RCSwitch::timings[changeCount++] = duration; lastTime = time; } + +#if defined( RCSwitchEnableBlockingReceive ) +/** + * Pushes an event onto the end of the events ring. + */ +void RCSwitch::pushEvent(unsigned long event) { + RCSwitch::events[RCSwitch::eventsTail++] = event; + if (RCSwitch::eventsTail >= RCSWITCH_MAX_EVENTS) { + RCSwitch::eventsTail = 0; + } + ::sem_post(&eventSem); +} + +/** + * Blocks until the events ring contains at least one event then pops + * an event from the head of the events ring and returns it. + */ +unsigned long RCSwitch::popEvent() { + ::sem_wait(&eventSem); + unsigned long event = RCSwitch::events[RCSwitch::eventsHead++]; + if (RCSwitch::eventsHead >= RCSWITCH_MAX_EVENTS) { + RCSwitch::eventsHead = 0; + } + return event; +} +#endif #endif diff --git a/RCSwitch.h b/RCSwitch.h index 9424e12..10f918b 100644 --- a/RCSwitch.h +++ b/RCSwitch.h @@ -41,6 +41,11 @@ #include /* memcpy */ #include /* abs */ #include + + #if not defined ( RCSwitchDisableReceiving ) + #define RCSwitchEnableBlockingReceive + #include + #endif #else #include "WProgram.h" #endif @@ -51,13 +56,17 @@ // At least for the ATTiny X4/X5, receiving has to be disabled due to // missing libm depencies (udivmodhi4) #if defined( __AVR_ATtinyX5__ ) or defined ( __AVR_ATtinyX4__ ) -#define RCSwitchDisableReceiving + #define RCSwitchDisableReceiving #endif // Number of maximum High/Low changes per packet. // We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync #define RCSWITCH_MAX_CHANGES 67 +#if defined( RCSwitchEnableBlockingReceive ) + #define RCSWITCH_MAX_EVENTS 100 +#endif + class RCSwitch { public: @@ -85,6 +94,10 @@ class RCSwitch { bool available(); void resetAvailable(); + #if defined( RCSwitchEnableBlockingReceive ) + unsigned long popEvent(); + #endif + unsigned long getReceivedValue(); unsigned int getReceivedBitlength(); unsigned int getReceivedDelay(); @@ -146,6 +159,15 @@ class RCSwitch { * timings[0] contains sync timing, followed by a number of bits */ static unsigned int timings[RCSWITCH_MAX_CHANGES]; + + #if defined( RCSwitchEnableBlockingReceive ) + static void pushEvent(unsigned long); + + static unsigned long events[RCSWITCH_MAX_EVENTS]; + static int eventsHead; + static int eventsTail; + static sem_t eventSem; + #endif #endif