PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

240 lines
6.5KB

  1. #include "IRremote.h"
  2. #include "IRremoteInt.h"
  3. #ifdef TIMER_INT_DECLARE
  4. TIMER_INT_DECLARE
  5. #endif
  6. #ifdef IR_TIMER_USE_ESP32
  7. hw_timer_t *timer;
  8. void IRTimer(); // defined in IRremote.cpp
  9. #endif
  10. //+=============================================================================
  11. // Decodes the received IR message
  12. // Returns 0 if no data ready, 1 if data ready.
  13. // Results of decoding are stored in results
  14. //
  15. int IRrecv::decode (decode_results *results)
  16. {
  17. results->rawbuf = irparams.rawbuf;
  18. results->rawlen = irparams.rawlen;
  19. results->overflow = irparams.overflow;
  20. if (irparams.rcvstate != STATE_STOP) return false ;
  21. #if DECODE_NEC
  22. DBG_PRINTLN("Attempting NEC decode");
  23. if (decodeNEC(results)) return true ;
  24. #endif
  25. #if DECODE_SONY
  26. DBG_PRINTLN("Attempting Sony decode");
  27. if (decodeSony(results)) return true ;
  28. #endif
  29. #if DECODE_SANYO
  30. DBG_PRINTLN("Attempting Sanyo decode");
  31. if (decodeSanyo(results)) return true ;
  32. #endif
  33. #if DECODE_MITSUBISHI
  34. DBG_PRINTLN("Attempting Mitsubishi decode");
  35. if (decodeMitsubishi(results)) return true ;
  36. #endif
  37. #if DECODE_RC5
  38. DBG_PRINTLN("Attempting RC5 decode");
  39. if (decodeRC5(results)) return true ;
  40. #endif
  41. #if DECODE_RC6
  42. DBG_PRINTLN("Attempting RC6 decode");
  43. if (decodeRC6(results)) return true ;
  44. #endif
  45. #if DECODE_PANASONIC
  46. DBG_PRINTLN("Attempting Panasonic decode");
  47. if (decodePanasonic(results)) return true ;
  48. #endif
  49. #if DECODE_LG
  50. DBG_PRINTLN("Attempting LG decode");
  51. if (decodeLG(results)) return true ;
  52. #endif
  53. #if DECODE_JVC
  54. DBG_PRINTLN("Attempting JVC decode");
  55. if (decodeJVC(results)) return true ;
  56. #endif
  57. #if DECODE_SAMSUNG
  58. DBG_PRINTLN("Attempting SAMSUNG decode");
  59. if (decodeSAMSUNG(results)) return true ;
  60. #endif
  61. #if DECODE_WHYNTER
  62. DBG_PRINTLN("Attempting Whynter decode");
  63. if (decodeWhynter(results)) return true ;
  64. #endif
  65. #if DECODE_AIWA_RC_T501
  66. DBG_PRINTLN("Attempting Aiwa RC-T501 decode");
  67. if (decodeAiwaRCT501(results)) return true ;
  68. #endif
  69. #if DECODE_DENON
  70. DBG_PRINTLN("Attempting Denon decode");
  71. if (decodeDenon(results)) return true ;
  72. #endif
  73. #if DECODE_LEGO_PF
  74. DBG_PRINTLN("Attempting Lego Power Functions");
  75. if (decodeLegoPowerFunctions(results)) return true ;
  76. #endif
  77. // decodeHash returns a hash on any input.
  78. // Thus, it needs to be last in the list.
  79. // If you add any decodes, add them before this.
  80. if (decodeHash(results)) return true ;
  81. // Throw away and start over
  82. resume();
  83. return false;
  84. }
  85. //+=============================================================================
  86. IRrecv::IRrecv (int recvpin)
  87. {
  88. irparams.recvpin = recvpin;
  89. irparams.blinkflag = 0;
  90. }
  91. IRrecv::IRrecv (int recvpin, int blinkpin)
  92. {
  93. irparams.recvpin = recvpin;
  94. irparams.blinkpin = blinkpin;
  95. pinMode(blinkpin, OUTPUT);
  96. irparams.blinkflag = 0;
  97. }
  98. //+=============================================================================
  99. // initialization
  100. //
  101. void IRrecv::enableIRIn ( )
  102. {
  103. // Interrupt Service Routine - Fires every 50uS
  104. #ifdef ESP32
  105. // ESP32 has a proper API to setup timers, no weird chip macros needed
  106. // simply call the readable API versions :)
  107. // 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up
  108. timer = timerBegin(1, 80, 1);
  109. timerAttachInterrupt(timer, &IRTimer, 1);
  110. // every 50ns, autoreload = true
  111. timerAlarmWrite(timer, 50, true);
  112. timerAlarmEnable(timer);
  113. #else
  114. cli();
  115. // Setup pulse clock timer interrupt
  116. // Prescale /8 (16M/8 = 0.5 microseconds per tick)
  117. // Therefore, the timer interval can range from 0.5 to 128 microseconds
  118. // Depending on the reset value (255 to 0)
  119. TIMER_CONFIG_NORMAL();
  120. // Timer2 Overflow Interrupt Enable
  121. TIMER_ENABLE_INTR;
  122. TIMER_RESET;
  123. sei(); // enable interrupts
  124. #endif
  125. // Initialize state machine variables
  126. irparams.rcvstate = STATE_IDLE;
  127. irparams.rawlen = 0;
  128. // Set pin modes
  129. pinMode(irparams.recvpin, INPUT);
  130. }
  131. //+=============================================================================
  132. // Enable/disable blinking of pin 13 on IR processing
  133. //
  134. void IRrecv::blink13 (int blinkflag)
  135. {
  136. irparams.blinkflag = blinkflag;
  137. if (blinkflag) pinMode(BLINKLED, OUTPUT) ;
  138. }
  139. //+=============================================================================
  140. // Return if receiving new IR signals
  141. //
  142. bool IRrecv::isIdle ( )
  143. {
  144. return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false;
  145. }
  146. //+=============================================================================
  147. // Restart the ISR state machine
  148. //
  149. void IRrecv::resume ( )
  150. {
  151. irparams.rcvstate = STATE_IDLE;
  152. irparams.rawlen = 0;
  153. }
  154. //+=============================================================================
  155. // hashdecode - decode an arbitrary IR code.
  156. // Instead of decoding using a standard encoding scheme
  157. // (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.
  158. //
  159. // The algorithm: look at the sequence of MARK signals, and see if each one
  160. // is shorter (0), the same length (1), or longer (2) than the previous.
  161. // Do the same with the SPACE signals. Hash the resulting sequence of 0's,
  162. // 1's, and 2's to a 32-bit value. This will give a unique value for each
  163. // different code (probably), for most code systems.
  164. //
  165. // http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
  166. //
  167. // Compare two tick values, returning 0 if newval is shorter,
  168. // 1 if newval is equal, and 2 if newval is longer
  169. // Use a tolerance of 20%
  170. //
  171. int IRrecv::compare (unsigned int oldval, unsigned int newval)
  172. {
  173. if (newval < oldval * .8) return 0 ;
  174. else if (oldval < newval * .8) return 2 ;
  175. else return 1 ;
  176. }
  177. //+=============================================================================
  178. // Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
  179. // Converts the raw code values into a 32-bit hash code.
  180. // Hopefully this code is unique for each button.
  181. // This isn't a "real" decoding, just an arbitrary value.
  182. //
  183. #define FNV_PRIME_32 16777619
  184. #define FNV_BASIS_32 2166136261
  185. long IRrecv::decodeHash (decode_results *results)
  186. {
  187. long hash = FNV_BASIS_32;
  188. // Require at least 6 samples to prevent triggering on noise
  189. if (results->rawlen < 6) return false ;
  190. for (int i = 1; (i + 2) < results->rawlen; i++) {
  191. int value = compare(results->rawbuf[i], results->rawbuf[i+2]);
  192. // Add value into the hash
  193. hash = (hash * FNV_PRIME_32) ^ value;
  194. }
  195. results->value = hash;
  196. results->bits = 32;
  197. results->decode_type = UNKNOWN;
  198. return true;
  199. }