diff --git a/src/IRrecv.h b/src/IRrecv.h index a9cbce610..73050dca3 100644 --- a/src/IRrecv.h +++ b/src/IRrecv.h @@ -889,6 +889,11 @@ class IRrecv { const uint16_t nbits = kBluestarHeavyBits, const bool strict = true); #endif // DECODE_BLUESTARHEAVY +#if DECODE_BRYSTON + bool decodeBryston(decode_results *results, uint16_t offset = kStartOffset, + const uint16_t nbits = kBrystonBits, + const bool strict = true); +#endif // DECODE_BRYSTON }; #endif // IRRECV_H_ diff --git a/src/IRremoteESP8266.h b/src/IRremoteESP8266.h index 4a0e60bf2..6574ee9a6 100644 --- a/src/IRremoteESP8266.h +++ b/src/IRremoteESP8266.h @@ -959,6 +959,15 @@ #define SEND_BLUESTARHEAVY _IR_ENABLE_DEFAULT_ #endif // SEND_BLUESTARHEAVY +#ifndef DECODE_BRYSTON +#define DECODE_BRYSTON _IR_ENABLE_DEFAULT_ +#endif // DECODE_BRYSTON +#ifndef SEND_BRYSTON +#define SEND_BRYSTON _IR_ENABLE_DEFAULT_ +#endif // SEND_BRYSTON + + + #if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \ DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \ DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \ @@ -1145,8 +1154,9 @@ enum decode_type_t { CARRIER_AC84, // 125 YORK, BLUESTARHEAVY, + BRYSTON, // Add new entries before this one, and update it to point to the last entry. - kLastDecodeType = BLUESTARHEAVY, + kLastDecodeType = BRYSTON, }; // Message lengths & required repeat values @@ -1445,6 +1455,7 @@ const uint16_t kRhossDefaultRepeat = 0; const uint16_t kClimaButlerBits = 52; const uint16_t kYorkBits = 136; const uint16_t kYorkStateLength = 17; +const uint16_t kBrystonBits = 18; // Legacy defines. (Deprecated) #define AIWA_RC_T501_BITS kAiwaRcT501Bits diff --git a/src/IRsend.cpp b/src/IRsend.cpp index 8b2309b8f..10183806b 100644 --- a/src/IRsend.cpp +++ b/src/IRsend.cpp @@ -1145,6 +1145,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, sendZepeal(data, nbits, min_repeat); break; #endif // SEND_ZEPEAL +#if SEND_BRYSTON + case BRYSTON: + sendBryston(data, nbits, min_repeat); + break; +#endif default: return false; } diff --git a/src/IRsend.h b/src/IRsend.h index 80e5d65d5..dcca62cba 100644 --- a/src/IRsend.h +++ b/src/IRsend.h @@ -899,7 +899,10 @@ class IRsend { const uint16_t nbytes = kBluestarHeavyStateLength, const uint16_t repeat = kNoRepeat); #endif // SEND_BLUESTARHEAVY - +#if SEND_BRYSTON + void sendBryston(uint64_t data, uint16_t nbits = kBrystonBits, + uint16_t repeat = kNoRepeat); +#endif protected: #ifdef UNIT_TEST #ifndef HIGH diff --git a/src/ir_Bryston.cpp b/src/ir_Bryston.cpp new file mode 100644 index 000000000..4a2606770 --- /dev/null +++ b/src/ir_Bryston.cpp @@ -0,0 +1,72 @@ +// Copyright 2025 Guillaume Giraudon - Colquhoun Audio Laboratories + + +/// @file +/// @brief Support for Bryston Protocols. +/// @note Currently only tested BP19/BR20 but should work for all Bryston Products. + + +// Supports: +// Brand: Bryston + +#include +#include "IRrecv.h" +#include "IRsend.h" +#include "IRutils.h" + + +// Constants +const uint16_t kBrystonTicks = 315; // Number of bits in a Bryston message. +const uint16_t kBrystonHdrMark = 0; +const uint16_t kBrystonHdrSpace = 0; +const uint16_t kBrystonOneMark = 6 * kBrystonTicks; +const uint16_t kBrystonOneSpace = 1 * kBrystonTicks; +const uint16_t kBrystonZeroMark = 1 * kBrystonTicks; +const uint16_t kBrystonZeroSpace = 6 * kBrystonTicks; +const uint16_t kBrystonMinGap = 0; +const uint16_t kBrystonFooterMark = 0; + +#if SEND_BRYSTON +/// Send a Bryston formatted message. +/// @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::sendBryston(uint64_t data, uint16_t nbits, uint16_t repeat) { + Serial.printf("Sending Bryston: %016llX\n", data); + + sendGeneric(kBrystonHdrMark, kBrystonHdrSpace, kBrystonOneMark, kBrystonOneSpace, + kBrystonZeroMark, kBrystonZeroSpace, kBrystonFooterMark, kBrystonMinGap, data, + nbits, 38, true, repeat, 33); +} +#endif // SEND_Bryston + +#if DECODE_BRYSTON +/// Decode the supplied Bryston message. +/// @param[in,out] results Ptr to the data to decode & where to store the 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. +bool IRrecv::decodeBryston(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (strict && nbits != kBrystonBits) + return false; // We expect Bryston to be a certain sized message. + + uint64_t data = 0; + + // Match Header + Data + Footer + if (!matchGeneric(results->rawbuf + offset, &data, + results->rawlen - offset, nbits, + kBrystonHdrMark, kBrystonHdrSpace, + kBrystonOneMark, kBrystonOneSpace, + kBrystonZeroMark, kBrystonZeroSpace, + kBrystonFooterMark, kBrystonMinGap, true)) return false; + // Success + results->bits = nbits; + results->value = data; + results->decode_type = decode_type_t::BRYSTON; + results->command = 0; + results->address = 0; + return true; +} +#endif // DECODE_Bryston