protocol_cyfral.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #include "protocol_cyfral.h"
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <furi/check.h>
  5. #include <furi_hal_delay.h>
  6. #define CYFRAL_DATA_SIZE 2
  7. #define CYFRAL_MAX_PERIOD_US 230
  8. typedef enum {
  9. CYFRAL_BIT_WAIT_FRONT_HIGH,
  10. CYFRAL_BIT_WAIT_FRONT_LOW,
  11. } CyfralBitState;
  12. typedef enum {
  13. CYFRAL_WAIT_START_NIBBLE,
  14. CYFRAL_READ_NIBBLE,
  15. CYFRAL_READ_STOP_NIBBLE,
  16. } CyfralState;
  17. struct ProtocolCyfral {
  18. PulseProtocol* protocol;
  19. CyfralState state;
  20. CyfralBitState bit_state;
  21. // ready flag, key is read and valid
  22. // TODO: atomic access
  23. bool ready;
  24. // key data storage
  25. uint16_t key_data;
  26. // high + low period time
  27. uint32_t period_time;
  28. // temporary nibble storage
  29. uint8_t nibble;
  30. // data valid flag
  31. // MUST be checked only in READ_STOP_NIBBLE state
  32. bool data_valid;
  33. // nibble index, we expect 8 nibbles
  34. uint8_t index;
  35. // bit index in nibble, 4 bit per nibble
  36. uint8_t bit_index;
  37. // max period, 230us x clock per us
  38. uint32_t max_period;
  39. };
  40. static void cyfral_pulse(void* context, bool polarity, uint32_t length);
  41. static void cyfral_reset(void* context);
  42. static void cyfral_get_data(void* context, uint8_t* data, size_t length);
  43. static bool cyfral_decoded(void* context);
  44. ProtocolCyfral* protocol_cyfral_alloc() {
  45. ProtocolCyfral* cyfral = malloc(sizeof(ProtocolCyfral));
  46. cyfral_reset(cyfral);
  47. cyfral->protocol = pulse_protocol_alloc();
  48. pulse_protocol_set_context(cyfral->protocol, cyfral);
  49. pulse_protocol_set_pulse_cb(cyfral->protocol, cyfral_pulse);
  50. pulse_protocol_set_reset_cb(cyfral->protocol, cyfral_reset);
  51. pulse_protocol_set_get_data_cb(cyfral->protocol, cyfral_get_data);
  52. pulse_protocol_set_decoded_cb(cyfral->protocol, cyfral_decoded);
  53. return cyfral;
  54. }
  55. void protocol_cyfral_free(ProtocolCyfral* cyfral) {
  56. furi_assert(cyfral);
  57. pulse_protocol_free(cyfral->protocol);
  58. free(cyfral);
  59. }
  60. PulseProtocol* protocol_cyfral_get_protocol(ProtocolCyfral* cyfral) {
  61. furi_assert(cyfral);
  62. return cyfral->protocol;
  63. }
  64. static void cyfral_get_data(void* context, uint8_t* data, size_t length) {
  65. furi_assert(context);
  66. furi_check(length >= CYFRAL_DATA_SIZE);
  67. ProtocolCyfral* cyfral = context;
  68. memcpy(data, &cyfral->key_data, CYFRAL_DATA_SIZE);
  69. }
  70. static bool cyfral_decoded(void* context) {
  71. furi_assert(context);
  72. ProtocolCyfral* cyfral = context;
  73. bool decoded = cyfral->ready;
  74. return decoded;
  75. }
  76. static void cyfral_reset(void* context) {
  77. furi_assert(context);
  78. ProtocolCyfral* cyfral = context;
  79. cyfral->state = CYFRAL_WAIT_START_NIBBLE;
  80. cyfral->bit_state = CYFRAL_BIT_WAIT_FRONT_LOW;
  81. cyfral->period_time = 0;
  82. cyfral->bit_index = 0;
  83. cyfral->ready = false;
  84. cyfral->index = 0;
  85. cyfral->key_data = 0;
  86. cyfral->nibble = 0;
  87. cyfral->data_valid = true;
  88. cyfral->max_period = CYFRAL_MAX_PERIOD_US * furi_hal_delay_instructions_per_microsecond();
  89. }
  90. static bool cyfral_process_bit(
  91. ProtocolCyfral* cyfral,
  92. bool polarity,
  93. uint32_t length,
  94. bool* bit_ready,
  95. bool* bit_value) {
  96. bool result = true;
  97. *bit_ready = false;
  98. // bit start from low
  99. switch(cyfral->bit_state) {
  100. case CYFRAL_BIT_WAIT_FRONT_LOW:
  101. if(polarity == true) {
  102. cyfral->period_time += length;
  103. *bit_ready = true;
  104. if(cyfral->period_time <= cyfral->max_period) {
  105. if((cyfral->period_time / 2) > length) {
  106. *bit_value = false;
  107. } else {
  108. *bit_value = true;
  109. }
  110. } else {
  111. result = false;
  112. }
  113. cyfral->bit_state = CYFRAL_BIT_WAIT_FRONT_HIGH;
  114. } else {
  115. result = false;
  116. }
  117. break;
  118. case CYFRAL_BIT_WAIT_FRONT_HIGH:
  119. if(polarity == false) {
  120. cyfral->period_time = length;
  121. cyfral->bit_state = CYFRAL_BIT_WAIT_FRONT_LOW;
  122. } else {
  123. result = false;
  124. }
  125. break;
  126. }
  127. return result;
  128. }
  129. static void cyfral_pulse(void* context, bool polarity, uint32_t length) {
  130. furi_assert(context);
  131. ProtocolCyfral* cyfral = context;
  132. bool bit_ready;
  133. bool bit_value;
  134. if(cyfral->ready) return;
  135. switch(cyfral->state) {
  136. case CYFRAL_WAIT_START_NIBBLE:
  137. // wait for start word
  138. if(cyfral_process_bit(cyfral, polarity, length, &bit_ready, &bit_value)) {
  139. if(bit_ready) {
  140. cyfral->nibble = ((cyfral->nibble << 1) | bit_value) & 0x0F;
  141. if(cyfral->nibble == 0b0001) {
  142. cyfral->nibble = 0;
  143. cyfral->state = CYFRAL_READ_NIBBLE;
  144. }
  145. }
  146. } else {
  147. cyfral_reset(cyfral);
  148. }
  149. break;
  150. case CYFRAL_READ_NIBBLE:
  151. // read nibbles
  152. if(cyfral_process_bit(cyfral, polarity, length, &bit_ready, &bit_value)) {
  153. if(bit_ready) {
  154. cyfral->nibble = (cyfral->nibble << 1) | bit_value;
  155. cyfral->bit_index++;
  156. //convert every nibble to 2-bit index
  157. if(cyfral->bit_index == 4) {
  158. switch(cyfral->nibble) {
  159. case 0b1110:
  160. cyfral->key_data = (cyfral->key_data << 2) | 0b11;
  161. break;
  162. case 0b1101:
  163. cyfral->key_data = (cyfral->key_data << 2) | 0b10;
  164. break;
  165. case 0b1011:
  166. cyfral->key_data = (cyfral->key_data << 2) | 0b01;
  167. break;
  168. case 0b0111:
  169. cyfral->key_data = (cyfral->key_data << 2) | 0b00;
  170. break;
  171. default:
  172. cyfral->data_valid = false;
  173. break;
  174. }
  175. cyfral->nibble = 0;
  176. cyfral->bit_index = 0;
  177. cyfral->index++;
  178. }
  179. // succefully read 8 nibbles
  180. if(cyfral->index == 8) {
  181. cyfral->state = CYFRAL_READ_STOP_NIBBLE;
  182. }
  183. }
  184. } else {
  185. cyfral_reset(cyfral);
  186. }
  187. break;
  188. case CYFRAL_READ_STOP_NIBBLE:
  189. // read stop nibble
  190. if(cyfral_process_bit(cyfral, polarity, length, &bit_ready, &bit_value)) {
  191. if(bit_ready) {
  192. cyfral->nibble = ((cyfral->nibble << 1) | bit_value) & 0x0F;
  193. cyfral->bit_index++;
  194. switch(cyfral->bit_index) {
  195. case 0:
  196. case 1:
  197. case 2:
  198. case 3:
  199. break;
  200. case 4:
  201. if(cyfral->nibble == 0b0001) {
  202. // validate data
  203. if(cyfral->data_valid) {
  204. cyfral->ready = true;
  205. } else {
  206. cyfral_reset(cyfral);
  207. }
  208. } else {
  209. cyfral_reset(cyfral);
  210. }
  211. break;
  212. default:
  213. cyfral_reset(cyfral);
  214. break;
  215. }
  216. }
  217. } else {
  218. cyfral_reset(cyfral);
  219. }
  220. break;
  221. }
  222. }