subghz_frequency_analyzer_worker.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include "subghz_frequency_analyzer_worker.h"
  2. #include <furi.h>
  3. #include "../subghz_i.h"
  4. struct SubGhzFrequencyAnalyzerWorker {
  5. FuriThread* thread;
  6. volatile bool worker_running;
  7. uint8_t count_repet;
  8. FrequencyRSSI frequency_rssi_buf;
  9. float filVal;
  10. SubGhzFrequencyAnalyzerWorkerPairCallback pair_callback;
  11. void* context;
  12. };
  13. // running average with adaptive coefficient
  14. static uint32_t subghz_frequency_analyzer_worker_expRunningAverageAdaptive(
  15. SubGhzFrequencyAnalyzerWorker* instance,
  16. uint32_t newVal) {
  17. float k;
  18. float newValFloat = newVal;
  19. // the sharpness of the filter depends on the absolute value of the difference
  20. if(abs(newValFloat - instance->filVal) > 500000)
  21. k = 0.9;
  22. else
  23. k = 0.03;
  24. instance->filVal += (newValFloat - instance->filVal) * k;
  25. return (uint32_t)instance->filVal;
  26. }
  27. /** Worker thread
  28. *
  29. * @param context
  30. * @return exit code
  31. */
  32. static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
  33. SubGhzFrequencyAnalyzerWorker* instance = context;
  34. FrequencyRSSI frequency_rssi;
  35. float rssi;
  36. uint32_t frequency;
  37. uint32_t frequency_start;
  38. //Start CC1101
  39. furi_hal_subghz_reset();
  40. furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
  41. furi_hal_subghz_set_frequency(433920000);
  42. furi_hal_subghz_flush_rx();
  43. furi_hal_subghz_rx();
  44. while(instance->worker_running) {
  45. osDelay(10);
  46. frequency_rssi.rssi = -127.0f;
  47. for(size_t i = 0; i < subghz_frequencies_count; i++) {
  48. if(furi_hal_subghz_is_frequency_valid(subghz_frequencies[i])) {
  49. furi_hal_subghz_idle();
  50. frequency = furi_hal_subghz_set_frequency(subghz_frequencies[i]);
  51. furi_hal_subghz_rx();
  52. osDelay(3);
  53. rssi = furi_hal_subghz_get_rssi();
  54. if(frequency_rssi.rssi < rssi) {
  55. frequency_rssi.rssi = rssi;
  56. frequency_rssi.frequency = frequency;
  57. }
  58. }
  59. }
  60. if(frequency_rssi.rssi > -90.0) {
  61. // -0.5 ... 433.92 ... +0.5
  62. frequency_start = frequency_rssi.frequency - 250000;
  63. //step 10KHz
  64. for(uint32_t i = frequency_start; i < frequency_start + 500000; i += 10000) {
  65. if(furi_hal_subghz_is_frequency_valid(i)) {
  66. furi_hal_subghz_idle();
  67. frequency = furi_hal_subghz_set_frequency(i);
  68. furi_hal_subghz_rx();
  69. osDelay(3);
  70. rssi = furi_hal_subghz_get_rssi();
  71. if(frequency_rssi.rssi < rssi) {
  72. frequency_rssi.rssi = rssi;
  73. frequency_rssi.frequency = frequency;
  74. }
  75. }
  76. }
  77. }
  78. if(frequency_rssi.rssi > -90.0) {
  79. instance->count_repet = 20;
  80. if(instance->filVal) {
  81. frequency_rssi.frequency =
  82. subghz_frequency_analyzer_worker_expRunningAverageAdaptive(
  83. instance, frequency_rssi.frequency);
  84. }
  85. if(instance->pair_callback)
  86. instance->pair_callback(
  87. instance->context, frequency_rssi.frequency, frequency_rssi.rssi);
  88. } else {
  89. if(instance->count_repet > 0) {
  90. instance->count_repet--;
  91. } else {
  92. instance->filVal = 0;
  93. if(instance->pair_callback) instance->pair_callback(instance->context, 0, 0);
  94. }
  95. }
  96. }
  97. //Stop CC1101
  98. furi_hal_subghz_idle();
  99. furi_hal_subghz_sleep();
  100. return 0;
  101. }
  102. SubGhzFrequencyAnalyzerWorker* subghz_frequency_analyzer_worker_alloc() {
  103. SubGhzFrequencyAnalyzerWorker* instance = furi_alloc(sizeof(SubGhzFrequencyAnalyzerWorker));
  104. instance->thread = furi_thread_alloc();
  105. furi_thread_set_name(instance->thread, "subghz_frequency_analyzer_worker");
  106. furi_thread_set_stack_size(instance->thread, 2048);
  107. furi_thread_set_context(instance->thread, instance);
  108. furi_thread_set_callback(instance->thread, subghz_frequency_analyzer_worker_thread);
  109. return instance;
  110. }
  111. void subghz_frequency_analyzer_worker_free(SubGhzFrequencyAnalyzerWorker* instance) {
  112. furi_assert(instance);
  113. furi_thread_free(instance->thread);
  114. free(instance);
  115. }
  116. void subghz_frequency_analyzer_worker_set_pair_callback(
  117. SubGhzFrequencyAnalyzerWorker* instance,
  118. SubGhzFrequencyAnalyzerWorkerPairCallback callback,
  119. void* context) {
  120. furi_assert(instance);
  121. furi_assert(context);
  122. instance->pair_callback = callback;
  123. instance->context = context;
  124. }
  125. void subghz_frequency_analyzer_worker_start(SubGhzFrequencyAnalyzerWorker* instance) {
  126. furi_assert(instance);
  127. furi_assert(!instance->worker_running);
  128. instance->worker_running = true;
  129. furi_thread_start(instance->thread);
  130. }
  131. void subghz_frequency_analyzer_worker_stop(SubGhzFrequencyAnalyzerWorker* instance) {
  132. furi_assert(instance);
  133. furi_assert(instance->worker_running);
  134. instance->worker_running = false;
  135. furi_thread_join(instance->thread);
  136. }
  137. bool subghz_frequency_analyzer_worker_is_running(SubGhzFrequencyAnalyzerWorker* instance) {
  138. furi_assert(instance);
  139. return instance->worker_running;
  140. }