forked from Arduino-IRremote/Arduino-IRremote
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathir_BoseWave.hpp
136 lines (114 loc) · 4.99 KB
/
ir_BoseWave.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
* ir_BoseWave.cpp
*
* Contains functions for receiving and sending Bose IR Protocol
*
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
*
*/
#ifndef IR_BOSEWAVE_HPP
#define IR_BOSEWAVE_HPP
#include <Arduino.h>
//#define DEBUG // Activate this for lots of lovely debug output from this decoder.
#include "IRremoteInt.h" // evaluates the DEBUG for IR_DEBUG_PRINT
/** \addtogroup Decoder Decoders and encoders for different protocols
* @{
*/
//==============================================================================
// BBBB OOO SSSS EEEEE
// B B O O S E
// BB B O O SSS EEEE
// B B O O S E
// BBBB OOO SSSS EEEEE
//==============================================================================
// see http://lirc.sourceforge.net/remotes/bose/WAVERADIO
//
// Support for Bose Wave Radio CD initially provided by https://github.com/uvotguy.
//
// As seen on my trusty oscilloscope, there is no repeat code. Instead, when I
// press and hold a button on my remote, it sends a command, makes a 51.2ms space,
// and resends the command, etc, etc.
// LSB first, 1 start bit + 8 bit data + 8 bit inverted data + 1 stop bit.
#define BOSEWAVE_BITS 16 // Command and inverted command
#define BOSEWAVE_HEADER_MARK 1060
#define BOSEWAVE_HEADER_SPACE 1450
#define BOSEWAVE_BIT_MARK 534
#define BOSEWAVE_ONE_SPACE 468
#define BOSEWAVE_ZERO_SPACE 1447
#define BOSEWAVE_REPEAT_SPACE 52000
//+=============================================================================
void IRsend::sendBoseWave(uint8_t aCommand, uint_fast8_t aNumberOfRepeats) {
// Set IR carrier frequency
enableIROut(BOSEWAVE_KHZ); // 38 kHz
uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;
while (tNumberOfCommands > 0) {
// Header
mark(BOSEWAVE_HEADER_MARK);
space(BOSEWAVE_HEADER_SPACE);
// send 8 command bits and then 8 inverted command bits LSB first
uint16_t tData = ((~aCommand) << 8) | aCommand;
sendPulseDistanceWidthData(BOSEWAVE_BIT_MARK, BOSEWAVE_ONE_SPACE, BOSEWAVE_BIT_MARK, BOSEWAVE_ZERO_SPACE, tData,
BOSEWAVE_BITS, PROTOCOL_IS_LSB_FIRST, SEND_STOP_BIT);
tNumberOfCommands--;
// skip last delay!
if (tNumberOfCommands > 0) {
// send repeated command with a fixed space gap
delay( BOSEWAVE_REPEAT_SPACE / MICROS_IN_ONE_MILLI);
}
}
}
//+=============================================================================
bool IRrecv::decodeBoseWave() {
// Check header "mark"
if (!matchMark(decodedIRData.rawDataPtr->rawbuf[1], BOSEWAVE_HEADER_MARK)) {
// no debug output, since this check is mainly to determine the received protocol
return false;
}
// Check we have enough data +4 for initial gap, start bit mark and space + stop bit mark
if (decodedIRData.rawDataPtr->rawlen != (2 * BOSEWAVE_BITS) + 4) {
IR_DEBUG_PRINT("Bose: ");
IR_DEBUG_PRINT("Data length=");
IR_DEBUG_PRINT(decodedIRData.rawDataPtr->rawlen);
IR_DEBUG_PRINTLN(" is not 36");
return false;
}
// Check header "space"
if (!matchSpace(decodedIRData.rawDataPtr->rawbuf[2], BOSEWAVE_HEADER_SPACE)) {
IR_DEBUG_PRINT("Bose: ");
IR_DEBUG_PRINTLN("Header space length is wrong");
return false;
}
if (!decodePulseDistanceData(BOSEWAVE_BITS, 3, BOSEWAVE_BIT_MARK, BOSEWAVE_ONE_SPACE, BOSEWAVE_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST)) {
IR_DEBUG_PRINT("Bose: ");
IR_DEBUG_PRINTLN("Decode failed");
return false;
}
// Stop bit
if (!matchMark(decodedIRData.rawDataPtr->rawbuf[3 + (2 * BOSEWAVE_BITS)], BOSEWAVE_BIT_MARK)) {
IR_DEBUG_PRINT("Bose: ");
IR_DEBUG_PRINTLN(F("Stop bit mark length is wrong"));
return false;
}
// Success
// decodedIRData.flags = IRDATA_FLAGS_IS_LSB_FIRST; // Not required, since this is the start value
uint16_t tDecodedValue = decodedIRData.decodedRawData;
uint8_t tCommandNotInverted = tDecodedValue & 0xFF;
uint8_t tCommandInverted = tDecodedValue >> 8;
// parity check for command. Use this variant to avoid compiler warning "comparison of promoted ~unsigned with unsigned [-Wsign-compare]"
if ((tCommandNotInverted ^ tCommandInverted) != 0xFF) {
IR_DEBUG_PRINT("Bose: ");
IR_DEBUG_PRINT("Command and inverted command check failed");
return false;
}
// check for repeat
if (decodedIRData.rawDataPtr->rawbuf[0] < ((BOSEWAVE_REPEAT_SPACE + (BOSEWAVE_REPEAT_SPACE / 4)) / MICROS_PER_TICK)) {
decodedIRData.flags = IRDATA_FLAGS_IS_REPEAT | IRDATA_FLAGS_IS_LSB_FIRST;
}
decodedIRData.command = tCommandNotInverted;
decodedIRData.protocol = BOSEWAVE;
decodedIRData.numberOfBits = BOSEWAVE_BITS;
return true;
}
/** @}*/
#endif // #ifndef IR_BOSEWAVE_HPP
#pragma once