123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- 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;
- }
- };
|