subghz_protocol_kia.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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. }
  71. break;
  72. case KIADecoderStepCheckPreambula:
  73. if(!level) {
  74. if((DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) ||
  75. (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
  76. instance->common.te_last = duration;
  77. } else {
  78. instance->common.parser_step = KIADecoderStepReset;
  79. }
  80. } else if(
  81. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) &&
  82. (DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
  83. instance->common.te_delta)) {
  84. // Found header
  85. instance->common.header_count++;
  86. break;
  87. } else if(
  88. (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta) &&
  89. (DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
  90. instance->common.te_delta)) {
  91. // Found start bit
  92. if(instance->common.header_count > 15) {
  93. instance->common.parser_step = KIADecoderStepSaveDuration;
  94. instance->common.code_found = 0;
  95. instance->common.code_count_bit = 1;
  96. subghz_protocol_common_add_bit(&instance->common, 1);
  97. } else {
  98. instance->common.parser_step = KIADecoderStepReset;
  99. }
  100. } else {
  101. instance->common.parser_step = KIADecoderStepReset;
  102. }
  103. break;
  104. case KIADecoderStepSaveDuration:
  105. if(!level) {
  106. if(duration >= (instance->common.te_long + instance->common.te_delta * 2)) {
  107. //Found stop bit
  108. instance->common.parser_step = KIADecoderStepReset;
  109. if(instance->common.code_count_bit >=
  110. instance->common.code_min_count_bit_for_found) {
  111. instance->common.code_last_found = instance->common.code_found;
  112. instance->common.code_last_count_bit = instance->common.code_count_bit;
  113. if(instance->common.callback)
  114. instance->common.callback(
  115. (SubGhzProtocolCommon*)instance, instance->common.context);
  116. }
  117. instance->common.code_found = 0;
  118. instance->common.code_count_bit = 0;
  119. break;
  120. } else {
  121. instance->common.te_last = duration;
  122. instance->common.parser_step = KIADecoderStepCheckDuration;
  123. }
  124. } else {
  125. instance->common.parser_step = KIADecoderStepReset;
  126. }
  127. break;
  128. case KIADecoderStepCheckDuration:
  129. if(level) {
  130. if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
  131. instance->common.te_delta) &&
  132. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  133. subghz_protocol_common_add_bit(&instance->common, 0);
  134. instance->common.parser_step = KIADecoderStepSaveDuration;
  135. } else if(
  136. (DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
  137. instance->common.te_delta) &&
  138. (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
  139. subghz_protocol_common_add_bit(&instance->common, 1);
  140. instance->common.parser_step = KIADecoderStepSaveDuration;
  141. } else {
  142. instance->common.parser_step = KIADecoderStepReset;
  143. }
  144. } else {
  145. instance->common.parser_step = KIADecoderStepReset;
  146. }
  147. break;
  148. }
  149. }
  150. void subghz_protocol_kia_to_str(SubGhzProtocolKIA* instance, string_t output) {
  151. uint32_t code_found_hi = instance->common.code_last_found >> 32;
  152. uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
  153. string_cat_printf(
  154. output,
  155. "%s %dbit\r\n"
  156. "Key:%08lX%08lX\r\n"
  157. "Sn:%07lX Btn:%lX Cnt:%04X\r\n",
  158. instance->common.name,
  159. instance->common.code_last_count_bit,
  160. code_found_hi,
  161. code_found_lo,
  162. instance->common.serial,
  163. instance->common.btn,
  164. instance->common.cnt);
  165. }
  166. void subghz_decoder_kia_to_load_protocol(SubGhzProtocolKIA* instance, void* context) {
  167. furi_assert(context);
  168. furi_assert(instance);
  169. SubGhzProtocolCommonLoad* data = context;
  170. instance->common.code_last_found = data->code_found;
  171. instance->common.code_last_count_bit = data->code_count_bit;
  172. subghz_protocol_kia_check_remote_controller(instance);
  173. }