subghz_capture.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #include "subghz_capture.h"
  2. #include "../subghz_i.h"
  3. #include <math.h>
  4. #include <furi.h>
  5. #include <api-hal.h>
  6. #include <input/input.h>
  7. #include <gui/elements.h>
  8. #include <notification/notification-messages.h>
  9. #include <fl_subghz/subghz_worker.h>
  10. #include <fl_subghz/protocols/subghz_protocol.h>
  11. struct SubghzCapture {
  12. View* view;
  13. SubGhzWorker* worker;
  14. SubGhzProtocol* protocol;
  15. };
  16. typedef struct {
  17. uint8_t frequency;
  18. uint32_t real_frequency;
  19. uint32_t counter;
  20. string_t text;
  21. } SubghzCaptureModel;
  22. static const char subghz_symbols[] = {'-', '\\', '|', '/'};
  23. void subghz_capture_draw(Canvas* canvas, SubghzCaptureModel* model) {
  24. char buffer[64];
  25. canvas_set_color(canvas, ColorBlack);
  26. canvas_set_font(canvas, FontPrimary);
  27. snprintf(
  28. buffer,
  29. sizeof(buffer),
  30. "Capture: %03ld.%03ldMHz %c",
  31. model->real_frequency / 1000000 % 1000,
  32. model->real_frequency / 1000 % 1000,
  33. subghz_symbols[model->counter % 4]);
  34. canvas_draw_str(canvas, 0, 8, buffer);
  35. canvas_set_font(canvas, FontSecondary);
  36. elements_multiline_text(canvas, 0, 20, string_get_cstr(model->text));
  37. }
  38. bool subghz_capture_input(InputEvent* event, void* context) {
  39. furi_assert(context);
  40. SubghzCapture* subghz_capture = context;
  41. if(event->key == InputKeyBack) {
  42. return false;
  43. }
  44. with_view_model(
  45. subghz_capture->view, (SubghzCaptureModel * model) {
  46. bool reconfigure = false;
  47. if(event->type == InputTypeShort) {
  48. if(event->key == InputKeyLeft) {
  49. if(model->frequency > 0) model->frequency--;
  50. reconfigure = true;
  51. } else if(event->key == InputKeyRight) {
  52. if(model->frequency < subghz_frequencies_count - 1) model->frequency++;
  53. reconfigure = true;
  54. }
  55. }
  56. if(reconfigure) {
  57. api_hal_subghz_idle();
  58. model->real_frequency =
  59. api_hal_subghz_set_frequency_and_path(subghz_frequencies[model->frequency]);
  60. api_hal_subghz_rx();
  61. }
  62. return reconfigure;
  63. });
  64. return true;
  65. }
  66. void subghz_capture_text_callback(string_t text, void* context) {
  67. furi_assert(context);
  68. SubghzCapture* subghz_capture = context;
  69. with_view_model(
  70. subghz_capture->view, (SubghzCaptureModel * model) {
  71. model->counter++;
  72. string_set(model->text, text);
  73. return true;
  74. });
  75. }
  76. void subghz_capture_enter(void* context) {
  77. furi_assert(context);
  78. SubghzCapture* subghz_capture = context;
  79. api_hal_subghz_reset();
  80. api_hal_subghz_idle();
  81. api_hal_subghz_load_preset(ApiHalSubGhzPresetMP);
  82. with_view_model(
  83. subghz_capture->view, (SubghzCaptureModel * model) {
  84. model->frequency = subghz_frequencies_433_92;
  85. model->real_frequency =
  86. api_hal_subghz_set_frequency_and_path(subghz_frequencies[model->frequency]);
  87. return true;
  88. });
  89. hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
  90. api_hal_subghz_set_capture_callback(subghz_worker_rx_callback, subghz_capture->worker);
  91. api_hal_subghz_enable_capture();
  92. subghz_worker_start(subghz_capture->worker);
  93. api_hal_subghz_flush_rx();
  94. api_hal_subghz_rx();
  95. }
  96. void subghz_capture_exit(void* context) {
  97. furi_assert(context);
  98. SubghzCapture* subghz_capture = context;
  99. subghz_worker_stop(subghz_capture->worker);
  100. api_hal_subghz_disable_capture();
  101. api_hal_subghz_init();
  102. }
  103. uint32_t subghz_capture_back(void* context) {
  104. return SubGhzViewMenu;
  105. }
  106. SubghzCapture* subghz_capture_alloc() {
  107. SubghzCapture* subghz_capture = furi_alloc(sizeof(SubghzCapture));
  108. // View allocation and configuration
  109. subghz_capture->view = view_alloc();
  110. view_allocate_model(subghz_capture->view, ViewModelTypeLocking, sizeof(SubghzCaptureModel));
  111. view_set_context(subghz_capture->view, subghz_capture);
  112. view_set_draw_callback(subghz_capture->view, (ViewDrawCallback)subghz_capture_draw);
  113. view_set_input_callback(subghz_capture->view, subghz_capture_input);
  114. view_set_enter_callback(subghz_capture->view, subghz_capture_enter);
  115. view_set_exit_callback(subghz_capture->view, subghz_capture_exit);
  116. view_set_previous_callback(subghz_capture->view, subghz_capture_back);
  117. with_view_model(
  118. subghz_capture->view, (SubghzCaptureModel * model) {
  119. string_init(model->text);
  120. return true;
  121. });
  122. subghz_capture->worker = subghz_worker_alloc();
  123. subghz_capture->protocol = subghz_protocol_alloc();
  124. subghz_worker_set_overrun_callback(
  125. subghz_capture->worker, (SubGhzWorkerOverrunCallback)subghz_protocol_reset);
  126. subghz_worker_set_pair_callback(
  127. subghz_capture->worker, (SubGhzWorkerPairCallback)subghz_protocol_parse);
  128. subghz_worker_set_context(subghz_capture->worker, subghz_capture->protocol);
  129. subghz_protocol_load_keeloq_file(subghz_capture->protocol, "/assets/subghz/keeloq_mfcodes");
  130. subghz_protocol_load_nice_flor_s_file(
  131. subghz_capture->protocol, "/assets/subghz/nice_floor_s_rx");
  132. subghz_protocol_enable_dump(
  133. subghz_capture->protocol, subghz_capture_text_callback, subghz_capture);
  134. return subghz_capture;
  135. }
  136. void subghz_capture_free(SubghzCapture* subghz_capture) {
  137. furi_assert(subghz_capture);
  138. subghz_protocol_free(subghz_capture->protocol);
  139. subghz_worker_free(subghz_capture->worker);
  140. with_view_model(
  141. subghz_capture->view, (SubghzCaptureModel * model) {
  142. string_clear(model->text);
  143. return true;
  144. });
  145. view_free(subghz_capture->view);
  146. free(subghz_capture);
  147. }
  148. View* subghz_capture_get_view(SubghzCapture* subghz_capture) {
  149. furi_assert(subghz_capture);
  150. return subghz_capture->view;
  151. }