decoder-hid26.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include "decoder-hid26.h"
  2. #include <api-hal.h>
  3. constexpr uint32_t clocks_in_us = 64;
  4. constexpr uint32_t jitter_time_us = 20;
  5. constexpr uint32_t min_time_us = 64;
  6. constexpr uint32_t max_time_us = 80;
  7. constexpr uint32_t min_time = (min_time_us - jitter_time_us) * clocks_in_us;
  8. constexpr uint32_t mid_time = ((max_time_us - min_time_us) / 2 + min_time_us) * clocks_in_us;
  9. constexpr uint32_t max_time = (max_time_us + jitter_time_us) * clocks_in_us;
  10. bool DecoderHID26::read(uint8_t* data, uint8_t data_size) {
  11. bool result = false;
  12. furi_assert(data_size >= 3);
  13. if(ready) {
  14. result = true;
  15. data[0] = facility;
  16. data[1] = (uint8_t)(number >> 8);
  17. data[2] = (uint8_t)number;
  18. //printf("HID %02X %02X %02X\r\n", facility, (uint8_t)(number >> 8), (uint8_t)number);
  19. ready = false;
  20. }
  21. return result;
  22. }
  23. void DecoderHID26::process_front(bool polarity, uint32_t time) {
  24. if(ready) return;
  25. if(polarity == true) {
  26. last_pulse_time = time;
  27. } else {
  28. last_pulse_time += time;
  29. if(last_pulse_time > min_time && last_pulse_time < max_time) {
  30. bool pulse;
  31. if(last_pulse_time < mid_time) {
  32. // 6 pulses
  33. pulse = false;
  34. } else {
  35. // 5 pulses
  36. pulse = true;
  37. }
  38. if(last_pulse == pulse) {
  39. pulse_count++;
  40. if(pulse) {
  41. if(pulse_count > 4) {
  42. pulse_count = 0;
  43. store_data(1);
  44. }
  45. } else {
  46. if(pulse_count > 5) {
  47. pulse_count = 0;
  48. store_data(0);
  49. }
  50. }
  51. } else {
  52. if(last_pulse) {
  53. if(pulse_count > 2) {
  54. store_data(1);
  55. }
  56. } else {
  57. if(pulse_count > 3) {
  58. store_data(0);
  59. }
  60. }
  61. pulse_count = 0;
  62. last_pulse = pulse;
  63. }
  64. }
  65. }
  66. }
  67. DecoderHID26::DecoderHID26() {
  68. reset_state();
  69. }
  70. void DecoderHID26::store_data(bool data) {
  71. stored_data[0] = (stored_data[0] << 1) | ((stored_data[1] >> 31) & 1);
  72. stored_data[1] = (stored_data[1] << 1) | ((stored_data[2] >> 31) & 1);
  73. stored_data[2] = (stored_data[2] << 1) | data;
  74. validate_stored_data();
  75. }
  76. void DecoderHID26::validate_stored_data() {
  77. // packet preamble
  78. // raw data
  79. if(*(reinterpret_cast<uint8_t*>(stored_data) + 3) != 0x1D) {
  80. return;
  81. }
  82. // encoded company/oem
  83. // coded with 01 = 0, 10 = 1 transitions
  84. // stored in word 0
  85. if((*stored_data >> 10 & 0x3FFF) != 0x1556) {
  86. return;
  87. }
  88. // encoded format/length
  89. // coded with 01 = 0, 10 = 1 transitions
  90. // stored in word 0 and word 1
  91. if((((*stored_data & 0x3FF) << 12) | ((*(stored_data + 1) >> 20) & 0xFFF)) != 0x155556) {
  92. return;
  93. }
  94. // data decoding
  95. uint32_t result = 0;
  96. // decode from word 1
  97. // coded with 01 = 0, 10 = 1 transitions
  98. for(int8_t i = 9; i >= 0; i--) {
  99. switch((*(stored_data + 1) >> (2 * i)) & 0b11) {
  100. case 0b01:
  101. result = (result << 1) | 0;
  102. break;
  103. case 0b10:
  104. result = (result << 1) | 1;
  105. break;
  106. default:
  107. return;
  108. break;
  109. }
  110. }
  111. // decode from word 2
  112. // coded with 01 = 0, 10 = 1 transitions
  113. for(int8_t i = 15; i >= 0; i--) {
  114. switch((*(stored_data + 2) >> (2 * i)) & 0b11) {
  115. case 0b01:
  116. result = (result << 1) | 0;
  117. break;
  118. case 0b10:
  119. result = (result << 1) | 1;
  120. break;
  121. default:
  122. return;
  123. break;
  124. }
  125. }
  126. // store decoded data
  127. facility = result >> 17;
  128. number = result >> 1;
  129. // trailing parity (odd) test
  130. uint8_t parity_sum = 0;
  131. for(int8_t i = 0; i < 13; i++) {
  132. if(((result >> i) & 1) == 1) {
  133. parity_sum++;
  134. }
  135. }
  136. if((parity_sum % 2) != 1) {
  137. return;
  138. }
  139. // leading parity (even) test
  140. parity_sum = 0;
  141. for(int8_t i = 13; i < 26; i++) {
  142. if(((result >> i) & 1) == 1) {
  143. parity_sum++;
  144. }
  145. }
  146. if((parity_sum % 2) == 1) {
  147. return;
  148. }
  149. ready = true;
  150. }
  151. void DecoderHID26::reset_state() {
  152. last_pulse = false;
  153. pulse_count = 0;
  154. ready = false;
  155. last_pulse_time = 0;
  156. }