subghz_protocol_kia.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #include "subghz_protocol_kia.h"
  2. struct SubGhzProtocolKIA {
  3. SubGhzProtocolCommon common;
  4. };
  5. typedef enum {
  6. KIADecoderStepReset = 0,
  7. KIADecoderStepCheckPreambula,
  8. KIADecoderStepSaveDuration,
  9. KIADecoderStepCheckDuration,
  10. } KIADecoderStep;
  11. SubGhzProtocolKIA* subghz_protocol_kia_alloc(void) {
  12. SubGhzProtocolKIA* instance = furi_alloc(sizeof(SubGhzProtocolKIA));
  13. instance->common.name = "KIA";
  14. instance->common.code_min_count_bit_for_found = 60;
  15. instance->common.te_short = 250;
  16. instance->common.te_long = 500;
  17. instance->common.te_delta = 100;
  18. instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic;
  19. instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_kia_to_str;
  20. instance->common.to_load_protocol =
  21. (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_kia_to_load_protocol;
  22. return instance;
  23. }
  24. void subghz_protocol_kia_free(SubGhzProtocolKIA* instance) {
  25. furi_assert(instance);
  26. free(instance);
  27. }
  28. void subghz_protocol_kia_reset(SubGhzProtocolKIA* instance) {
  29. instance->common.parser_step = KIADecoderStepReset;
  30. }
  31. uint8_t subghz_protocol_kia_crc8(uint8_t* data, size_t len) {
  32. uint8_t crc = 0x08;
  33. size_t i, j;
  34. for(i = 0; i < len; i++) {
  35. crc ^= data[i];
  36. for(j = 0; j < 8; j++) {
  37. if((crc & 0x80) != 0)
  38. crc = (uint8_t)((crc << 1) ^ 0x7F);
  39. else
  40. crc <<= 1;
  41. }
  42. }
  43. return crc;
  44. }
  45. /** Analysis of received data
  46. *
  47. * @param instance SubGhzProtocolKIA instance
  48. */
  49. void subghz_protocol_kia_check_remote_controller(SubGhzProtocolKIA* instance) {
  50. /*
  51. * 0x0F 0112 43B04EC 1 7D
  52. * 0x0F 0113 43B04EC 1 DF
  53. * 0x0F 0114 43B04EC 1 30
  54. * 0x0F 0115 43B04EC 2 13
  55. * 0x0F 0116 43B04EC 3 F5
  56. * CNT Serial K CRC8 Kia (CRC8, poly 0x7f, start_crc 0x08)
  57. */
  58. instance->common.serial = (uint32_t)((instance->common.code_last_found >> 12) & 0x0FFFFFFF);
  59. instance->common.btn = (instance->common.code_last_found >> 8) & 0x0F;
  60. instance->common.cnt = (instance->common.code_last_found >> 40) & 0xFFFF;
  61. }
  62. void subghz_protocol_kia_parse(SubGhzProtocolKIA* instance, bool level, uint32_t duration) {
  63. switch(instance->common.parser_step) {
  64. case KIADecoderStepReset:
  65. if((!level) &&
  66. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  67. instance->common.parser_step = KIADecoderStepCheckPreambula;
  68. instance->common.te_last = duration;
  69. instance->common.header_count = 0;
  70. } else {
  71. instance->common.parser_step = KIADecoderStepReset;
  72. }
  73. break;
  74. case KIADecoderStepCheckPreambula:
  75. if(!level) {
  76. if((DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) ||
  77. (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
  78. instance->common.te_last = duration;
  79. } else {
  80. instance->common.parser_step = KIADecoderStepReset;
  81. }
  82. } else if(
  83. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) &&
  84. (DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
  85. instance->common.te_delta)) {
  86. // Found header
  87. instance->common.header_count++;
  88. break;
  89. } else if(
  90. (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta) &&
  91. (DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
  92. instance->common.te_delta)) {
  93. // Found start bit
  94. if(instance->common.header_count > 15) {
  95. instance->common.parser_step = KIADecoderStepSaveDuration;
  96. instance->common.code_found = 0;
  97. instance->common.code_count_bit = 1;
  98. subghz_protocol_common_add_bit(&instance->common, 1);
  99. } else {
  100. instance->common.parser_step = KIADecoderStepReset;
  101. }
  102. } else {
  103. instance->common.parser_step = KIADecoderStepReset;
  104. }
  105. break;
  106. case KIADecoderStepSaveDuration:
  107. if(!level) {
  108. if(duration >= (instance->common.te_long + instance->common.te_delta * 2)) {
  109. //Found stop bit
  110. instance->common.parser_step = KIADecoderStepReset;
  111. if(instance->common.code_count_bit >=
  112. instance->common.code_min_count_bit_for_found) {
  113. instance->common.code_last_found = instance->common.code_found;
  114. instance->common.code_last_count_bit = instance->common.code_count_bit;
  115. if(instance->common.callback)
  116. instance->common.callback(
  117. (SubGhzProtocolCommon*)instance, instance->common.context);
  118. }
  119. instance->common.code_found = 0;
  120. instance->common.code_count_bit = 0;
  121. break;
  122. } else {
  123. instance->common.te_last = duration;
  124. instance->common.parser_step = KIADecoderStepCheckDuration;
  125. }
  126. } else {
  127. instance->common.parser_step = KIADecoderStepReset;
  128. }
  129. break;
  130. case KIADecoderStepCheckDuration:
  131. if(level) {
  132. if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
  133. instance->common.te_delta) &&
  134. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  135. subghz_protocol_common_add_bit(&instance->common, 0);
  136. instance->common.parser_step = KIADecoderStepSaveDuration;
  137. } else if(
  138. (DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
  139. instance->common.te_delta) &&
  140. (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
  141. subghz_protocol_common_add_bit(&instance->common, 1);
  142. instance->common.parser_step = KIADecoderStepSaveDuration;
  143. } else {
  144. instance->common.parser_step = KIADecoderStepReset;
  145. }
  146. } else {
  147. instance->common.parser_step = KIADecoderStepReset;
  148. }
  149. break;
  150. }
  151. }
  152. void subghz_protocol_kia_to_str(SubGhzProtocolKIA* instance, string_t output) {
  153. uint32_t code_found_hi = instance->common.code_last_found >> 32;
  154. uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
  155. string_cat_printf(
  156. output,
  157. "%s %dbit\r\n"
  158. "Key:%08lX%08lX\r\n"
  159. "Sn:%07lX Btn:%lX Cnt:%04X\r\n",
  160. instance->common.name,
  161. instance->common.code_last_count_bit,
  162. code_found_hi,
  163. code_found_lo,
  164. instance->common.serial,
  165. instance->common.btn,
  166. instance->common.cnt);
  167. }
  168. void subghz_decoder_kia_to_load_protocol(SubGhzProtocolKIA* instance, void* context) {
  169. furi_assert(context);
  170. furi_assert(instance);
  171. SubGhzProtocolCommonLoad* data = context;
  172. instance->common.code_last_found = data->code_found;
  173. instance->common.code_last_count_bit = data->code_count_bit;
  174. subghz_protocol_kia_check_remote_controller(instance);
  175. }