summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/daewoo_decoder.h91
-rw-r--r--include/decoder.h77
-rw-r--r--include/samsung_decoder.h38
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