34 #ifndef _IR_BANG_OLUFSEN_HPP
35 #define _IR_BANG_OLUFSEN_HPP
92 #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
94 #if defined(DECODE_BEO)
95 # if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
96 # if RECORD_GAP_MICROS > 13000
97 #warning If defined ENABLE_BEO_WITHOUT_FRAME_GAP, RECORD_GAP_MICROS must be set to 1300 by "#define RECORD_GAP_MICROS 13000"
100 # if RECORD_GAP_MICROS < 16000
101 #error If not defined ENABLE_BEO_WITHOUT_FRAME_GAP, RECORD_GAP_MICROS must be set to a value >= 1600 by "#define RECORD_GAP_MICROS 16000"
106 #define BEO_DATA_BITS 8 // Command or character
108 #define BEO_UNIT 3125 // All timings are in microseconds
110 #define BEO_IR_MARK 200 // The length of a mark in the IR protocol
111 #define BEO_DATALINK_MARK (BEO_UNIT / 2) // The length of a mark in the Datalink protocol
113 #define BEO_PULSE_LENGTH_ZERO BEO_UNIT // The length of a one to zero transition
114 #define BEO_PULSE_LENGTH_EQUAL (2 * BEO_UNIT) // 6250 The length of an equal bit
115 #define BEO_PULSE_LENGTH_ONE (3 * BEO_UNIT) // 9375 The length of a zero to one transition
116 #define BEO_PULSE_LENGTH_TRAILING_BIT (4 * BEO_UNIT) // 12500 The length of the stop bit
117 #define BEO_PULSE_LENGTH_START_BIT (5 * BEO_UNIT) // 15625 The length of the start bit
123 #ifdef BEO_LOCAL_DEBUG
124 # define BEO_DEBUG_PRINT(...) Serial.print(__VA_ARGS__)
125 # define BEO_DEBUG_PRINTLN(...) Serial.println(__VA_ARGS__)
127 # define BEO_DEBUG_PRINT(...) void()
128 # define BEO_DEBUG_PRINTLN(...) void()
131 #ifdef BEO_LOCAL_TRACE
132 # undef BEO_TRACE_PRINT
133 # undef BEO_TRACE_PRINTLN
134 # define BEO_TRACE_PRINT(...) Serial.print(__VA_ARGS__)
135 # define BEO_TRACE_PRINTLN(...) Serial.println(__VA_ARGS__)
137 # define BEO_TRACE_PRINT(...) void()
138 # define BEO_TRACE_PRINTLN(...) void()
150 sendBangOlufsenRaw((uint32_t(aHeader) << 8) | aData, aNumberOfHeaderBits + 8, i != 0);
164 #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
169 # if !defined(USE_NO_SEND_PWM)
170 # if defined(SEND_PWM_BY_TIMER)
171 enableHighFrequencyIROut (
BEO_KHZ);
172 # elif (BEO_KHZ == 38)
191 bool tLastBitValueWasOne =
false;
194 uint32_t mask = 1UL << (aBits - 1);
195 for (; mask; mask >>= 1) {
196 if (tLastBitValueWasOne && !(aRawData & mask)) {
199 tLastBitValueWasOne =
false;
200 }
else if (!tLastBitValueWasOne && (aRawData & mask)) {
203 tLastBitValueWasOne =
true;
228 #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
234 #if !defined(USE_NO_SEND_PWM)
240 mark(tSendBEOMarkLength);
243 mark(tSendBEOMarkLength);
245 mark(tSendBEOMarkLength);
250 mark(tSendBEOMarkLength);
252 bool tLastBitValueWasOne =
false;
255 uint32_t mask = 1UL << (aBits - 1);
256 for (; mask; mask >>= 1) {
257 if (tLastBitValueWasOne && !(aRawData & mask)) {
258 mark(tSendBEOMarkLength);
260 tLastBitValueWasOne =
false;
261 }
else if (!tLastBitValueWasOne && (aRawData & mask)) {
262 mark(tSendBEOMarkLength);
264 tLastBitValueWasOne =
true;
266 mark(tSendBEOMarkLength);
272 mark(tSendBEOMarkLength);
274 mark(tSendBEOMarkLength);
279 (void) aUseDatalinkTiming;
284 #define BEO_MATCH_DELTA (BEO_UNIT / 2 - MICROS_PER_TICK)
285 static bool matchBeoLength(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) {
291 #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)
339 #if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
351 for (uint8_t tRawBufferMarkIndex = 3; tRawBufferMarkIndex <
decodedIRData.
rawlen; tRawBufferMarkIndex += 2) {
353 for (uint8_t tRawBufferMarkIndex = 1; tRawBufferMarkIndex <
decodedIRData.
rawlen; tRawBufferMarkIndex += 2) {
368 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
373 if (tPulseNumber < 4) {
374 if (tPulseNumber < 2) {
381 if (tPulseNumber == 3) {
383 #if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
409 #if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
410 if (!
matchMark(markLength, protocolMarkLength)) {
428 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
441 tLastDecodedBitValue = 1;
443 tLastDecodedBitValue = 0;
453 tDecodedRawData <<= 1;
454 tDecodedRawData |= tLastDecodedBitValue;
463 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
479 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
493 #endif // _IR_BANG_OLUFSEN_HPP