diff --git a/applications/external/barcode_gen/barcode_app.c b/applications/external/barcode_gen/barcode_app.c index aff437f2e..9dde93931 100644 --- a/applications/external/barcode_gen/barcode_app.c +++ b/applications/external/barcode_gen/barcode_app.c @@ -2,6 +2,9 @@ #include "barcode_app_icons.h" #include +#include +#include +#include /** * Opens a file browser dialog and returns the filepath of the selected file @@ -11,6 +14,9 @@ * file_path will be the folder path is nothing is selected * @returns true if a file is selected */ + +NotificationApp* notifications = 0; + static bool select_file(const char* folder, FuriString* file_path) { DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); DialogsFileBrowserOptions browser_options; @@ -287,6 +293,12 @@ void free_app(BarcodeApp* app) { free(app); } +void set_backlight_brightness(float brightness) { + NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); + notifications->settings.display_brightness = brightness; + notification_message(notifications, &sequence_display_backlight_on); +} + int32_t barcode_main(void* p) { UNUSED(p); BarcodeApp* app = malloc(sizeof(BarcodeApp)); @@ -307,6 +319,13 @@ int32_t barcode_main(void* p) { submenu_add_item(app->main_menu, "Edit Barcode", EditBarcodeItem, submenu_callback, app); + NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); + // Save original brightness + float originalBrightness = notifications->settings.display_brightness; + // force backlight and increase brightness + notification_message_block(notifications, &sequence_display_backlight_enforce_on); + set_backlight_brightness(10); // set to highest + /***************************** * Creating Text Input View ******************************/ @@ -344,6 +363,8 @@ int32_t barcode_main(void* p) { view_dispatcher_run(app->view_dispatcher); free_app(app); + notification_message_block(notifications, &sequence_display_backlight_enforce_auto); + set_backlight_brightness(originalBrightness); return 0; } diff --git a/applications/external/radar_scanner/application.fam b/applications/external/radar_scanner/application.fam index 40b06c236..4c6d40047 100644 --- a/applications/external/radar_scanner/application.fam +++ b/applications/external/radar_scanner/application.fam @@ -9,6 +9,6 @@ App( fap_category="GPIO", fap_author="@MatthewKuKanich", fap_weburl="https://github.com/MatthewKuKanich/flipper-radar", - fap_version="1.0", + fap_version="2.0", fap_description="Detects the movement of living things using radar", ) diff --git a/applications/external/radar_scanner/radar_scanner.c b/applications/external/radar_scanner/radar_scanner.c index 8f0d4bd96..ec9971de3 100644 --- a/applications/external/radar_scanner/radar_scanner.c +++ b/applications/external/radar_scanner/radar_scanner.c @@ -10,10 +10,14 @@ static const uint32_t EVENT_PERIOD_MS = 10; static const float BEEP_FREQ = 1000.0f; static const float BEEP_VOL = 0.9f; static const GpioPin* const radarPin = &gpio_ext_pc3; // Pin 7 +static const GpioPin* const altRadarPin = &gpio_ext_pa7; // Pin 2 +static const GpioPin* const altGroundPin = &gpio_ext_pa6; // Pin 3 bool presenceDetected = false; bool muted = false; bool active = false; +bool continuous = false; // Start with no signal from OUT +bool altPinout; // Sets which GPIO pinout config to use static void start_feedback(NotificationApp* notifications) { // Set LED to red for detection @@ -50,7 +54,7 @@ static void draw_callback(Canvas* canvas, void* ctx) { canvas_clear(canvas); canvas_set_font(canvas, FontPrimary); elements_multiline_text_aligned(canvas, 64, 2, AlignCenter, AlignTop, "Microwave Radar"); - + canvas_set_font(canvas, FontSecondary); if(active) { elements_multiline_text_aligned(canvas, 64, 12, AlignCenter, AlignTop, "Active"); } else { @@ -58,22 +62,36 @@ static void draw_callback(Canvas* canvas, void* ctx) { } // Display presence status + canvas_set_font(canvas, FontPrimary); if(presenceDetected) { elements_multiline_text_aligned( - canvas, 64, 25, AlignCenter, AlignTop, "Presence Detected"); + canvas, 64, 20, AlignCenter, AlignTop, "Presence Detected"); } else { - elements_multiline_text_aligned(canvas, 64, 25, AlignCenter, AlignTop, "No Presence"); - } - - if(muted) { - elements_multiline_text_aligned(canvas, 64, 35, AlignCenter, AlignTop, "Muted"); + elements_multiline_text_aligned(canvas, 64, 20, AlignCenter, AlignTop, "No Presence"); } canvas_set_font(canvas, FontSecondary); - elements_multiline_text_aligned( - canvas, 64, 45, AlignCenter, AlignTop, "RCWL-0516 :: OUT -> Pin7"); - elements_multiline_text_aligned( - canvas, 64, 55, AlignCenter, AlignTop, "VIN -> 5v :: GND -> GND"); + if(muted) { + elements_multiline_text_aligned(canvas, 64, 32, AlignCenter, AlignTop, "Muted"); + } + + canvas_set_font(canvas, FontBatteryPercent); + + if(altPinout) { + elements_multiline_text_aligned( + canvas, 64, 42, AlignCenter, AlignTop, "Alt-Pinout Enabled"); + elements_multiline_text_aligned( + canvas, 64, 49, AlignCenter, AlignTop, "VIN -> 5v :: GND -> Pin 3"); + elements_multiline_text_aligned( + canvas, 64, 56, AlignCenter, AlignTop, "OUT -> Pin 2 (A7)"); + } else if(!altPinout) { + elements_multiline_text_aligned( + canvas, 64, 42, AlignCenter, AlignTop, "Alt-Pinout Disabled"); + elements_multiline_text_aligned( + canvas, 64, 49, AlignCenter, AlignTop, "VIN -> 5v :: GND -> GND"); + elements_multiline_text_aligned( + canvas, 64, 56, AlignCenter, AlignTop, "OUT -> Pin 7 (C3)"); + } } static void input_callback(InputEvent* input_event, void* ctx) { @@ -82,6 +100,14 @@ static void input_callback(InputEvent* input_event, void* ctx) { furi_message_queue_put(event_queue, input_event, FuriWaitForever); } +static void get_reading() { + if(altPinout) { + continuous = furi_hal_gpio_read(altRadarPin); + } else { + continuous = furi_hal_gpio_read(radarPin); + } +} + int32_t app_radar_scanner(void* p) { UNUSED(p); FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); @@ -102,6 +128,17 @@ int32_t app_radar_scanner(void* p) { // set input to be low; RCWL-0516 outputs High (3v) on detection furi_hal_gpio_init(radarPin, GpioModeInput, GpioPullDown, GpioSpeedVeryHigh); + furi_hal_gpio_init(altRadarPin, GpioModeInput, GpioPullDown, GpioSpeedVeryHigh); + furi_hal_gpio_init(altGroundPin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_write(altGroundPin, false); + + // Auto 5v power + uint8_t attempts = 0; + bool otg_was_enabled = furi_hal_power_is_otg_enabled(); + while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { + furi_hal_power_enable_otg(); + furi_delay_ms(10); + } bool alarming = false; // Sensor begins in-active until user starts bool running = true; // to prevent unwanted false positives @@ -109,7 +146,7 @@ int32_t app_radar_scanner(void* p) { while(running) { if(active) { // start and stop feedback if sensor state is active - bool continuous = furi_hal_gpio_read(radarPin); + get_reading(); if(continuous && !alarming) { presenceDetected = true; @@ -138,6 +175,9 @@ int32_t app_radar_scanner(void* p) { muted = !muted; // Toggle the value of 'muted' stop_feedback(notifications); } + if(event.key == InputKeyRight) { + altPinout = !altPinout; // Toggle alternate pinout + } } } } @@ -146,6 +186,11 @@ int32_t app_radar_scanner(void* p) { stop_feedback(notifications); notification_message_block(notifications, &sequence_display_backlight_enforce_auto); + // Disable 5v power + if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) { + furi_hal_power_disable_otg(); + } + view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); view_port_free(view_port); diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu.c index ccebe4740..b72c8062e 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu.c @@ -23,6 +23,7 @@ const char* const menu_style_names[MenuStyleCount] = { "C64", "Eurocorp", "Compact", + "Terminal", }; static void xtreme_app_scene_interface_mainmenu_menu_style_changed(VariableItem* item) { XtremeApp* app = variable_item_get_context(item); diff --git a/applications/services/gui/modules/menu.c b/applications/services/gui/modules/menu.c index 41a5d321f..6307a4ebe 100644 --- a/applications/services/gui/modules/menu.c +++ b/applications/services/gui/modules/menu.c @@ -387,9 +387,51 @@ static void menu_draw_callback(Canvas* canvas, void* _model) { break; } + case MenuStyleTerminal: { + // Draw a border around the screen + canvas_draw_frame(canvas, 0, 0, 128, 64); + + // current dir on the title bar + canvas_set_font(canvas, FontSecondary); + char title[20]; + snprintf(title, sizeof(title), "%s@fz: ~/Home", furi_hal_version_get_name_ptr()); + canvas_draw_str(canvas, 20, 10, title); + + canvas_draw_str(canvas, 118, 9, "x"); // "X" button on the top-right corner + canvas_draw_frame(canvas, 116, 2, 8, 9); + canvas_draw_frame(canvas, 0, 0, 128, 13); + + // Display the user's name line at the bottom + canvas_set_font(canvas, FontBatteryPercent); + char prefix[15]; + snprintf(prefix, sizeof(prefix), "%s@fz:~$", furi_hal_version_get_name_ptr()); + canvas_draw_str(canvas, 2, 56, prefix); + + size_t name_start_x = 2 + (strlen(prefix) - 1) * 6; + + for(size_t i = 0; i < 4 && (position + i) < items_count; i++) { + item = MenuItemArray_get(model->items, position + i); + menu_short_name(item, name); + + size_t scroll_counter = menu_scroll_counter(model, item); + if(i == 0) { + // Display selected item to the right of the $ symbol + // May want to reduce spacing + elements_scrollable_text_line( + canvas, name_start_x, 56, 60, name, scroll_counter, false); + } else { + // Display the previous items above the user's name line + canvas_draw_str(canvas, 2, 56 - i * 12, item->label); + } + } + + break; + } + default: break; } + furi_string_free(name); } else { canvas_draw_str(canvas, 2, 32, "Empty"); @@ -612,6 +654,7 @@ static void menu_process_up(Menu* menu) { switch(XTREME_SETTINGS()->menu_style) { case MenuStyleList: case MenuStyleEurocorp: + case MenuStyleTerminal: if(position > 0) { position--; if(vertical_offset && vertical_offset == position) { @@ -639,6 +682,7 @@ static void menu_process_up(Menu* menu) { } vertical_offset = CLAMP(MAX((int)position - 4, 0), MAX((int)count - 8, 0), 0); break; + default: break; } @@ -662,6 +706,7 @@ static void menu_process_down(Menu* menu) { switch(XTREME_SETTINGS()->menu_style) { case MenuStyleList: case MenuStyleEurocorp: + case MenuStyleTerminal: if(position < count - 1) { position++; if(vertical_offset < count - 8 && vertical_offset == position - 7) { @@ -689,6 +734,7 @@ static void menu_process_down(Menu* menu) { } vertical_offset = CLAMP(MAX((int)position - 4, 0), MAX((int)count - 8, 0), 0); break; + default: break; } @@ -751,6 +797,7 @@ static void menu_process_left(Menu* menu) { } vertical_offset = CLAMP(MAX((int)position - 4, 0), MAX((int)count - 8, 0), 0); break; + default: break; } @@ -818,6 +865,7 @@ static void menu_process_right(Menu* menu) { } vertical_offset = CLAMP(MAX((int)position - 4, 0), MAX((int)count - 8, 0), 0); break; + default: break; } diff --git a/lib/xtreme/xtreme.h b/lib/xtreme/xtreme.h index f11d6e70f..89a2fdb01 100644 --- a/lib/xtreme/xtreme.h +++ b/lib/xtreme/xtreme.h @@ -34,6 +34,7 @@ typedef enum { MenuStyleC64, MenuStyleEurocorp, MenuStyleCompact, + MenuStyleTerminal, MenuStyleCount, } MenuStyle;