cyfral_decoder.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include "cyfral_decoder.h"
  2. #include <furi.h>
  3. void CyfralDecoder::reset_state() {
  4. state = State::WAIT_START_NIBBLE;
  5. bit_state = BitState::WAIT_FRONT_LOW;
  6. period_time = 0;
  7. bit_index = 0;
  8. ready = false;
  9. index = 0;
  10. key_data = 0;
  11. readed_nibble = 0;
  12. data_valid = true;
  13. }
  14. bool CyfralDecoder::nibble_valid(uint8_t data) {
  15. uint8_t data_value = data & 0x0F;
  16. switch(data_value) {
  17. case 0b1110:
  18. case 0b1101:
  19. case 0b1011:
  20. case 0b0111:
  21. return true;
  22. break;
  23. default:
  24. return false;
  25. }
  26. }
  27. CyfralDecoder::CyfralDecoder() {
  28. reset_state();
  29. max_period = 0;
  30. }
  31. void CyfralDecoder::process_front(bool polarity, uint32_t time) {
  32. bool readed;
  33. bool value;
  34. if(max_period == 0) {
  35. max_period = 230 * (SystemCoreClock / 1000000.0f);
  36. }
  37. if(ready) return;
  38. switch(state) {
  39. case State::WAIT_START_NIBBLE:
  40. // wait for start word
  41. if(process_bit(polarity, time, &readed, &value)) {
  42. if(readed) {
  43. readed_nibble = ((readed_nibble << 1) | value) & 0x0F;
  44. if(readed_nibble == 0b0001) {
  45. readed_nibble = 0;
  46. state = State::READ_NIBBLE;
  47. }
  48. }
  49. } else {
  50. reset_state();
  51. }
  52. break;
  53. case State::READ_NIBBLE:
  54. // read nibbles
  55. if(process_bit(polarity, time, &readed, &value)) {
  56. if(readed) {
  57. readed_nibble = (readed_nibble << 1) | value;
  58. bit_index++;
  59. //convert every nibble to 2-bit index
  60. if(bit_index == 4) {
  61. switch(readed_nibble) {
  62. case 0b1110:
  63. key_data = (key_data << 2) | 0b11;
  64. break;
  65. case 0b1101:
  66. key_data = (key_data << 2) | 0b10;
  67. break;
  68. case 0b1011:
  69. key_data = (key_data << 2) | 0b01;
  70. break;
  71. case 0b0111:
  72. key_data = (key_data << 2) | 0b00;
  73. break;
  74. default:
  75. data_valid = false;
  76. break;
  77. }
  78. readed_nibble = 0;
  79. bit_index = 0;
  80. index++;
  81. }
  82. // succefully read 8 nibbles
  83. if(index == 8) {
  84. state = State::READ_STOP_NIBBLE;
  85. }
  86. }
  87. } else {
  88. reset_state();
  89. }
  90. break;
  91. case State::READ_STOP_NIBBLE:
  92. // read stop nibble
  93. if(process_bit(polarity, time, &readed, &value)) {
  94. if(readed) {
  95. readed_nibble = ((readed_nibble << 1) | value) & 0x0F;
  96. bit_index++;
  97. switch(bit_index) {
  98. case 0:
  99. case 1:
  100. case 2:
  101. case 3:
  102. break;
  103. case 4:
  104. if(readed_nibble == 0b0001) {
  105. // validate data
  106. if(data_valid) {
  107. ready = true;
  108. } else {
  109. reset_state();
  110. }
  111. } else {
  112. reset_state();
  113. }
  114. break;
  115. default:
  116. reset_state();
  117. break;
  118. }
  119. }
  120. } else {
  121. reset_state();
  122. }
  123. break;
  124. }
  125. }
  126. bool CyfralDecoder::process_bit(bool polarity, uint32_t time, bool* readed, bool* readed_value) {
  127. bool result = true;
  128. *readed = false;
  129. // bit start from low
  130. switch(bit_state) {
  131. case BitState::WAIT_FRONT_LOW:
  132. if(polarity == true) {
  133. period_time += time;
  134. *readed = true;
  135. if(period_time <= max_period) {
  136. if((period_time / 2) > time) {
  137. *readed_value = false;
  138. } else {
  139. *readed_value = true;
  140. }
  141. } else {
  142. result = false;
  143. }
  144. bit_state = BitState::WAIT_FRONT_HIGH;
  145. } else {
  146. result = false;
  147. }
  148. break;
  149. case BitState::WAIT_FRONT_HIGH:
  150. if(polarity == false) {
  151. period_time = time;
  152. bit_state = BitState::WAIT_FRONT_LOW;
  153. } else {
  154. result = false;
  155. }
  156. break;
  157. }
  158. return result;
  159. }
  160. bool CyfralDecoder::read(uint8_t* _data, uint8_t data_size) {
  161. furi_check(data_size <= 2);
  162. bool result = false;
  163. if(ready) {
  164. memcpy(_data, &key_data, data_size);
  165. reset_state();
  166. result = true;
  167. }
  168. return result;
  169. }