Просмотр исходного кода

Move apps from flipperzero firmware into separate repository

Aleksandr Kutuzov 2 лет назад
Сommit
b7c727ebc3

+ 13 - 0
application.fam

@@ -0,0 +1,13 @@
+App(
+    appid="nfc_rfid_detector",
+    name="NFC/RFID detector",
+    apptype=FlipperAppType.EXTERNAL,
+    targets=["f7"],
+    entry_point="nfc_rfid_detector_app",
+    requires=["gui"],
+    stack_size=4 * 1024,
+    order=50,
+    fap_icon="nfc_rfid_detector_10px.png",
+    fap_category="Tools",
+    fap_icon_assets="images",
+)

+ 7 - 0
helpers/nfc_rfid_detector_event.h

@@ -0,0 +1,7 @@
+#pragma once
+
+typedef enum {
+    //NfcRfidDetectorCustomEvent
+    NfcRfidDetectorCustomEventStartId = 100,
+
+} NfcRfidDetectorCustomEvent;

+ 15 - 0
helpers/nfc_rfid_detector_types.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include <furi.h>
+#include <furi_hal.h>
+
+#define NFC_RFID_DETECTOR_VERSION_APP "0.1"
+#define NFC_RFID_DETECTOR_DEVELOPED "SkorP"
+#define NFC_RFID_DETECTOR_GITHUB "https://github.com/flipperdevices/flipperzero-firmware"
+
+typedef enum {
+    NfcRfidDetectorViewVariableItemList,
+    NfcRfidDetectorViewSubmenu,
+    NfcRfidDetectorViewFieldPresence,
+    NfcRfidDetectorViewWidget,
+} NfcRfidDetectorView;

BIN
images/Modern_reader_18x34.png


BIN
images/Move_flipper_26x39.png


BIN
images/NFC_detect_45x30.png


BIN
images/Rfid_detect_45x30.png


BIN
nfc_rfid_detector_10px.png


+ 108 - 0
nfc_rfid_detector_app.c

@@ -0,0 +1,108 @@
+#include "nfc_rfid_detector_app_i.h"
+
+#include <furi.h>
+#include <furi_hal.h>
+
+static bool nfc_rfid_detector_app_custom_event_callback(void* context, uint32_t event) {
+    furi_assert(context);
+    NfcRfidDetectorApp* app = context;
+    return scene_manager_handle_custom_event(app->scene_manager, event);
+}
+
+static bool nfc_rfid_detector_app_back_event_callback(void* context) {
+    furi_assert(context);
+    NfcRfidDetectorApp* app = context;
+    return scene_manager_handle_back_event(app->scene_manager);
+}
+
+static void nfc_rfid_detector_app_tick_event_callback(void* context) {
+    furi_assert(context);
+    NfcRfidDetectorApp* app = context;
+    scene_manager_handle_tick_event(app->scene_manager);
+}
+
+NfcRfidDetectorApp* nfc_rfid_detector_app_alloc() {
+    NfcRfidDetectorApp* app = malloc(sizeof(NfcRfidDetectorApp));
+
+    // GUI
+    app->gui = furi_record_open(RECORD_GUI);
+
+    // View Dispatcher
+    app->view_dispatcher = view_dispatcher_alloc();
+    app->scene_manager = scene_manager_alloc(&nfc_rfid_detector_scene_handlers, app);
+    view_dispatcher_enable_queue(app->view_dispatcher);
+
+    view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
+    view_dispatcher_set_custom_event_callback(
+        app->view_dispatcher, nfc_rfid_detector_app_custom_event_callback);
+    view_dispatcher_set_navigation_event_callback(
+        app->view_dispatcher, nfc_rfid_detector_app_back_event_callback);
+    view_dispatcher_set_tick_event_callback(
+        app->view_dispatcher, nfc_rfid_detector_app_tick_event_callback, 100);
+
+    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
+
+    // Open Notification record
+    app->notifications = furi_record_open(RECORD_NOTIFICATION);
+
+    // SubMenu
+    app->submenu = submenu_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher, NfcRfidDetectorViewSubmenu, submenu_get_view(app->submenu));
+
+    // Widget
+    app->widget = widget_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher, NfcRfidDetectorViewWidget, widget_get_view(app->widget));
+
+    // Field Presence
+    app->nfc_rfid_detector_field_presence = nfc_rfid_detector_view_field_presence_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher,
+        NfcRfidDetectorViewFieldPresence,
+        nfc_rfid_detector_view_field_presence_get_view(app->nfc_rfid_detector_field_presence));
+
+    scene_manager_next_scene(app->scene_manager, NfcRfidDetectorSceneStart);
+
+    return app;
+}
+
+void nfc_rfid_detector_app_free(NfcRfidDetectorApp* app) {
+    furi_assert(app);
+
+    // Submenu
+    view_dispatcher_remove_view(app->view_dispatcher, NfcRfidDetectorViewSubmenu);
+    submenu_free(app->submenu);
+
+    //  Widget
+    view_dispatcher_remove_view(app->view_dispatcher, NfcRfidDetectorViewWidget);
+    widget_free(app->widget);
+
+    // Field Presence
+    view_dispatcher_remove_view(app->view_dispatcher, NfcRfidDetectorViewFieldPresence);
+    nfc_rfid_detector_view_field_presence_free(app->nfc_rfid_detector_field_presence);
+
+    // View dispatcher
+    view_dispatcher_free(app->view_dispatcher);
+    scene_manager_free(app->scene_manager);
+
+    // Notifications
+    furi_record_close(RECORD_NOTIFICATION);
+    app->notifications = NULL;
+
+    // Close records
+    furi_record_close(RECORD_GUI);
+
+    free(app);
+}
+
+int32_t nfc_rfid_detector_app(void* p) {
+    UNUSED(p);
+    NfcRfidDetectorApp* nfc_rfid_detector_app = nfc_rfid_detector_app_alloc();
+
+    view_dispatcher_run(nfc_rfid_detector_app->view_dispatcher);
+
+    nfc_rfid_detector_app_free(nfc_rfid_detector_app);
+
+    return 0;
+}

+ 40 - 0
nfc_rfid_detector_app_i.c

@@ -0,0 +1,40 @@
+#include "nfc_rfid_detector_app_i.h"
+
+#include <furi.h>
+
+#define TAG "NfcRfidDetector"
+
+void nfc_rfid_detector_app_field_presence_start(NfcRfidDetectorApp* app) {
+    furi_assert(app);
+
+    // start the field presence rfid detection
+    furi_hal_rfid_field_detect_start();
+
+    // start the field presence nfc detection
+    furi_hal_nfc_exit_sleep();
+    furi_hal_nfc_field_detect_start();
+}
+
+void nfc_rfid_detector_app_field_presence_stop(NfcRfidDetectorApp* app) {
+    furi_assert(app);
+
+    // stop the field presence rfid detection
+    furi_hal_rfid_field_detect_stop();
+
+    // stop the field presence nfc detection
+    furi_hal_nfc_start_sleep();
+}
+
+bool nfc_rfid_detector_app_field_presence_is_nfc(NfcRfidDetectorApp* app) {
+    furi_assert(app);
+
+    // check if the field presence is nfc
+    return furi_hal_nfc_field_is_present();
+}
+
+bool nfc_rfid_detector_app_field_presence_is_rfid(NfcRfidDetectorApp* app, uint32_t* frequency) {
+    furi_assert(app);
+
+    // check if the field presence is rfid
+    return furi_hal_rfid_field_is_present(frequency);
+}

+ 30 - 0
nfc_rfid_detector_app_i.h

@@ -0,0 +1,30 @@
+#pragma once
+
+#include "helpers/nfc_rfid_detector_types.h"
+#include "helpers/nfc_rfid_detector_event.h"
+
+#include "scenes/nfc_rfid_detector_scene.h"
+#include <gui/gui.h>
+#include <gui/view_dispatcher.h>
+#include <gui/scene_manager.h>
+#include <gui/modules/submenu.h>
+#include <gui/modules/widget.h>
+#include <notification/notification_messages.h>
+#include "views/nfc_rfid_detector_view_field_presence.h"
+
+typedef struct NfcRfidDetectorApp NfcRfidDetectorApp;
+
+struct NfcRfidDetectorApp {
+    Gui* gui;
+    ViewDispatcher* view_dispatcher;
+    SceneManager* scene_manager;
+    NotificationApp* notifications;
+    Submenu* submenu;
+    Widget* widget;
+    NfcRfidDetectorFieldPresence* nfc_rfid_detector_field_presence;
+};
+
+void nfc_rfid_detector_app_field_presence_start(NfcRfidDetectorApp* app);
+void nfc_rfid_detector_app_field_presence_stop(NfcRfidDetectorApp* app);
+bool nfc_rfid_detector_app_field_presence_is_nfc(NfcRfidDetectorApp* app);
+bool nfc_rfid_detector_app_field_presence_is_rfid(NfcRfidDetectorApp* app, uint32_t* frequency);

+ 31 - 0
scenes/nfc_rfid_detector_scene.c

@@ -0,0 +1,31 @@
+#include "../nfc_rfid_detector_app_i.h"
+
+// Generate scene on_enter handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
+void (*const nfc_rfid_detector_scene_on_enter_handlers[])(void*) = {
+#include "nfc_rfid_detector_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Generate scene on_event handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
+bool (*const nfc_rfid_detector_scene_on_event_handlers[])(void* context, SceneManagerEvent event) =
+    {
+#include "nfc_rfid_detector_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Generate scene on_exit handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
+void (*const nfc_rfid_detector_scene_on_exit_handlers[])(void* context) = {
+#include "nfc_rfid_detector_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Initialize scene handlers configuration structure
+const SceneManagerHandlers nfc_rfid_detector_scene_handlers = {
+    .on_enter_handlers = nfc_rfid_detector_scene_on_enter_handlers,
+    .on_event_handlers = nfc_rfid_detector_scene_on_event_handlers,
+    .on_exit_handlers = nfc_rfid_detector_scene_on_exit_handlers,
+    .scene_num = NfcRfidDetectorSceneNum,
+};

+ 29 - 0
scenes/nfc_rfid_detector_scene.h

@@ -0,0 +1,29 @@
+#pragma once
+
+#include <gui/scene_manager.h>
+
+// Generate scene id and total number
+#define ADD_SCENE(prefix, name, id) NfcRfidDetectorScene##id,
+typedef enum {
+#include "nfc_rfid_detector_scene_config.h"
+    NfcRfidDetectorSceneNum,
+} NfcRfidDetectorScene;
+#undef ADD_SCENE
+
+extern const SceneManagerHandlers nfc_rfid_detector_scene_handlers;
+
+// Generate scene on_enter handlers declaration
+#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
+#include "nfc_rfid_detector_scene_config.h"
+#undef ADD_SCENE
+
+// Generate scene on_event handlers declaration
+#define ADD_SCENE(prefix, name, id) \
+    bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
+#include "nfc_rfid_detector_scene_config.h"
+#undef ADD_SCENE
+
+// Generate scene on_exit handlers declaration
+#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
+#include "nfc_rfid_detector_scene_config.h"
+#undef ADD_SCENE

+ 69 - 0
scenes/nfc_rfid_detector_scene_about.c

@@ -0,0 +1,69 @@
+#include "../nfc_rfid_detector_app_i.h"
+
+void nfc_rfid_detector_scene_about_widget_callback(
+    GuiButtonType result,
+    InputType type,
+    void* context) {
+    NfcRfidDetectorApp* app = context;
+    if(type == InputTypeShort) {
+        view_dispatcher_send_custom_event(app->view_dispatcher, result);
+    }
+}
+
+void nfc_rfid_detector_scene_about_on_enter(void* context) {
+    NfcRfidDetectorApp* app = context;
+
+    FuriString* temp_str;
+    temp_str = furi_string_alloc();
+    furi_string_printf(temp_str, "\e#%s\n", "Information");
+
+    furi_string_cat_printf(temp_str, "Version: %s\n", NFC_RFID_DETECTOR_VERSION_APP);
+    furi_string_cat_printf(temp_str, "Developed by: %s\n", NFC_RFID_DETECTOR_DEVELOPED);
+    furi_string_cat_printf(temp_str, "Github: %s\n\n", NFC_RFID_DETECTOR_GITHUB);
+
+    furi_string_cat_printf(temp_str, "\e#%s\n", "Description");
+    furi_string_cat_printf(
+        temp_str,
+        "This application allows\nyou to determine what\ntype of electromagnetic\nfield the reader is using.\nFor LF RFID you can also\nsee the carrier frequency\n\n");
+
+    widget_add_text_box_element(
+        app->widget,
+        0,
+        0,
+        128,
+        14,
+        AlignCenter,
+        AlignBottom,
+        "\e#\e!                                                      \e!\n",
+        false);
+    widget_add_text_box_element(
+        app->widget,
+        0,
+        2,
+        128,
+        14,
+        AlignCenter,
+        AlignBottom,
+        "\e#\e!      NFC/RFID detector      \e!\n",
+        false);
+    widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str));
+    furi_string_free(temp_str);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, NfcRfidDetectorViewWidget);
+}
+
+bool nfc_rfid_detector_scene_about_on_event(void* context, SceneManagerEvent event) {
+    NfcRfidDetectorApp* app = context;
+    bool consumed = false;
+    UNUSED(app);
+    UNUSED(event);
+
+    return consumed;
+}
+
+void nfc_rfid_detector_scene_about_on_exit(void* context) {
+    NfcRfidDetectorApp* app = context;
+
+    // Clear views
+    widget_reset(app->widget);
+}

+ 3 - 0
scenes/nfc_rfid_detector_scene_config.h

@@ -0,0 +1,3 @@
+ADD_SCENE(nfc_rfid_detector, start, Start)
+ADD_SCENE(nfc_rfid_detector, about, About)
+ADD_SCENE(nfc_rfid_detector, field_presence, FieldPresence)

+ 60 - 0
scenes/nfc_rfid_detector_scene_field_presence.c

@@ -0,0 +1,60 @@
+#include "../nfc_rfid_detector_app_i.h"
+#include "../views/nfc_rfid_detector_view_field_presence.h"
+
+void nfc_rfid_detector_scene_field_presence_callback(
+    NfcRfidDetectorCustomEvent event,
+    void* context) {
+    furi_assert(context);
+    NfcRfidDetectorApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, event);
+}
+
+static const NotificationSequence notification_app_display_on = {
+
+    &message_display_backlight_on,
+    NULL,
+};
+
+static void nfc_rfid_detector_scene_field_presence_update(void* context) {
+    furi_assert(context);
+    NfcRfidDetectorApp* app = context;
+
+    uint32_t frequency = 0;
+    bool nfc_field = nfc_rfid_detector_app_field_presence_is_nfc(app);
+    bool rfid_field = nfc_rfid_detector_app_field_presence_is_rfid(app, &frequency);
+
+    if(nfc_field || rfid_field)
+        notification_message(app->notifications, &notification_app_display_on);
+
+    nfc_rfid_detector_view_field_presence_update(
+        app->nfc_rfid_detector_field_presence, nfc_field, rfid_field, frequency);
+}
+
+void nfc_rfid_detector_scene_field_presence_on_enter(void* context) {
+    furi_assert(context);
+    NfcRfidDetectorApp* app = context;
+
+    // Start detection of field presence
+    nfc_rfid_detector_app_field_presence_start(app);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, NfcRfidDetectorViewFieldPresence);
+}
+
+bool nfc_rfid_detector_scene_field_presence_on_event(void* context, SceneManagerEvent event) {
+    furi_assert(context);
+    NfcRfidDetectorApp* app = context;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeTick) {
+        nfc_rfid_detector_scene_field_presence_update(app);
+    }
+
+    return consumed;
+}
+
+void nfc_rfid_detector_scene_field_presence_on_exit(void* context) {
+    furi_assert(context);
+    NfcRfidDetectorApp* app = context;
+    // Stop detection of field presence
+    nfc_rfid_detector_app_field_presence_stop(app);
+}

+ 58 - 0
scenes/nfc_rfid_detector_scene_start.c

@@ -0,0 +1,58 @@
+#include "../nfc_rfid_detector_app_i.h"
+
+typedef enum {
+    SubmenuIndexNfcRfidDetectorFieldPresence,
+    SubmenuIndexNfcRfidDetectorAbout,
+} SubmenuIndex;
+
+void nfc_rfid_detector_scene_start_submenu_callback(void* context, uint32_t index) {
+    NfcRfidDetectorApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, index);
+}
+
+void nfc_rfid_detector_scene_start_on_enter(void* context) {
+    UNUSED(context);
+    NfcRfidDetectorApp* app = context;
+    Submenu* submenu = app->submenu;
+
+    submenu_add_item(
+        submenu,
+        "Detect field type",
+        SubmenuIndexNfcRfidDetectorFieldPresence,
+        nfc_rfid_detector_scene_start_submenu_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "About",
+        SubmenuIndexNfcRfidDetectorAbout,
+        nfc_rfid_detector_scene_start_submenu_callback,
+        app);
+
+    submenu_set_selected_item(
+        submenu, scene_manager_get_scene_state(app->scene_manager, NfcRfidDetectorSceneStart));
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, NfcRfidDetectorViewSubmenu);
+}
+
+bool nfc_rfid_detector_scene_start_on_event(void* context, SceneManagerEvent event) {
+    NfcRfidDetectorApp* app = context;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == SubmenuIndexNfcRfidDetectorAbout) {
+            scene_manager_next_scene(app->scene_manager, NfcRfidDetectorSceneAbout);
+            consumed = true;
+        } else if(event.event == SubmenuIndexNfcRfidDetectorFieldPresence) {
+            scene_manager_next_scene(app->scene_manager, NfcRfidDetectorSceneFieldPresence);
+            consumed = true;
+        }
+        scene_manager_set_scene_state(app->scene_manager, NfcRfidDetectorSceneStart, event.event);
+    }
+
+    return consumed;
+}
+
+void nfc_rfid_detector_scene_start_on_exit(void* context) {
+    NfcRfidDetectorApp* app = context;
+    submenu_reset(app->submenu);
+}

+ 164 - 0
views/nfc_rfid_detector_view_field_presence.c

@@ -0,0 +1,164 @@
+#include "nfc_rfid_detector_view_field_presence.h"
+#include "../nfc_rfid_detector_app_i.h"
+#include <nfc_rfid_detector_icons.h>
+
+#include <input/input.h>
+#include <gui/elements.h>
+
+#define FIELD_FOUND_WEIGHT 5
+
+typedef enum {
+    NfcRfidDetectorTypeFieldPresenceNfc,
+    NfcRfidDetectorTypeFieldPresenceRfid,
+} NfcRfidDetectorTypeFieldPresence;
+
+static const Icon* NfcRfidDetectorFieldPresenceIcons[] = {
+    [NfcRfidDetectorTypeFieldPresenceNfc] = &I_NFC_detect_45x30,
+    [NfcRfidDetectorTypeFieldPresenceRfid] = &I_Rfid_detect_45x30,
+};
+
+struct NfcRfidDetectorFieldPresence {
+    View* view;
+};
+
+typedef struct {
+    uint8_t nfc_field;
+    uint8_t rfid_field;
+    uint32_t rfid_frequency;
+} NfcRfidDetectorFieldPresenceModel;
+
+void nfc_rfid_detector_view_field_presence_update(
+    NfcRfidDetectorFieldPresence* instance,
+    bool nfc_field,
+    bool rfid_field,
+    uint32_t rfid_frequency) {
+    furi_assert(instance);
+    with_view_model(
+        instance->view,
+        NfcRfidDetectorFieldPresenceModel * model,
+        {
+            if(nfc_field) {
+                model->nfc_field = FIELD_FOUND_WEIGHT;
+            } else if(model->nfc_field) {
+                model->nfc_field--;
+            }
+            if(rfid_field) {
+                model->rfid_field = FIELD_FOUND_WEIGHT;
+                model->rfid_frequency = rfid_frequency;
+            } else if(model->rfid_field) {
+                model->rfid_field--;
+            }
+        },
+        true);
+}
+
+void nfc_rfid_detector_view_field_presence_draw(
+    Canvas* canvas,
+    NfcRfidDetectorFieldPresenceModel* model) {
+    canvas_clear(canvas);
+    canvas_set_color(canvas, ColorBlack);
+
+    if(!model->nfc_field && !model->rfid_field) {
+        canvas_draw_icon(canvas, 0, 16, &I_Modern_reader_18x34);
+        canvas_draw_icon(canvas, 22, 12, &I_Move_flipper_26x39);
+        canvas_set_font(canvas, FontSecondary);
+        canvas_draw_str(canvas, 56, 36, "Touch the reader");
+    } else {
+        if(model->nfc_field) {
+            canvas_set_font(canvas, FontPrimary);
+            canvas_draw_str(canvas, 21, 10, "NFC");
+            canvas_draw_icon(
+                canvas,
+                9,
+                17,
+                NfcRfidDetectorFieldPresenceIcons[NfcRfidDetectorTypeFieldPresenceNfc]);
+            canvas_set_font(canvas, FontSecondary);
+            canvas_draw_str(canvas, 9, 62, "13,56 MHz");
+        }
+
+        if(model->rfid_field) {
+            char str[16];
+            snprintf(str, sizeof(str), "%.02f KHz", (double)model->rfid_frequency / 1000);
+            canvas_set_font(canvas, FontPrimary);
+            canvas_draw_str(canvas, 76, 10, "LF RFID");
+            canvas_draw_icon(
+                canvas,
+                71,
+                17,
+                NfcRfidDetectorFieldPresenceIcons[NfcRfidDetectorTypeFieldPresenceRfid]);
+            canvas_set_font(canvas, FontSecondary);
+            canvas_draw_str(canvas, 69, 62, str);
+        }
+    }
+}
+
+bool nfc_rfid_detector_view_field_presence_input(InputEvent* event, void* context) {
+    furi_assert(context);
+    NfcRfidDetectorFieldPresence* instance = context;
+    UNUSED(instance);
+
+    if(event->key == InputKeyBack) {
+        return false;
+    }
+
+    return true;
+}
+
+void nfc_rfid_detector_view_field_presence_enter(void* context) {
+    furi_assert(context);
+    NfcRfidDetectorFieldPresence* instance = context;
+    with_view_model(
+        instance->view,
+        NfcRfidDetectorFieldPresenceModel * model,
+        {
+            model->nfc_field = 0;
+            model->rfid_field = 0;
+            model->rfid_frequency = 0;
+        },
+        true);
+}
+
+void nfc_rfid_detector_view_field_presence_exit(void* context) {
+    furi_assert(context);
+    NfcRfidDetectorFieldPresence* instance = context;
+    UNUSED(instance);
+}
+
+NfcRfidDetectorFieldPresence* nfc_rfid_detector_view_field_presence_alloc() {
+    NfcRfidDetectorFieldPresence* instance = malloc(sizeof(NfcRfidDetectorFieldPresence));
+
+    // View allocation and configuration
+    instance->view = view_alloc();
+
+    view_allocate_model(
+        instance->view, ViewModelTypeLocking, sizeof(NfcRfidDetectorFieldPresenceModel));
+    view_set_context(instance->view, instance);
+    view_set_draw_callback(
+        instance->view, (ViewDrawCallback)nfc_rfid_detector_view_field_presence_draw);
+    view_set_input_callback(instance->view, nfc_rfid_detector_view_field_presence_input);
+    view_set_enter_callback(instance->view, nfc_rfid_detector_view_field_presence_enter);
+    view_set_exit_callback(instance->view, nfc_rfid_detector_view_field_presence_exit);
+
+    with_view_model(
+        instance->view,
+        NfcRfidDetectorFieldPresenceModel * model,
+        {
+            model->nfc_field = 0;
+            model->rfid_field = 0;
+            model->rfid_frequency = 0;
+        },
+        true);
+    return instance;
+}
+
+void nfc_rfid_detector_view_field_presence_free(NfcRfidDetectorFieldPresence* instance) {
+    furi_assert(instance);
+
+    view_free(instance->view);
+    free(instance);
+}
+
+View* nfc_rfid_detector_view_field_presence_get_view(NfcRfidDetectorFieldPresence* instance) {
+    furi_assert(instance);
+    return instance->view;
+}

+ 19 - 0
views/nfc_rfid_detector_view_field_presence.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#include <gui/view.h>
+#include "../helpers/nfc_rfid_detector_types.h"
+#include "../helpers/nfc_rfid_detector_event.h"
+
+typedef struct NfcRfidDetectorFieldPresence NfcRfidDetectorFieldPresence;
+
+void nfc_rfid_detector_view_field_presence_update(
+    NfcRfidDetectorFieldPresence* instance,
+    bool nfc_field,
+    bool rfid_field,
+    uint32_t rfid_frequency);
+
+NfcRfidDetectorFieldPresence* nfc_rfid_detector_view_field_presence_alloc();
+
+void nfc_rfid_detector_view_field_presence_free(NfcRfidDetectorFieldPresence* instance);
+
+View* nfc_rfid_detector_view_field_presence_get_view(NfcRfidDetectorFieldPresence* instance);