subghz_frequency_analyzer.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "subghz_frequency_analyzer.h"
  2. #include "../subghz_i.h"
  3. #include <math.h>
  4. #include <furi.h>
  5. #include <furi_hal.h>
  6. #include <input/input.h>
  7. #include <notification/notification_messages.h>
  8. #include "../helpers/subghz_frequency_analyzer_worker.h"
  9. #include <assets_icons.h>
  10. typedef enum {
  11. SubGhzFrequencyAnalyzerStatusIDLE,
  12. } SubGhzFrequencyAnalyzerStatus;
  13. struct SubGhzFrequencyAnalyzer {
  14. View* view;
  15. SubGhzFrequencyAnalyzerWorker* worker;
  16. SubGhzFrequencyAnalyzerCallback callback;
  17. void* context;
  18. };
  19. typedef struct {
  20. uint32_t frequency;
  21. float rssi;
  22. } SubGhzFrequencyAnalyzerModel;
  23. void subghz_frequency_analyzer_set_callback(
  24. SubGhzFrequencyAnalyzer* subghz_frequency_analyzer,
  25. SubGhzFrequencyAnalyzerCallback callback,
  26. void* context) {
  27. furi_assert(subghz_frequency_analyzer);
  28. furi_assert(callback);
  29. subghz_frequency_analyzer->callback = callback;
  30. subghz_frequency_analyzer->context = context;
  31. }
  32. void subghz_frequency_analyzer_draw_rssi(Canvas* canvas, float rssi) {
  33. uint8_t x = 48;
  34. uint8_t y = 56;
  35. uint8_t column_number = 0;
  36. if(rssi) {
  37. rssi = (rssi + 90) / 3;
  38. for(size_t i = 1; i < (uint8_t)rssi; i++) {
  39. if(i > 20) break;
  40. if(i % 4) {
  41. column_number++;
  42. canvas_draw_box(canvas, x + 2 * i, y - column_number, 2, 4 + column_number);
  43. }
  44. }
  45. }
  46. }
  47. void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel* model) {
  48. char buffer[64];
  49. canvas_set_color(canvas, ColorBlack);
  50. canvas_set_font(canvas, FontSecondary);
  51. canvas_draw_str(canvas, 20, 8, "Frequency Analyzer");
  52. canvas_draw_str(canvas, 28, 60, "RSSI");
  53. subghz_frequency_analyzer_draw_rssi(canvas, model->rssi);
  54. //Frequency
  55. canvas_set_font(canvas, FontBigNumbers);
  56. snprintf(
  57. buffer,
  58. sizeof(buffer),
  59. "%03ld.%03ld",
  60. model->frequency / 1000000 % 1000,
  61. model->frequency / 1000 % 1000);
  62. canvas_draw_str(canvas, 8, 35, buffer);
  63. canvas_draw_icon(canvas, 96, 24, &I_MHz_25x11);
  64. }
  65. bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
  66. furi_assert(context);
  67. if(event->key == InputKeyBack) {
  68. return false;
  69. }
  70. return true;
  71. }
  72. void subghz_frequency_analyzer_pair_callback(void* context, uint32_t frequency, float rssi) {
  73. SubGhzFrequencyAnalyzer* instance = context;
  74. with_view_model(
  75. instance->view, (SubGhzFrequencyAnalyzerModel * model) {
  76. model->rssi = rssi;
  77. model->frequency = frequency;
  78. return true;
  79. });
  80. }
  81. void subghz_frequency_analyzer_enter(void* context) {
  82. furi_assert(context);
  83. SubGhzFrequencyAnalyzer* instance = context;
  84. //Start worker
  85. instance->worker = subghz_frequency_analyzer_worker_alloc();
  86. subghz_frequency_analyzer_worker_set_pair_callback(
  87. instance->worker,
  88. (SubGhzFrequencyAnalyzerWorkerPairCallback)subghz_frequency_analyzer_pair_callback,
  89. instance);
  90. subghz_frequency_analyzer_worker_start(instance->worker);
  91. with_view_model(
  92. instance->view, (SubGhzFrequencyAnalyzerModel * model) {
  93. model->rssi = 0;
  94. model->frequency = 0;
  95. return true;
  96. });
  97. }
  98. void subghz_frequency_analyzer_exit(void* context) {
  99. furi_assert(context);
  100. SubGhzFrequencyAnalyzer* instance = context;
  101. //Stop worker
  102. if(subghz_frequency_analyzer_worker_is_running(instance->worker)) {
  103. subghz_frequency_analyzer_worker_stop(instance->worker);
  104. }
  105. subghz_frequency_analyzer_worker_free(instance->worker);
  106. with_view_model(
  107. instance->view, (SubGhzFrequencyAnalyzerModel * model) {
  108. model->rssi = 0;
  109. return true;
  110. });
  111. }
  112. SubGhzFrequencyAnalyzer* subghz_frequency_analyzer_alloc() {
  113. SubGhzFrequencyAnalyzer* instance = malloc(sizeof(SubGhzFrequencyAnalyzer));
  114. // View allocation and configuration
  115. instance->view = view_alloc();
  116. view_allocate_model(
  117. instance->view, ViewModelTypeLocking, sizeof(SubGhzFrequencyAnalyzerModel));
  118. view_set_context(instance->view, instance);
  119. view_set_draw_callback(instance->view, (ViewDrawCallback)subghz_frequency_analyzer_draw);
  120. view_set_input_callback(instance->view, subghz_frequency_analyzer_input);
  121. view_set_enter_callback(instance->view, subghz_frequency_analyzer_enter);
  122. view_set_exit_callback(instance->view, subghz_frequency_analyzer_exit);
  123. with_view_model(
  124. instance->view, (SubGhzFrequencyAnalyzerModel * model) {
  125. model->rssi = 0;
  126. return true;
  127. });
  128. return instance;
  129. }
  130. void subghz_frequency_analyzer_free(SubGhzFrequencyAnalyzer* instance) {
  131. furi_assert(instance);
  132. view_free(instance->view);
  133. free(instance);
  134. }
  135. View* subghz_frequency_analyzer_get_view(SubGhzFrequencyAnalyzer* instance) {
  136. furi_assert(instance);
  137. return instance->view;
  138. }