diff options
Diffstat (limited to 'include/script_decoder.h')
-rw-r--r-- | include/script_decoder.h | 110 |
1 files changed, 110 insertions, 0 deletions
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 |