MX 9 месяцев назад
Родитель
Сommit
9e747a9497

+ 16 - 1
CHANGELOG.md

@@ -1,3 +1,18 @@
-## v1.0
+## 1.1.2
+
+- Blue LED blinks on data reception
+- Backlight is now enabled during communication
+
+## 1.1.1
+
+- Bump for README acknowledgement fixes
+
+## 1.1.0
+
+- Fixed app for latest firmware
+- Desktop app QR code
+- Minor code refactoring
+
+## 1.0.0
 
 - Stable release.

+ 3 - 2
application.fam

@@ -7,7 +7,8 @@ App(
     stack_size=1 * 1024,
     fap_description="Application for monitoring PC resources",
     fap_category="Bluetooth",
-    fap_icon="icons/icon_10px.png",
-    fap_version="1.0",
+    fap_icon_assets="assets",
+    fap_icon="assets/icon_10px.png",
+    fap_version="1.1.2",
     fap_author="Olejka",
 )

BIN
assets/icon_10px.png


BIN
assets/qr_33px.png


+ 33 - 17
helpers/ble_serial.c

@@ -1,9 +1,20 @@
+/*
+ * This code is based on the Willy-JL's (https://github.com/Willy-JL) BLE fix.
+ * 
+ * Thank you to Willy-JL for providing this code and making it available under the https://github.com/Flipper-XFW/Xtreme-Apps repository.
+ * Your contribution has been invaluable for this project.
+ * 
+ * Based on <targets/f7/ble_glue/profiles/serial_profile.c>
+ * and on <lib/ble_profile/extra_profiles/hid_profile.c>
+ */
+
 #include "ble_serial.h"
 
 #include <gap.h>
 #include <furi_ble/profile_interface.h>
 #include <services/serial_service.h>
 #include <furi.h>
+#include <ble/core/ble_defs.h>
 
 typedef struct {
     FuriHalBleProfileBase base;
@@ -32,14 +43,24 @@ static void ble_profile_serial_stop(FuriHalBleProfileBase* profile) {
     ble_svc_serial_stop(serial_profile->serial_svc);
 }
 
-static GapConfig serial_template_config = {
-    .adv_service_uuid = 0x3080,
+// AN5289: 4.7, in order to use flash controller interval must be at least 25ms + advertisement, which is 30 ms
+// Since we don't use flash controller anymore interval can be lowered to 7.5ms
+#define CONNECTION_INTERVAL_MIN (0x06)
+// Up to 45 ms
+#define CONNECTION_INTERVAL_MAX (0x24)
+
+static const GapConfig serial_template_config = {
+    .adv_service =
+        {
+            .UUID_Type = UUID_TYPE_16,
+            .Service_UUID_16 = 0x3080,
+        },
     .appearance_char = 0x8600,
     .bonding_mode = true,
     .pairing_method = GapPairingPinCodeShow,
     .conn_param = {
-        .conn_int_min = 0x18, // 30 ms
-        .conn_int_max = 0x24, // 45 ms
+        .conn_int_min = CONNECTION_INTERVAL_MIN,
+        .conn_int_max = CONNECTION_INTERVAL_MAX,
         .slave_latency = 0,
         .supervisor_timeout = 0,
     }};
@@ -53,7 +74,7 @@ static void
     // Set mac address
     memcpy(config->mac_address, furi_hal_version_get_ble_mac(), sizeof(config->mac_address));
 
-    // Change MAC address for HID profile
+    // Change MAC address for Serial profile
     config->mac_address[2]++;
     if(serial_profile_params) {
         config->mac_address[0] ^= serial_profile_params->mac_xor;
@@ -61,25 +82,20 @@ static void
     }
 
     // Set advertise name
-    memset(config->adv_name, 0, sizeof(config->adv_name));
-
     const char* clicker_str = "Serial";
     if(serial_profile_params && serial_profile_params->device_name_prefix) {
         clicker_str = serial_profile_params->device_name_prefix;
     }
-    // We don't have Flipper in BLE name, use printf instead of replace
-    FuriString* name = furi_string_alloc_printf(
+    snprintf(
+        config->adv_name,
+        sizeof(config->adv_name),
         "%c%s %s",
         furi_hal_version_get_ble_local_device_name_ptr()[0],
         clicker_str,
-        furi_hal_version_get_ble_local_device_name_ptr() + 1);
-    if(furi_string_size(name) >= sizeof(config->adv_name)) {
-        furi_string_left(name, sizeof(config->adv_name) - 1);
-    }
-    memcpy(config->adv_name, furi_string_get_cstr(name), furi_string_size(name));
-    furi_string_free(name);
+        furi_hal_version_get_name_ptr());
 
-    config->adv_service_uuid |= furi_hal_version_get_hw_color();
+    config->adv_service.UUID_Type = UUID_TYPE_16;
+    config->adv_service.Service_UUID_16 |= furi_hal_version_get_hw_color();
 }
 
 static const FuriHalBleProfileTemplate profile_callbacks = {
@@ -88,7 +104,7 @@ static const FuriHalBleProfileTemplate profile_callbacks = {
     .get_gap_config = ble_profile_serial_get_config,
 };
 
-const FuriHalBleProfileTemplate* ble_profile_serial = &profile_callbacks;
+const FuriHalBleProfileTemplate* const ble_profile_serial = &profile_callbacks;
 
 void ble_profile_serial_set_event_callback(
     FuriHalBleProfileBase* profile,

+ 11 - 1
helpers/ble_serial.h

@@ -1,3 +1,13 @@
+/*
+ * This code is based on the Willy-JL's (https://github.com/Willy-JL) BLE fix.
+ * 
+ * Thank you to Willy-JL for providing this code and making it available under the https://github.com/Flipper-XFW/Xtreme-Apps repository.
+ * Your contribution has been invaluable for this project.
+ * 
+ * Based on <targets/f7/ble_glue/profiles/serial_profile.h>
+ * and on <lib/ble_profile/extra_profiles/hid_profile.h>
+ */
+
 #pragma once
 
 #include <furi_ble/profile_interface.h>
@@ -23,7 +33,7 @@ typedef struct {
 typedef SerialServiceEventCallback FuriHalBtSerialCallback;
 
 /** Serial profile descriptor */
-extern const FuriHalBleProfileTemplate* ble_profile_serial;
+extern const FuriHalBleProfileTemplate* const ble_profile_serial;
 
 /** Send data through BLE
  *

+ 18 - 101
pc_monitor.c

@@ -4,106 +4,18 @@ static void render_callback(Canvas* canvas, void* ctx) {
     furi_assert(ctx);
     PcMonitorApp* app = ctx;
 
-    if(app->bt_state == BtStateRecieving) {
-        canvas_clear(canvas);
-        canvas_set_color(canvas, ColorBlack);
-        canvas_set_font(canvas, FontKeyboard);
-
-        uint8_t line = 0;
-        uint8_t spacing = app->lines_count ? SCREEN_HEIGHT / app->lines_count : 0;
-        uint8_t margin_top = spacing ? (spacing - LINE_HEIGHT) / 2 : 0;
-        char str[32];
-
-        if(app->data.cpu_usage <= 100) {
-            if(app->lines_count) {
-                canvas_draw_str(canvas, 1, margin_top + line * spacing + 9, "CPU");
-                snprintf(str, 32, "%d%%", app->data.cpu_usage);
-                elements_progress_bar_with_text(
-                    canvas,
-                    BAR_X,
-                    margin_top + line * spacing,
-                    BAR_WIDTH,
-                    app->data.cpu_usage / 100.0f,
-                    str);
-            }
-
-            line++;
-        }
-
-        if(app->data.ram_usage <= 100) {
-            if(app->lines_count) {
-                canvas_draw_str(canvas, 1, margin_top + line * spacing + 9, "RAM");
-                snprintf(
-                    str,
-                    32,
-                    "%.1f/%.1f %s",
-                    (double)(app->data.ram_max * 0.1f * app->data.ram_usage * 0.01f),
-                    (double)(app->data.ram_max * 0.1f),
-                    app->data.ram_unit);
-                elements_progress_bar_with_text(
-                    canvas,
-                    BAR_X,
-                    margin_top + line * spacing,
-                    BAR_WIDTH,
-                    app->data.ram_usage * 0.01f,
-                    str);
-            }
-
-            line++;
-        }
-
-        if(app->data.gpu_usage <= 100) {
-            if(app->lines_count) {
-                canvas_draw_str(canvas, 1, margin_top + line * spacing + 9, "GPU");
-                snprintf(str, 32, "%d%%", app->data.gpu_usage);
-                elements_progress_bar_with_text(
-                    canvas,
-                    BAR_X,
-                    margin_top + line * spacing,
-                    BAR_WIDTH,
-                    app->data.gpu_usage / 100.0f,
-                    str);
-            }
-
-            line++;
-        }
-
-        if(app->data.vram_usage <= 100) {
-            if(app->lines_count) {
-                canvas_draw_str(canvas, 1, margin_top + line * spacing + 9, "VRAM");
-                snprintf(
-                    str,
-                    32,
-                    "%.1f/%.1f %s",
-                    (double)(app->data.vram_max * 0.1f * app->data.vram_usage * 0.01f),
-                    (double)(app->data.vram_max * 0.1f),
-                    app->data.vram_unit);
-                elements_progress_bar_with_text(
-                    canvas,
-                    BAR_X,
-                    margin_top + line * spacing,
-                    BAR_WIDTH,
-                    app->data.vram_usage * 0.01f,
-                    str);
-            }
-
-            line++;
-        }
-
-        if(line == 0) app->bt_state = BtStateNoData;
-        app->lines_count = line;
-    } else {
-        canvas_draw_str_aligned(
-            canvas,
-            64,
-            32,
-            AlignCenter,
-            AlignCenter,
-            app->bt_state == BtStateChecking ? "Checking BLE..." :
-            app->bt_state == BtStateInactive ? "BLE inactive!" :
-            app->bt_state == BtStateWaiting  ? "Waiting for data..." :
-            app->bt_state == BtStateLost     ? "Connection lost!" :
-                                               "No data!");
+    switch(app->bt_state) {
+    case BtStateWaiting:
+        draw_connect_view(canvas);
+        break;
+
+    case BtStateRecieving:
+        draw_bars_view(canvas, app);
+        break;
+
+    default:
+        draw_status_view(canvas, app);
+        break;
     }
 }
 
@@ -129,6 +41,11 @@ static uint16_t bt_serial_callback(SerialServiceEvent event, void* ctx) {
             memcpy(&app->data, event.data.buffer, sizeof(DataStruct));
             app->bt_state = BtStateRecieving;
             app->last_packet = furi_hal_rtc_get_timestamp();
+
+            // Elegant solution, the backlight is only on when there is continuous communication
+            notification_message(app->notification, &sequence_display_backlight_on);
+
+            notification_message(app->notification, &sequence_blink_blue_10);
         }
     }
 
@@ -211,4 +128,4 @@ int32_t pc_monitor_app(void* p) {
     pc_monitor_free(app);
 
     return 0;
-}
+}

+ 8 - 4
pc_monitor.h

@@ -11,13 +11,17 @@
 #include <input/input.h>
 #include <storage/storage.h>
 
-#define TAG "PCMonitor"
+#include "views/bars_view.h"
+#include "views/connect_view.h"
+#include "views/status_view.h"
+
+#define TAG                   "PCMonitor"
 #define BT_SERIAL_BUFFER_SIZE 128
 
 #define SCREEN_HEIGHT 64
-#define LINE_HEIGHT 11
+#define LINE_HEIGHT   11
 
-#define BAR_X 30
+#define BAR_X     30
 #define BAR_WIDTH 97
 
 typedef enum {
@@ -55,4 +59,4 @@ typedef struct {
     DataStruct data;
     uint8_t lines_count;
     uint32_t last_packet;
-} PcMonitorApp;
+} PcMonitorApp;

BIN
screenshots/0.png


BIN
screenshots/1.png


BIN
screenshots/2.png


BIN
screenshots/qFlipper.png


+ 93 - 0
views/bars_view.c

@@ -0,0 +1,93 @@
+#include "bars_view.h"
+
+void draw_bars_view(Canvas* canvas, void* ctx) {
+    PcMonitorApp* app = ctx;
+
+    canvas_clear(canvas);
+    canvas_set_color(canvas, ColorBlack);
+    canvas_set_font(canvas, FontKeyboard);
+
+    uint8_t line = 0;
+    uint8_t spacing = app->lines_count ? SCREEN_HEIGHT / app->lines_count : 0;
+    uint8_t margin_top = spacing ? (spacing - LINE_HEIGHT) / 2 : 0;
+    char str[32];
+
+    if(app->data.cpu_usage <= 100) {
+        if(app->lines_count) {
+            canvas_draw_str(canvas, 1, margin_top + line * spacing + 9, "CPU");
+            snprintf(str, 32, "%d%%", app->data.cpu_usage);
+            elements_progress_bar_with_text(
+                canvas,
+                BAR_X,
+                margin_top + line * spacing,
+                BAR_WIDTH,
+                app->data.cpu_usage / 100.0f,
+                str);
+        }
+
+        line++;
+    }
+
+    if(app->data.ram_usage <= 100) {
+        if(app->lines_count) {
+            canvas_draw_str(canvas, 1, margin_top + line * spacing + 9, "RAM");
+            snprintf(
+                str,
+                32,
+                "%.1f/%.1f %s",
+                (double)(app->data.ram_max * 0.1f * app->data.ram_usage * 0.01f),
+                (double)(app->data.ram_max * 0.1f),
+                app->data.ram_unit);
+            elements_progress_bar_with_text(
+                canvas,
+                BAR_X,
+                margin_top + line * spacing,
+                BAR_WIDTH,
+                app->data.ram_usage * 0.01f,
+                str);
+        }
+
+        line++;
+    }
+
+    if(app->data.gpu_usage <= 100) {
+        if(app->lines_count) {
+            canvas_draw_str(canvas, 1, margin_top + line * spacing + 9, "GPU");
+            snprintf(str, 32, "%d%%", app->data.gpu_usage);
+            elements_progress_bar_with_text(
+                canvas,
+                BAR_X,
+                margin_top + line * spacing,
+                BAR_WIDTH,
+                app->data.gpu_usage / 100.0f,
+                str);
+        }
+
+        line++;
+    }
+
+    if(app->data.vram_usage <= 100) {
+        if(app->lines_count) {
+            canvas_draw_str(canvas, 1, margin_top + line * spacing + 9, "VRAM");
+            snprintf(
+                str,
+                32,
+                "%.1f/%.1f %s",
+                (double)(app->data.vram_max * 0.1f * app->data.vram_usage * 0.01f),
+                (double)(app->data.vram_max * 0.1f),
+                app->data.vram_unit);
+            elements_progress_bar_with_text(
+                canvas,
+                BAR_X,
+                margin_top + line * spacing,
+                BAR_WIDTH,
+                app->data.vram_usage * 0.01f,
+                str);
+        }
+
+        line++;
+    }
+
+    if(line == 0) app->bt_state = BtStateNoData;
+    app->lines_count = line;
+}

+ 6 - 0
views/bars_view.h

@@ -0,0 +1,6 @@
+#pragma once
+
+#include <gui/gui.h>
+#include "../pc_monitor.h"
+
+void draw_bars_view(Canvas* canvas, void* ctx);

+ 13 - 0
views/connect_view.c

@@ -0,0 +1,13 @@
+#include "connect_view.h"
+
+void draw_connect_view(Canvas* canvas) {
+    canvas_draw_str(
+        canvas, 1, 10, "Waiting for connection...");
+
+    canvas_draw_str(
+        canvas, 1, 40, "Download back-end");
+    canvas_draw_str(
+        canvas, 1, 50, "app for your PC from:");
+
+    canvas_draw_icon(canvas, 128-34, 64-34, &I_qr_33px);
+}

+ 7 - 0
views/connect_view.h

@@ -0,0 +1,7 @@
+#pragma once
+
+#include <gui/gui.h>
+#include <pc_monitor_icons.h>
+#include "../pc_monitor.h"
+
+void draw_connect_view(Canvas* canvas);

+ 16 - 0
views/status_view.c

@@ -0,0 +1,16 @@
+#include "status_view.h"
+
+void draw_status_view(Canvas* canvas, void* ctx) {
+    PcMonitorApp* app = ctx;
+
+    canvas_draw_str_aligned(
+        canvas,
+        64,
+        32,
+        AlignCenter,
+        AlignCenter,
+        app->bt_state == BtStateChecking ? "Checking BLE..." :
+        app->bt_state == BtStateInactive ? "BLE inactive!" :
+        app->bt_state == BtStateLost     ? "Connection lost!" :
+                                           "No data!");
+}

+ 6 - 0
views/status_view.h

@@ -0,0 +1,6 @@
+#pragma once
+
+#include <gui/gui.h>
+#include "../pc_monitor.h"
+
+void draw_status_view(Canvas* canvas, void* ctx);