34 #ifndef _IR_BANG_OLUFSEN_HPP
35 #define _IR_BANG_OLUFSEN_HPP
94 #define ENABLE_BEO_WITHOUT_FRAME_GAP // Requires additional 30 bytes program memory. Enabled by default, see https://github.com/Arduino-IRremote/Arduino-IRremote/discussions/1181
96 #if defined(DECODE_BEO)
97 # if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
98 # if RECORD_GAP_MICROS > 15000 && !defined(SUPPRESS_BEO_RECORD_GAP_MICROS_WARNING)
99 #warning If defined ENABLE_BEO_WITHOUT_FRAME_GAP, RECORD_GAP_MICROS must be set to <= 15000 by "#define RECORD_GAP_MICROS 12750"
102 # if RECORD_GAP_MICROS < 16000 && !defined(SUPPRESS_BEO_RECORD_GAP_MICROS_WARNING)
103 #error If not defined ENABLE_BEO_WITHOUT_FRAME_GAP, RECORD_GAP_MICROS must be set to a value >= 16000 by "#define RECORD_GAP_MICROS 16000"
108 #define BEO_DATA_BITS 8 // Command or character
110 #define BEO_UNIT 3125 // All timings are in microseconds
112 #define BEO_BIT_MARK 200 // The length of a mark in the IR protocol
116 #define BEO_BIT_MARK_FOR_DECODE 250
117 #define BEO_DATALINK_BIT_MARK (BEO_UNIT / 2) // The length of a mark in the Datalink protocol
122 #define BEO_ZERO_SPACE BEO_UNIT // 3125
123 #define BEO_REPETITION_OF_PREVIOUS_BIT_SPACE (2 * BEO_UNIT) // 6250 The length of an repetition bit
124 #define BEO_ONE_SPACE (3 * BEO_UNIT) // 9375
125 #define BEO_TRAILING_BIT_SPACE (4 * BEO_UNIT) // 12500 The length of the space of stop bit
126 #define BEO_START_BIT_SPACE (5 * BEO_UNIT) // 15625
127 #define BEO_REPEAT_PERIOD 100000 // 100 ms - Not used yet
158 #if defined(USE_NO_SEND_PWM) || defined(SEND_PWM_BY_TIMER) || BEO_KHZ == 38 // BEO_KHZ == 38 is for unit test which runs the B&O protocol with 38 kHz
163 # if !defined(USE_NO_SEND_PWM)
164 # if defined(SEND_PWM_BY_TIMER)
165 enableHighFrequencyIROut (
BEO_KHZ);
166 # elif (BEO_KHZ == 38)
185 bool tLastBitValueWasOne =
false;
188 uint32_t mask = 1UL << (aBits - 1);
189 for (; mask; mask >>= 1) {
190 if (tLastBitValueWasOne && !(aRawData & mask)) {
193 tLastBitValueWasOne =
false;
194 }
else if (!tLastBitValueWasOne && (aRawData & mask)) {
197 tLastBitValueWasOne =
true;
222 #if defined(USE_NO_SEND_PWM) || BEO_KHZ == 38 // BEO_KHZ == 38 is for unit test which runs the B&O protocol with 38 kHz instead 0f 455 kHz
228 #if !defined(USE_NO_SEND_PWM)
234 mark(tSendBEOMarkLength);
237 mark(tSendBEOMarkLength);
239 mark(tSendBEOMarkLength);
244 mark(tSendBEOMarkLength);
246 bool tLastBitValueWasOne =
false;
249 uint32_t mask = 1UL << (aBits - 1);
250 for (; mask; mask >>= 1) {
251 if (tLastBitValueWasOne && !(aRawData & mask)) {
252 mark(tSendBEOMarkLength);
254 tLastBitValueWasOne =
false;
255 }
else if (!tLastBitValueWasOne && (aRawData & mask)) {
256 mark(tSendBEOMarkLength);
258 tLastBitValueWasOne =
true;
260 mark(tSendBEOMarkLength);
266 mark(tSendBEOMarkLength);
268 mark(tSendBEOMarkLength);
273 (void) aUseDatalinkTiming;
278 #define BEO_MATCH_DELTA (BEO_UNIT / 2 - MICROS_PER_TICK) // use a bigger margin for match than regular matching function
279 static bool matchBeoLength(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) {
285 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
299 #if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
300 uint16_t protocolMarkLength = 0;
301 uint64_t tDecodedRawData = 0;
303 uint32_t tDecodedRawData = 0;
305 uint8_t tLastDecodedBitValue = 0;
306 uint8_t tPulseNumber = 0;
307 uint8_t tBitNumber = 0;
314 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
322 TRACE_PRINTLN(F(
"B&O: AGC only part (start bits 1 + 2 of 4) detected"));
338 # if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
349 for (uint8_t tRawBufferMarkIndex = 3; tRawBufferMarkIndex <
decodedIRData.
rawlen; tRawBufferMarkIndex += 2) {
351 for (uint8_t tRawBufferMarkIndex = 1; tRawBufferMarkIndex <
decodedIRData.
rawlen; tRawBufferMarkIndex += 2) {
352 #endif // defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
366 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
371 if (tPulseNumber < 4) {
372 if (tPulseNumber < 2) {
375 TRACE_PRINTLN(F(
": detected long start bit -> synchronize state now"));
379 if (tPulseNumber == 3) {
381 # if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
399 #endif // !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
405 #if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
406 if (!
matchMark(markLength, protocolMarkLength)) {
422 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
424 DEBUG_PRINTLN(F(
"B&O: End of buffer, but no trailing bit detected"));
434 tLastDecodedBitValue = 1;
436 tLastDecodedBitValue = 0;
445 tDecodedRawData <<= 1;
446 tDecodedRawData |= tLastDecodedBitValue;
455 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
470 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
475 tValue.
ULong = tDecodedRawData;
483 if (tBitNumber > 24) {
496 #endif // _IR_BANG_OLUFSEN_HPP