Arduino-IRremote/src/ir_BoseWave.hpp

124 lines
4.7 KiB
C++

/*
* 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
#if defined(DEBUG) && !defined(LOCAL_DEBUG)
#define LOCAL_DEBUG
#else
//#define LOCAL_DEBUG // This enables debug output only for this file
#endif
/** \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
// see: https://www.mikrocontroller.net/articles/IRMP_-_english#BOSE
//
// Support for Bose Wave Radio CD initially provided by https://github.com/uvotguy.
//
// As seen on my 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 again, and so on.
// 38 kHz, 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 1014 // 1014 are 39 clock periods (I counted 3 times!)
#define BOSEWAVE_HEADER_SPACE 1468 // 1468(measured), 1456 are 56 clock periods
#define BOSEWAVE_BIT_MARK 520 // 520 are 20 clock periods
#define BOSEWAVE_ZERO_SPACE 468 // 468 are 18 clock periods
#define BOSEWAVE_ONE_SPACE 1468 // 1468(measured), 1456 are 56 clock periods
#define BOSEWAVE_REPEAT_PERIOD 75000
#define BOSEWAVE_REPEAT_DISTANCE 50000
#define BOSEWAVE_MAXIMUM_REPEAT_DISTANCE 62000
struct PulseDistanceWidthProtocolConstants BoseWaveProtocolConstants = { BOSEWAVE, BOSEWAVE_KHZ, BOSEWAVE_HEADER_MARK,
BOSEWAVE_HEADER_SPACE, BOSEWAVE_BIT_MARK, BOSEWAVE_ONE_SPACE, BOSEWAVE_BIT_MARK, BOSEWAVE_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST
, (BOSEWAVE_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), NULL };
/************************************
* Start of send and decode functions
************************************/
void IRsend::sendBoseWave(uint8_t aCommand, int_fast8_t aNumberOfRepeats) {
// send 8 command bits and then 8 inverted command bits LSB first
uint16_t tData = ((~aCommand) << 8) | aCommand;
sendPulseDistanceWidth(&BoseWaveProtocolConstants, tData, BOSEWAVE_BITS, aNumberOfRepeats);
}
bool IRrecv::decodeBoseWave() {
if (!checkHeader(&BoseWaveProtocolConstants)) {
return false;
}
// Check we have enough data +4 for initial gap, start bit mark and space + stop bit mark
if (decodedIRData.rawlen != (2 * BOSEWAVE_BITS) + 4) {
IR_DEBUG_PRINT(F("Bose: "));
IR_DEBUG_PRINT(F("Data length="));
IR_DEBUG_PRINT(decodedIRData.rawlen);
IR_DEBUG_PRINTLN(F(" is not 36"));
return false;
}
if (!decodePulseDistanceWidthData(&BoseWaveProtocolConstants, BOSEWAVE_BITS)) {
#if defined(LOCAL_DEBUG)
Serial.print(F("Bose: "));
Serial.println(F("Decode failed"));
#endif
return false;
}
// Stop bit
if (!matchMark(decodedIRData.rawDataPtr->rawbuf[3 + (2 * BOSEWAVE_BITS)], BOSEWAVE_BIT_MARK)) {
#if defined(LOCAL_DEBUG)
Serial.print(F("Bose: "));
Serial.println(F("Stop bit mark length is wrong"));
#endif
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; // comes first and is in the lower bits (LSB first :-))
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) {
#if defined(LOCAL_DEBUG)
Serial.print(F("Bose: "));
Serial.println(F("Command and inverted command check failed"));
#endif
return false;
}
decodedIRData.command = tCommandNotInverted;
decodedIRData.numberOfBits = BOSEWAVE_BITS;
decodedIRData.protocol = BOSEWAVE;
// check for repeat
checkForRepeatSpaceTicksAndSetFlag(BOSEWAVE_MAXIMUM_REPEAT_DISTANCE / MICROS_PER_TICK);
return true;
}
/** @}*/
#if defined(LOCAL_DEBUG)
#undef LOCAL_DEBUG
#endif
#endif // _IR_BOSEWAVE_HPP