34 #ifndef _IR_BANG_OLUFSEN_HPP
35 #define _IR_BANG_OLUFSEN_HPP
95 #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
97 #if defined(DECODE_BEO)
98 # if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
99 # if RECORD_GAP_MICROS > 15000
100 #warning If defined ENABLE_BEO_WITHOUT_FRAME_GAP, RECORD_GAP_MICROS must be set to <= 15000 by "#define RECORD_GAP_MICROS 12750"
103 # if RECORD_GAP_MICROS < 16000
104 #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"
109 #define BEO_DATA_BITS 8 // Command or character
111 #define BEO_UNIT 3125 // All timings are in microseconds
113 #define BEO_IR_MARK 200 // The length of a mark in the IR protocol
114 #define BEO_DATALINK_MARK (BEO_UNIT / 2) // The length of a mark in the Datalink protocol
116 #define BEO_PULSE_LENGTH_ZERO BEO_UNIT // The length of a one to zero transition
117 #define BEO_PULSE_LENGTH_EQUAL (2 * BEO_UNIT) // 6250 The length of an equal bit
118 #define BEO_PULSE_LENGTH_ONE (3 * BEO_UNIT) // 9375 The length of a zero to one transition
119 #define BEO_PULSE_LENGTH_TRAILING_BIT (4 * BEO_UNIT) // 12500 The length of the stop bit
120 #define BEO_PULSE_LENGTH_START_BIT (5 * BEO_UNIT) // 15625 The length of the start bit
126 #ifdef BEO_LOCAL_DEBUG
127 # define BEO_DEBUG_PRINT(...) Serial.print(__VA_ARGS__)
128 # define BEO_DEBUG_PRINTLN(...) Serial.println(__VA_ARGS__)
130 # define BEO_DEBUG_PRINT(...) void()
131 # define BEO_DEBUG_PRINTLN(...) void()
134 #ifdef BEO_LOCAL_TRACE
135 # undef BEO_TRACE_PRINT
136 # undef BEO_TRACE_PRINTLN
137 # define BEO_TRACE_PRINT(...) Serial.print(__VA_ARGS__)
138 # define BEO_TRACE_PRINTLN(...) Serial.println(__VA_ARGS__)
140 # define BEO_TRACE_PRINT(...) void()
141 # define BEO_TRACE_PRINTLN(...) void()
153 sendBangOlufsenRaw((uint32_t(aHeader) << 8) | aData, aNumberOfHeaderBits + 8, i != 0);
167 #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
172 # if !defined(USE_NO_SEND_PWM)
173 # if defined(SEND_PWM_BY_TIMER)
174 enableHighFrequencyIROut (
BEO_KHZ);
175 # elif (BEO_KHZ == 38)
194 bool tLastBitValueWasOne =
false;
197 uint32_t mask = 1UL << (aBits - 1);
198 for (; mask; mask >>= 1) {
199 if (tLastBitValueWasOne && !(aRawData & mask)) {
202 tLastBitValueWasOne =
false;
203 }
else if (!tLastBitValueWasOne && (aRawData & mask)) {
206 tLastBitValueWasOne =
true;
231 #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
237 #if !defined(USE_NO_SEND_PWM)
243 mark(tSendBEOMarkLength);
246 mark(tSendBEOMarkLength);
248 mark(tSendBEOMarkLength);
253 mark(tSendBEOMarkLength);
255 bool tLastBitValueWasOne =
false;
258 uint32_t mask = 1UL << (aBits - 1);
259 for (; mask; mask >>= 1) {
260 if (tLastBitValueWasOne && !(aRawData & mask)) {
261 mark(tSendBEOMarkLength);
263 tLastBitValueWasOne =
false;
264 }
else if (!tLastBitValueWasOne && (aRawData & mask)) {
265 mark(tSendBEOMarkLength);
267 tLastBitValueWasOne =
true;
269 mark(tSendBEOMarkLength);
275 mark(tSendBEOMarkLength);
277 mark(tSendBEOMarkLength);
282 (void) aUseDatalinkTiming;
287 #define BEO_MATCH_DELTA (BEO_UNIT / 2 - MICROS_PER_TICK)
288 static bool matchBeoLength(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) {
294 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
302 #if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
303 uint16_t protocolMarkLength = 0;
304 uint64_t tDecodedRawData = 0;
306 uint32_t tDecodedRawData = 0;
308 uint8_t tLastDecodedBitValue = 0;
309 uint8_t tPulseNumber = 0;
310 uint8_t tBitNumber = 0;
317 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
342 # if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
354 for (uint8_t tRawBufferMarkIndex = 3; tRawBufferMarkIndex <
decodedIRData.
rawlen; tRawBufferMarkIndex += 2) {
356 for (uint8_t tRawBufferMarkIndex = 1; tRawBufferMarkIndex <
decodedIRData.
rawlen; tRawBufferMarkIndex += 2) {
357 #endif // defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
371 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
376 if (tPulseNumber < 4) {
377 if (tPulseNumber < 2) {
384 if (tPulseNumber == 3) {
386 # if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
406 #endif // !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
412 #if defined(SUPPORT_BEO_DATALINK_TIMING_FOR_DECODE)
413 if (!
matchMark(markLength, protocolMarkLength)) {
431 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
444 tLastDecodedBitValue = 1;
446 tLastDecodedBitValue = 0;
456 tDecodedRawData <<= 1;
457 tDecodedRawData |= tLastDecodedBitValue;
466 #if !defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
482 #if defined(ENABLE_BEO_WITHOUT_FRAME_GAP)
496 #endif // _IR_BANG_OLUFSEN_HPP