subghz_static.c 6.5 KB

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