Sfoglia il codice sorgente

[FL-123] SubGhz static code replay (#410)

* SubGhz: static code emulation view
* SubGhz: add dumb static replay
あく 4 anni fa
parent
commit
3e281175da

+ 9 - 0
applications/subghz/subghz.c

@@ -11,6 +11,8 @@ void subghz_menu_callback(void* context, uint32_t index) {
         view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTestBasic);
     } else if(index == 1) {
         view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTestPacket);
+    } else if(index == 2) {
+        view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewStatic);
     }
 }
 
@@ -37,6 +39,8 @@ SubGhz* subghz_alloc() {
     subghz->submenu = submenu_alloc();
     submenu_add_item(subghz->submenu, "Basic Test", 0, subghz_menu_callback, subghz);
     submenu_add_item(subghz->submenu, "Packet Test", 1, subghz_menu_callback, subghz);
+    submenu_add_item(subghz->submenu, "Static Code", 2, subghz_menu_callback, subghz);
+
     View* submenu_view = submenu_get_view(subghz->submenu);
     view_set_previous_callback(submenu_view, subghz_exit);
     view_dispatcher_add_view(subghz->view_dispatcher, SubGhzViewMenu, submenu_view);
@@ -55,6 +59,11 @@ SubGhz* subghz_alloc() {
         SubGhzViewTestPacket,
         subghz_test_packet_get_view(subghz->subghz_test_packet));
 
+    // Static send
+    subghz->subghz_static = subghz_static_alloc();
+    view_dispatcher_add_view(
+        subghz->view_dispatcher, SubGhzViewStatic, subghz_static_get_view(subghz->subghz_static));
+
     // Switch to menu
     view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewMenu);
 

+ 4 - 0
applications/subghz/subghz_i.h

@@ -3,6 +3,7 @@
 #include "subghz.h"
 #include "subghz_test_basic.h"
 #include "subghz_test_packet.h"
+#include "subghz_static.h"
 
 #include <furi.h>
 #include <gui/gui.h>
@@ -35,10 +36,13 @@ struct SubGhz {
     SubghzTestBasic* subghz_test_basic;
 
     SubghzTestPacket* subghz_test_packet;
+
+    SubghzStatic* subghz_static;
 };
 
 typedef enum {
     SubGhzViewMenu,
     SubGhzViewTestBasic,
     SubGhzViewTestPacket,
+    SubGhzViewStatic,
 } SubGhzView;

+ 187 - 0
applications/subghz/subghz_static.c

@@ -0,0 +1,187 @@
+#include "subghz_static.h"
+#include "subghz_i.h"
+
+#include <math.h>
+#include <furi.h>
+#include <api-hal.h>
+#include <input/input.h>
+
+static const uint8_t subghz_static_keys[][4] = {
+    {0x74, 0xBA, 0xDE, 0x80},
+    {0x74, 0xBA, 0xDD, 0x80},
+    {0x74, 0xBA, 0xDB, 0x80},
+};
+
+struct SubghzStatic {
+    View* view;
+};
+
+typedef enum {
+    SubghzStaticStatusRx,
+    SubghzStaticStatusTx,
+} SubghzStaticStatus;
+
+typedef struct {
+    uint32_t real_frequency;
+    ApiHalSubGhzPath path;
+    uint8_t button;
+} SubghzStaticModel;
+
+void subghz_static_draw(Canvas* canvas, SubghzStaticModel* model) {
+    char buffer[64];
+
+    canvas_set_color(canvas, ColorBlack);
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str(canvas, 2, 12, "CC1101 Static");
+
+    canvas_set_font(canvas, FontSecondary);
+    // Frequency
+    snprintf(
+        buffer,
+        sizeof(buffer),
+        "Freq: %03ld.%03ld.%03ld Hz",
+        model->real_frequency / 1000000 % 1000,
+        model->real_frequency / 1000 % 1000,
+        model->real_frequency % 1000);
+    canvas_draw_str(canvas, 2, 24, buffer);
+    // Path
+    char* path_name = "Unknown";
+    if(model->path == ApiHalSubGhzPathIsolate) {
+        path_name = "isolate";
+    } else if(model->path == ApiHalSubGhzPath1) {
+        path_name = "433MHz";
+    } else if(model->path == ApiHalSubGhzPath2) {
+        path_name = "315MHz";
+    } else if(model->path == ApiHalSubGhzPath3) {
+        path_name = "868MHz";
+    }
+    snprintf(buffer, sizeof(buffer), "Path: %d - %s", model->path, path_name);
+    canvas_draw_str(canvas, 2, 36, buffer);
+    snprintf(buffer, sizeof(buffer), "Key: %d", model->button);
+    canvas_draw_str(canvas, 2, 48, buffer);
+}
+
+bool subghz_static_input(InputEvent* event, void* context) {
+    furi_assert(context);
+    SubghzStatic* subghz_static = context;
+
+    if(event->key == InputKeyBack) {
+        return false;
+    }
+
+    with_view_model(
+        subghz_static->view, (SubghzStaticModel * model) {
+            if(event->type == InputTypeShort) {
+                if(event->key == InputKeyLeft) {
+                    if(model->button > 0) model->button--;
+                } else if(event->key == InputKeyRight) {
+                    if(model->button < 2) model->button++;
+
+                } else if(event->key == InputKeyDown) {
+                    if(model->path > 0) model->path--;
+                } else if(event->key == InputKeyUp) {
+                    if(model->path < ApiHalSubGhzPath3) model->path++;
+                }
+                api_hal_subghz_set_path(model->path);
+            }
+
+            if(event->key == InputKeyOk) {
+                if(event->type == InputTypePress) {
+                    const uint8_t* key = subghz_static_keys[model->button];
+
+                    api_hal_light_set(LightRed, 0xff);
+                    __disable_irq();
+                    gpio_write(&cc1101_g0_gpio, false);
+                    delay_us(136);
+                    gpio_write(&cc1101_g0_gpio, true);
+                    delay_us(10000);
+                    for(uint8_t r = 0; r < 8; r++) {
+                        for(uint8_t i = 0; i < 25; i++) {
+                            uint8_t byte = i / 8;
+                            uint8_t bit = i % 8;
+                            bool value = (key[byte] >> (7 - bit)) & 1;
+                            gpio_write(&cc1101_g0_gpio, false);
+                            if(value) {
+                                delay_us(360);
+                            } else {
+                                delay_us(1086);
+                            }
+                            gpio_write(&cc1101_g0_gpio, true);
+                            if(value) {
+                                delay_us(1086);
+                            } else {
+                                delay_us(360);
+                            }
+                        }
+                        delay_us(10000);
+                    }
+                    __enable_irq();
+                    api_hal_light_set(LightRed, 0x00);
+                }
+            }
+
+            return true;
+        });
+
+    return true;
+}
+
+void subghz_static_enter(void* context) {
+    furi_assert(context);
+    SubghzStatic* subghz_static = context;
+
+    api_hal_subghz_reset();
+    api_hal_subghz_load_preset(ApiHalSubGhzPresetOokAsync);
+
+    gpio_init(&cc1101_g0_gpio, GpioModeOutputPushPull);
+    gpio_write(&cc1101_g0_gpio, true);
+
+    with_view_model(
+        subghz_static->view, (SubghzStaticModel * model) {
+            model->real_frequency = api_hal_subghz_set_frequency(433920000);
+            model->path = ApiHalSubGhzPathIsolate; // isolate
+            model->button = 0;
+            return true;
+        });
+
+    api_hal_subghz_tx();
+}
+
+void subghz_static_exit(void* context) {
+    furi_assert(context);
+    // SubghzStatic* subghz_static = context;
+
+    // Reinitialize IC to default state
+    api_hal_subghz_init();
+}
+
+uint32_t subghz_static_back(void* context) {
+    return SubGhzViewMenu;
+}
+
+SubghzStatic* subghz_static_alloc() {
+    SubghzStatic* subghz_static = furi_alloc(sizeof(SubghzStatic));
+
+    // View allocation and configuration
+    subghz_static->view = view_alloc();
+    view_allocate_model(subghz_static->view, ViewModelTypeLockFree, sizeof(SubghzStaticModel));
+    view_set_context(subghz_static->view, subghz_static);
+    view_set_draw_callback(subghz_static->view, (ViewDrawCallback)subghz_static_draw);
+    view_set_input_callback(subghz_static->view, subghz_static_input);
+    view_set_enter_callback(subghz_static->view, subghz_static_enter);
+    view_set_exit_callback(subghz_static->view, subghz_static_exit);
+    view_set_previous_callback(subghz_static->view, subghz_static_back);
+
+    return subghz_static;
+}
+
+void subghz_static_free(SubghzStatic* subghz_static) {
+    furi_assert(subghz_static);
+    view_free(subghz_static->view);
+    free(subghz_static);
+}
+
+View* subghz_static_get_view(SubghzStatic* subghz_static) {
+    furi_assert(subghz_static);
+    return subghz_static->view;
+}

+ 11 - 0
applications/subghz/subghz_static.h

@@ -0,0 +1,11 @@
+#pragma once
+
+#include <gui/view.h>
+
+typedef struct SubghzStatic SubghzStatic;
+
+SubghzStatic* subghz_static_alloc();
+
+void subghz_static_free(SubghzStatic* subghz_static);
+
+View* subghz_static_get_view(SubghzStatic* subghz_static);

+ 2 - 2
flash_otp_version.sh

@@ -12,6 +12,6 @@ if [ ! -f $1 ]; then
     exit
 fi
 
-STM32_Programmer_CLI -c port=usb1 -d $1 0x1FFF7000
+STM32_Programmer_CLI -c port=swd -d $1 0x1FFF7000
 
-STM32_Programmer_CLI -c port=usb1 -r8 0x1FFF7000 8
+STM32_Programmer_CLI -c port=swd -r8 0x1FFF7000 8