diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2017-06-04 17:33:51 +0200 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2017-06-04 17:33:51 +0200 |
commit | d30e3fa68d7192da22c1569f56f564b92896170d (patch) | |
tree | fdbfbe53a9c9cb6f5136af53e17f831b069337a2 /include | |
parent | a484b095fb03313f5f192b23c90d04972ca3b957 (diff) | |
download | radio-controller-d30e3fa68d7192da22c1569f56f564b92896170d.tar.gz radio-controller-d30e3fa68d7192da22c1569f56f564b92896170d.tar.bz2 radio-controller-d30e3fa68d7192da22c1569f56f564b92896170d.tar.xz radio-controller-d30e3fa68d7192da22c1569f56f564b92896170d.zip |
o Working decoder for Samsung remotes.
Diffstat (limited to 'include')
-rw-r--r-- | include/daewoo_decoder.h | 91 | ||||
-rw-r--r-- | include/decoder.h | 77 | ||||
-rw-r--r-- | include/samsung_decoder.h | 38 |
3 files changed, 160 insertions, 46 deletions
diff --git a/include/daewoo_decoder.h b/include/daewoo_decoder.h new file mode 100644 index 0000000..b790a1a --- /dev/null +++ b/include/daewoo_decoder.h @@ -0,0 +1,91 @@ +#pragma + +#include "decoder.h" + +namespace radio_controller { + +class daewoo_decoder : public decoder { + + inline + bool between(uint16_t smallest, uint16_t biggest, uint16_t value) + { + return smallest <= value && value <= biggest; + } + + template<uint16_t PeriodTime, uint16_t PulseTime> + bool check_pulse(sample s) + { +// printf("between(%d, %d, %d) && between(%d, %d, %d)\n", +// int(PeriodTime * 0.8), int(PeriodTime * 1.2), s.period_us, +// int(PulseTime * 0.8), int(PulseTime * 1.2), s.pulse_us); + + return between(uint16_t(PeriodTime * 0.8), uint16_t(PeriodTime * 1.2), s.period_us) && + between(uint16_t(PulseTime * 0.8), uint16_t(PulseTime * 1.2), s.pulse_us); + } + + inline + bool start_bit(sample s) + { + return check_pulse<9000, 4500>(s); + } + + inline + bool one_bit(sample s) + { + return check_pulse<2250, 560>(s); + } + + inline + bool zero_bit(sample s) + { + return check_pulse<1125, 560>(s); + } + + __noinline + void dump_values(sample_iterator *it) { + while (it->next()) { + auto s = it->value(); + auto pct = int(s.pulse_us / double(s.period_us) * 100); + auto type = start_bit(s) ? "start" : one_bit(s) ? "1" : zero_bit(s) ? "0" : "?"; + printf("% 5d us % 5d us, %s\n", s.period_us, s.pulse_us, type); + } + } + +public: + + __noinline + decoding_result decode(sample_iterator *it) override + { + printf("Daewoo, 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}; + } +}; + +} // namespace radio_controller diff --git a/include/decoder.h b/include/decoder.h index 2a8c58e..55e7d96 100644 --- a/include/decoder.h +++ b/include/decoder.h @@ -2,25 +2,86 @@ namespace radio_controller { -template<typename T> -class iterator { +struct sample { + uint16_t period_us; + uint16_t pulse_us; +}; + +class sample_iterator { public: + virtual int size() = 0; + + virtual void reset() = 0; + virtual bool next() = 0; virtual bool has_next() const = 0; - virtual const T &value() const = 0; + virtual const sample &value() const = 0; }; -struct sample { - uint16_t period_us; - uint16_t pulse_us; +class bit_string final { + uint32_t a_ = 0; + uint32_t b_ = 0; + int size_ = 0; + +public: + int size() const { + return size_; + } + + uint32_t u32(int i) + { + switch (i) { + case 0: + return a_; + case 1: + return b_; + default: + return 0; + } + } + + __noinline + void append(bool value) + { + if (size_ < 32) { + if (value) { + a_ |= 1 << size_; + } + } else if (size_ < 64) { + if (value) { + b_ |= 1 << size_ - 32; + } + } else { + return; + } + size_++; + } +}; + +enum class decoding_state { + OK, + TOO_SHORT, + BAD_START, + SHORT_BODY +}; + +class decoding_result { +public: + decoding_state state; + bit_string data; + + decoding_result(decoding_state state) : state(state), data() + {} + + decoding_result(decoding_state state, bit_string data) : state(state), data(data) + {} }; -//template<typename T> class decoder { public: - virtual void decode(iterator<sample> *it) = 0; + virtual decoding_result decode(sample_iterator *it) = 0; }; } // namespace radio_controller diff --git a/include/samsung_decoder.h b/include/samsung_decoder.h deleted file mode 100644 index 5d2b555..0000000 --- a/include/samsung_decoder.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma - -#include "decoder.h" - -namespace radio_controller { - -class samsung_decoder : public decoder { - - inline - bool between(uint16_t smallest, uint16_t biggest, uint16_t value) - { - return smallest <= value && value <= biggest; - } - - inline - bool start_bit(uint16_t time) - { - return between(4200, 4700, time); - } - - inline - bool one_bit(uint16_t time) - { - return between(4200, 4700, time); - } - -public: - void decode(iterator<sample> *it) override - { - printf("Samsung\n"); - while (it->next()) { - auto s = it->value(); - printf("% 5d us % 5d us, %.02d%%\n", s.period_us, s.pulse_us, int(s.pulse_us / double(s.period_us) * 100)); - } - } -}; - -} // namespace radio_controller |