|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- #include "IRremote.h"
- #include "IRremoteInt.h"
-
- #ifdef TIMER_INT_DECLARE
- TIMER_INT_DECLARE
- #endif
-
- #ifdef IR_TIMER_USE_ESP32
- hw_timer_t *timer;
- void IRTimer(); // defined in IRremote.cpp
- #endif
-
- //+=============================================================================
- // Decodes the received IR message
- // Returns 0 if no data ready, 1 if data ready.
- // Results of decoding are stored in results
- //
- int IRrecv::decode (decode_results *results)
- {
- results->rawbuf = irparams.rawbuf;
- results->rawlen = irparams.rawlen;
-
- results->overflow = irparams.overflow;
-
- if (irparams.rcvstate != STATE_STOP) return false ;
-
- #if DECODE_NEC
- DBG_PRINTLN("Attempting NEC decode");
- if (decodeNEC(results)) return true ;
- #endif
-
- #if DECODE_SONY
- DBG_PRINTLN("Attempting Sony decode");
- if (decodeSony(results)) return true ;
- #endif
-
- #if DECODE_SANYO
- DBG_PRINTLN("Attempting Sanyo decode");
- if (decodeSanyo(results)) return true ;
- #endif
-
- #if DECODE_MITSUBISHI
- DBG_PRINTLN("Attempting Mitsubishi decode");
- if (decodeMitsubishi(results)) return true ;
- #endif
-
- #if DECODE_RC5
- DBG_PRINTLN("Attempting RC5 decode");
- if (decodeRC5(results)) return true ;
- #endif
-
- #if DECODE_RC6
- DBG_PRINTLN("Attempting RC6 decode");
- if (decodeRC6(results)) return true ;
- #endif
-
- #if DECODE_PANASONIC
- DBG_PRINTLN("Attempting Panasonic decode");
- if (decodePanasonic(results)) return true ;
- #endif
-
- #if DECODE_LG
- DBG_PRINTLN("Attempting LG decode");
- if (decodeLG(results)) return true ;
- #endif
-
- #if DECODE_JVC
- DBG_PRINTLN("Attempting JVC decode");
- if (decodeJVC(results)) return true ;
- #endif
-
- #if DECODE_SAMSUNG
- DBG_PRINTLN("Attempting SAMSUNG decode");
- if (decodeSAMSUNG(results)) return true ;
- #endif
-
- #if DECODE_WHYNTER
- DBG_PRINTLN("Attempting Whynter decode");
- if (decodeWhynter(results)) return true ;
- #endif
-
- #if DECODE_AIWA_RC_T501
- DBG_PRINTLN("Attempting Aiwa RC-T501 decode");
- if (decodeAiwaRCT501(results)) return true ;
- #endif
-
- #if DECODE_DENON
- DBG_PRINTLN("Attempting Denon decode");
- if (decodeDenon(results)) return true ;
- #endif
-
- #if DECODE_LEGO_PF
- DBG_PRINTLN("Attempting Lego Power Functions");
- if (decodeLegoPowerFunctions(results)) return true ;
- #endif
-
- // decodeHash returns a hash on any input.
- // Thus, it needs to be last in the list.
- // If you add any decodes, add them before this.
- if (decodeHash(results)) return true ;
-
- // Throw away and start over
- resume();
- return false;
- }
-
- //+=============================================================================
- IRrecv::IRrecv (int recvpin)
- {
- irparams.recvpin = recvpin;
- irparams.blinkflag = 0;
- }
-
- IRrecv::IRrecv (int recvpin, int blinkpin)
- {
- irparams.recvpin = recvpin;
- irparams.blinkpin = blinkpin;
- pinMode(blinkpin, OUTPUT);
- irparams.blinkflag = 0;
- }
-
-
-
- //+=============================================================================
- // initialization
- //
- void IRrecv::enableIRIn ( )
- {
- // Interrupt Service Routine - Fires every 50uS
- #ifdef ESP32
- // ESP32 has a proper API to setup timers, no weird chip macros needed
- // simply call the readable API versions :)
- // 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up
- timer = timerBegin(1, 80, 1);
- timerAttachInterrupt(timer, &IRTimer, 1);
- // every 50ns, autoreload = true
- timerAlarmWrite(timer, 50, true);
- timerAlarmEnable(timer);
- #else
- cli();
- // Setup pulse clock timer interrupt
- // Prescale /8 (16M/8 = 0.5 microseconds per tick)
- // Therefore, the timer interval can range from 0.5 to 128 microseconds
- // Depending on the reset value (255 to 0)
- TIMER_CONFIG_NORMAL();
-
- // Timer2 Overflow Interrupt Enable
- TIMER_ENABLE_INTR;
-
- TIMER_RESET;
-
- sei(); // enable interrupts
- #endif
-
- // Initialize state machine variables
- irparams.rcvstate = STATE_IDLE;
- irparams.rawlen = 0;
-
- // Set pin modes
- pinMode(irparams.recvpin, INPUT);
- }
-
- //+=============================================================================
- // Enable/disable blinking of pin 13 on IR processing
- //
- void IRrecv::blink13 (int blinkflag)
- {
- irparams.blinkflag = blinkflag;
- if (blinkflag) pinMode(BLINKLED, OUTPUT) ;
- }
-
- //+=============================================================================
- // Return if receiving new IR signals
- //
- bool IRrecv::isIdle ( )
- {
- return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false;
- }
- //+=============================================================================
- // Restart the ISR state machine
- //
- void IRrecv::resume ( )
- {
- irparams.rcvstate = STATE_IDLE;
- irparams.rawlen = 0;
- }
-
- //+=============================================================================
- // hashdecode - decode an arbitrary IR code.
- // Instead of decoding using a standard encoding scheme
- // (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.
- //
- // The algorithm: look at the sequence of MARK signals, and see if each one
- // is shorter (0), the same length (1), or longer (2) than the previous.
- // Do the same with the SPACE signals. Hash the resulting sequence of 0's,
- // 1's, and 2's to a 32-bit value. This will give a unique value for each
- // different code (probably), for most code systems.
- //
- // http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
- //
- // Compare two tick values, returning 0 if newval is shorter,
- // 1 if newval is equal, and 2 if newval is longer
- // Use a tolerance of 20%
- //
- int IRrecv::compare (unsigned int oldval, unsigned int newval)
- {
- if (newval < oldval * .8) return 0 ;
- else if (oldval < newval * .8) return 2 ;
- else return 1 ;
- }
-
- //+=============================================================================
- // Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
- // Converts the raw code values into a 32-bit hash code.
- // Hopefully this code is unique for each button.
- // This isn't a "real" decoding, just an arbitrary value.
- //
- #define FNV_PRIME_32 16777619
- #define FNV_BASIS_32 2166136261
-
- long IRrecv::decodeHash (decode_results *results)
- {
- long hash = FNV_BASIS_32;
-
- // Require at least 6 samples to prevent triggering on noise
- if (results->rawlen < 6) return false ;
-
- for (int i = 1; (i + 2) < results->rawlen; i++) {
- int value = compare(results->rawbuf[i], results->rawbuf[i+2]);
- // Add value into the hash
- hash = (hash * FNV_PRIME_32) ^ value;
- }
-
- results->value = hash;
- results->bits = 32;
- results->decode_type = UNKNOWN;
-
- return true;
- }
|