From 63642617eeb74cfce8b0531921af641b59a36498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Wed, 15 Dec 2021 15:23:16 +0300 Subject: [PATCH] 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. --- applications/debug_tools/blink_test.c | 40 ++--- applications/debug_tools/keypad_test.c | 157 +++++++----------- applications/debug_tools/vibro_test.c | 41 ++--- applications/gui/modules/menu.c | 18 +- applications/gui/modules/menu.h | 2 +- applications/loader/loader.c | 31 ++-- applications/loader/loader.h | 3 + applications/system/system_settings.c | 2 + .../targets/f7/furi-hal/furi-hal-subghz.c | 32 +++- 9 files changed, 164 insertions(+), 162 deletions(-) diff --git a/applications/debug_tools/blink_test.c b/applications/debug_tools/blink_test.c index 36823b2e..7f813de0 100644 --- a/applications/debug_tools/blink_test.c +++ b/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; -} \ No newline at end of file +} diff --git a/applications/debug_tools/keypad_test.c b/applications/debug_tools/keypad_test.c index 20f259aa..ae980317 100644 --- a/applications/debug_tools/keypad_test.c +++ b/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); + FURI_LOG_I( + TAG, + "key: %s type: %s", + input_get_key_name(event.key), + input_get_type_name(event.type)); - 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; - } - } + 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; } diff --git a/applications/debug_tools/vibro_test.c b/applications/debug_tools/vibro_test.c index b5e9be63..25443088 100644 --- a/applications/debug_tools/vibro_test.c +++ b/applications/debug_tools/vibro_test.c @@ -5,10 +5,6 @@ #include #include -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; -} \ No newline at end of file +} diff --git a/applications/gui/modules/menu.c b/applications/gui/modules/menu.c index 110ff0c1..2b551d55 100644 --- a/applications/gui/modules/menu.c +++ b/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; diff --git a/applications/gui/modules/menu.h b/applications/gui/modules/menu.h index e7d52c84..b41930fd 100755 --- a/applications/gui/modules/menu.h +++ b/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); diff --git a/applications/loader/loader.c b/applications/loader/loader.c index 9d24f65d..7855cd20 100644 --- a/applications/loader/loader.c +++ b/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++) { diff --git a/applications/loader/loader.h b/applications/loader/loader.h index 6c231b7a..705133c6 100644 --- a/applications/loader/loader.h +++ b/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(); diff --git a/applications/system/system_settings.c b/applications/system/system_settings.c index f820645e..7d48451f 100644 --- a/applications/system/system_settings.c +++ b/applications/system/system_settings.c @@ -1,4 +1,5 @@ #include "system_settings.h" +#include 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) { diff --git a/firmware/targets/f7/furi-hal/furi-hal-subghz.c b/firmware/targets/f7/furi-hal/furi-hal-subghz.c index 3e810880..1b794182 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f7/furi-hal/furi-hal-subghz.c @@ -10,6 +10,9 @@ #include #include +#define __STDC_FORMAT_MACROS +#include + #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; }