From e6d5f4038b08e5aa550b00ac90aecf2c9376794a Mon Sep 17 00:00:00 2001 From: Albert Kharisov Date: Fri, 20 Aug 2021 23:51:15 +0300 Subject: [PATCH] [FL-1696, FL-1685] IRDA: Add RC5, decoder refactoring (#663) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [FL-1696] IRDA: Split decoders and protocols * IRDA: Restruct directories. * IRDA: fix long timings * [FL-1685] IRDA: Add RC5 Co-authored-by: あく --- .../irda_decoder_encoder_test.c | 35 ++- .../test_data/irda_rc5_test_data.srcdata | 160 +++++++++++++ .../test_data/irda_rc6_test_data.srcdata | 38 +-- firmware/targets/f6/furi-hal/furi-hal-irda.c | 4 +- .../{ => common}/irda_common_decoder.c | 32 ++- .../{ => common}/irda_common_encoder.c | 3 +- .../{ => common}/irda_common_i.h | 2 +- .../{ => common}/irda_common_protocol_defs.c | 40 ++-- lib/irda/encoder_decoder/irda.c | 226 ++++++++---------- lib/irda/encoder_decoder/irda.h | 5 + lib/irda/encoder_decoder/irda_i.h | 11 +- .../encoder_decoder/irda_protocol_defs_i.h | 66 ++++- .../encoder_decoder/nec/irda_decoder_nec.c | 33 +-- .../encoder_decoder/nec/irda_encoder_nec.c | 31 +-- lib/irda/encoder_decoder/nec/irda_nec_spec.c | 28 +++ .../encoder_decoder/rc5/irda_decoder_rc5.c | 79 ++++++ .../encoder_decoder/rc5/irda_encoder_rc5.c | 55 +++++ lib/irda/encoder_decoder/rc5/irda_rc5_spec.c | 28 +++ .../encoder_decoder/rc6/irda_decoder_rc6.c | 1 + .../encoder_decoder/rc6/irda_encoder_rc6.c | 2 +- lib/irda/encoder_decoder/rc6/irda_rc6_spec.c | 18 ++ .../samsung/irda_decoder_samsung.c | 2 + .../samsung/irda_encoder_samsung.c | 2 +- .../samsung/irda_samsung_spec.c | 18 ++ 24 files changed, 677 insertions(+), 242 deletions(-) create mode 100644 applications/tests/irda_decoder_encoder/test_data/irda_rc5_test_data.srcdata rename lib/irda/encoder_decoder/{ => common}/irda_common_decoder.c (89%) rename lib/irda/encoder_decoder/{ => common}/irda_common_encoder.c (97%) rename lib/irda/encoder_decoder/{ => common}/irda_common_i.h (98%) rename lib/irda/encoder_decoder/{ => common}/irda_common_protocol_defs.c (75%) create mode 100644 lib/irda/encoder_decoder/nec/irda_nec_spec.c create mode 100644 lib/irda/encoder_decoder/rc5/irda_decoder_rc5.c create mode 100644 lib/irda/encoder_decoder/rc5/irda_encoder_rc5.c create mode 100644 lib/irda/encoder_decoder/rc5/irda_rc5_spec.c create mode 100644 lib/irda/encoder_decoder/rc6/irda_rc6_spec.c create mode 100644 lib/irda/encoder_decoder/samsung/irda_samsung_spec.c diff --git a/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c b/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c index dc5a21c1..66ec689d 100644 --- a/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c +++ b/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c @@ -1,11 +1,12 @@ #include #include "../minunit.h" #include "irda.h" -#include "irda_common_i.h" +#include "common/irda_common_i.h" #include "test_data/irda_nec_test_data.srcdata" #include "test_data/irda_necext_test_data.srcdata" #include "test_data/irda_samsung_test_data.srcdata" #include "test_data/irda_rc6_test_data.srcdata" +#include "test_data/irda_rc5_test_data.srcdata" #define RUN_ENCODER(data, expected) \ run_encoder((data), COUNT_OF(data), (expected), COUNT_OF(expected)) @@ -153,16 +154,19 @@ MU_TEST(test_decoder_samsung32) { } MU_TEST(test_mix) { + RUN_DECODER(test_decoder_rc5_input2, test_decoder_rc5_expected2); RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); // can use encoder data for decoding, but can't do opposite RUN_DECODER(test_encoder_rc6_expected1, test_encoder_rc6_input1); RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1); RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1); RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1); + RUN_DECODER(test_decoder_rc5_input1, test_decoder_rc5_expected1); RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2); RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1); RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); + RUN_DECODER(test_decoder_rc5_input5, test_decoder_rc5_expected5); RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1); } @@ -187,6 +191,25 @@ MU_TEST(test_decoder_necext1) { RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); } +MU_TEST(test_decoder_rc5) { + RUN_DECODER(test_decoder_rc5x_input1, test_decoder_rc5x_expected1); + RUN_DECODER(test_decoder_rc5_input1, test_decoder_rc5_expected1); + RUN_DECODER(test_decoder_rc5_input2, test_decoder_rc5_expected2); + RUN_DECODER(test_decoder_rc5_input3, test_decoder_rc5_expected3); + RUN_DECODER(test_decoder_rc5_input4, test_decoder_rc5_expected4); + RUN_DECODER(test_decoder_rc5_input5, test_decoder_rc5_expected5); + RUN_DECODER(test_decoder_rc5_input6, test_decoder_rc5_expected6); + RUN_DECODER(test_decoder_rc5_input_all_repeats, test_decoder_rc5_expected_all_repeats); +} + +MU_TEST(test_encoder_rc5x) { + RUN_ENCODER(test_decoder_rc5x_expected1, test_decoder_rc5x_input1); +} + +MU_TEST(test_encoder_rc5) { + RUN_ENCODER(test_decoder_rc5_expected_all_repeats, test_decoder_rc5_input_all_repeats); +} + MU_TEST(test_decoder_rc6) { RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1); } @@ -200,20 +223,24 @@ MU_TEST(test_encoder_decoder_all) { run_encoder_decoder(test_necext_all, COUNT_OF(test_necext_all)); run_encoder_decoder(test_samsung32_all, COUNT_OF(test_samsung32_all)); run_encoder_decoder(test_rc6_all, COUNT_OF(test_rc6_all)); + run_encoder_decoder(test_rc5_all, COUNT_OF(test_rc5_all)); } MU_TEST_SUITE(test_irda_decoder_encoder) { MU_SUITE_CONFIGURE(&test_setup, &test_teardown); - MU_RUN_TEST(test_encoder_decoder_all); + MU_RUN_TEST(test_encoder_rc5x); + MU_RUN_TEST(test_encoder_rc5); + MU_RUN_TEST(test_decoder_rc5); + MU_RUN_TEST(test_decoder_rc6); + MU_RUN_TEST(test_encoder_rc6); MU_RUN_TEST(test_decoder_unexpected_end_in_sequence); MU_RUN_TEST(test_decoder_nec1); MU_RUN_TEST(test_decoder_nec2); MU_RUN_TEST(test_decoder_samsung32); MU_RUN_TEST(test_decoder_necext1); MU_RUN_TEST(test_mix); - MU_RUN_TEST(test_decoder_rc6); - MU_RUN_TEST(test_encoder_rc6); + MU_RUN_TEST(test_encoder_decoder_all); } int run_minunit_test_irda_decoder_encoder() { diff --git a/applications/tests/irda_decoder_encoder/test_data/irda_rc5_test_data.srcdata b/applications/tests/irda_decoder_encoder/test_data/irda_rc5_test_data.srcdata new file mode 100644 index 00000000..4cd39742 --- /dev/null +++ b/applications/tests/irda_decoder_encoder/test_data/irda_rc5_test_data.srcdata @@ -0,0 +1,160 @@ +/* +_______----__--____----__--____--__----____----__--__--__--__ + | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | + s1 s2 t | address | command | +*/ + +const uint32_t test_decoder_rc5x_input1[] = { +27000 + 888, 1776, 888, 888, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888, +}; + +const IrdaMessage test_decoder_rc5x_expected1[] = { + {IrdaProtocolRC5X, 0x13, 0x10, false}, // toggle 0 +}; + +/* +_______--__----____----__--____--__----____----__--__--__--__ + | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | + s1 s2 t | address | command | +*/ + +const uint32_t test_decoder_rc5_input1[] = { +27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888, +}; + +const IrdaMessage test_decoder_rc5_expected1[] = { + {IrdaProtocolRC5, 0x13, 0x10, false}, // toggle 0 +}; + + +/* +_______--__--__--__----__--____--__----____----__--__--__--__ + | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | + s1 s2 t | address | command | +*/ + +const uint32_t test_decoder_rc5_input2[] = { +27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888, +}; + +const IrdaMessage test_decoder_rc5_expected2[] = { + {IrdaProtocolRC5, 0x13, 0x10, false}, // toggle 1 +}; + +/* +_______--__----____----__--____--__----____----__--__--____-- + | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | + s1 s2 t | address | command | +*/ + +const uint32_t test_decoder_rc5_input3[] = { +27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, +}; + +const IrdaMessage test_decoder_rc5_expected3[] = { + {IrdaProtocolRC5, 0x13, 0x11, false}, // toggle 0 +}; + + +/* +_______--__--__--__----__--____--__----____----__--__--____-- + | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | + s1 s2 t | address | command | +*/ + +const uint32_t test_decoder_rc5_input4[] = { +27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, +}; + +const IrdaMessage test_decoder_rc5_expected4[] = { + {IrdaProtocolRC5, 0x13, 0x11, false}, // toggle 1 +}; + +/* +_______--__----____--__--__--__--__--__--__--__--__--__--__-- + | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | + s1 s2 t | address | command | +*/ + +const uint32_t test_decoder_rc5_input5[] = { +27000 + 888, 888, 888, 1776, 1776, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, +}; + +const IrdaMessage test_decoder_rc5_expected5[] = { + {IrdaProtocolRC5, 0x1F, 0x3F, false}, // toggle 0 +}; + +/* +_______--__--__--__--__--__--__--__--__--__--__--__--__--__-- + | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | + s1 s2 t | address | command | +*/ + +const uint32_t test_decoder_rc5_input6[] = { +27000 + 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, +}; + +const IrdaMessage test_decoder_rc5_expected6[] = { + {IrdaProtocolRC5, 0x1F, 0x3F, false}, // toggle 1 +}; + + +const uint32_t test_decoder_rc5_input_all_repeats[] = { +27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, +27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, +27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, +27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, +27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888, +27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888, +27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888, +27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888, +27000 + 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, +27000 + 888, 888, 888, 1776, 1776, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, +27000 + 888, 888, 888, 1776, 1776, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, +}; + +const IrdaMessage test_decoder_rc5_expected_all_repeats[] = { + {IrdaProtocolRC5, 0x13, 0x11, false}, // toggle 0 + {IrdaProtocolRC5, 0x13, 0x11, false}, // toggle 1 + {IrdaProtocolRC5, 0x13, 0x11, true}, // toggle 1 + {IrdaProtocolRC5, 0x13, 0x11, true}, // toggle 1 + {IrdaProtocolRC5, 0x13, 0x11, false}, // toggle 0 + {IrdaProtocolRC5, 0x13, 0x10, false}, // toggle 1 + {IrdaProtocolRC5, 0x13, 0x10, false}, // toggle 0 + {IrdaProtocolRC5, 0x13, 0x10, true}, // toggle 0 + {IrdaProtocolRC5, 0x1F, 0x3F, false}, // toggle 1 + {IrdaProtocolRC5, 0x1F, 0x3F, false}, // toggle 0 + {IrdaProtocolRC5, 0x1F, 0x3F, true}, // toggle 0 +}; + + +const IrdaMessage test_rc5_all[] = { + {IrdaProtocolRC5, 0x1F, 0x3F, false}, + {IrdaProtocolRC5, 0x00, 0x00, false}, + {IrdaProtocolRC5, 0x10, 0x01, false}, + {IrdaProtocolRC5, 0x01, 0x20, false}, + {IrdaProtocolRC5, 0x01, 0x20, false}, + {IrdaProtocolRC5, 0x01, 0x20, true}, + {IrdaProtocolRC5, 0x01, 0x20, true}, + {IrdaProtocolRC5, 0x01, 0x20, true}, + {IrdaProtocolRC5, 0x01, 0x20, true}, + {IrdaProtocolRC5, 0x1F, 0x3F, false}, + {IrdaProtocolRC5, 0x0A, 0x2A, false}, + {IrdaProtocolRC5, 0x15, 0x15, false}, + {IrdaProtocolRC5, 0x15, 0x15, true}, + + {IrdaProtocolRC5X, 0x1F, 0x3F, false}, + {IrdaProtocolRC5X, 0x00, 0x00, false}, + {IrdaProtocolRC5X, 0x10, 0x01, false}, + {IrdaProtocolRC5X, 0x01, 0x20, false}, + {IrdaProtocolRC5X, 0x01, 0x20, false}, + {IrdaProtocolRC5X, 0x01, 0x20, true}, + {IrdaProtocolRC5X, 0x01, 0x20, true}, + {IrdaProtocolRC5X, 0x01, 0x20, true}, + {IrdaProtocolRC5X, 0x01, 0x20, true}, + {IrdaProtocolRC5X, 0x1F, 0x3F, false}, + {IrdaProtocolRC5X, 0x0A, 0x2A, false}, + {IrdaProtocolRC5X, 0x15, 0x15, false}, + {IrdaProtocolRC5X, 0x15, 0x15, true}, +}; + diff --git a/applications/tests/irda_decoder_encoder/test_data/irda_rc6_test_data.srcdata b/applications/tests/irda_decoder_encoder/test_data/irda_rc6_test_data.srcdata index eb31c6d4..ea764d43 100644 --- a/applications/tests/irda_decoder_encoder/test_data/irda_rc6_test_data.srcdata +++ b/applications/tests/irda_decoder_encoder/test_data/irda_rc6_test_data.srcdata @@ -15,17 +15,17 @@ _____---------______--____--__--__------____--____--__----____--__----__--__--__ */ const uint32_t test_decoder_rc6_input1[] = { -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed }; const IrdaMessage test_decoder_rc6_expected1[] = { @@ -54,14 +54,14 @@ const IrdaMessage test_encoder_rc6_input1[] = { }; const uint32_t test_encoder_rc6_expected1[] = { -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, }; diff --git a/firmware/targets/f6/furi-hal/furi-hal-irda.c b/firmware/targets/f6/furi-hal/furi-hal-irda.c index 370fea42..7e3d371f 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-irda.c +++ b/firmware/targets/f6/furi-hal/furi-hal-irda.c @@ -471,8 +471,8 @@ static void furi_hal_irda_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift irda_tim_tx.tx_timing_rest_duration = num_of_impulses - 1; irda_tim_tx.tx_timing_rest_status = status; irda_tim_tx.tx_timing_rest_level = level; - buffer->polarity[polarity_counter] = level ? IRDA_TX_CCMR_HIGH : IRDA_TX_CCMR_LOW; - buffer->data[*size] = 0xFFFF; + --(*size); + --polarity_counter; status = FuriHalIrdaTxGetDataStateOk; } else { buffer->polarity[polarity_counter] = level ? IRDA_TX_CCMR_HIGH : IRDA_TX_CCMR_LOW; diff --git a/lib/irda/encoder_decoder/irda_common_decoder.c b/lib/irda/encoder_decoder/common/irda_common_decoder.c similarity index 89% rename from lib/irda/encoder_decoder/irda_common_decoder.c rename to lib/irda/encoder_decoder/common/irda_common_decoder.c index a9a29e87..b402ed14 100644 --- a/lib/irda/encoder_decoder/irda_common_decoder.c +++ b/lib/irda/encoder_decoder/common/irda_common_decoder.c @@ -21,6 +21,10 @@ static bool irda_check_preamble(IrdaCommonDecoder* decoder) { } } + if (decoder->protocol->timings.preamble_mark == 0) { + return true; + } + while ((!result) && (decoder->timings_cnt >= 2)) { float preamble_tolerance = decoder->protocol->timings.preamble_tolerance; uint16_t preamble_mark = decoder->protocol->timings.preamble_mark; @@ -94,7 +98,7 @@ IrdaStatus irda_common_decode_pdwm(IrdaCommonDecoder* decoder) { /* level switch detection goes in middle of time-quant */ IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder) { furi_assert(decoder); - IrdaStatus status = IrdaStatusError; + IrdaStatus status = IrdaStatusOk; uint16_t bit = decoder->protocol->timings.bit1_mark; uint16_t tolerance = decoder->protocol->timings.bit_tolerance; @@ -106,12 +110,22 @@ IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder) { bool single_timing = MATCH_BIT_TIMING(timing, bit, tolerance); bool double_timing = MATCH_BIT_TIMING(timing, 2*bit, tolerance); - if((!single_timing && !double_timing) || (double_timing && !*switch_detect)) { + if(!single_timing && !double_timing) { status = IrdaStatusError; break; } + if ((decoder->protocol->manchester_start_from_space) && (decoder->databit_cnt == 0)) { + *switch_detect = 1; /* fake as we were previously in the middle of time-quant */ + decoder->data[0] = 0; /* first captured timing should be Mark */ + ++decoder->databit_cnt; + } + if (*switch_detect == 0) { + if (double_timing) { + status = IrdaStatusError; + break; + } /* only single timing - level switch required in the middle of time-quant */ *switch_detect = 1; } else { @@ -123,6 +137,7 @@ IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder) { --decoder->timings_cnt; shift_left_array(decoder->timings, decoder->timings_cnt, 1); status = IrdaStatusOk; + bool level = (decoder->level + decoder->timings_cnt) % 2; if (decoder->databit_cnt < decoder->protocol->databit_len) { if (*switch_detect) { @@ -130,19 +145,17 @@ IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder) { uint8_t shift = decoder->databit_cnt % 8; // LSB first if (!shift) decoder->data[index] = 0; - bool inverse_level = decoder->protocol->manchester_inverse_level; - uint8_t logic_value = inverse_level ? !decoder->level : decoder->level; - decoder->data[index] |= (logic_value << shift); + decoder->data[index] |= (level << shift); ++decoder->databit_cnt; } if (decoder->databit_cnt == decoder->protocol->databit_len) { - if (decoder->level) { + if (level) { status = IrdaStatusReady; break; } } } else { - furi_assert(decoder->level); + furi_assert(level); /* cover case: sequence should be stopped after last bit was received */ if (single_timing) { status = IrdaStatusReady; @@ -178,6 +191,7 @@ IrdaMessage* irda_common_decode(IrdaCommonDecoder* decoder, bool level, uint32_t decoder->state = IrdaCommonDecoderStateDecode; decoder->databit_cnt = 0; decoder->switch_detect = false; + continue; } break; case IrdaCommonDecoderStateDecode: @@ -243,6 +257,10 @@ void irda_common_decoder_reset_state(IrdaCommonDecoder* common_decoder) { common_decoder->databit_cnt = 0; common_decoder->switch_detect = false; common_decoder->message.protocol = IrdaProtocolUnknown; + if (common_decoder->protocol->timings.preamble_mark == 0) { + --common_decoder->timings_cnt; + shift_left_array(common_decoder->timings, common_decoder->timings_cnt, 1); + } } void irda_common_decoder_reset(void* decoder) { diff --git a/lib/irda/encoder_decoder/irda_common_encoder.c b/lib/irda/encoder_decoder/common/irda_common_encoder.c similarity index 97% rename from lib/irda/encoder_decoder/irda_common_encoder.c rename to lib/irda/encoder_decoder/common/irda_common_encoder.c index 237b3191..6e897233 100644 --- a/lib/irda/encoder_decoder/irda_common_encoder.c +++ b/lib/irda/encoder_decoder/common/irda_common_encoder.c @@ -28,10 +28,9 @@ IrdaStatus irda_common_encode_manchester(IrdaCommonEncoder* encoder, uint32_t* d uint8_t index = encoder->bits_encoded / 8; uint8_t shift = encoder->bits_encoded % 8; // LSB first bool logic_value = !!(encoder->data[index] & (0x01 << shift)); - bool inverse = encoder->protocol->manchester_inverse_level; bool even_timing = !(encoder->timings_encoded % 2); - *level = even_timing ^ logic_value ^ inverse; + *level = even_timing ^ logic_value; *duration = timings->bit1_mark; if (even_timing) /* start encoding from space */ ++encoder->bits_encoded; diff --git a/lib/irda/encoder_decoder/irda_common_i.h b/lib/irda/encoder_decoder/common/irda_common_i.h similarity index 98% rename from lib/irda/encoder_decoder/irda_common_i.h rename to lib/irda/encoder_decoder/common/irda_common_i.h index 56f77790..c73ebee9 100644 --- a/lib/irda/encoder_decoder/irda_common_i.h +++ b/lib/irda/encoder_decoder/common/irda_common_i.h @@ -20,7 +20,7 @@ typedef IrdaStatus (*IrdaCommonEncode)(IrdaCommonEncoder* encoder, uint32_t* out typedef struct { IrdaTimings timings; - bool manchester_inverse_level; + bool manchester_start_from_space; uint32_t databit_len; IrdaCommonDecode decode; IrdaCommonDecode decode_repeat; diff --git a/lib/irda/encoder_decoder/irda_common_protocol_defs.c b/lib/irda/encoder_decoder/common/irda_common_protocol_defs.c similarity index 75% rename from lib/irda/encoder_decoder/irda_common_protocol_defs.c rename to lib/irda/encoder_decoder/common/irda_common_protocol_defs.c index 46327045..e516ab0c 100644 --- a/lib/irda/encoder_decoder/irda_common_protocol_defs.c +++ b/lib/irda/encoder_decoder/common/irda_common_protocol_defs.c @@ -21,26 +21,6 @@ const IrdaCommonProtocolSpec protocol_nec = { .encode_repeat = irda_encoder_nec_encode_repeat, }; -const IrdaCommonProtocolSpec protocol_necext = { - .timings = { - .preamble_mark = IRDA_NEC_PREAMBULE_MARK, - .preamble_space = IRDA_NEC_PREAMBULE_SPACE, - .bit1_mark = IRDA_NEC_BIT1_MARK, - .bit1_space = IRDA_NEC_BIT1_SPACE, - .bit0_mark = IRDA_NEC_BIT0_MARK, - .bit0_space = IRDA_NEC_BIT0_SPACE, - .preamble_tolerance = IRDA_NEC_PREAMBLE_TOLERANCE, - .bit_tolerance = IRDA_NEC_BIT_TOLERANCE, - .silence_time = IRDA_NEC_SILENCE, - }, - .databit_len = 32, - .decode = irda_common_decode_pdwm, - .encode = irda_common_encode_pdwm, - .interpret = irda_decoder_necext_interpret, - .decode_repeat = irda_decoder_nec_decode_repeat, - .encode_repeat = irda_encoder_nec_encode_repeat, -}; - const IrdaCommonProtocolSpec protocol_samsung32 = { .timings = { .preamble_mark = IRDA_SAMSUNG_PREAMBULE_MARK, @@ -71,7 +51,7 @@ const IrdaCommonProtocolSpec protocol_rc6 = { .silence_time = IRDA_RC6_SILENCE, }, .databit_len = 1 + 3 + 1 + 8 + 8, // start_bit + 3 mode bits, + 1 toggle bit (x2 timing) + 8 address + 8 command - .manchester_inverse_level = false, + .manchester_start_from_space = false, .decode = irda_decoder_rc6_decode_manchester, .encode = irda_encoder_rc6_encode_manchester, .interpret = irda_decoder_rc6_interpret, @@ -79,3 +59,21 @@ const IrdaCommonProtocolSpec protocol_rc6 = { .encode_repeat = NULL, }; +const IrdaCommonProtocolSpec protocol_rc5 = { + .timings = { + .preamble_mark = 0, + .preamble_space = 0, + .bit1_mark = IRDA_RC5_BIT, + .preamble_tolerance = 0, + .bit_tolerance = IRDA_RC5_BIT_TOLERANCE, + .silence_time = IRDA_RC5_SILENCE, + }, + .databit_len = 1 + 1 + 1 + 5 + 6, // start_bit + start_bit/command_bit + toggle_bit + 5 address + 6 command + .manchester_start_from_space = true, + .decode = irda_common_decode_manchester, + .encode = irda_common_encode_manchester, + .interpret = irda_decoder_rc5_interpret, + .decode_repeat = NULL, + .encode_repeat = NULL, +}; + diff --git a/lib/irda/encoder_decoder/irda.c b/lib/irda/encoder_decoder/irda.c index 6c7866d1..89552030 100644 --- a/lib/irda/encoder_decoder/irda.c +++ b/lib/irda/encoder_decoder/irda.c @@ -1,6 +1,6 @@ #include "irda.h" #include "furi/check.h" -#include "irda_common_i.h" +#include "common/irda_common_i.h" #include "irda_protocol_defs_i.h" #include #include @@ -9,10 +9,6 @@ #include "irda_i.h" #include -struct IrdaDecoderHandler { - void** ctx; -}; - typedef struct { IrdaAlloc alloc; IrdaDecode decode; @@ -27,27 +23,36 @@ typedef struct { IrdaFree free; } IrdaEncoders; -typedef struct { - IrdaProtocol protocol; - const char* name; - IrdaDecoders decoder; - IrdaEncoders encoder; - uint8_t address_length; - uint8_t command_length; - uint32_t frequency; - float duty_cycle; -} IrdaProtocolImplementation; - -struct IrdaEncoderHandler { - void* encoder; - IrdaProtocol protocol; +struct IrdaDecoderHandler { + void** ctx; }; -// TODO: replace with key-value, Now we refer by enum index, which is dangerous. -static const IrdaProtocolImplementation irda_protocols[] = { - // #0 - { .protocol = IrdaProtocolNEC, - .name = "NEC", +struct IrdaEncoderHandler { + void* handler; + const IrdaEncoders* encoder; +}; + +typedef struct { + IrdaEncoders encoder; + IrdaDecoders decoder; + IrdaGetProtocolSpec get_protocol_spec; +} IrdaEncoderDecoder; + +static const IrdaEncoderDecoder irda_encoder_decoder[] = { + { + .decoder = { + .alloc = irda_decoder_rc5_alloc, + .decode = irda_decoder_rc5_decode, + .reset = irda_decoder_rc5_reset, + .free = irda_decoder_rc5_free}, + .encoder = { + .alloc = irda_encoder_rc5_alloc, + .encode = irda_encoder_rc5_encode, + .reset = irda_encoder_rc5_reset, + .free = irda_encoder_rc5_free}, + .get_protocol_spec = irda_rc5_get_spec, + }, + { .decoder = { .alloc = irda_decoder_nec_alloc, .decode = irda_decoder_nec_decode, @@ -58,32 +63,9 @@ static const IrdaProtocolImplementation irda_protocols[] = { .encode = irda_encoder_nec_encode, .reset = irda_encoder_nec_reset, .free = irda_encoder_nec_free}, - .address_length = 2, - .command_length = 2, - .frequency = IRDA_COMMON_CARRIER_FREQUENCY, - .duty_cycle = IRDA_COMMON_DUTY_CYCLE, + .get_protocol_spec = irda_nec_get_spec, }, - // #1 - have to be after NEC - { .protocol = IrdaProtocolNECext, - .name = "NECext", - .decoder = { - .alloc = irda_decoder_necext_alloc, - .decode = irda_decoder_nec_decode, - .reset = irda_decoder_nec_reset, - .free = irda_decoder_nec_free}, - .encoder = { - .alloc = irda_encoder_necext_alloc, - .encode = irda_encoder_nec_encode, - .reset = irda_encoder_necext_reset, - .free = irda_encoder_nec_free}, - .address_length = 4, - .command_length = 2, - .frequency = IRDA_COMMON_CARRIER_FREQUENCY, - .duty_cycle = IRDA_COMMON_DUTY_CYCLE, - }, - // #2 - { .protocol = IrdaProtocolSamsung32, - .name ="Samsung32", + { .decoder = { .alloc = irda_decoder_samsung32_alloc, .decode = irda_decoder_samsung32_decode, @@ -94,14 +76,9 @@ static const IrdaProtocolImplementation irda_protocols[] = { .encode = irda_encoder_samsung32_encode, .reset = irda_encoder_samsung32_reset, .free = irda_encoder_samsung32_free}, - .address_length = 2, - .command_length = 2, - .frequency = IRDA_COMMON_CARRIER_FREQUENCY, - .duty_cycle = IRDA_COMMON_DUTY_CYCLE, + .get_protocol_spec = irda_samsung32_get_spec, }, - // #3 - { .protocol = IrdaProtocolRC6, - .name = "RC6", + { .decoder = { .alloc = irda_decoder_rc6_alloc, .decode = irda_decoder_rc6_decode, @@ -112,10 +89,7 @@ static const IrdaProtocolImplementation irda_protocols[] = { .encode = irda_encoder_rc6_encode, .reset = irda_encoder_rc6_reset, .free = irda_encoder_rc6_free}, - .address_length = 2, - .command_length = 2, - .frequency = IRDA_COMMON_CARRIER_FREQUENCY, - .duty_cycle = IRDA_COMMON_DUTY_CYCLE, + .get_protocol_spec = irda_rc6_get_spec, }, }; @@ -125,11 +99,10 @@ const IrdaMessage* irda_decode(IrdaDecoderHandler* handler, bool level, uint32_t IrdaMessage* message = NULL; IrdaMessage* result = NULL; - for (int i = 0; i < COUNT_OF(irda_protocols); ++i) { - if (irda_protocols[i].decoder.decode) { - message = irda_protocols[i].decoder.decode(handler->ctx[i], level, duration); + for (int i = 0; i < COUNT_OF(irda_encoder_decoder); ++i) { + if (irda_encoder_decoder[i].decoder.decode) { + message = irda_encoder_decoder[i].decoder.decode(handler->ctx[i], level, duration); if (!result && message) { - message->protocol = irda_protocols[i].protocol; result = message; } } @@ -140,12 +113,12 @@ const IrdaMessage* irda_decode(IrdaDecoderHandler* handler, bool level, uint32_t IrdaDecoderHandler* irda_alloc_decoder(void) { IrdaDecoderHandler* handler = furi_alloc(sizeof(IrdaDecoderHandler)); - handler->ctx = furi_alloc(sizeof(void*) * COUNT_OF(irda_protocols)); + handler->ctx = furi_alloc(sizeof(void*) * COUNT_OF(irda_encoder_decoder)); - for (int i = 0; i < COUNT_OF(irda_protocols); ++i) { + for (int i = 0; i < COUNT_OF(irda_encoder_decoder); ++i) { handler->ctx[i] = 0; - if (irda_protocols[i].decoder.alloc) - handler->ctx[i] = irda_protocols[i].decoder.alloc(); + if (irda_encoder_decoder[i].decoder.alloc) + handler->ctx[i] = irda_encoder_decoder[i].decoder.alloc(); } return handler; @@ -155,9 +128,9 @@ void irda_free_decoder(IrdaDecoderHandler* handler) { furi_assert(handler); furi_assert(handler->ctx); - for (int i = 0; i < COUNT_OF(irda_protocols); ++i) { - if (irda_protocols[i].decoder.free) - irda_protocols[i].decoder.free(handler->ctx[i]); + for (int i = 0; i < COUNT_OF(irda_encoder_decoder); ++i) { + if (irda_encoder_decoder[i].decoder.free) + irda_encoder_decoder[i].decoder.free(handler->ctx[i]); } free(handler->ctx); @@ -165,114 +138,119 @@ void irda_free_decoder(IrdaDecoderHandler* handler) { } void irda_reset_decoder(IrdaDecoderHandler* handler) { - for (int i = 0; i < COUNT_OF(irda_protocols); ++i) { - if (irda_protocols[i].decoder.reset) - irda_protocols[i].decoder.reset(handler->ctx[i]); + for (int i = 0; i < COUNT_OF(irda_encoder_decoder); ++i) { + if (irda_encoder_decoder[i].decoder.reset) + irda_encoder_decoder[i].decoder.reset(handler->ctx[i]); } } IrdaEncoderHandler* irda_alloc_encoder(void) { IrdaEncoderHandler* handler = furi_alloc(sizeof(IrdaEncoderHandler)); + handler->handler = NULL; handler->encoder = NULL; - handler->protocol = IrdaProtocolUnknown; return handler; } void irda_free_encoder(IrdaEncoderHandler* handler) { furi_assert(handler); + const IrdaEncoders* encoder = handler->encoder; - if (handler->encoder) { - furi_assert(irda_is_protocol_valid(handler->protocol)); - furi_assert(irda_protocols[handler->protocol].encoder.free); - irda_protocols[handler->protocol].encoder.free(handler->encoder); + if (encoder || handler->handler) { + furi_assert(encoder); + furi_assert(handler->handler); + furi_assert(encoder->free); + encoder->free(handler->handler); } free(handler); } +static int irda_find_index_by_protocol(IrdaProtocol protocol) { + for (int i = 0; i < COUNT_OF(irda_encoder_decoder); ++i) { + if (irda_encoder_decoder[i].get_protocol_spec(protocol)) { + return i; + } + } + + return -1; +} + void irda_reset_encoder(IrdaEncoderHandler* handler, const IrdaMessage* message) { furi_assert(handler); furi_assert(message); - furi_assert(irda_is_protocol_valid(message->protocol)); - furi_assert(irda_protocols[message->protocol].encoder.reset); - furi_assert(irda_protocols[message->protocol].encoder.alloc); + int index = irda_find_index_by_protocol(message->protocol); + furi_check(index >= 0); + + const IrdaEncoders* required_encoder = &irda_encoder_decoder[index].encoder; + furi_assert(required_encoder); + furi_assert(required_encoder->reset); + furi_assert(required_encoder->alloc); /* Realloc encoder if different protocol set */ - if (message->protocol != handler->protocol) { - if (handler->encoder != NULL) { - furi_assert(handler->protocol != IrdaProtocolUnknown); - irda_protocols[handler->protocol].encoder.free(handler->encoder); + if (required_encoder != handler->encoder) { + if (handler->handler != NULL) { + furi_assert(handler->encoder->free); + handler->encoder->free(handler->handler); } - handler->encoder = irda_protocols[message->protocol].encoder.alloc(); - handler->protocol = message->protocol; + handler->encoder = required_encoder; + handler->handler = handler->encoder->alloc(); } - irda_protocols[handler->protocol].encoder.reset(handler->encoder, message); + handler->encoder->reset(handler->handler, message); } - IrdaStatus irda_encode(IrdaEncoderHandler* handler, uint32_t* duration, bool* level) { furi_assert(handler); - furi_assert(irda_is_protocol_valid(handler->protocol)); - furi_assert(irda_protocols[handler->protocol].encoder.encode); + furi_assert(duration); + furi_assert(level); + const IrdaEncoders* encoder = handler->encoder; + furi_assert(encoder); + furi_assert(encoder->encode); - IrdaStatus status = irda_protocols[handler->protocol].encoder.encode(handler->encoder, duration, level); + IrdaStatus status = encoder->encode(handler->handler, duration, level); furi_assert(status != IrdaStatusError); return status; } - bool irda_is_protocol_valid(IrdaProtocol protocol) { - return (protocol >= 0) && (protocol < COUNT_OF(irda_protocols)); + return irda_find_index_by_protocol(protocol) >= 0; } IrdaProtocol irda_get_protocol_by_name(const char* protocol_name) { - for (int i = 0; i < COUNT_OF(irda_protocols); ++i) { - if (!strcmp(irda_protocols[i].name, protocol_name)) - return i; + for (IrdaProtocol protocol = 0; protocol < IrdaProtocolMAX; ++protocol) { + const char* name = irda_get_protocol_name(protocol); + if (!strcmp(name, protocol_name)) + return protocol; } - furi_assert(0); return IrdaProtocolUnknown; } +static const IrdaProtocolSpecification* irda_get_spec_by_protocol(IrdaProtocol protocol) { + int index = irda_find_index_by_protocol(protocol); + furi_check(index >= 0); + const IrdaProtocolSpecification* spec = irda_encoder_decoder[index].get_protocol_spec(protocol); + furi_assert(spec); + return spec; +} + const char* irda_get_protocol_name(IrdaProtocol protocol) { - furi_assert(irda_is_protocol_valid(protocol)); - if (irda_is_protocol_valid(protocol)) - return irda_protocols[protocol].name; - else - return "Invalid"; + return irda_get_spec_by_protocol(protocol)->name; } uint8_t irda_get_protocol_address_length(IrdaProtocol protocol) { - furi_assert(irda_is_protocol_valid(protocol)); - if (irda_is_protocol_valid(protocol)) - return irda_protocols[protocol].address_length; - else - return 0; + return irda_get_spec_by_protocol(protocol)->address_length; } uint8_t irda_get_protocol_command_length(IrdaProtocol protocol) { - furi_assert(irda_is_protocol_valid(protocol)); - if (irda_is_protocol_valid(protocol)) - return irda_protocols[protocol].command_length; - else - return 0; + return irda_get_spec_by_protocol(protocol)->command_length; } uint32_t irda_get_protocol_frequency(IrdaProtocol protocol) { - furi_assert(irda_is_protocol_valid(protocol)); - if (irda_is_protocol_valid(protocol)) - return irda_protocols[protocol].frequency; - else - return 0; + return irda_get_spec_by_protocol(protocol)->frequency; } float irda_get_protocol_duty_cycle(IrdaProtocol protocol) { - furi_assert(irda_is_protocol_valid(protocol)); - if (irda_is_protocol_valid(protocol)) - return irda_protocols[protocol].duty_cycle; - else - return 0; + return irda_get_spec_by_protocol(protocol)->duty_cycle; } diff --git a/lib/irda/encoder_decoder/irda.h b/lib/irda/encoder_decoder/irda.h index 954be818..d1887e26 100644 --- a/lib/irda/encoder_decoder/irda.h +++ b/lib/irda/encoder_decoder/irda.h @@ -26,6 +26,9 @@ typedef enum { IrdaProtocolNECext = 1, IrdaProtocolSamsung32 = 2, IrdaProtocolRC6 = 3, + IrdaProtocolRC5 = 4, + IrdaProtocolRC5X = 5, + IrdaProtocolMAX, } IrdaProtocol; typedef struct { @@ -58,6 +61,8 @@ IrdaDecoderHandler* irda_alloc_decoder(void); * and decoder resets its state and start decoding from the start. * \param[in] duration - duration of steady high/low input signal. * \return if message is ready, returns pointer to decoded message, returns NULL. + * Note: ownership of returned ptr belongs to handler. So pointer is valid + * up to next irda_free_decoder(), irda_reset_decoder(), irda_decode() calls. */ const IrdaMessage* irda_decode(IrdaDecoderHandler* handler, bool level, uint32_t duration); diff --git a/lib/irda/encoder_decoder/irda_i.h b/lib/irda/encoder_decoder/irda_i.h index 021f1263..4ca194a8 100644 --- a/lib/irda/encoder_decoder/irda_i.h +++ b/lib/irda/encoder_decoder/irda_i.h @@ -14,6 +14,16 @@ typedef struct { uint32_t bit_tolerance; } IrdaTimings; +typedef struct { + const char* name; + uint8_t address_length; + uint8_t command_length; + uint32_t frequency; + float duty_cycle; +} IrdaProtocolSpecification; + +typedef const IrdaProtocolSpecification* (*IrdaGetProtocolSpec) (IrdaProtocol protocol); + typedef void* (*IrdaAlloc) (void); typedef IrdaMessage* (*IrdaDecode) (void* ctx, bool level, uint32_t duration); typedef void (*IrdaReset) (void*); @@ -21,7 +31,6 @@ typedef void (*IrdaFree) (void*); typedef void (*IrdaEncoderReset)(void* encoder, const IrdaMessage* message); typedef IrdaStatus (*IrdaEncode)(void* encoder, uint32_t* out, bool* polarity); -typedef IrdaTimings (*IrdaTimingsGet)(void); static inline uint8_t reverse(uint8_t value) { uint8_t reverse_value = 0; diff --git a/lib/irda/encoder_decoder/irda_protocol_defs_i.h b/lib/irda/encoder_decoder/irda_protocol_defs_i.h index 9c4e5ae9..43703ea9 100644 --- a/lib/irda/encoder_decoder/irda_protocol_defs_i.h +++ b/lib/irda/encoder_decoder/irda_protocol_defs_i.h @@ -4,7 +4,7 @@ #include #include #include "irda.h" -#include "irda_common_i.h" +#include "common/irda_common_i.h" /*************************************************************************************************** * NEC protocol description @@ -40,22 +40,15 @@ void* irda_decoder_nec_alloc(void); void irda_decoder_nec_reset(void* decoder); void irda_decoder_nec_free(void* decoder); IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duration); - void* irda_encoder_nec_alloc(void); IrdaStatus irda_encoder_nec_encode(void* encoder_ptr, uint32_t* duration, bool* level); void irda_encoder_nec_reset(void* encoder_ptr, const IrdaMessage* message); void irda_encoder_nec_free(void* encoder_ptr); - -void* irda_decoder_necext_alloc(void); -void* irda_encoder_necext_alloc(void); -void irda_encoder_necext_reset(void* encoder_ptr, const IrdaMessage* message); - bool irda_decoder_nec_interpret(IrdaCommonDecoder* decoder); -bool irda_decoder_necext_interpret(IrdaCommonDecoder* decoder); IrdaStatus irda_decoder_nec_decode_repeat(IrdaCommonDecoder* decoder); IrdaStatus irda_encoder_nec_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level); +const IrdaProtocolSpecification* irda_nec_get_spec(IrdaProtocol protocol); -extern const IrdaCommonProtocolSpec protocol_necext; extern const IrdaCommonProtocolSpec protocol_nec; @@ -98,15 +91,14 @@ void* irda_decoder_samsung32_alloc(void); void irda_decoder_samsung32_reset(void* decoder); void irda_decoder_samsung32_free(void* decoder); 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); void* irda_encoder_samsung32_alloc(void); void irda_encoder_samsung32_free(void* encoder_ptr); - bool irda_decoder_samsung32_interpret(IrdaCommonDecoder* decoder); IrdaStatus irda_decoder_samsung32_decode_repeat(IrdaCommonDecoder* decoder); IrdaStatus irda_encoder_samsung32_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level); +const IrdaProtocolSpecification* irda_samsung32_get_spec(IrdaProtocol protocol); extern const IrdaCommonProtocolSpec protocol_samsung32; @@ -132,6 +124,9 @@ extern const IrdaCommonProtocolSpec protocol_samsung32; * command - 8 bit ***************************************************************************************************/ +#define IRDA_RC6_CARRIER_FREQUENCY 36000 +#define IRDA_RC6_DUTY_CYCLE 0.33 + #define IRDA_RC6_PREAMBULE_MARK 2666 #define IRDA_RC6_PREAMBULE_SPACE 889 #define IRDA_RC6_BIT 444 // half of time-quant for 1 bit @@ -148,10 +143,57 @@ void* irda_encoder_rc6_alloc(void); void irda_encoder_rc6_reset(void* encoder_ptr, const IrdaMessage* message); void irda_encoder_rc6_free(void* decoder); IrdaStatus irda_encoder_rc6_encode(void* encoder_ptr, uint32_t* duration, bool* polarity); - bool irda_decoder_rc6_interpret(IrdaCommonDecoder* decoder); IrdaStatus irda_decoder_rc6_decode_manchester(IrdaCommonDecoder* decoder); IrdaStatus irda_encoder_rc6_encode_manchester(IrdaCommonEncoder* encoder_ptr, uint32_t* duration, bool* polarity); +const IrdaProtocolSpecification* irda_rc6_get_spec(IrdaProtocol protocol); extern const IrdaCommonProtocolSpec protocol_rc6; + +/*************************************************************************************************** +* RC5 protocol description +* https://www.mikrocontroller.net/articles/IRMP_-_english#RC5_.2B_RC5X +**************************************************************************************************** +* Manchester/biphase +* Modulation +* +* 888/1776 - bit (x2 for toggle bit) +* +* __ ____ __ __ __ __ __ __ __ __ +* __ __ ____ __ __ __ __ __ __ __ _ +* | 1 | 1 | 0 | ... | ... | +* s si T address (MSB) command (MSB) +* +* Note: manchester starts from space timing, so it have to be handled properly +* s - start bit (always 1) +* si - RC5: start bit (always 1), RC5X - 7-th bit of address (in our case always 0) +* T - toggle bit, change it's value every button press +* address - 8 bit +* command - 8 bit +***************************************************************************************************/ + +#define IRDA_RC5_CARRIER_FREQUENCY 36000 +#define IRDA_RC5_DUTY_CYCLE 0.33 + +#define IRDA_RC5_PREAMBULE_MARK 0 +#define IRDA_RC5_PREAMBULE_SPACE 0 +#define IRDA_RC5_BIT 888 // half of time-quant for 1 bit +#define IRDA_RC5_PREAMBLE_TOLERANCE 0.07 // percents +#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) + +void* irda_decoder_rc5_alloc(void); +void irda_decoder_rc5_reset(void* decoder); +void irda_decoder_rc5_free(void* decoder); +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); +void irda_encoder_rc5_free(void* decoder); +IrdaStatus irda_encoder_rc5_encode(void* encoder_ptr, uint32_t* duration, bool* polarity); +bool irda_decoder_rc5_interpret(IrdaCommonDecoder* decoder); +const IrdaProtocolSpecification* irda_rc5_get_spec(IrdaProtocol protocol); + +extern const IrdaCommonProtocolSpec protocol_rc5; + diff --git a/lib/irda/encoder_decoder/nec/irda_decoder_nec.c b/lib/irda/encoder_decoder/nec/irda_decoder_nec.c index 1abe1b9d..aaea7ec5 100644 --- a/lib/irda/encoder_decoder/nec/irda_decoder_nec.c +++ b/lib/irda/encoder_decoder/nec/irda_decoder_nec.c @@ -1,3 +1,4 @@ +#include "irda.h" #include "irda_protocol_defs_i.h" #include #include @@ -14,27 +15,15 @@ bool irda_decoder_nec_interpret(IrdaCommonDecoder* decoder) { uint8_t command = decoder->data[2]; uint8_t command_inverse = decoder->data[3]; - if ((command == (uint8_t) ~command_inverse) && (address == (uint8_t) ~address_inverse)) { + if (command == (uint8_t) ~command_inverse) { + if (address == (uint8_t) ~address_inverse) { + decoder->message.protocol = IrdaProtocolNEC; + decoder->message.address = address; + } else { + decoder->message.protocol = IrdaProtocolNECext; + decoder->message.address = decoder->data[0] | (decoder->data[1] << 8); + } decoder->message.command = command; - decoder->message.address = address; - decoder->message.repeat = false; - result = true; - } - - return result; -} - -// Some NEC's extensions allow 16 bit address -bool irda_decoder_necext_interpret(IrdaCommonDecoder* decoder) { - furi_assert(decoder); - - bool result = false; - uint8_t command = decoder->data[2]; - uint8_t command_inverse = decoder->data[3]; - - if(command == (uint8_t)~command_inverse) { - decoder->message.command = command; - decoder->message.address = decoder->data[0] | (decoder->data[1] << 8); decoder->message.repeat = false; result = true; } @@ -70,10 +59,6 @@ void* irda_decoder_nec_alloc(void) { return irda_common_decoder_alloc(&protocol_nec); } -void* irda_decoder_necext_alloc(void) { - return irda_common_decoder_alloc(&protocol_necext); -} - IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duration) { return irda_common_decode(decoder, level, duration); } diff --git a/lib/irda/encoder_decoder/nec/irda_encoder_nec.c b/lib/irda/encoder_decoder/nec/irda_encoder_nec.c index ecd403b3..8bf2dfd5 100644 --- a/lib/irda/encoder_decoder/nec/irda_encoder_nec.c +++ b/lib/irda/encoder_decoder/nec/irda_encoder_nec.c @@ -1,5 +1,6 @@ #include "furi/check.h" -#include "irda_common_i.h" +#include "irda.h" +#include "common/irda_common_i.h" #include #include "../irda_i.h" #include "irda_protocol_defs_i.h" @@ -14,6 +15,7 @@ static const uint32_t repeat_timings[] = { void irda_encoder_nec_reset(void* encoder_ptr, const IrdaMessage* message) { furi_assert(encoder_ptr); + furi_assert(message); IrdaCommonEncoder* encoder = encoder_ptr; irda_common_encoder_reset(encoder); @@ -24,24 +26,11 @@ void irda_encoder_nec_reset(void* encoder_ptr, const IrdaMessage* message) { uint8_t command_inverse = ~command; uint32_t* data = (void*) encoder->data; - *data |= address; - *data |= address_inverse << 8; - *data |= command << 16; - *data |= command_inverse << 24; -} - -void irda_encoder_necext_reset(void* encoder_ptr, const IrdaMessage* message) { - furi_assert(encoder_ptr); - - IrdaCommonEncoder* encoder = encoder_ptr; - irda_common_encoder_reset(encoder); - - uint16_t address = message->address; - uint8_t command = message->command; - uint8_t command_inverse = ~command; - - uint32_t* data = (void*) encoder->data; - *data |= address; + if (message->protocol == IrdaProtocolNEC) { + *data = (address | (address_inverse << 8)); + } else if (message->protocol == IrdaProtocolNECext) { + *data = (uint16_t) message->address; + } *data |= command << 16; *data |= command_inverse << 24; } @@ -67,10 +56,6 @@ IrdaStatus irda_encoder_nec_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* return done ? IrdaStatusDone : IrdaStatusOk; } -void* irda_encoder_necext_alloc(void) { - return irda_common_encoder_alloc(&protocol_necext); -} - void* irda_encoder_nec_alloc(void) { return irda_common_encoder_alloc(&protocol_nec); } diff --git a/lib/irda/encoder_decoder/nec/irda_nec_spec.c b/lib/irda/encoder_decoder/nec/irda_nec_spec.c new file mode 100644 index 00000000..707e3595 --- /dev/null +++ b/lib/irda/encoder_decoder/nec/irda_nec_spec.c @@ -0,0 +1,28 @@ +#include "../irda_i.h" +#include "irda_protocol_defs_i.h" + +static const IrdaProtocolSpecification irda_nec_protocol_specification = { + .name = "NEC", + .address_length = 2, + .command_length = 2, + .frequency = IRDA_COMMON_CARRIER_FREQUENCY, + .duty_cycle = IRDA_COMMON_DUTY_CYCLE, +}; + +static const IrdaProtocolSpecification irda_necext_protocol_specification = { + .name = "NECext", + .address_length = 4, + .command_length = 2, + .frequency = IRDA_COMMON_CARRIER_FREQUENCY, + .duty_cycle = IRDA_COMMON_DUTY_CYCLE, +}; + +const IrdaProtocolSpecification* irda_nec_get_spec(IrdaProtocol protocol) { + if (protocol == IrdaProtocolNEC) + return &irda_nec_protocol_specification; + else if (protocol == IrdaProtocolNECext) + return &irda_necext_protocol_specification; + else + return NULL; +} + diff --git a/lib/irda/encoder_decoder/rc5/irda_decoder_rc5.c b/lib/irda/encoder_decoder/rc5/irda_decoder_rc5.c new file mode 100644 index 00000000..704dc5ae --- /dev/null +++ b/lib/irda/encoder_decoder/rc5/irda_decoder_rc5.c @@ -0,0 +1,79 @@ +#include "irda.h" +#include +#include +#include +#include +#include "../irda_i.h" +#include "../irda_protocol_defs_i.h" + +typedef struct { + IrdaCommonDecoder* common_decoder; + bool toggle; +} IrdaRc5Decoder; + +bool irda_decoder_rc5_interpret(IrdaCommonDecoder* decoder) { + furi_assert(decoder); + + bool result = false; + uint32_t* data = (void*) &decoder->data[0]; + /* Manchester (inverse): + * 0->1 : 1 + * 1->0 : 0 + */ + decoder->data[0] = ~decoder->data[0]; + decoder->data[1] = ~decoder->data[1]; + + // MSB first + uint8_t address = reverse((uint8_t) decoder->data[0]) & 0x1F; + uint8_t command = (reverse((uint8_t) decoder->data[1]) >> 2) & 0x3F; + bool start_bit1 = *data & 0x01; + bool start_bit2 = *data & 0x02; + bool toggle = !!(*data & 0x04); + + if (start_bit1 == 1) { + IrdaProtocol protocol = start_bit2 ? IrdaProtocolRC5 : IrdaProtocolRC5X; + IrdaMessage* message = &decoder->message; + IrdaRc5Decoder *rc5_decoder = decoder->context; + bool *prev_toggle = &rc5_decoder->toggle; + if ((message->address == address) + && (message->command == command) + && (message->protocol == protocol)) { + message->repeat = (toggle == *prev_toggle); + } else { + message->repeat = false; + } + *prev_toggle = toggle; + message->command = command; + message->address = address; + message->protocol = protocol; + + result = true; + } + + return result; +} + +void* irda_decoder_rc5_alloc(void) { + IrdaRc5Decoder* decoder = furi_alloc(sizeof(IrdaRc5Decoder)); + decoder->toggle = false; + decoder->common_decoder = irda_common_decoder_alloc(&protocol_rc5); + irda_common_decoder_set_context(decoder->common_decoder, decoder); + return decoder; +} + +IrdaMessage* irda_decoder_rc5_decode(void* decoder, bool level, uint32_t duration) { + IrdaRc5Decoder* decoder_rc5 = decoder; + return irda_common_decode(decoder_rc5->common_decoder, level, duration); +} + +void irda_decoder_rc5_free(void* decoder) { + IrdaRc5Decoder* decoder_rc5 = decoder; + irda_common_decoder_free(decoder_rc5->common_decoder); + free(decoder_rc5); +} + +void irda_decoder_rc5_reset(void* decoder) { + IrdaRc5Decoder* decoder_rc5 = decoder; + irda_common_decoder_reset(decoder_rc5->common_decoder); +} + diff --git a/lib/irda/encoder_decoder/rc5/irda_encoder_rc5.c b/lib/irda/encoder_decoder/rc5/irda_encoder_rc5.c new file mode 100644 index 00000000..e6fa9f0d --- /dev/null +++ b/lib/irda/encoder_decoder/rc5/irda_encoder_rc5.c @@ -0,0 +1,55 @@ +#include "furi/memmgr.h" +#include "irda.h" +#include "common/irda_common_i.h" +#include "irda_protocol_defs_i.h" +#include +#include "../irda_i.h" + +typedef struct IrdaEncoderRC5 { + IrdaCommonEncoder* common_encoder; + bool toggle_bit; +} IrdaEncoderRC5; + +void irda_encoder_rc5_reset(void* encoder_ptr, const IrdaMessage* message) { + furi_assert(encoder_ptr); + + IrdaEncoderRC5* encoder = encoder_ptr; + IrdaCommonEncoder* common_encoder = encoder->common_encoder; + irda_common_encoder_reset(common_encoder); + + uint32_t* data = (void*) common_encoder->data; + /* RC5 */ + *data |= 0x01; // start bit + if (message->protocol == IrdaProtocolRC5) { + *data |= 0x02; // start bit + } + *data |= encoder->toggle_bit ? 0x04 : 0; + *data |= (reverse(message->address) >> 3) << 3; /* address 5 bit */ + *data |= (reverse(message->command) >> 2) << 8; /* command 6 bit */ + + common_encoder->data[0] = ~common_encoder->data[0]; + common_encoder->data[1] = ~common_encoder->data[1]; + + encoder->toggle_bit ^= 1; +} + +IrdaStatus irda_encoder_rc5_encode(void* encoder_ptr, uint32_t* duration, bool* level) { + IrdaEncoderRC5* encoder = encoder_ptr; + return irda_common_encode(encoder->common_encoder, duration, level); +} + +void* irda_encoder_rc5_alloc(void) { + IrdaEncoderRC5* encoder = furi_alloc(sizeof(IrdaEncoderRC5)); + encoder->common_encoder = irda_common_encoder_alloc(&protocol_rc5); + encoder->toggle_bit = false; + return encoder; +} + +void irda_encoder_rc5_free(void* encoder_ptr) { + furi_assert(encoder_ptr); + + IrdaEncoderRC5* encoder = encoder_ptr; + free(encoder->common_encoder); + free(encoder); +} + diff --git a/lib/irda/encoder_decoder/rc5/irda_rc5_spec.c b/lib/irda/encoder_decoder/rc5/irda_rc5_spec.c new file mode 100644 index 00000000..565b328c --- /dev/null +++ b/lib/irda/encoder_decoder/rc5/irda_rc5_spec.c @@ -0,0 +1,28 @@ +#include "../irda_i.h" +#include "irda_protocol_defs_i.h" + +static const IrdaProtocolSpecification irda_rc5_protocol_specification = { + .name = "RC5", + .address_length = 2, + .command_length = 2, + .frequency = IRDA_RC5_CARRIER_FREQUENCY, + .duty_cycle = IRDA_RC5_DUTY_CYCLE, +}; + +static const IrdaProtocolSpecification irda_rc5x_protocol_specification = { + .name = "RC5X", + .address_length = 2, + .command_length = 2, + .frequency = IRDA_RC5_CARRIER_FREQUENCY, + .duty_cycle = IRDA_RC5_DUTY_CYCLE, +}; + +const IrdaProtocolSpecification* irda_rc5_get_spec(IrdaProtocol protocol) { + if (protocol == IrdaProtocolRC5) + return &irda_rc5_protocol_specification; + else if (protocol == IrdaProtocolRC5X) + return &irda_rc5x_protocol_specification; + else + return NULL; +} + diff --git a/lib/irda/encoder_decoder/rc6/irda_decoder_rc6.c b/lib/irda/encoder_decoder/rc6/irda_decoder_rc6.c index 96246357..d561adad 100644 --- a/lib/irda/encoder_decoder/rc6/irda_decoder_rc6.c +++ b/lib/irda/encoder_decoder/rc6/irda_decoder_rc6.c @@ -37,6 +37,7 @@ bool irda_decoder_rc6_interpret(IrdaCommonDecoder* decoder) { *prev_toggle = toggle; message->command = command; message->address = address; + message->protocol = IrdaProtocolRC6; result = true; } diff --git a/lib/irda/encoder_decoder/rc6/irda_encoder_rc6.c b/lib/irda/encoder_decoder/rc6/irda_encoder_rc6.c index 6b534805..2d099b7d 100644 --- a/lib/irda/encoder_decoder/rc6/irda_encoder_rc6.c +++ b/lib/irda/encoder_decoder/rc6/irda_encoder_rc6.c @@ -1,6 +1,6 @@ #include "furi/memmgr.h" #include "irda.h" -#include "irda_common_i.h" +#include "common/irda_common_i.h" #include "irda_protocol_defs_i.h" #include #include "../irda_i.h" diff --git a/lib/irda/encoder_decoder/rc6/irda_rc6_spec.c b/lib/irda/encoder_decoder/rc6/irda_rc6_spec.c new file mode 100644 index 00000000..bd7977c5 --- /dev/null +++ b/lib/irda/encoder_decoder/rc6/irda_rc6_spec.c @@ -0,0 +1,18 @@ +#include "../irda_i.h" +#include "irda_protocol_defs_i.h" + +static const IrdaProtocolSpecification irda_rc6_protocol_specification = { + .name = "RC6", + .address_length = 2, + .command_length = 2, + .frequency = IRDA_RC6_CARRIER_FREQUENCY, + .duty_cycle = IRDA_RC6_DUTY_CYCLE, +}; + +const IrdaProtocolSpecification* irda_rc6_get_spec(IrdaProtocol protocol) { + if (protocol == IrdaProtocolRC6) + return &irda_rc6_protocol_specification; + else + return NULL; +} + diff --git a/lib/irda/encoder_decoder/samsung/irda_decoder_samsung.c b/lib/irda/encoder_decoder/samsung/irda_decoder_samsung.c index 7311403e..1a92de41 100644 --- a/lib/irda/encoder_decoder/samsung/irda_decoder_samsung.c +++ b/lib/irda/encoder_decoder/samsung/irda_decoder_samsung.c @@ -1,3 +1,4 @@ +#include "irda.h" #include "irda_protocol_defs_i.h" #include #include @@ -17,6 +18,7 @@ bool irda_decoder_samsung32_interpret(IrdaCommonDecoder* decoder) { if ((address1 == address2) && (command == (uint8_t) ~command_inverse)) { decoder->message.command = command; decoder->message.address = address1; + decoder->message.protocol = IrdaProtocolSamsung32; decoder->message.repeat = false; result = true; } diff --git a/lib/irda/encoder_decoder/samsung/irda_encoder_samsung.c b/lib/irda/encoder_decoder/samsung/irda_encoder_samsung.c index 016a1271..5a3c5f50 100644 --- a/lib/irda/encoder_decoder/samsung/irda_encoder_samsung.c +++ b/lib/irda/encoder_decoder/samsung/irda_encoder_samsung.c @@ -1,5 +1,5 @@ #include "furi/check.h" -#include "irda_common_i.h" +#include "common/irda_common_i.h" #include #include "../irda_i.h" #include "irda_protocol_defs_i.h" diff --git a/lib/irda/encoder_decoder/samsung/irda_samsung_spec.c b/lib/irda/encoder_decoder/samsung/irda_samsung_spec.c new file mode 100644 index 00000000..2043ce0a --- /dev/null +++ b/lib/irda/encoder_decoder/samsung/irda_samsung_spec.c @@ -0,0 +1,18 @@ +#include "../irda_i.h" +#include "irda_protocol_defs_i.h" + +static const IrdaProtocolSpecification irda_samsung32_protocol_specification = { + .name = "Samsung32", + .address_length = 2, + .command_length = 2, + .frequency = IRDA_COMMON_CARRIER_FREQUENCY, + .duty_cycle = IRDA_COMMON_DUTY_CYCLE, +}; + +const IrdaProtocolSpecification* irda_samsung32_get_spec(IrdaProtocol protocol) { + if (protocol == IrdaProtocolSamsung32) + return &irda_samsung32_protocol_specification; + else + return NULL; +} +