ir_Denon.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright 2016 Massimiliano Pinto
  2. // Copyright 2017 David Conran
  3. #include <algorithm>
  4. #include "IRrecv.h"
  5. #include "IRsend.h"
  6. #include "IRutils.h"
  7. // DDDD EEEEE N N OOO N N
  8. // D D E NN N O O NN N
  9. // D D EEE N N N O O N N N
  10. // D D E N NN O O N NN
  11. // DDDD EEEEE N N OOO N N
  12. // Original Denon support added by https://github.com/csBlueChip
  13. // Ported over by Massimiliano Pinto
  14. // Constants
  15. // Ref:
  16. // https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp
  17. const uint16_t kDenonTick = 263;
  18. const uint16_t kDenonHdrMarkTicks = 1;
  19. const uint16_t kDenonHdrMark = kDenonHdrMarkTicks * kDenonTick;
  20. const uint16_t kDenonHdrSpaceTicks = 3;
  21. const uint16_t kDenonHdrSpace = kDenonHdrSpaceTicks * kDenonTick;
  22. const uint16_t kDenonBitMarkTicks = 1;
  23. const uint16_t kDenonBitMark = kDenonBitMarkTicks * kDenonTick;
  24. const uint16_t kDenonOneSpaceTicks = 7;
  25. const uint16_t kDenonOneSpace = kDenonOneSpaceTicks * kDenonTick;
  26. const uint16_t kDenonZeroSpaceTicks = 3;
  27. const uint16_t kDenonZeroSpace = kDenonZeroSpaceTicks * kDenonTick;
  28. const uint16_t kDenonMinCommandLengthTicks = 510;
  29. const uint16_t kDenonMinGapTicks =
  30. kDenonMinCommandLengthTicks -
  31. (kDenonHdrMarkTicks + kDenonHdrSpaceTicks +
  32. kDenonBits * (kDenonBitMarkTicks + kDenonOneSpaceTicks) +
  33. kDenonBitMarkTicks);
  34. const uint32_t kDenonMinGap = kDenonMinGapTicks * kDenonTick;
  35. const uint64_t kDenonManufacturer = 0x2A4CULL;
  36. #if SEND_DENON
  37. // Send a Denon message
  38. //
  39. // Args:
  40. // data: Contents of the message to be sent.
  41. // nbits: Nr. of bits of data to be sent. Typically DENON_BITS.
  42. // repeat: Nr. of additional times the message is to be sent.
  43. //
  44. // Status: BETA / Should be working.
  45. //
  46. // Notes:
  47. // Some Denon devices use a Kaseikyo/Panasonic 48-bit format
  48. // Others use the Sharp protocol.
  49. // Ref:
  50. // https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp
  51. // http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls
  52. void IRsend::sendDenon(uint64_t data, uint16_t nbits, uint16_t repeat) {
  53. if (nbits >= kPanasonicBits) // Is this really Panasonic?
  54. sendPanasonic64(data, nbits, repeat);
  55. else if (nbits == kDenonLegacyBits)
  56. // Support legacy (broken) calls of sendDenon().
  57. sendSharpRaw(data & (~0x2000ULL), nbits + 1, repeat);
  58. else
  59. sendSharpRaw(data, nbits, repeat);
  60. }
  61. #endif
  62. #if DECODE_DENON
  63. // Decode a Denon message.
  64. //
  65. // Args:
  66. // results: Ptr to the data to decode and where to store the decode result.
  67. // nbits: Expected nr. of data bits. (Typically DENON_BITS)
  68. // Returns:
  69. // boolean: True if it can decode it, false if it can't.
  70. //
  71. // Status: BETA / Should work fine.
  72. //
  73. // Ref:
  74. // https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp
  75. bool IRrecv::decodeDenon(decode_results *results, uint16_t nbits, bool strict) {
  76. // Compliance
  77. if (strict) {
  78. switch (nbits) {
  79. case DENON_BITS:
  80. case DENON_48_BITS:
  81. case kDenonLegacyBits:
  82. break;
  83. default:
  84. return false;
  85. }
  86. }
  87. // Denon uses the Sharp & Panasonic(Kaseikyo) protocol for some
  88. // devices, so check for those first.
  89. // It is not exactly like Sharp's protocols, but close enough.
  90. // e.g. The expansion bit is not set for Denon vs. set for Sharp.
  91. // Ditto for Panasonic, it's the same except for a different
  92. // manufacturer code.
  93. if (!decodeSharp(results, nbits, true, false) &&
  94. !decodePanasonic(results, nbits, true, kDenonManufacturer)) {
  95. // We couldn't decode it as expected, so try the old legacy method.
  96. // NOTE: I don't think this following protocol actually exists.
  97. // Looks like a partial version of the Sharp protocol.
  98. // Check we have enough data
  99. if (results->rawlen < 2 * nbits + kHeader + kFooter - 1) return false;
  100. if (strict && nbits != kDenonLegacyBits) return false;
  101. uint64_t data = 0;
  102. uint16_t offset = kStartOffset;
  103. // Header
  104. if (!matchMark(results->rawbuf[offset], kDenonHdrMark)) return false;
  105. // Calculate how long the common tick time is based on the header mark.
  106. uint32_t m_tick = results->rawbuf[offset++] * kRawTick / kDenonHdrMarkTicks;
  107. if (!matchSpace(results->rawbuf[offset], kDenonHdrSpace)) return false;
  108. uint32_t s_tick =
  109. results->rawbuf[offset++] * kRawTick / kDenonHdrSpaceTicks;
  110. // Data
  111. match_result_t data_result =
  112. matchData(&(results->rawbuf[offset]), nbits,
  113. kDenonBitMarkTicks * m_tick, kDenonOneSpaceTicks * s_tick,
  114. kDenonBitMarkTicks * m_tick, kDenonZeroSpaceTicks * s_tick);
  115. if (data_result.success == false) return false;
  116. data = data_result.data;
  117. offset += data_result.used;
  118. // Footer
  119. if (!matchMark(results->rawbuf[offset++], kDenonBitMarkTicks * m_tick))
  120. return false;
  121. // Success
  122. results->bits = nbits;
  123. results->value = data;
  124. results->address = 0;
  125. results->command = 0;
  126. } // Legacy decode.
  127. // Compliance
  128. if (strict && nbits != results->bits) return false;
  129. // Success
  130. results->decode_type = DENON;
  131. return true;
  132. }
  133. #endif