/* IRrecvBase.cpp * Part of IRLib Library for Arduino receiving, decoding, and sending * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. * * This module contains the base class classes for receiving IR signals. You will not create * instances of this class, rather it is used as a base class for the 3 different * receiver classes. These are the original IRrecv which uses a 50us timer interrupt. * The IRrecvPCI version that uses pin change interrupts and IRrecvLoop which uses no timers * or interrupts. Each of these has its own .h and .cpp file. * * The IRrecvLoop files are in this folder. However the other two receivers in their own * separate libraries. That is because their interrupt service routines can conflict * with other ISRs. The ISRs conflict would occur even if you did not create an instance * of their receiver classes. Similarly the frequency detection receiver which also uses * interrupts is also in a separate folder IRLibFreq. */ #include "IRLibRecvBase.h" #include "IRLibHardware.h" /* This structure contains all of the global variables used by the ISRs to communicate * with the receiver and decoder objects. You cannot pass parameters to an ISR so * these values must be global. The fields are defined in IRLibRecvBase.h */ recvGlobal_t recvGlobal; // The base constructor receives the pin number IRrecvBase::IRrecvBase(uint8_t recvPin) { recvGlobal.recvPin = recvPin; init(); } // Initialization common to all three receiver classes void IRrecvBase::init(void) { //These first two lines would normally be done by the decoder //however in rare circumstances there is no decoder. recvGlobal.decoderWantsData=false; //turned on by enableIRIn. recvGlobal.decodeBuffer=recvGlobal.recvBuffer;//default buffer recvGlobal.enableAutoResume=false; recvGlobal.frameTimeout=DEFAULT_FRAME_TIMEOUT; recvGlobal.frameTimeoutTicks=recvGlobal.frameTimeout/USEC_PER_TICK; markExcess=DEFAULT_MARK_EXCESS; recvGlobal.newDataAvailable=false; recvGlobal.enableBlinkLED=false; recvGlobal.currentState=STATE_FINISHED;//i.e. Not running. } // Turn on or off a blinking LED which indicates signal received. Usually pin 13. void blink13(bool enableBlinkLED){ #if (BLINKLED>0) pinMode(BLINKLED,OUTPUT); recvGlobal.enableBlinkLED=enableBlinkLED; #endif } /* Any receiver class must implement a getResults method that will return true when * a complete frame of data has been received. When your getResults determines that * the frame is complete, it must guarantee that there will be no further changes to * the data in the buffer or the length value. It can do that by either disabling * interrupts or putting the ISR in a state that ensures it will not * change those values. Then it must then call IRrecvBase::getResults. This base method * will then will perform some math on the values and copy them to the decodeBuffer. * Some receivers provide results in recvBuffer measured in ticks of some number of * microseconds while others return results in actual microseconds. If you use ticks then * you should pass a multiplier value in timePerTicks. * NOTE: Only call the base method if newDataAvailable is true. */ bool IRrecvBase::getResults(const uint16_t timePerTick) { //Conceptually the loop below copies data from the receiver buffer to the decode buffer //while performing some math. In some instances, the source and destination are the same. //The decoder has already set up decodeBuffer to point to the proper destination. //Here we need to figure out the source. If didAutoResume is true then the ISR has already //copied the data to decodeBuffer so it is both source and destination. In all //other circumstances the source is always recvGlobal.recvBuffer. recvGlobal.newDataAvailable=false; volatile uint16_t *Source; //DEBUG_VALUE("recvGlobal.didAutoResume",recvGlobal.didAutoResume); if(recvGlobal.didAutoResume) { Source=recvGlobal.decodeBuffer; recvGlobal.didAutoResume=false; } else { Source=recvGlobal.recvBuffer; recvGlobal.decodeLength=recvGlobal.recvLength;//if auto resumed, was already copied } //If the receiver counts time intervals rather than actual microseconds we will multiply //the data by timePerTick. It also adjusts the data by adding or subtracting the //markExcess value. See the documentation on markExcess for details. for(uint8_t i=0; i