* Mode is stored in the upper nibble of command */
| 142 | * Mode is stored in the upper nibble of command |
| 143 | */ |
| 144 | bool IRrecv::decodeLegoPowerFunctions() { |
| 145 | |
| 146 | /* |
| 147 | * Check header timings |
| 148 | * Since LEGO_HEADER_MARK is just 158 us use a relaxed threshold compare (237) for it instead of matchMark() |
| 149 | */ |
| 150 | if (!(matchMarkWithGreaterRange(irparams.rawbuf[1], LEGO_HEADER_MARK) && (matchSpace(irparams.rawbuf[2], LEGO_HEADER_SPACE)))) { |
| 151 | DEBUG_PRINTLN(F("LEGO: No header mark and space")); |
| 152 | return false; |
| 153 | } |
| 154 | |
| 155 | // Check we have enough data - +4 for initial gap, start bit mark and space + stop bit mark |
| 156 | if (decodedIRData.rawlen != (2 * LEGO_BITS) + 4) { |
| 157 | DEBUG_PRINT(F("LEGO: Data length=")); |
| 158 | DEBUG_PRINT(irparams.rawlen); |
| 159 | DEBUG_PRINTLN(F(" is not 36")); |
| 160 | return false; |
| 161 | } |
| 162 | |
| 163 | decodePulseDistanceWidthData(&LegoProtocolConstants, LEGO_BITS); |
| 164 | |
| 165 | // Stop bit, use threshold decoding - not required :-) |
| 166 | // if (irparams.rawbuf[3 + (2 * LEGO_BITS)] > (2 * LEGO_BIT_MARK)) { |
| 167 | // DEBUG_PRINT(F("LEGO: ")); |
| 168 | // DEBUG_PRINTLN(F("Stop bit mark length is wrong")); |
| 169 | // return false; |
| 170 | // } |
| 171 | |
| 172 | // Success |
| 173 | decodedIRData.flags = IRDATA_FLAGS_IS_MSB_FIRST; |
| 174 | uint16_t tDecodedValue = decodedIRData.decodedRawData; |
| 175 | uint8_t tToggleEscapeChannel = tDecodedValue >> (LEGO_MODE_BITS + LEGO_COMMAND_BITS + LEGO_PARITY_BITS); |
| 176 | uint8_t tMode = (tDecodedValue >> (LEGO_COMMAND_BITS + LEGO_PARITY_BITS)) & 0xF; |
| 177 | uint8_t tData = (tDecodedValue >> LEGO_PARITY_BITS) & 0xF; // lego calls this field "data" |
| 178 | uint8_t tParityReceived = tDecodedValue & 0xF; |
| 179 | |
| 180 | // This is parity as defined in the specifications |
| 181 | // But in some scans I saw 0x9 ^ .. as parity formula |
| 182 | uint8_t tParityComputed = 0xF ^ tToggleEscapeChannel ^ tMode ^ tData; |
| 183 | |
| 184 | // parity check |
| 185 | if (tParityReceived != tParityComputed) { |
| 186 | DEBUG_PRINT(F("LEGO: Parity is not correct. expected=0x")); |
| 187 | DEBUG_PRINT(tParityComputed, HEX); |
| 188 | DEBUG_PRINT(F(" received=0x")); |
| 189 | DEBUG_PRINT(tParityReceived, HEX); |
| 190 | DEBUG_PRINT(F(", raw=0x")); |
| 191 | DEBUG_PRINT(tDecodedValue, HEX); |
| 192 | DEBUG_PRINT(F(", 3 nibbles are 0x")); |
| 193 | DEBUG_PRINT(tToggleEscapeChannel, HEX); |
| 194 | DEBUG_PRINT(F(", 0x")); |
| 195 | DEBUG_PRINT(tMode, HEX); |
| 196 | DEBUG_PRINT(F(", 0x")); |
| 197 | DEBUG_PRINTLN(tData, HEX); |
| 198 | // might not be an error, so just continue |
| 199 | decodedIRData.flags = IRDATA_FLAGS_PARITY_FAILED | IRDATA_FLAGS_IS_MSB_FIRST; |
| 200 | } |
| 201 |
nothing calls this directly
no test coverage detected