瀏覽代碼

Added oregon

Chef Thomas 7 年之前
父節點
當前提交
f3baea7a36
共有 2 個文件被更改,包括 218 次插入0 次删除
  1. 209 0
      Src/oregon.c
  2. 9 0
      Src/oregon.h

+ 209 - 0
Src/oregon.c

@@ -0,0 +1,209 @@
+class DecodeOOK {
+protected:
+    byte total_bits, bits, flip, state, pos, data[25];
+
+    virtual char decode (word width) =0;
+    
+public:
+
+    enum { UNKNOWN, T0, T1, T2, T3, OK, DONE };
+
+    DecodeOOK () { resetDecoder(); }
+
+    bool nextPulse (word width) {
+        if (state != DONE)
+        
+            switch (decode(width)) {
+                case -1: resetDecoder(); break;
+                case 1:  done(); break;
+            }
+        return isDone();
+    }
+    
+    bool isDone () const { return state == DONE; }
+
+    const byte* getData (byte& count) const {
+        count = pos;
+        return data; 
+    }
+    
+    void resetDecoder () {
+        total_bits = bits = pos = flip = 0;
+        state = UNKNOWN;
+    }
+    
+    // add one bit to the packet data buffer
+    
+    virtual void gotBit (char value) {
+        total_bits++;
+        byte *ptr = data + pos;
+        *ptr = (*ptr >> 1) | (value << 7);
+
+        if (++bits >= 8) {
+            bits = 0;
+            if (++pos >= sizeof data) {
+                resetDecoder();
+                return;
+            }
+        }
+        state = OK;
+    }
+    
+    // store a bit using Manchester encoding
+    void manchester (char value) {
+        flip ^= value; // manchester code, long pulse flips the bit
+        gotBit(flip);
+    }
+    
+    // move bits to the front so that all the bits are aligned to the end
+    void alignTail (byte max =0) {
+        // align bits
+        if (bits != 0) {
+            data[pos] >>= 8 - bits;
+            for (byte i = 0; i < pos; ++i)
+                data[i] = (data[i] >> bits) | (data[i+1] << (8 - bits));
+            bits = 0;
+        }
+        // optionally shift bytes down if there are too many of 'em
+        if (max > 0 && pos > max) {
+            byte n = pos - max;
+            pos = max;
+            for (byte i = 0; i < pos; ++i)
+                data[i] = data[i+n];
+        }
+    }
+    
+    void reverseBits () {
+        for (byte i = 0; i < pos; ++i) {
+            byte b = data[i];
+            for (byte j = 0; j < 8; ++j) {
+                data[i] = (data[i] << 1) | (b & 1);
+                b >>= 1;
+            }
+        }
+    }
+    
+    void reverseNibbles () {
+        for (byte i = 0; i < pos; ++i)
+            data[i] = (data[i] << 4) | (data[i] >> 4);
+    }
+    
+    void done () {
+        while (bits)
+            gotBit(0); // padding
+        state = DONE;
+    }
+};
+
+
+class OregonDecoderV2 : public DecodeOOK {
+public:
+    OregonDecoderV2() {}
+    
+    // add one bit to the packet data buffer
+    virtual void gotBit (char value) {
+        if(!(total_bits & 0x01))
+        {
+            data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00);
+        }
+        total_bits++;
+        pos = total_bits >> 4;
+        if (pos >= sizeof data) {
+            resetDecoder();
+            return;
+        }
+        state = OK;
+    }
+    
+    virtual char decode (word width) {
+        if (200 <= width && width < 1200) {
+            byte w = width >= 700;
+            switch (state) {
+                case UNKNOWN:
+                    if (w != 0) {
+                        // Long pulse
+                        ++flip;
+                    } else if (32 <= flip) {
+                        // Short pulse, start bit
+                        flip = 0;
+                        state = T0;
+                    } else {
+                      // Reset decoder
+                        return -1;
+                    }
+                    break;
+                case OK:
+                    if (w == 0) {
+                        // Short pulse
+                        state = T0;
+                    } else {
+                        // Long pulse
+                        manchester(1);
+                    }
+                    break;
+                case T0:
+                    if (w == 0) {
+                      // Second short pulse
+                        manchester(0);
+                    } else {
+                        // Reset decoder
+                        return -1;
+                    }
+                    break;
+            }
+        } else {
+            return -1;
+        }
+        return total_bits == 160 ? 1: 0;
+    }
+};
+
+class OregonDecoderV3 : public DecodeOOK {
+public:
+    OregonDecoderV3() {}
+    
+    // add one bit to the packet data buffer
+    virtual void gotBit (char value) {
+        data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00);
+        total_bits++;
+        pos = total_bits >> 3;
+        if (pos >= sizeof data) {
+            resetDecoder();
+            return;
+        }
+        state = OK;
+    }
+    
+    virtual char decode (word width) {
+        if (200 <= width && width < 1200) {
+            byte w = width >= 700;
+            switch (state) {
+                case UNKNOWN:
+                    if (w == 0)
+                        ++flip;
+                    else if (32 <= flip) {
+                        flip = 1;
+                        manchester(1);
+                    } else
+                        return -1;
+                    break;
+                case OK:
+                    if (w == 0)
+                        state = T0;
+                    else
+                        manchester(1);
+                    break;
+                case T0:
+                    if (w == 0)
+                        manchester(0);
+                    else
+                        return -1;
+                    break;
+            }
+        } else {
+            return -1;
+        }
+        return  total_bits == 80 ? 1: 0;
+    }
+};
+

+ 9 - 0
Src/oregon.h

@@ -0,0 +1,9 @@
+#ifndef __OREGON1__
+#define __OREGON1__
+
+#include "app.h"
+
+
+
+
+#endif