├── .gitignore ├── LICENSE ├── README.md ├── application.fam ├── flash10px.png ├── flashlight.c ├── icons └── led_connections.png └── img └── 1.png /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 MX 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flashlight Plugin for Flipper Zero 2 | 3 | Simple Flashlight special for @Svaarich by @xMasterX 4 | 5 | Icon by @Svaarich 6 | 7 | Connection diagram picture by @Kuronons 8 | 9 | Enables 3.3v on pin 7/C3 and leaves it on when you exit app 10 | 11 | **Connect LED to (+ -> 7/C3) | (GND -> GND)** 12 | -------------------------------------------------------------------------------- /application.fam: -------------------------------------------------------------------------------- 1 | App( 2 | appid="flashlight", 3 | name="Flashlight", 4 | apptype=FlipperAppType.EXTERNAL, 5 | entry_point="flashlight_app", 6 | cdefines=["APP_FLASHLIGHT"], 7 | requires=[ 8 | "gui", 9 | ], 10 | stack_size=2 * 1024, 11 | order=20, 12 | fap_icon_assets="icons", 13 | fap_icon="flash10px.png", 14 | fap_category="GPIO", 15 | fap_author="@xMasterX", 16 | fap_weburl="https://github.com/xMasterX/flipper-flashlight", 17 | fap_version="1.1", 18 | fap_description="Enables 3.3v on pin 7/C3 when you press Ok and leaves it on when you exit app", 19 | ) 20 | -------------------------------------------------------------------------------- /flash10px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xMasterX/flipper-flashlight/4e93f13f49760aa4a0b87c281870496eb3b5a55f/flash10px.png -------------------------------------------------------------------------------- /flashlight.c: -------------------------------------------------------------------------------- 1 | // by @xMasterX 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "flashlight_icons.h" 11 | 12 | typedef enum { 13 | EventTypeTick, 14 | EventTypeKey, 15 | } EventType; 16 | 17 | typedef struct { 18 | EventType type; 19 | InputEvent input; 20 | } PluginEvent; 21 | 22 | typedef struct { 23 | FuriMutex* mutex; 24 | bool is_on; 25 | } PluginState; 26 | 27 | static void render_callback(Canvas* const canvas, void* ctx) { 28 | furi_assert(ctx); 29 | const PluginState* plugin_state = ctx; 30 | furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); 31 | 32 | canvas_set_font(canvas, FontPrimary); 33 | elements_multiline_text_aligned(canvas, 64, 4, AlignCenter, AlignTop, "Flashlight"); 34 | 35 | canvas_set_font(canvas, FontSecondary); 36 | 37 | canvas_draw_icon(canvas, 0, 17, &I_led_connections); 38 | 39 | if(!plugin_state->is_on) { 40 | elements_multiline_text_aligned( 41 | canvas, 64, 44, AlignCenter, AlignTop, "Press OK button turn on"); 42 | } else { 43 | elements_multiline_text_aligned(canvas, 64, 38, AlignCenter, AlignTop, "Light is on!"); 44 | elements_multiline_text_aligned( 45 | canvas, 64, 50, AlignCenter, AlignTop, "Press OK button to off"); 46 | } 47 | 48 | furi_mutex_release(plugin_state->mutex); 49 | } 50 | 51 | static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { 52 | furi_assert(event_queue); 53 | 54 | PluginEvent event = {.type = EventTypeKey, .input = *input_event}; 55 | furi_message_queue_put(event_queue, &event, FuriWaitForever); 56 | } 57 | 58 | static void flash_toggle(PluginState* const plugin_state) { 59 | furi_hal_gpio_write(&gpio_ext_pc3, false); 60 | furi_hal_gpio_init(&gpio_ext_pc3, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); 61 | 62 | if(plugin_state->is_on) { 63 | furi_hal_gpio_write(&gpio_ext_pc3, false); 64 | plugin_state->is_on = false; 65 | } else { 66 | furi_hal_gpio_write(&gpio_ext_pc3, true); 67 | plugin_state->is_on = true; 68 | } 69 | } 70 | 71 | int32_t flashlight_app() { 72 | FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); 73 | 74 | PluginState* plugin_state = malloc(sizeof(PluginState)); 75 | 76 | plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); 77 | if(!plugin_state->mutex) { 78 | FURI_LOG_E("flashlight", "cannot create mutex\r\n"); 79 | furi_message_queue_free(event_queue); 80 | free(plugin_state); 81 | return 255; 82 | } 83 | 84 | // Set system callbacks 85 | ViewPort* view_port = view_port_alloc(); 86 | view_port_draw_callback_set(view_port, render_callback, plugin_state); 87 | view_port_input_callback_set(view_port, input_callback, event_queue); 88 | 89 | // Open GUI and register view_port 90 | Gui* gui = furi_record_open(RECORD_GUI); 91 | gui_add_view_port(gui, view_port, GuiLayerFullscreen); 92 | 93 | PluginEvent event; 94 | for(bool processing = true; processing;) { 95 | FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); 96 | 97 | furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); 98 | 99 | if(event_status == FuriStatusOk) { 100 | // press events 101 | if(event.type == EventTypeKey) { 102 | if(event.input.type == InputTypePress) { 103 | switch(event.input.key) { 104 | case InputKeyUp: 105 | case InputKeyDown: 106 | case InputKeyRight: 107 | case InputKeyLeft: 108 | break; 109 | case InputKeyOk: 110 | flash_toggle(plugin_state); 111 | break; 112 | case InputKeyBack: 113 | processing = false; 114 | break; 115 | default: 116 | break; 117 | } 118 | } 119 | } 120 | } 121 | 122 | furi_mutex_release(plugin_state->mutex); 123 | view_port_update(view_port); 124 | } 125 | 126 | view_port_enabled_set(view_port, false); 127 | gui_remove_view_port(gui, view_port); 128 | furi_record_close(RECORD_GUI); 129 | view_port_free(view_port); 130 | furi_message_queue_free(event_queue); 131 | furi_mutex_free(plugin_state->mutex); 132 | 133 | return 0; 134 | } 135 | -------------------------------------------------------------------------------- /icons/led_connections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xMasterX/flipper-flashlight/4e93f13f49760aa4a0b87c281870496eb3b5a55f/icons/led_connections.png -------------------------------------------------------------------------------- /img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xMasterX/flipper-flashlight/4e93f13f49760aa4a0b87c281870496eb3b5a55f/img/1.png --------------------------------------------------------------------------------