oregon.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include "app.h"
  2. #include "nexa.h"
  3. #include "oregon.h"
  4. // Constructor must run resetDecoder()
  5. unsigned char total_bits, bits, flip, state, pos, data[25];
  6. enum { UNKNOWN, T0, T1, T2, T3, OK, DONE };
  7. boolean nextPulse (unsigned short width) {
  8. if (state != DONE)
  9. switch (decode(width)) {
  10. case -1: resetDecoder(); break;
  11. case 1: done(); break;
  12. }
  13. return isDone();
  14. }
  15. boolean isDone() {
  16. return state == DONE;
  17. }
  18. const unsigned char* getData (unsigned char& count) {
  19. count = pos;
  20. return data;
  21. }
  22. void resetDecoder () {
  23. total_bits = bits = pos = flip = 0;
  24. state = UNKNOWN;
  25. }
  26. // add one bit to the packet data buffer
  27. virtual void gotBit (unsigned char value) {
  28. total_bits++;
  29. byte *ptr = data + pos;
  30. *ptr = (*ptr >> 1) | (value << 7);
  31. if (++bits >= 8) {
  32. bits = 0;
  33. if (++pos >= sizeof data) {
  34. resetDecoder();
  35. return;
  36. }
  37. }
  38. state = OK;
  39. }
  40. // store a bit using Manchester encoding
  41. void manchester (char value) {
  42. flip ^= value; // manchester code, long pulse flips the bit
  43. gotBit(flip);
  44. }
  45. // move bits to the front so that all the bits are aligned to the end
  46. void alignTail (byte max =0) {
  47. // align bits
  48. if (bits != 0) {
  49. data[pos] >>= 8 - bits;
  50. for (byte i = 0; i < pos; ++i)
  51. data[i] = (data[i] >> bits) | (data[i+1] << (8 - bits));
  52. bits = 0;
  53. }
  54. // optionally shift bytes down if there are too many of 'em
  55. if (max > 0 && pos > max) {
  56. byte n = pos - max;
  57. pos = max;
  58. for (byte i = 0; i < pos; ++i)
  59. data[i] = data[i+n];
  60. }
  61. }
  62. void reverseBits () {
  63. for (byte i = 0; i < pos; ++i) {
  64. byte b = data[i];
  65. for (byte j = 0; j < 8; ++j) {
  66. data[i] = (data[i] << 1) | (b & 1);
  67. b >>= 1;
  68. }
  69. }
  70. }
  71. void reverseNibbles () {
  72. for (byte i = 0; i < pos; ++i)
  73. data[i] = (data[i] << 4) | (data[i] >> 4);
  74. }
  75. void done () {
  76. while (bits)
  77. gotBit(0); // padding
  78. state = DONE;
  79. }
  80. // add one bit to the packet data buffer
  81. void gotBit (char value) {
  82. data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00);
  83. total_bits++;
  84. pos = total_bits >> 3;
  85. if (pos >= sizeof data) {
  86. resetDecoder();
  87. return;
  88. }
  89. state = OK;
  90. }
  91. virtual char decode (word width) {
  92. if (200 <= width && width < 1200) {
  93. byte w = width >= 700;
  94. switch (state) {
  95. case UNKNOWN:
  96. if (w == 0)
  97. ++flip;
  98. else if (32 <= flip) {
  99. flip = 1;
  100. manchester(1);
  101. } else
  102. return -1;
  103. break;
  104. case OK:
  105. if (w == 0)
  106. state = T0;
  107. else
  108. manchester(1);
  109. break;
  110. case T0:
  111. if (w == 0)
  112. manchester(0);
  113. else
  114. return -1;
  115. break;
  116. }
  117. } else {
  118. return -1;
  119. }
  120. return total_bits == 80 ? 1: 0;
  121. }