summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/decoder.h29
-rw-r--r--include/samsung_decoder.h59
-rw-r--r--include/script_decoder.h110
3 files changed, 166 insertions, 32 deletions
diff --git a/include/decoder.h b/include/decoder.h
index 9aee34d..4ae723c 100644
--- a/include/decoder.h
+++ b/include/decoder.h
@@ -2,6 +2,7 @@
#include <cstdint>
#include <mcu/init.h>
+#include <cstdio>
namespace radio_controller {
@@ -10,6 +11,26 @@ struct sample {
uint16_t pulse_us;
};
+namespace decoder_ns {
+
+inline static
+bool between(uint16_t smallest, uint16_t biggest, uint16_t value)
+{
+ return smallest <= value && value <= biggest;
+}
+
+inline static
+bool check_pulse(sample s, uint16_t period_time, uint16_t pulse_time)
+{
+ printf("check_pulse: between(%d, %d, %d) && between(%d, %d, %d)\n",
+ uint16_t(period_time * 0.8), uint16_t(period_time * 1.2), s.period_us,
+ uint16_t(pulse_time * 0.8), uint16_t(pulse_time * 1.2), s.pulse_us);
+
+ return between(uint16_t(period_time * 0.8), uint16_t(period_time * 1.2), s.period_us) &&
+ between(uint16_t(pulse_time * 0.8), uint16_t(pulse_time * 1.2), s.pulse_us);
+}
+} // namespace decoder_ns
+
class sample_iterator {
public:
virtual int size() = 0;
@@ -77,9 +98,11 @@ public:
enum class decoding_state {
OK,
- TOO_SHORT,
- BAD_START,
- SHORT_BODY
+ FAIL,
+// TOO_SHORT,
+// BAD_START,
+// SHORT_BODY,
+// UNKNOWN_TOKEN,
};
class decoding_result {
diff --git a/include/samsung_decoder.h b/include/samsung_decoder.h
index 52978ec..3e55a94 100644
--- a/include/samsung_decoder.h
+++ b/include/samsung_decoder.h
@@ -57,35 +57,36 @@ public:
decoding_result decode(sample_iterator *it) override
{
- printf("Samsung, size=%d\n", it->size());
-
- dump_values(it);
- it->reset();
-
- sample s{};
- bit_string data;
-
- if (!it->next()) {
- return {decoding_state::TOO_SHORT};
- }
- s = it->value();
- if (!start_bit(s)) {
- return {decoding_state::BAD_START};
- }
-
- for (int i = 0; i < 32 && it->next(); i++) {
- s = it->value();
-
- if (one_bit(s)) {
- data.append(true);
- } else if (zero_bit(s)) {
- data.append(false);
- } else {
- return {decoding_state::SHORT_BODY};
- }
- }
-
- return {decoding_state::OK, data};
+ return decoding_result{decoding_state::FAIL};
+// printf("Samsung, size=%d\n", it->size());
+//
+// dump_values(it);
+// it->reset();
+//
+// sample s{};
+// bit_string data;
+//
+// if (!it->next()) {
+// return {decoding_state::TOO_SHORT};
+// }
+// s = it->value();
+// if (!start_bit(s)) {
+// return {decoding_state::BAD_START};
+// }
+//
+// for (int i = 0; i < 32 && it->next(); i++) {
+// s = it->value();
+//
+// if (one_bit(s)) {
+// data.append(true);
+// } else if (zero_bit(s)) {
+// data.append(false);
+// } else {
+// return {decoding_state::SHORT_BODY};
+// }
+// }
+//
+// return {decoding_state::OK, data};
}
};
diff --git a/include/script_decoder.h b/include/script_decoder.h
new file mode 100644
index 0000000..c3ad281
--- /dev/null
+++ b/include/script_decoder.h
@@ -0,0 +1,110 @@
+#pragma
+
+#include <cstdint>
+#include <cstdio>
+#include "decoder.h"
+
+namespace radio_controller {
+
+enum class token_type {
+ START,
+ DATA,
+ SPACE,
+};
+
+enum class instruction_return {
+ CONTINUE,
+ FAIL,
+ END,
+};
+
+class instruction {
+public:
+ virtual instruction_return execute(sample s, bit_string &data) const = 0;
+};
+
+class start : public instruction {
+ const uint16_t period_us_;
+ const uint16_t pulse_us_;
+
+public:
+ start(uint16_t period_us, uint16_t pulse_us) noexcept: period_us_(period_us), pulse_us_(pulse_us)
+ {}
+
+ instruction_return execute(sample s, bit_string &data) const override
+ {
+ return decoder_ns::check_pulse(s, period_us_, pulse_us_) ? instruction_return::CONTINUE
+ : instruction_return::FAIL;
+ }
+};
+
+class data : public instruction {
+ const uint16_t one_period_us_;
+ const uint16_t one_pulse_us_;
+ const uint16_t zero_period_us_;
+ const uint16_t zero_pulse_us_;
+
+public:
+ data(uint16_t one_period_us, uint16_t one_pulse_us, uint16_t zero_period_us, uint16_t zero_pulse_us) noexcept:
+ one_period_us_(one_period_us), one_pulse_us_(one_pulse_us),
+ zero_period_us_(zero_period_us), zero_pulse_us_(zero_pulse_us)
+ {}
+
+ instruction_return execute(sample s, bit_string &data) const override
+ {
+ if (decoder_ns::check_pulse(s, one_period_us_, one_pulse_us_)) {
+ data.append(true);
+ return instruction_return::CONTINUE;
+ }
+
+ if (decoder_ns::check_pulse(s, zero_period_us_, zero_pulse_us_)) {
+ data.append(false);
+ return instruction_return::CONTINUE;
+ }
+
+ return instruction_return::FAIL;
+ }
+};
+
+class end : public instruction {
+public:
+ instruction_return execute(sample s, bit_string &data) const override
+ {
+ return instruction_return::END;
+ }
+};
+
+class script_decoder : public decoder {
+
+ const instruction *const *const instructions_;
+ const int count_;
+
+public:
+ script_decoder(const instruction *const *const instructions, int count) : instructions_(instructions), count_(count)
+ {}
+
+ decoding_result decode(sample_iterator *it) override
+ {
+ printf("Script, size=%d\n", it->size());
+ bit_string data;
+
+ for (int i = 0; i < count_ && it->next(); i++) {
+ sample s = it->value();
+// printf("script: period=%d, pulse=%d\n", s.period_us, s.pulse_us);
+
+ auto &inst = instructions_[i];
+ switch (inst->execute(s, data)) {
+ case instruction_return::CONTINUE:
+ break;
+ case instruction_return::END:
+ return decoding_result{decoding_state::OK, data};
+ case instruction_return::FAIL:
+ return decoding_result{decoding_state::FAIL};
+ }
+ }
+
+ return {decoding_state::OK, data};
+ }
+};
+
+} // namespace radio_controller