// Copyright 2018 David Conran /// @file /// @brief G.I. Cable /// @see https://github.com/cyborg5/IRLib2/blob/master/IRLibProtocols/IRLib_P09_GICable.h /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/447 // Supports: // Brand: G.I. Cable, Model: XRC-200 remote #define __STDC_LIMIT_MACROS #include #include #include "IRrecv.h" #include "IRsend.h" #include "IRutils.h" // Constants const uint16_t kGicableHdrMark = 9000; const uint16_t kGicableHdrSpace = 4400; const uint16_t kGicableBitMark = 550; const uint16_t kGicableOneSpace = 4400; const uint16_t kGicableZeroSpace = 2200; const uint16_t kGicableRptSpace = 2200; const uint32_t kGicableMinCommandLength = 99600; const uint32_t kGicableMinGap = kGicableMinCommandLength - (kGicableHdrMark + kGicableHdrSpace + kGicableBits * (kGicableBitMark + kGicableOneSpace) + kGicableBitMark); #if SEND_GICABLE /// Send a raw G.I. Cable formatted message. /// Status: Alpha / Untested. /// @param[in] data The message to be sent. /// @param[in] nbits The number of bits of message to be sent. /// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendGICable(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(kGicableHdrMark, kGicableHdrSpace, kGicableBitMark, kGicableOneSpace, kGicableBitMark, kGicableZeroSpace, kGicableBitMark, kGicableMinGap, kGicableMinCommandLength, data, nbits, 39, true, 0, // Repeats are handled later. 50); // Message repeat sequence. if (repeat) sendGeneric(kGicableHdrMark, kGicableRptSpace, 0, 0, 0, 0, // No actual data sent. kGicableBitMark, kGicableMinGap, kGicableMinCommandLength, 0, 0, // No data to be sent. 39, true, repeat - 1, 50); } #endif // SEND_GICABLE #if DECODE_GICABLE /// Decode the supplied G.I. Cable message. /// Status: Alpha / Not tested against a real device. /// @param[in,out] results Ptr to the data to decode & where to store the decode /// result. /// @param[in] offset The starting index to use when attempting to decode the /// raw data. Typically/Defaults to kStartOffset. /// @param[in] nbits The number of data bits to expect. /// @param[in] strict Flag indicating if we should perform strict matching. /// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeGICable(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kGicableBits) return false; // Not strictly an GICABLE message. uint64_t data = 0; // Match Header + Data + Footer uint16_t used; used = matchGeneric(results->rawbuf + offset, &data, results->rawlen - offset, nbits, kGicableHdrMark, kGicableHdrSpace, kGicableBitMark, kGicableOneSpace, kGicableBitMark, kGicableZeroSpace, kGicableBitMark, kGicableMinGap, true); if (!used) return false; offset += used; // Compliance if (strict) { // We expect a repeat frame. if (!matchMark(results->rawbuf[offset++], kGicableHdrMark)) return false; if (!matchSpace(results->rawbuf[offset++], kGicableRptSpace)) return false; if (!matchMark(results->rawbuf[offset++], kGicableBitMark)) return false; } // Success results->bits = nbits; results->value = data; results->decode_type = GICABLE; results->command = 0; results->address = 0; return true; } #endif // DECODE_GICABLE