subghz_static.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #include "subghz_static.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 <notification/notification-messages.h>
  8. static const uint8_t subghz_static_keys[][4] = {
  9. {0x74, 0xBA, 0xDE},
  10. {0x74, 0xBA, 0xDD},
  11. {0x74, 0xBA, 0xDB},
  12. {0xE3, 0x4A, 0x4E},
  13. };
  14. #define SUBGHZ_PT_ONE 376
  15. #define SUBGHZ_PT_ZERO (SUBGHZ_PT_ONE * 3)
  16. #define SUBGHZ_PT_GUARD 10600
  17. struct SubghzStatic {
  18. View* view;
  19. };
  20. typedef enum {
  21. SubghzStaticStatusRx,
  22. SubghzStaticStatusTx,
  23. } SubghzStaticStatus;
  24. typedef struct {
  25. uint8_t frequency;
  26. uint32_t real_frequency;
  27. ApiHalSubGhzPath path;
  28. uint8_t button;
  29. } SubghzStaticModel;
  30. void subghz_static_draw(Canvas* canvas, SubghzStaticModel* model) {
  31. char buffer[64];
  32. canvas_set_color(canvas, ColorBlack);
  33. canvas_set_font(canvas, FontPrimary);
  34. canvas_draw_str(canvas, 2, 12, "CC1101 Static");
  35. canvas_set_font(canvas, FontSecondary);
  36. // Frequency
  37. snprintf(
  38. buffer,
  39. sizeof(buffer),
  40. "Freq: %03ld.%03ld.%03ld Hz",
  41. model->real_frequency / 1000000 % 1000,
  42. model->real_frequency / 1000 % 1000,
  43. model->real_frequency % 1000);
  44. canvas_draw_str(canvas, 2, 24, buffer);
  45. // Path
  46. char* path_name = "Unknown";
  47. if(model->path == ApiHalSubGhzPathIsolate) {
  48. path_name = "isolate";
  49. } else if(model->path == ApiHalSubGhzPath433) {
  50. path_name = "433MHz";
  51. } else if(model->path == ApiHalSubGhzPath315) {
  52. path_name = "315MHz";
  53. } else if(model->path == ApiHalSubGhzPath868) {
  54. path_name = "868MHz";
  55. }
  56. snprintf(buffer, sizeof(buffer), "Path: %d - %s", model->path, path_name);
  57. canvas_draw_str(canvas, 2, 36, buffer);
  58. snprintf(buffer, sizeof(buffer), "Key: %d", model->button);
  59. canvas_draw_str(canvas, 2, 48, buffer);
  60. }
  61. bool subghz_static_input(InputEvent* event, void* context) {
  62. furi_assert(context);
  63. SubghzStatic* subghz_static = context;
  64. if(event->key == InputKeyBack) {
  65. return false;
  66. }
  67. with_view_model(
  68. subghz_static->view, (SubghzStaticModel * model) {
  69. bool reconfigure = false;
  70. if(event->type == InputTypeShort) {
  71. if(event->key == InputKeyLeft) {
  72. if(model->frequency > 0) model->frequency--;
  73. reconfigure = true;
  74. } else if(event->key == InputKeyRight) {
  75. if(model->frequency < subghz_frequencies_count - 1) model->frequency++;
  76. reconfigure = true;
  77. } else if(event->key == InputKeyDown) {
  78. if(model->button > 0) model->button--;
  79. } else if(event->key == InputKeyUp) {
  80. if(model->button < 3) model->button++;
  81. }
  82. model->path = subghz_frequencies[model->frequency].path;
  83. }
  84. if(reconfigure) {
  85. api_hal_subghz_idle();
  86. model->real_frequency =
  87. api_hal_subghz_set_frequency(subghz_frequencies[model->frequency].frequency);
  88. api_hal_subghz_set_path(model->path);
  89. api_hal_subghz_tx();
  90. }
  91. if(event->key == InputKeyOk) {
  92. if(event->type == InputTypePress) {
  93. const uint8_t* key = subghz_static_keys[model->button];
  94. NotificationApp* notification = furi_record_open("notification");
  95. notification_message_block(notification, &sequence_set_red_255);
  96. __disable_irq();
  97. for(uint8_t r = 0; r < 20; r++) {
  98. //Payload
  99. for(uint8_t i = 0; i < 24; i++) {
  100. uint8_t byte = i / 8;
  101. uint8_t bit = i % 8;
  102. bool value = (key[byte] >> (7 - bit)) & 1;
  103. // Payload send
  104. hal_gpio_write(&gpio_cc1101_g0, false);
  105. delay_us(value ? SUBGHZ_PT_ONE : SUBGHZ_PT_ZERO);
  106. hal_gpio_write(&gpio_cc1101_g0, true);
  107. delay_us(value ? SUBGHZ_PT_ZERO : SUBGHZ_PT_ONE);
  108. }
  109. // Last bit
  110. hal_gpio_write(&gpio_cc1101_g0, false);
  111. delay_us(SUBGHZ_PT_ONE);
  112. hal_gpio_write(&gpio_cc1101_g0, true);
  113. // Guard time
  114. delay_us(10600);
  115. }
  116. __enable_irq();
  117. notification_message(notification, &sequence_reset_red);
  118. furi_record_close("notification");
  119. }
  120. }
  121. return true;
  122. });
  123. return true;
  124. }
  125. void subghz_static_enter(void* context) {
  126. furi_assert(context);
  127. SubghzStatic* subghz_static = context;
  128. api_hal_subghz_reset();
  129. api_hal_subghz_load_preset(ApiHalSubGhzPresetOokAsync);
  130. hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
  131. hal_gpio_write(&gpio_cc1101_g0, true);
  132. with_view_model(
  133. subghz_static->view, (SubghzStaticModel * model) {
  134. model->frequency = subghz_frequencies_433_92;
  135. model->real_frequency =
  136. api_hal_subghz_set_frequency(subghz_frequencies[model->frequency].frequency);
  137. model->path = subghz_frequencies[model->frequency].path;
  138. model->button = 0;
  139. api_hal_subghz_set_path(model->path);
  140. return true;
  141. });
  142. api_hal_subghz_tx();
  143. }
  144. void subghz_static_exit(void* context) {
  145. furi_assert(context);
  146. // SubghzStatic* subghz_static = context;
  147. // Reinitialize IC to default state
  148. api_hal_subghz_init();
  149. }
  150. uint32_t subghz_static_back(void* context) {
  151. return SubGhzViewMenu;
  152. }
  153. SubghzStatic* subghz_static_alloc() {
  154. SubghzStatic* subghz_static = furi_alloc(sizeof(SubghzStatic));
  155. // View allocation and configuration
  156. subghz_static->view = view_alloc();
  157. view_allocate_model(subghz_static->view, ViewModelTypeLockFree, sizeof(SubghzStaticModel));
  158. view_set_context(subghz_static->view, subghz_static);
  159. view_set_draw_callback(subghz_static->view, (ViewDrawCallback)subghz_static_draw);
  160. view_set_input_callback(subghz_static->view, subghz_static_input);
  161. view_set_enter_callback(subghz_static->view, subghz_static_enter);
  162. view_set_exit_callback(subghz_static->view, subghz_static_exit);
  163. view_set_previous_callback(subghz_static->view, subghz_static_back);
  164. return subghz_static;
  165. }
  166. void subghz_static_free(SubghzStatic* subghz_static) {
  167. furi_assert(subghz_static);
  168. view_free(subghz_static->view);
  169. free(subghz_static);
  170. }
  171. View* subghz_static_get_view(SubghzStatic* subghz_static) {
  172. furi_assert(subghz_static);
  173. return subghz_static->view;
  174. }