[FL-1956] Fix long packets bug, fix Manchester overrun (#766)
Also fix RC6 test to detect this manchester bug
This commit is contained in:
@@ -84,16 +84,22 @@ static IrdaStatus irda_common_decode_bits(IrdaCommonDecoder* decoder) {
|
||||
bool level = (decoder->level + decoder->timings_cnt + 1) % 2;
|
||||
uint32_t timing = decoder->timings[0];
|
||||
|
||||
/* check if short protocol version can be decoded */
|
||||
if (timings->min_split_time && !level && (timing > timings->min_split_time)) {
|
||||
for (int i = 1; decoder->protocol->databit_len[i] && (i < COUNT_OF(decoder->protocol->databit_len)); ++i) {
|
||||
if (decoder->protocol->databit_len[i] == decoder->databit_cnt) {
|
||||
return IrdaStatusReady;
|
||||
if (timings->min_split_time && !level) {
|
||||
if (timing > timings->min_split_time) {
|
||||
/* long low timing - check if we're ready for any of protocol modification */
|
||||
for (int i = 0; decoder->protocol->databit_len[i] && (i < COUNT_OF(decoder->protocol->databit_len)); ++i) {
|
||||
if (decoder->protocol->databit_len[i] == decoder->databit_cnt) {
|
||||
return IrdaStatusReady;
|
||||
}
|
||||
}
|
||||
} else if (decoder->protocol->databit_len[0] == decoder->databit_cnt) {
|
||||
/* short low timing for longest protocol - this is signal is longer than we expected */
|
||||
return IrdaStatusError;
|
||||
}
|
||||
}
|
||||
|
||||
status = decoder->protocol->decode(decoder, level, timing);
|
||||
furi_check(decoder->databit_cnt <= decoder->protocol->databit_len[0]);
|
||||
furi_assert(status == IrdaStatusError || status == IrdaStatusOk);
|
||||
if (status == IrdaStatusError) {
|
||||
break;
|
||||
@@ -101,7 +107,7 @@ static IrdaStatus irda_common_decode_bits(IrdaCommonDecoder* decoder) {
|
||||
decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 1);
|
||||
|
||||
/* check if largest protocol version can be decoded */
|
||||
if (level && (decoder->protocol->databit_len[0] == decoder->databit_cnt)) {
|
||||
if (level && (decoder->protocol->databit_len[0] == decoder->databit_cnt) && !timings->min_split_time) {
|
||||
status = IrdaStatusReady;
|
||||
break;
|
||||
}
|
||||
@@ -177,6 +183,9 @@ IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder, bool level,
|
||||
}
|
||||
|
||||
if (*switch_detect) {
|
||||
if (decoder->protocol->databit_len[0] == decoder->databit_cnt) {
|
||||
return IrdaStatusError;
|
||||
}
|
||||
accumulate_lsb(decoder, level);
|
||||
}
|
||||
|
||||
@@ -185,8 +194,16 @@ IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder, bool level,
|
||||
|
||||
IrdaMessage* irda_common_decoder_check_ready(IrdaCommonDecoder* decoder) {
|
||||
IrdaMessage* message = NULL;
|
||||
bool found_length = false;
|
||||
|
||||
if (decoder->protocol->interpret(decoder)) {
|
||||
for (int i = 0; decoder->protocol->databit_len[i] && (i < COUNT_OF(decoder->protocol->databit_len)); ++i) {
|
||||
if (decoder->protocol->databit_len[i] == decoder->databit_cnt) {
|
||||
found_length = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_length && decoder->protocol->interpret(decoder)) {
|
||||
decoder->databit_cnt = 0;
|
||||
message = &decoder->message;
|
||||
if (decoder->protocol->decode_repeat) {
|
||||
@@ -268,7 +285,6 @@ void* irda_common_decoder_alloc(const IrdaCommonProtocolSpec* protocol) {
|
||||
+ protocol->databit_len[0] / 8
|
||||
+ !!(protocol->databit_len[0] % 8);
|
||||
IrdaCommonDecoder* decoder = furi_alloc(alloc_size);
|
||||
memset(decoder, 0, alloc_size);
|
||||
decoder->protocol = protocol;
|
||||
decoder->level = true;
|
||||
return decoder;
|
||||
|
@@ -35,6 +35,7 @@ const IrdaCommonProtocolSpec protocol_samsung32 = {
|
||||
.preamble_tolerance = IRDA_SAMSUNG_PREAMBLE_TOLERANCE,
|
||||
.bit_tolerance = IRDA_SAMSUNG_BIT_TOLERANCE,
|
||||
.silence_time = IRDA_SAMSUNG_SILENCE,
|
||||
.min_split_time = IRDA_SAMSUNG_MIN_SPLIT_TIME,
|
||||
},
|
||||
.databit_len[0] = 32,
|
||||
.no_stop_bit = false,
|
||||
@@ -53,6 +54,7 @@ const IrdaCommonProtocolSpec protocol_rc6 = {
|
||||
.preamble_tolerance = IRDA_RC6_PREAMBLE_TOLERANCE,
|
||||
.bit_tolerance = IRDA_RC6_BIT_TOLERANCE,
|
||||
.silence_time = IRDA_RC6_SILENCE,
|
||||
.min_split_time = IRDA_RC6_MIN_SPLIT_TIME,
|
||||
},
|
||||
.databit_len[0] = 1 + 3 + 1 + 8 + 8, // start_bit + 3 mode bits, + 1 toggle bit (x2 timing) + 8 address + 8 command
|
||||
.manchester_start_from_space = false,
|
||||
@@ -71,6 +73,7 @@ const IrdaCommonProtocolSpec protocol_rc5 = {
|
||||
.preamble_tolerance = 0,
|
||||
.bit_tolerance = IRDA_RC5_BIT_TOLERANCE,
|
||||
.silence_time = IRDA_RC5_SILENCE,
|
||||
.min_split_time = IRDA_RC5_MIN_SPLIT_TIME,
|
||||
},
|
||||
.databit_len[0] = 1 + 1 + 1 + 5 + 6, // start_bit + start_bit/command_bit + toggle_bit + 5 address + 6 command
|
||||
.manchester_start_from_space = true,
|
||||
|
@@ -59,6 +59,7 @@ static const IrdaEncoderDecoder irda_encoder_decoder[] = {
|
||||
.alloc = irda_decoder_samsung32_alloc,
|
||||
.decode = irda_decoder_samsung32_decode,
|
||||
.reset = irda_decoder_samsung32_reset,
|
||||
.check_ready = irda_decoder_samsung32_check_ready,
|
||||
.free = irda_decoder_samsung32_free},
|
||||
.encoder = {
|
||||
.alloc = irda_encoder_samsung32_alloc,
|
||||
@@ -72,6 +73,7 @@ static const IrdaEncoderDecoder irda_encoder_decoder[] = {
|
||||
.alloc = irda_decoder_rc5_alloc,
|
||||
.decode = irda_decoder_rc5_decode,
|
||||
.reset = irda_decoder_rc5_reset,
|
||||
.check_ready = irda_decoder_rc5_check_ready,
|
||||
.free = irda_decoder_rc5_free},
|
||||
.encoder = {
|
||||
.alloc = irda_encoder_rc5_alloc,
|
||||
@@ -85,6 +87,7 @@ static const IrdaEncoderDecoder irda_encoder_decoder[] = {
|
||||
.alloc = irda_decoder_rc6_alloc,
|
||||
.decode = irda_decoder_rc6_decode,
|
||||
.reset = irda_decoder_rc6_reset,
|
||||
.check_ready = irda_decoder_rc6_check_ready,
|
||||
.free = irda_decoder_rc6_free},
|
||||
.encoder = {
|
||||
.alloc = irda_encoder_rc6_alloc,
|
||||
|
@@ -81,6 +81,7 @@ extern const IrdaCommonProtocolSpec protocol_nec;
|
||||
* of some data. Real tolerances we don't know, but in real life
|
||||
* silence time should be greater than max repeat time. This is
|
||||
* because of similar preambule timings for repeat and first messages. */
|
||||
#define IRDA_SAMSUNG_MIN_SPLIT_TIME 5000
|
||||
#define IRDA_SAMSUNG_SILENCE 145000
|
||||
#define IRDA_SAMSUNG_REPEAT_PAUSE_MAX 140000
|
||||
#define IRDA_SAMSUNG_REPEAT_MARK 4500
|
||||
@@ -91,6 +92,7 @@ extern const IrdaCommonProtocolSpec protocol_nec;
|
||||
void* irda_decoder_samsung32_alloc(void);
|
||||
void irda_decoder_samsung32_reset(void* decoder);
|
||||
void irda_decoder_samsung32_free(void* decoder);
|
||||
IrdaMessage* irda_decoder_samsung32_check_ready(void* ctx);
|
||||
IrdaMessage* irda_decoder_samsung32_decode(void* decoder, bool level, uint32_t duration);
|
||||
IrdaStatus irda_encoder_samsung32_encode(void* encoder_ptr, uint32_t* duration, bool* level);
|
||||
void irda_encoder_samsung32_reset(void* encoder_ptr, const IrdaMessage* message);
|
||||
@@ -135,10 +137,12 @@ extern const IrdaCommonProtocolSpec protocol_samsung32;
|
||||
#define IRDA_RC6_BIT_TOLERANCE 120 // us
|
||||
/* protocol allows 2700 silence, but it is hard to send 1 message without repeat */
|
||||
#define IRDA_RC6_SILENCE (2700 * 10)
|
||||
#define IRDA_RC6_MIN_SPLIT_TIME 2700
|
||||
|
||||
void* irda_decoder_rc6_alloc(void);
|
||||
void irda_decoder_rc6_reset(void* decoder);
|
||||
void irda_decoder_rc6_free(void* decoder);
|
||||
IrdaMessage* irda_decoder_rc6_check_ready(void* ctx);
|
||||
IrdaMessage* irda_decoder_rc6_decode(void* decoder, bool level, uint32_t duration);
|
||||
void* irda_encoder_rc6_alloc(void);
|
||||
void irda_encoder_rc6_reset(void* encoder_ptr, const IrdaMessage* message);
|
||||
@@ -184,10 +188,12 @@ extern const IrdaCommonProtocolSpec protocol_rc6;
|
||||
#define IRDA_RC5_BIT_TOLERANCE 120 // us
|
||||
/* protocol allows 2700 silence, but it is hard to send 1 message without repeat */
|
||||
#define IRDA_RC5_SILENCE (2700 * 10)
|
||||
#define IRDA_RC5_MIN_SPLIT_TIME 2700
|
||||
|
||||
void* irda_decoder_rc5_alloc(void);
|
||||
void irda_decoder_rc5_reset(void* decoder);
|
||||
void irda_decoder_rc5_free(void* decoder);
|
||||
IrdaMessage* irda_decoder_rc5_check_ready(void* ctx);
|
||||
IrdaMessage* irda_decoder_rc5_decode(void* decoder, bool level, uint32_t duration);
|
||||
void* irda_encoder_rc5_alloc(void);
|
||||
void irda_encoder_rc5_reset(void* encoder_ptr, const IrdaMessage* message);
|
||||
|
@@ -11,6 +11,11 @@ typedef struct {
|
||||
bool toggle;
|
||||
} IrdaRc5Decoder;
|
||||
|
||||
IrdaMessage* irda_decoder_rc5_check_ready(void* ctx) {
|
||||
IrdaRc5Decoder* decoder = ctx;
|
||||
return irda_common_decoder_check_ready(decoder->common_decoder);
|
||||
}
|
||||
|
||||
bool irda_decoder_rc5_interpret(IrdaCommonDecoder* decoder) {
|
||||
furi_assert(decoder);
|
||||
|
||||
|
@@ -11,6 +11,11 @@ typedef struct {
|
||||
bool toggle;
|
||||
} IrdaRc6Decoder;
|
||||
|
||||
IrdaMessage* irda_decoder_rc6_check_ready(void* ctx) {
|
||||
IrdaRc6Decoder* decoder_rc6 = ctx;
|
||||
return irda_common_decoder_check_ready(decoder_rc6->common_decoder);
|
||||
}
|
||||
|
||||
bool irda_decoder_rc6_interpret(IrdaCommonDecoder* decoder) {
|
||||
furi_assert(decoder);
|
||||
|
||||
|
@@ -6,6 +6,10 @@
|
||||
#include "../irda_i.h"
|
||||
|
||||
|
||||
IrdaMessage* irda_decoder_samsung32_check_ready(void* ctx) {
|
||||
return irda_common_decoder_check_ready(ctx);
|
||||
}
|
||||
|
||||
bool irda_decoder_samsung32_interpret(IrdaCommonDecoder* decoder) {
|
||||
furi_assert(decoder);
|
||||
|
||||
|
Reference in New Issue
Block a user