subghz_protocol_hormann.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include "subghz_protocol_hormann.h"
  2. #include "subghz_protocol_common.h"
  3. struct SubGhzProtocolHormann {
  4. SubGhzProtocolCommon common;
  5. };
  6. typedef enum {
  7. HormannDecoderStepReset = 0,
  8. HormannDecoderStepFoundStartHeader,
  9. HormannDecoderStepFoundHeader,
  10. HormannDecoderStepFoundStartBit,
  11. HormannDecoderStepSaveDuration,
  12. HormannDecoderStepCheckDuration,
  13. } HormannDecoderStep;
  14. SubGhzProtocolHormann* subghz_protocol_hormann_alloc() {
  15. SubGhzProtocolHormann* instance = furi_alloc(sizeof(SubGhzProtocolHormann));
  16. instance->common.name = "Hormann HSM";
  17. instance->common.code_min_count_bit_for_found = 44;
  18. instance->common.te_short = 511;
  19. instance->common.te_long = 1022;
  20. instance->common.te_delta = 200;
  21. instance->common.type_protocol = SubGhzProtocolCommonTypeStatic;
  22. instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_hormann_to_str;
  23. instance->common.to_save_file =
  24. (SubGhzProtocolCommonSaveFile)subghz_protocol_hormann_to_save_file;
  25. instance->common.to_load_protocol_from_file =
  26. (SubGhzProtocolCommonLoadFromFile)subghz_protocol_hormann_to_load_protocol_from_file;
  27. instance->common.to_load_protocol =
  28. (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_hormann_to_load_protocol;
  29. instance->common.get_upload_protocol =
  30. (SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_hormann_send_key;
  31. return instance;
  32. }
  33. void subghz_protocol_hormann_free(SubGhzProtocolHormann* instance) {
  34. furi_assert(instance);
  35. free(instance);
  36. }
  37. bool subghz_protocol_hormann_send_key(
  38. SubGhzProtocolHormann* instance,
  39. SubGhzProtocolCommonEncoder* encoder) {
  40. furi_assert(instance);
  41. furi_assert(encoder);
  42. size_t index = 0;
  43. encoder->size_upload = 3 + (instance->common.code_last_count_bit * 2 + 2) * 20 + 1;
  44. if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
  45. //Send header
  46. encoder->upload[index++] =
  47. level_duration_make(false, (uint32_t)instance->common.te_short * 64);
  48. encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short * 64);
  49. encoder->upload[index++] =
  50. level_duration_make(false, (uint32_t)instance->common.te_short * 64);
  51. encoder->repeat = 10;
  52. for(size_t repeat = 0; repeat < 20; repeat++) {
  53. //Send start bit
  54. encoder->upload[index++] =
  55. level_duration_make(true, (uint32_t)instance->common.te_short * 24);
  56. encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
  57. //Send key data
  58. for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
  59. if(bit_read(instance->common.code_last_found, i - 1)) {
  60. //send bit 1
  61. encoder->upload[index++] =
  62. level_duration_make(true, (uint32_t)instance->common.te_long);
  63. encoder->upload[index++] =
  64. level_duration_make(false, (uint32_t)instance->common.te_short);
  65. } else {
  66. //send bit 0
  67. encoder->upload[index++] =
  68. level_duration_make(true, (uint32_t)instance->common.te_short);
  69. encoder->upload[index++] =
  70. level_duration_make(false, (uint32_t)instance->common.te_long);
  71. }
  72. }
  73. }
  74. encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short * 24);
  75. return true;
  76. }
  77. void subghz_protocol_hormann_reset(SubGhzProtocolHormann* instance) {
  78. instance->common.parser_step = HormannDecoderStepReset;
  79. }
  80. void subghz_protocol_hormann_parse(SubGhzProtocolHormann* instance, bool level, uint32_t duration) {
  81. switch(instance->common.parser_step) {
  82. case HormannDecoderStepReset:
  83. if((level) && (DURATION_DIFF(duration, instance->common.te_short * 64) <
  84. instance->common.te_delta * 64)) {
  85. instance->common.parser_step = HormannDecoderStepFoundStartHeader;
  86. }
  87. break;
  88. case HormannDecoderStepFoundStartHeader:
  89. if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 64) <
  90. instance->common.te_delta * 64)) {
  91. instance->common.parser_step = HormannDecoderStepFoundHeader;
  92. } else {
  93. instance->common.parser_step = HormannDecoderStepReset;
  94. }
  95. break;
  96. case HormannDecoderStepFoundHeader:
  97. if((level) && (DURATION_DIFF(duration, instance->common.te_short * 24) <
  98. instance->common.te_delta * 24)) {
  99. instance->common.parser_step = HormannDecoderStepFoundStartBit;
  100. } else {
  101. instance->common.parser_step = HormannDecoderStepReset;
  102. }
  103. break;
  104. case HormannDecoderStepFoundStartBit:
  105. if((!level) &&
  106. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  107. instance->common.parser_step = HormannDecoderStepSaveDuration;
  108. instance->common.code_found = 0;
  109. instance->common.code_count_bit = 0;
  110. } else {
  111. instance->common.parser_step = HormannDecoderStepReset;
  112. }
  113. break;
  114. case HormannDecoderStepSaveDuration:
  115. if(level) { //save interval
  116. if(duration >= (instance->common.te_short * 5)) {
  117. instance->common.parser_step = HormannDecoderStepFoundStartBit;
  118. if(instance->common.code_count_bit >=
  119. instance->common.code_min_count_bit_for_found) {
  120. instance->common.serial = 0x0;
  121. instance->common.btn = 0x0;
  122. instance->common.code_last_found = instance->common.code_found;
  123. instance->common.code_last_count_bit = instance->common.code_count_bit;
  124. if(instance->common.callback)
  125. instance->common.callback(
  126. (SubGhzProtocolCommon*)instance, instance->common.context);
  127. }
  128. break;
  129. }
  130. instance->common.te_last = duration;
  131. instance->common.parser_step = HormannDecoderStepCheckDuration;
  132. } else {
  133. instance->common.parser_step = HormannDecoderStepReset;
  134. }
  135. break;
  136. case HormannDecoderStepCheckDuration:
  137. if(!level) {
  138. if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
  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, 0);
  142. instance->common.parser_step = HormannDecoderStepSaveDuration;
  143. } else if(
  144. (DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
  145. instance->common.te_delta) &&
  146. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  147. subghz_protocol_common_add_bit(&instance->common, 1);
  148. instance->common.parser_step = HormannDecoderStepSaveDuration;
  149. } else
  150. instance->common.parser_step = HormannDecoderStepReset;
  151. } else {
  152. instance->common.parser_step = HormannDecoderStepReset;
  153. }
  154. break;
  155. }
  156. }
  157. void subghz_protocol_hormann_to_str(SubGhzProtocolHormann* instance, string_t output) {
  158. uint32_t code_found_hi = instance->common.code_last_found >> 32;
  159. uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
  160. instance->common.btn = (instance->common.code_last_found >> 4) & 0xF;
  161. string_cat_printf(
  162. output,
  163. "%s\r\n"
  164. "%dbit\r\n"
  165. "Key:0x%03lX%08lX\r\n"
  166. "Btn:0x%01X",
  167. instance->common.name,
  168. instance->common.code_last_count_bit,
  169. code_found_hi,
  170. code_found_lo,
  171. instance->common.btn);
  172. }
  173. bool subghz_protocol_hormann_to_save_file(
  174. SubGhzProtocolHormann* instance,
  175. FlipperFile* flipper_file) {
  176. return subghz_protocol_common_to_save_file((SubGhzProtocolCommon*)instance, flipper_file);
  177. }
  178. bool subghz_protocol_hormann_to_load_protocol_from_file(
  179. FlipperFile* flipper_file,
  180. SubGhzProtocolHormann* instance,
  181. const char* file_path) {
  182. return subghz_protocol_common_to_load_protocol_from_file(
  183. (SubGhzProtocolCommon*)instance, flipper_file);
  184. }
  185. void subghz_decoder_hormann_to_load_protocol(SubGhzProtocolHormann* instance, void* context) {
  186. furi_assert(context);
  187. furi_assert(instance);
  188. SubGhzProtocolCommonLoad* data = context;
  189. instance->common.code_last_found = data->code_found;
  190. instance->common.code_last_count_bit = data->code_count_bit;
  191. }