subghz_test_packet.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #include "subghz_test_packet.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. static const uint8_t subghz_test_packet_data[] = {
  8. 0x30, // 48bytes to transmit
  9. 'F', 'L', 'I', 'P', 'P', 'E', 'R', ' ', 'T', 'E', 'S', 'T', ' ', 'P', 'A', 'C',
  10. 'K', 'E', 'T', ' ', 'D', 'A', 'T', 'A', ' ', 'A', 'N', 'D', ' ', 'P', 'A', 'D',
  11. 'F', 'L', 'I', 'P', 'P', 'E', 'R', ' ', 'T', 'E', 'S', 'T', ' ', 'P', 'A', 'C',
  12. };
  13. struct SubghzTestPacket {
  14. View* view;
  15. osTimerId timer;
  16. };
  17. typedef enum {
  18. SubghzTestPacketModelStatusRx,
  19. SubghzTestPacketModelStatusTx,
  20. } SubghzTestPacketModelStatus;
  21. typedef struct {
  22. uint8_t frequency;
  23. uint32_t real_frequency;
  24. ApiHalSubGhzPath path;
  25. float rssi;
  26. SubghzTestPacketModelStatus status;
  27. } SubghzTestPacketModel;
  28. void subghz_test_packet_draw(Canvas* canvas, SubghzTestPacketModel* model) {
  29. char buffer[64];
  30. canvas_set_color(canvas, ColorBlack);
  31. canvas_set_font(canvas, FontPrimary);
  32. canvas_draw_str(canvas, 2, 12, "CC1101 Packet Test");
  33. canvas_set_font(canvas, FontSecondary);
  34. // Frequency
  35. snprintf(
  36. buffer,
  37. sizeof(buffer),
  38. "Freq: %03ld.%03ld.%03ld Hz",
  39. model->real_frequency / 1000000 % 1000,
  40. model->real_frequency / 1000 % 1000,
  41. model->real_frequency % 1000);
  42. canvas_draw_str(canvas, 2, 24, buffer);
  43. // Path
  44. char* path_name = "Unknown";
  45. if(model->path == ApiHalSubGhzPathIsolate) {
  46. path_name = "isolate";
  47. } else if(model->path == ApiHalSubGhzPath1) {
  48. path_name = "433MHz";
  49. } else if(model->path == ApiHalSubGhzPath2) {
  50. path_name = "315MHz";
  51. } else if(model->path == ApiHalSubGhzPath3) {
  52. path_name = "868MHz";
  53. }
  54. snprintf(buffer, sizeof(buffer), "Path: %d - %s", model->path, path_name);
  55. canvas_draw_str(canvas, 2, 36, buffer);
  56. if(model->status == SubghzTestPacketModelStatusRx) {
  57. snprintf(
  58. buffer,
  59. sizeof(buffer),
  60. "RSSI: %ld.%ld dBm",
  61. (int32_t)(model->rssi),
  62. (int32_t)fabs(model->rssi * 10) % 10);
  63. canvas_draw_str(canvas, 2, 48, buffer);
  64. } else {
  65. canvas_draw_str(canvas, 2, 48, "TX");
  66. }
  67. }
  68. bool subghz_test_packet_input(InputEvent* event, void* context) {
  69. furi_assert(context);
  70. SubghzTestPacket* subghz_test_packet = context;
  71. if(event->key == InputKeyBack) {
  72. return false;
  73. }
  74. with_view_model(
  75. subghz_test_packet->view, (SubghzTestPacketModel * model) {
  76. osTimerStop(subghz_test_packet->timer);
  77. api_hal_subghz_idle();
  78. if(event->type == InputTypeShort) {
  79. if(event->key == InputKeyLeft) {
  80. if(model->frequency > 0) model->frequency--;
  81. } else if(event->key == InputKeyRight) {
  82. if(model->frequency < subghz_frequencies_count - 1) model->frequency++;
  83. } else if(event->key == InputKeyDown) {
  84. if(model->path > 0) model->path--;
  85. } else if(event->key == InputKeyUp) {
  86. if(model->path < ApiHalSubGhzPath3) model->path++;
  87. }
  88. model->real_frequency =
  89. api_hal_subghz_set_frequency(subghz_frequencies[model->frequency]);
  90. api_hal_subghz_set_path(model->path);
  91. }
  92. if(event->key == InputKeyOk) {
  93. if(event->type == InputTypePress) {
  94. model->status = SubghzTestPacketModelStatusTx;
  95. } else if(event->type == InputTypeRelease) {
  96. model->status = SubghzTestPacketModelStatusRx;
  97. }
  98. }
  99. if(model->status == SubghzTestPacketModelStatusRx) {
  100. api_hal_subghz_rx();
  101. osTimerStart(subghz_test_packet->timer, 1024 / 4);
  102. } else {
  103. api_hal_subghz_write_packet(
  104. subghz_test_packet_data, sizeof(subghz_test_packet_data));
  105. api_hal_subghz_tx();
  106. }
  107. return true;
  108. });
  109. return true;
  110. }
  111. void subghz_test_packet_enter(void* context) {
  112. furi_assert(context);
  113. SubghzTestPacket* subghz_test_packet = context;
  114. api_hal_subghz_reset();
  115. api_hal_subghz_load_preset(ApiHalSubGhzPreset2FskPacket);
  116. hal_gpio_init(&cc1101_g0_gpio, GpioModeInput, GpioPullNo, GpioSpeedLow);
  117. with_view_model(
  118. subghz_test_packet->view, (SubghzTestPacketModel * model) {
  119. model->frequency = 4; // 433
  120. model->real_frequency =
  121. api_hal_subghz_set_frequency(subghz_frequencies[model->frequency]);
  122. model->path = ApiHalSubGhzPathIsolate; // isolate
  123. model->rssi = 0.0f;
  124. model->status = SubghzTestPacketModelStatusRx;
  125. return true;
  126. });
  127. api_hal_subghz_rx();
  128. osTimerStart(subghz_test_packet->timer, 1024 / 4);
  129. }
  130. void subghz_test_packet_exit(void* context) {
  131. furi_assert(context);
  132. SubghzTestPacket* subghz_test_packet = context;
  133. osTimerStop(subghz_test_packet->timer);
  134. // Reinitialize IC to default state
  135. api_hal_subghz_init();
  136. }
  137. void subghz_test_packet_rssi_timer_callback(void* context) {
  138. furi_assert(context);
  139. SubghzTestPacket* subghz_test_packet = context;
  140. with_view_model(
  141. subghz_test_packet->view, (SubghzTestPacketModel * model) {
  142. model->rssi = api_hal_subghz_get_rssi();
  143. return true;
  144. });
  145. }
  146. uint32_t subghz_test_packet_back(void* context) {
  147. return SubGhzViewMenu;
  148. }
  149. SubghzTestPacket* subghz_test_packet_alloc() {
  150. SubghzTestPacket* subghz_test_packet = furi_alloc(sizeof(SubghzTestPacket));
  151. // View allocation and configuration
  152. subghz_test_packet->view = view_alloc();
  153. view_allocate_model(
  154. subghz_test_packet->view, ViewModelTypeLockFree, sizeof(SubghzTestPacketModel));
  155. view_set_context(subghz_test_packet->view, subghz_test_packet);
  156. view_set_draw_callback(subghz_test_packet->view, (ViewDrawCallback)subghz_test_packet_draw);
  157. view_set_input_callback(subghz_test_packet->view, subghz_test_packet_input);
  158. view_set_enter_callback(subghz_test_packet->view, subghz_test_packet_enter);
  159. view_set_exit_callback(subghz_test_packet->view, subghz_test_packet_exit);
  160. view_set_previous_callback(subghz_test_packet->view, subghz_test_packet_back);
  161. subghz_test_packet->timer = osTimerNew(
  162. subghz_test_packet_rssi_timer_callback, osTimerPeriodic, subghz_test_packet, NULL);
  163. return subghz_test_packet;
  164. }
  165. void subghz_test_packet_free(SubghzTestPacket* subghz_test_packet) {
  166. furi_assert(subghz_test_packet);
  167. osTimerDelete(subghz_test_packet->timer);
  168. view_free(subghz_test_packet->view);
  169. free(subghz_test_packet);
  170. }
  171. View* subghz_test_packet_get_view(SubghzTestPacket* subghz_test_packet) {
  172. furi_assert(subghz_test_packet);
  173. return subghz_test_packet->view;
  174. }