Selaa lähdekoodia

Hide debug tools if debug is not enabled. Application: update debug tools code base. SubGhz: log duty cycle. (#903)

* Application: clean debug_tools code base.
* SubGhz: add duty cycle logging.
* Application: hide debug tools if not enabled. Gui: move icon_animation allocation to menu module.
あく 4 vuotta sitten
vanhempi
commit
63642617ee

+ 20 - 20
applications/debug_tools/blink_test.c

@@ -9,20 +9,20 @@
 #define BLINK_COLOR_COUNT 7
 
 typedef enum {
-    EventTypeTick,
-    EventTypeKey,
-} EventType;
+    BlinkEventTypeTick,
+    BlinkEventTypeInput,
+} BlinkEventType;
 
 typedef struct {
-    EventType type;
+    BlinkEventType type;
     InputEvent input;
 } BlinkEvent;
 
 static void blink_test_update(void* ctx) {
     furi_assert(ctx);
     osMessageQueueId_t event_queue = ctx;
-
-    BlinkEvent event = {.type = EventTypeTick};
+    BlinkEvent event = {.type = BlinkEventTypeTick};
+    // It's OK to loose this event if system overloaded
     osMessageQueuePut(event_queue, &event, 0, 0);
 }
 
@@ -36,8 +36,8 @@ static void blink_test_input_callback(InputEvent* input_event, void* ctx) {
     furi_assert(ctx);
     osMessageQueueId_t event_queue = ctx;
 
-    BlinkEvent event = {.type = EventTypeKey, .input = *input_event};
-    osMessageQueuePut(event_queue, &event, 0, 0);
+    BlinkEvent event = {.type = BlinkEventTypeInput, .input = *input_event};
+    osMessageQueuePut(event_queue, &event, 0, osWaitForever);
 }
 
 int32_t blink_test_app(void* p) {
@@ -45,7 +45,6 @@ int32_t blink_test_app(void* p) {
 
     // Configure view port
     ViewPort* view_port = view_port_alloc();
-    furi_check(view_port);
     view_port_draw_callback_set(view_port, blink_test_draw_callback, NULL);
     view_port_input_callback_set(view_port, blink_test_input_callback, event_queue);
     osTimerId_t timer = osTimerNew(blink_test_update, osTimerPeriodic, event_queue, NULL);
@@ -72,20 +71,12 @@ int32_t blink_test_app(void* p) {
 
     while(1) {
         furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK);
-        if(event.type == EventTypeKey) {
+        if(event.type == BlinkEventTypeInput) {
             if((event.input.type == InputTypeShort) && (event.input.key == InputKeyBack)) {
-                furi_record_close("notification");
-                view_port_enabled_set(view_port, false);
-                gui_remove_view_port(gui, view_port);
-                view_port_free(view_port);
-                osMessageQueueDelete(event_queue);
-                osTimerDelete(timer);
-
-                return 0;
+                break;
             }
         } else {
             notification_message(notifications, colors[state]);
-
             state++;
             if(state >= BLINK_COLOR_COUNT) {
                 state = 0;
@@ -93,5 +84,14 @@ int32_t blink_test_app(void* p) {
         }
     }
 
+    osTimerDelete(timer);
+
+    gui_remove_view_port(gui, view_port);
+    view_port_free(view_port);
+    osMessageQueueDelete(event_queue);
+
+    furi_record_close("notification");
+    furi_record_close("gui");
+
     return 0;
-}
+}

+ 61 - 98
applications/debug_tools/keypad_test.c

@@ -13,17 +13,6 @@ typedef struct {
     uint16_t ok;
 } KeypadTestState;
 
-typedef enum {
-    EventTypeInput,
-} EventType;
-
-typedef struct {
-    union {
-        InputEvent input;
-    };
-    EventType type;
-} KeypadTestEvent;
-
 static void keypad_test_reset_state(KeypadTestState* state) {
     state->left = 0;
     state->right = 0;
@@ -67,15 +56,11 @@ static void keypad_test_render_callback(Canvas* canvas, void* ctx) {
 
 static void keypad_test_input_callback(InputEvent* input_event, void* ctx) {
     osMessageQueueId_t event_queue = ctx;
-
-    KeypadTestEvent event;
-    event.type = EventTypeInput;
-    event.input = *input_event;
-    osMessageQueuePut(event_queue, &event, 0, osWaitForever);
+    osMessageQueuePut(event_queue, input_event, 0, osWaitForever);
 }
 
 int32_t keypad_test_app(void* p) {
-    osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(KeypadTestEvent), NULL);
+    osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL);
     furi_check(event_queue);
 
     KeypadTestState _state = {{false, false, false, false, false}, 0, 0, 0, 0, 0};
@@ -95,97 +80,75 @@ int32_t keypad_test_app(void* p) {
     Gui* gui = furi_record_open("gui");
     gui_add_view_port(gui, view_port, GuiLayerFullscreen);
 
-    KeypadTestEvent event;
-    while(1) {
-        osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, osWaitForever);
+    InputEvent event;
+    while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) {
         KeypadTestState* state = (KeypadTestState*)acquire_mutex_block(&state_mutex);
-
-        if(event_status == osOK) {
-            if(event.type == EventTypeInput) {
-                FURI_LOG_I(
-                    TAG,
-                    "key: %s type: %s",
-                    input_get_key_name(event.input.key),
-                    input_get_type_name(event.input.type));
-
-                if(event.input.type == InputTypeLong && event.input.key == InputKeyBack) {
-                    release_mutex(&state_mutex, state);
-                    break;
-                }
-
-                if(event.input.type == InputTypeShort && event.input.key == InputKeyBack) {
-                    keypad_test_reset_state(state);
-                }
-
-                if(event.input.key == InputKeyRight) {
-                    if(event.input.type == InputTypePress) {
-                        state->press[0] = true;
-                    } else if(event.input.type == InputTypeRelease) {
-                        state->press[0] = false;
-                    }
-
-                    if(event.input.type == InputTypeShort) {
-                        ++state->right;
-                    }
-                }
-
-                if(event.input.key == InputKeyLeft) {
-                    if(event.input.type == InputTypePress) {
-                        state->press[1] = true;
-                    } else if(event.input.type == InputTypeRelease) {
-                        state->press[1] = false;
-                    }
-
-                    if(event.input.type == InputTypeShort) {
-                        ++state->left;
-                    }
-                }
-
-                if(event.input.key == InputKeyUp) {
-                    if(event.input.type == InputTypePress) {
-                        state->press[2] = true;
-                    } else if(event.input.type == InputTypeRelease) {
-                        state->press[2] = false;
-                    }
-
-                    if(event.input.type == InputTypeShort) {
-                        ++state->up;
-                    }
-                }
-
-                if(event.input.key == InputKeyDown) {
-                    if(event.input.type == InputTypePress) {
-                        state->press[3] = true;
-                    } else if(event.input.type == InputTypeRelease) {
-                        state->press[3] = false;
-                    }
-
-                    if(event.input.type == InputTypeShort) {
-                        ++state->down;
-                    }
-                }
-
-                if(event.input.key == InputKeyOk) {
-                    if(event.input.type == InputTypePress) {
-                        state->press[4] = true;
-                    } else if(event.input.type == InputTypeRelease) {
-                        state->press[4] = false;
-                    }
-
-                    if(event.input.type == InputTypeShort) {
-                        ++state->ok;
-                    }
-                }
+        FURI_LOG_I(
+            TAG,
+            "key: %s type: %s",
+            input_get_key_name(event.key),
+            input_get_type_name(event.type));
+
+        if(event.key == InputKeyRight) {
+            if(event.type == InputTypePress) {
+                state->press[0] = true;
+            } else if(event.type == InputTypeRelease) {
+                state->press[0] = false;
+            } else if(event.type == InputTypeShort) {
+                ++state->right;
+            }
+        } else if(event.key == InputKeyLeft) {
+            if(event.type == InputTypePress) {
+                state->press[1] = true;
+            } else if(event.type == InputTypeRelease) {
+                state->press[1] = false;
+            } else if(event.type == InputTypeShort) {
+                ++state->left;
+            }
+        } else if(event.key == InputKeyUp) {
+            if(event.type == InputTypePress) {
+                state->press[2] = true;
+            } else if(event.type == InputTypeRelease) {
+                state->press[2] = false;
+            } else if(event.type == InputTypeShort) {
+                ++state->up;
+            }
+        } else if(event.key == InputKeyDown) {
+            if(event.type == InputTypePress) {
+                state->press[3] = true;
+            } else if(event.type == InputTypeRelease) {
+                state->press[3] = false;
+            } else if(event.type == InputTypeShort) {
+                ++state->down;
+            }
+        } else if(event.key == InputKeyOk) {
+            if(event.type == InputTypePress) {
+                state->press[4] = true;
+            } else if(event.type == InputTypeRelease) {
+                state->press[4] = false;
+            } else if(event.type == InputTypeShort) {
+                ++state->ok;
+            }
+        } else if(event.key == InputKeyBack) {
+            if(event.type == InputTypeLong) {
+                release_mutex(&state_mutex, state);
+                break;
+            } else if(event.type == InputTypeShort) {
+                keypad_test_reset_state(state);
             }
         }
-        view_port_update(view_port);
+
         release_mutex(&state_mutex, state);
+        view_port_update(view_port);
     }
+
     // remove & free all stuff created by app
     gui_remove_view_port(gui, view_port);
     view_port_free(view_port);
     osMessageQueueDelete(event_queue);
     delete_mutex(&state_mutex);
 
+    furi_record_close("gui");
+
     return 0;
 }

+ 17 - 24
applications/debug_tools/vibro_test.c

@@ -5,10 +5,6 @@
 #include <input/input.h>
 #include <notification/notification-messages.h>
 
-typedef struct {
-    InputEvent input;
-} VibroEvent;
-
 void vibro_test_draw_callback(Canvas* canvas, void* ctx) {
     canvas_clear(canvas);
     canvas_set_font(canvas, FontPrimary);
@@ -22,17 +18,14 @@ void vibro_test_draw_callback(Canvas* canvas, void* ctx) {
 void vibro_test_input_callback(InputEvent* input_event, void* ctx) {
     furi_assert(ctx);
     osMessageQueueId_t event_queue = ctx;
-
-    VibroEvent event = {.input = *input_event};
-    osMessageQueuePut(event_queue, &event, 0, 0);
+    osMessageQueuePut(event_queue, input_event, 0, osWaitForever);
 }
 
 int32_t vibro_test_app(void* p) {
-    osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(VibroEvent), NULL);
+    osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL);
 
     // Configure view port
     ViewPort* view_port = view_port_alloc();
-    furi_check(view_port);
     view_port_draw_callback_set(view_port, vibro_test_draw_callback, NULL);
     view_port_input_callback_set(view_port, vibro_test_input_callback, event_queue);
 
@@ -42,31 +35,31 @@ int32_t vibro_test_app(void* p) {
 
     NotificationApp* notification = furi_record_open("notification");
 
-    VibroEvent event;
+    InputEvent event;
 
-    while(1) {
-        furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK);
-        if(event.input.type == InputTypeShort && event.input.key == InputKeyBack) {
+    while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) {
+        if(event.type == InputTypeShort && event.key == InputKeyBack) {
             notification_message(notification, &sequence_reset_vibro);
             notification_message(notification, &sequence_reset_green);
-            furi_record_close("notification");
-            view_port_enabled_set(view_port, false);
-            gui_remove_view_port(gui, view_port);
-            view_port_free(view_port);
-            osMessageQueueDelete(event_queue);
-
-            return 0;
+            break;
         }
-        if(event.input.key == InputKeyOk) {
-            if(event.input.type == InputTypePress) {
+        if(event.key == InputKeyOk) {
+            if(event.type == InputTypePress) {
                 notification_message(notification, &sequence_set_vibro_on);
                 notification_message(notification, &sequence_set_green_255);
-            } else if(event.input.type == InputTypeRelease) {
+            } else if(event.type == InputTypeRelease) {
                 notification_message(notification, &sequence_reset_vibro);
                 notification_message(notification, &sequence_reset_green);
             }
         }
     }
 
+    gui_remove_view_port(gui, view_port);
+    view_port_free(view_port);
+    osMessageQueueDelete(event_queue);
+
+    furi_record_close("notification");
+    furi_record_close("gui");
+
     return 0;
-}
+}

+ 11 - 7
applications/gui/modules/menu.c

@@ -18,6 +18,8 @@ typedef struct {
 
 ARRAY_DEF(MenuItemArray, MenuItem, M_POD_OPLIST);
 
+#define M_OPL_MenuItemArray_t() ARRAY_OPLIST(MenuItemArray, M_POD_OPLIST)
+
 typedef struct {
     MenuItemArray_t items;
     size_t position;
@@ -136,11 +138,7 @@ Menu* menu_alloc() {
 
 void menu_free(Menu* menu) {
     furi_assert(menu);
-    with_view_model(
-        menu->view, (MenuModel * model) {
-            MenuItemArray_clear(model->items);
-            return true;
-        });
+    menu_clean(menu);
     view_free(menu->view);
     free(menu);
 }
@@ -153,7 +151,7 @@ View* menu_get_view(Menu* menu) {
 void menu_add_item(
     Menu* menu,
     const char* label,
-    IconAnimation* icon,
+    const Icon* icon,
     uint32_t index,
     MenuItemCallback callback,
     void* context) {
@@ -165,7 +163,7 @@ void menu_add_item(
         menu->view, (MenuModel * model) {
             item = MenuItemArray_push_new(model->items);
             item->label = label;
-            item->icon = icon;
+            item->icon = icon ? icon_animation_alloc(icon) : icon_animation_alloc(&A_Plugins_14);
             view_tie_icon_animation(menu->view, item->icon);
             item->index = index;
             item->callback = callback;
@@ -178,6 +176,12 @@ void menu_clean(Menu* menu) {
     furi_assert(menu);
     with_view_model(
         menu->view, (MenuModel * model) {
+            for
+                M_EACH(item, model->items, MenuItemArray_t) {
+                    icon_animation_stop(item->icon);
+                    icon_animation_free(item->icon);
+                }
+
             MenuItemArray_reset(model->items);
             model->position = 0;
             return true;

+ 1 - 1
applications/gui/modules/menu.h

@@ -49,7 +49,7 @@ View* menu_get_view(Menu* menu);
 void menu_add_item(
     Menu* menu,
     const char* label,
-    IconAnimation* icon,
+    const Icon* icon,
     uint32_t index,
     MenuItemCallback callback,
     void* context);

+ 21 - 10
applications/loader/loader.c

@@ -279,7 +279,7 @@ static void loader_build_menu() {
         menu_add_item(
             loader_instance->primary_menu,
             FLIPPER_APPS[i].name,
-            FLIPPER_APPS[i].icon ? icon_animation_alloc(FLIPPER_APPS[i].icon) : NULL,
+            FLIPPER_APPS[i].icon,
             i,
             loader_menu_callback,
             (void*)&FLIPPER_APPS[i]);
@@ -287,26 +287,31 @@ static void loader_build_menu() {
     menu_add_item(
         loader_instance->primary_menu,
         "Plugins",
-        icon_animation_alloc(&A_Plugins_14),
+        &A_Plugins_14,
         i++,
         loader_submenu_callback,
         (void*)LoaderMenuViewPlugins);
-    menu_add_item(
-        loader_instance->primary_menu,
-        "Debug tools",
-        icon_animation_alloc(&A_Debug_14),
-        i++,
-        loader_submenu_callback,
-        (void*)LoaderMenuViewDebug);
+    if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
+        menu_add_item(
+            loader_instance->primary_menu,
+            "Debug tools",
+            &A_Debug_14,
+            i++,
+            loader_submenu_callback,
+            (void*)LoaderMenuViewDebug);
+    }
     menu_add_item(
         loader_instance->primary_menu,
         "Settings",
-        icon_animation_alloc(&A_Settings_14),
+        &A_Settings_14,
         i++,
         loader_submenu_callback,
         (void*)LoaderMenuViewSettings);
+}
 
+static void loader_build_submenu() {
     FURI_LOG_I(TAG, "Building plugins menu");
+    size_t i;
     for(i = 0; i < FLIPPER_PLUGINS_COUNT; i++) {
         loader_add_cli_command((FlipperApplication*)&FLIPPER_PLUGINS[i]);
         submenu_add_item(
@@ -344,12 +349,18 @@ void loader_show_menu() {
     osThreadFlagsSet(loader_instance->loader_thread, LOADER_THREAD_FLAG_SHOW_MENU);
 }
 
+void loader_update_menu() {
+    menu_clean(loader_instance->primary_menu);
+    loader_build_menu();
+}
+
 int32_t loader_srv(void* p) {
     FURI_LOG_I(TAG, "Starting");
 
     loader_instance = loader_alloc();
 
     loader_build_menu();
+    loader_build_submenu();
 
     // Call on start hooks
     for(size_t i = 0; i < FLIPPER_ON_SYSTEM_START_COUNT; i++) {

+ 3 - 0
applications/loader/loader.h

@@ -31,3 +31,6 @@ bool loader_is_locked(Loader* instance);
 
 /** Show primary loader */
 void loader_show_menu();
+
+/** Show primary loader */
+void loader_update_menu();

+ 2 - 0
applications/system/system_settings.c

@@ -1,4 +1,5 @@
 #include "system_settings.h"
+#include <loader/loader.h>
 
 static uint8_t
     uint32_value_index(const uint32_t value, const uint32_t values[], uint8_t values_count) {
@@ -54,6 +55,7 @@ static void debug_changed(VariableItem* item) {
     } else {
         furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug);
     }
+    loader_update_menu();
 }
 
 static uint32_t system_settings_exit(void* context) {

+ 29 - 3
firmware/targets/f7/furi-hal/furi-hal-subghz.c

@@ -10,6 +10,9 @@
 #include <cc1101.h>
 #include <stdio.h>
 
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+
 #define TAG "FuriHalSubGhz"
 
 static volatile SubGhzState furi_hal_subghz_state = SubGhzStateInit;
@@ -808,6 +811,8 @@ typedef struct {
     bool flip_flop;
     FuriHalSubGhzAsyncTxCallback callback;
     void* callback_context;
+    uint64_t duty_high;
+    uint64_t duty_low;
 } FuriHalSubGhzAsyncTx;
 
 static FuriHalSubGhzAsyncTx furi_hal_subghz_async_tx = {0};
@@ -817,21 +822,30 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) {
         bool is_odd = samples % 2;
         LevelDuration ld =
             furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context);
-        if(level_duration_is_wait(ld)) return;
-        if(level_duration_is_reset(ld)) {
+
+        if(level_duration_is_wait(ld)) {
+            return;
+        } else if(level_duration_is_reset(ld)) {
             // One more even sample required to end at low level
             if(is_odd) {
                 *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME;
                 buffer++;
                 samples--;
+                furi_hal_subghz_async_tx.duty_low += API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME;
             }
             break;
         } else {
             // Inject guard time if level is incorrect
-            if(is_odd == level_duration_get_level(ld)) {
+            bool level = level_duration_get_level(ld);
+            if(is_odd == level) {
                 *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME;
                 buffer++;
                 samples--;
+                if (!level) {
+                    furi_hal_subghz_async_tx.duty_high += API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME;
+                } else {
+                    furi_hal_subghz_async_tx.duty_low += API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME;
+                }
             }
 
             uint32_t duration = level_duration_get_duration(ld);
@@ -839,6 +853,12 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) {
             *buffer = duration;
             buffer++;
             samples--;
+
+            if (level) {
+                furi_hal_subghz_async_tx.duty_high += duration;
+            } else {
+                furi_hal_subghz_async_tx.duty_low += duration;
+            }
         }
     }
 
@@ -888,6 +908,9 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
 
     furi_hal_subghz_state = SubGhzStateAsyncTx;
 
+    furi_hal_subghz_async_tx.duty_low = 0;
+    furi_hal_subghz_async_tx.duty_high = 0;
+
     furi_hal_subghz_async_tx.buffer =
         furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t));
     furi_hal_subghz_async_tx_refill(
@@ -994,5 +1017,8 @@ void furi_hal_subghz_stop_async_tx() {
 
     free(furi_hal_subghz_async_tx.buffer);
 
+    float duty_cycle = 100.0f * (float)furi_hal_subghz_async_tx.duty_high / ((float)furi_hal_subghz_async_tx.duty_low + (float)furi_hal_subghz_async_tx.duty_high);
+    FURI_LOG_D(TAG, "Async TX Radio stats: on %0.0fus, off %0.0fus, DutyCycle: %0.0f%%", (float)furi_hal_subghz_async_tx.duty_high, (float)furi_hal_subghz_async_tx.duty_low, duty_cycle);
+
     furi_hal_subghz_state = SubGhzStateIdle;
 }