decoder-emmarine.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #include "emmarine.h"
  2. #include "decoder-emmarine.h"
  3. #include <furi.h>
  4. #include <api-hal.h>
  5. constexpr uint32_t clocks_in_us = 64;
  6. constexpr uint32_t short_time = 255 * clocks_in_us;
  7. constexpr uint32_t long_time = 510 * clocks_in_us;
  8. constexpr uint32_t jitter_time = 100 * clocks_in_us;
  9. constexpr uint32_t short_time_low = short_time - jitter_time;
  10. constexpr uint32_t short_time_high = short_time + jitter_time;
  11. constexpr uint32_t long_time_low = long_time - jitter_time;
  12. constexpr uint32_t long_time_high = long_time + jitter_time;
  13. void DecoderEMMarine::reset_state() {
  14. ready = false;
  15. readed_data = 0;
  16. manchester_advance(
  17. manchester_saved_state, ManchesterEventReset, &manchester_saved_state, nullptr);
  18. }
  19. void printEM_raw(uint64_t data) {
  20. // header
  21. for(uint8_t i = 0; i < 9; i++) {
  22. printf("%u ", data & (1LLU << 63) ? 1 : 0);
  23. data = data << 1;
  24. }
  25. printf("\r\n");
  26. // nibbles
  27. for(uint8_t r = 0; r < 11; r++) {
  28. printf(" ");
  29. uint8_t value = 0;
  30. for(uint8_t i = 0; i < 5; i++) {
  31. printf("%u ", data & (1LLU << 63) ? 1 : 0);
  32. if(i < 4) value = (value << 1) | (data & (1LLU << 63) ? 1 : 0);
  33. data = data << 1;
  34. }
  35. printf("0x%X", value);
  36. printf("\r\n");
  37. }
  38. }
  39. void printEM_data(uint64_t data) {
  40. printf("EM ");
  41. // header
  42. for(uint8_t i = 0; i < 9; i++) {
  43. data = data << 1;
  44. }
  45. // nibbles
  46. for(uint8_t r = 0; r < EM_ROW_COUNT; r++) {
  47. uint8_t value = 0;
  48. for(uint8_t i = 0; i < 5; i++) {
  49. if(i < 4) value = (value << 1) | (data & (1LLU << 63) ? 1 : 0);
  50. data = data << 1;
  51. }
  52. printf("%X", value);
  53. if(r % 2) printf(" ");
  54. }
  55. printf("\r\n");
  56. }
  57. void copyEM_data(uint64_t data, uint8_t* result, uint8_t result_size) {
  58. furi_assert(result_size >= 5);
  59. uint8_t result_index = 0;
  60. // clean result
  61. memset(result, 0, result_size);
  62. // header
  63. for(uint8_t i = 0; i < 9; i++) {
  64. data = data << 1;
  65. }
  66. // nibbles
  67. uint8_t value = 0;
  68. for(uint8_t r = 0; r < EM_ROW_COUNT; r++) {
  69. uint8_t nibble = 0;
  70. for(uint8_t i = 0; i < 5; i++) {
  71. if(i < 4) nibble = (nibble << 1) | (data & (1LLU << 63) ? 1 : 0);
  72. data = data << 1;
  73. }
  74. value = (value << 4) | nibble;
  75. if(r % 2) {
  76. result[result_index] |= value;
  77. result_index++;
  78. value = 0;
  79. }
  80. }
  81. }
  82. bool DecoderEMMarine::read(uint8_t* data, uint8_t data_size) {
  83. bool result = false;
  84. if(ready) {
  85. result = true;
  86. copyEM_data(readed_data, data, data_size);
  87. ready = false;
  88. }
  89. return result;
  90. }
  91. void DecoderEMMarine::process_front(bool polarity, uint32_t time) {
  92. if(ready) return;
  93. if(time < short_time_low) return;
  94. ManchesterEvent event = ManchesterEventReset;
  95. if(time > short_time_low && time < short_time_high) {
  96. if(polarity) {
  97. event = ManchesterEventShortHigh;
  98. } else {
  99. event = ManchesterEventShortLow;
  100. }
  101. } else if(time > long_time_low && time < long_time_high) {
  102. if(polarity) {
  103. event = ManchesterEventLongHigh;
  104. } else {
  105. event = ManchesterEventLongLow;
  106. }
  107. }
  108. if(event != ManchesterEventReset) {
  109. bool data;
  110. bool data_ok =
  111. manchester_advance(manchester_saved_state, event, &manchester_saved_state, &data);
  112. if(data_ok) {
  113. readed_data = (readed_data << 1) | data;
  114. // header and stop bit
  115. if((readed_data & EM_HEADER_AND_STOP_MASK) != EM_HEADER_AND_STOP_DATA) return;
  116. // row parity
  117. for(uint8_t i = 0; i < EM_ROW_COUNT; i++) {
  118. uint8_t parity_sum = 0;
  119. for(uint8_t j = 0; j < 5; j++) {
  120. parity_sum += (readed_data >> (EM_FIRST_ROW_POS - i * 5 + j)) & 1;
  121. }
  122. if((parity_sum % 2)) {
  123. return;
  124. }
  125. }
  126. // columns parity
  127. for(uint8_t i = 0; i < 4; i++) {
  128. uint8_t parity_sum = 0;
  129. for(uint8_t j = 0; j < EM_ROW_COUNT + 1; j++) {
  130. parity_sum += (readed_data >> (EM_COLUMN_POS - i + j * 5)) & 1;
  131. }
  132. if((parity_sum % 2)) {
  133. return;
  134. }
  135. }
  136. // checks ok
  137. ready = true;
  138. }
  139. }
  140. }
  141. DecoderEMMarine::DecoderEMMarine() {
  142. reset_state();
  143. }