-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #541 from CodyTolene/camera-suite
Add Camera Suite GPIO application for the ESP32-CAM module.
- Loading branch information
Showing
30 changed files
with
2,061 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
App( | ||
appid="camerasuite", | ||
apptype=FlipperAppType.EXTERNAL, | ||
cdefines=["APP_CAMERA_SUITE"], | ||
entry_point="camera_suite_app", | ||
fap_author="Cody Tolene", | ||
fap_category="GPIO", | ||
fap_description="A camera suite application for the Flipper Zero ESP32-CAM module.", | ||
fap_icon="icons/camera-suite.png", | ||
fap_libs=["assets"], | ||
fap_weburl="https://github.com/CodyTolene/Flipper-Zero-Cam", | ||
name="[ESP32] Camera Suite", | ||
order=1, | ||
requires=["gui", "storage"], | ||
stack_size=8 * 1024 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
#include "camera-suite.h" | ||
#include <stdlib.h> | ||
|
||
bool camera_suite_custom_event_callback(void* context, uint32_t event) { | ||
furi_assert(context); | ||
CameraSuite* app = context; | ||
return scene_manager_handle_custom_event(app->scene_manager, event); | ||
} | ||
|
||
void camera_suite_tick_event_callback(void* context) { | ||
furi_assert(context); | ||
CameraSuite* app = context; | ||
scene_manager_handle_tick_event(app->scene_manager); | ||
} | ||
|
||
//leave app if back button pressed | ||
bool camera_suite_navigation_event_callback(void* context) { | ||
furi_assert(context); | ||
CameraSuite* app = context; | ||
return scene_manager_handle_back_event(app->scene_manager); | ||
} | ||
|
||
CameraSuite* camera_suite_app_alloc() { | ||
CameraSuite* app = malloc(sizeof(CameraSuite)); | ||
app->gui = furi_record_open(RECORD_GUI); | ||
app->notification = furi_record_open(RECORD_NOTIFICATION); | ||
|
||
//Turn backlight on, believe me this makes testing your app easier | ||
notification_message(app->notification, &sequence_display_backlight_on); | ||
|
||
//Scene additions | ||
app->view_dispatcher = view_dispatcher_alloc(); | ||
view_dispatcher_enable_queue(app->view_dispatcher); | ||
|
||
app->scene_manager = scene_manager_alloc(&camera_suite_scene_handlers, app); | ||
view_dispatcher_set_event_callback_context(app->view_dispatcher, app); | ||
view_dispatcher_set_navigation_event_callback( | ||
app->view_dispatcher, camera_suite_navigation_event_callback); | ||
view_dispatcher_set_tick_event_callback( | ||
app->view_dispatcher, camera_suite_tick_event_callback, 100); | ||
view_dispatcher_set_custom_event_callback( | ||
app->view_dispatcher, camera_suite_custom_event_callback); | ||
app->submenu = submenu_alloc(); | ||
|
||
// Set defaults, in case no config loaded | ||
app->orientation = 0; // Orientation is "portrait", zero degrees by default. | ||
app->haptic = 1; // Haptic is on by default | ||
app->speaker = 1; // Speaker is on by default | ||
app->led = 1; // LED is on by default | ||
|
||
// Load configs | ||
camera_suite_read_settings(app); | ||
|
||
view_dispatcher_add_view( | ||
app->view_dispatcher, CameraSuiteViewIdMenu, submenu_get_view(app->submenu)); | ||
|
||
app->camera_suite_view_start = camera_suite_view_start_alloc(); | ||
view_dispatcher_add_view( | ||
app->view_dispatcher, | ||
CameraSuiteViewIdStartscreen, | ||
camera_suite_view_start_get_view(app->camera_suite_view_start)); | ||
|
||
app->camera_suite_view_style_1 = camera_suite_view_style_1_alloc(); | ||
view_dispatcher_add_view( | ||
app->view_dispatcher, | ||
CameraSuiteViewIdScene1, | ||
camera_suite_view_style_1_get_view(app->camera_suite_view_style_1)); | ||
|
||
app->camera_suite_view_style_2 = camera_suite_view_style_2_alloc(); | ||
view_dispatcher_add_view( | ||
app->view_dispatcher, | ||
CameraSuiteViewIdScene2, | ||
camera_suite_view_style_2_get_view(app->camera_suite_view_style_2)); | ||
|
||
app->camera_suite_view_guide = camera_suite_view_guide_alloc(); | ||
view_dispatcher_add_view( | ||
app->view_dispatcher, | ||
CameraSuiteViewIdGuide, | ||
camera_suite_view_guide_get_view(app->camera_suite_view_guide)); | ||
|
||
app->button_menu = button_menu_alloc(); | ||
|
||
app->variable_item_list = variable_item_list_alloc(); | ||
view_dispatcher_add_view( | ||
app->view_dispatcher, | ||
CameraSuiteViewIdSettings, | ||
variable_item_list_get_view(app->variable_item_list)); | ||
|
||
//End Scene Additions | ||
|
||
return app; | ||
} | ||
|
||
void camera_suite_app_free(CameraSuite* app) { | ||
furi_assert(app); | ||
|
||
// Scene manager | ||
scene_manager_free(app->scene_manager); | ||
|
||
// View Dispatcher | ||
view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdMenu); | ||
view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdScene1); | ||
view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdScene2); | ||
view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdGuide); | ||
view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdSettings); | ||
submenu_free(app->submenu); | ||
|
||
view_dispatcher_free(app->view_dispatcher); | ||
furi_record_close(RECORD_GUI); | ||
|
||
// Free remaining resources | ||
camera_suite_view_start_free(app->camera_suite_view_start); | ||
camera_suite_view_style_1_free(app->camera_suite_view_style_1); | ||
camera_suite_view_style_2_free(app->camera_suite_view_style_2); | ||
camera_suite_view_guide_free(app->camera_suite_view_guide); | ||
button_menu_free(app->button_menu); | ||
variable_item_list_free(app->variable_item_list); | ||
|
||
app->gui = NULL; | ||
app->notification = NULL; | ||
|
||
//Remove whatever is left | ||
free(app); | ||
} | ||
|
||
/** Main entry point for initialization. */ | ||
int32_t camera_suite_app(void* p) { | ||
UNUSED(p); | ||
CameraSuite* app = camera_suite_app_alloc(); | ||
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); | ||
// Init with start scene. | ||
scene_manager_next_scene(app->scene_manager, CameraSuiteSceneStart); | ||
furi_hal_power_suppress_charge_enter(); | ||
view_dispatcher_run(app->view_dispatcher); | ||
camera_suite_save_settings(app); | ||
furi_hal_power_suppress_charge_exit(); | ||
camera_suite_app_free(app); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#pragma once | ||
|
||
#include "helpers/camera_suite_storage.h" | ||
#include "scenes/camera_suite_scene.h" | ||
#include "views/camera_suite_view_guide.h" | ||
#include "views/camera_suite_view_start.h" | ||
#include "views/camera_suite_view_style_1.h" | ||
#include "views/camera_suite_view_style_2.h" | ||
#include <assets_icons.h> | ||
#include <furi.h> | ||
#include <furi_hal.h> | ||
#include <gui/gui.h> | ||
#include <gui/modules/button_menu.h> | ||
#include <gui/modules/submenu.h> | ||
#include <gui/modules/variable_item_list.h> | ||
#include <gui/scene_manager.h> | ||
#include <gui/view_dispatcher.h> | ||
#include <input/input.h> | ||
#include <notification/notification_messages.h> | ||
#include <stdlib.h> | ||
|
||
#define TAG "Camera Suite" | ||
|
||
typedef struct { | ||
Gui* gui; | ||
NotificationApp* notification; | ||
ViewDispatcher* view_dispatcher; | ||
Submenu* submenu; | ||
SceneManager* scene_manager; | ||
VariableItemList* variable_item_list; | ||
CameraSuiteViewStart* camera_suite_view_start; | ||
CameraSuiteViewStyle1* camera_suite_view_style_1; | ||
CameraSuiteViewStyle2* camera_suite_view_style_2; | ||
CameraSuiteViewGuide* camera_suite_view_guide; | ||
uint32_t orientation; | ||
uint32_t haptic; | ||
uint32_t speaker; | ||
uint32_t led; | ||
ButtonMenu* button_menu; | ||
} CameraSuite; | ||
|
||
typedef enum { | ||
CameraSuiteViewIdStartscreen, | ||
CameraSuiteViewIdMenu, | ||
CameraSuiteViewIdScene1, | ||
CameraSuiteViewIdScene2, | ||
CameraSuiteViewIdGuide, | ||
CameraSuiteViewIdSettings, | ||
} CameraSuiteViewId; | ||
|
||
typedef enum { | ||
CameraSuiteOrientation0, | ||
CameraSuiteOrientation90, | ||
CameraSuiteOrientation180, | ||
CameraSuiteOrientation270, | ||
} CameraSuiteOrientationState; | ||
|
||
typedef enum { | ||
CameraSuiteHapticOff, | ||
CameraSuiteHapticOn, | ||
} CameraSuiteHapticState; | ||
|
||
typedef enum { | ||
CameraSuiteSpeakerOff, | ||
CameraSuiteSpeakerOn, | ||
} CameraSuiteSpeakerState; | ||
|
||
typedef enum { | ||
CameraSuiteLedOff, | ||
CameraSuiteLedOn, | ||
} CameraSuiteLedState; |
74 changes: 74 additions & 0 deletions
74
applications/external/camera-suite/helpers/camera_suite_custom_event.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#pragma once | ||
|
||
typedef enum { | ||
// Scene events: Start menu | ||
CameraSuiteCustomEventStartUp, | ||
CameraSuiteCustomEventStartDown, | ||
CameraSuiteCustomEventStartLeft, | ||
CameraSuiteCustomEventStartRight, | ||
CameraSuiteCustomEventStartOk, | ||
CameraSuiteCustomEventStartBack, | ||
// Scene events: Camera style 1 | ||
CameraSuiteCustomEventSceneStyle1Up, | ||
CameraSuiteCustomEventSceneStyle1Down, | ||
CameraSuiteCustomEventSceneStyle1Left, | ||
CameraSuiteCustomEventSceneStyle1Right, | ||
CameraSuiteCustomEventSceneStyle1Ok, | ||
CameraSuiteCustomEventSceneStyle1Back, | ||
// Scene events: Camera style 2 | ||
CameraSuiteCustomEventSceneStyle2Up, | ||
CameraSuiteCustomEventSceneStyle2Down, | ||
CameraSuiteCustomEventSceneStyle2Left, | ||
CameraSuiteCustomEventSceneStyle2Right, | ||
CameraSuiteCustomEventSceneStyle2Ok, | ||
CameraSuiteCustomEventSceneStyle2Back, | ||
// Scene events: Guide | ||
CameraSuiteCustomEventSceneGuideUp, | ||
CameraSuiteCustomEventSceneGuideDown, | ||
CameraSuiteCustomEventSceneGuideLeft, | ||
CameraSuiteCustomEventSceneGuideRight, | ||
CameraSuiteCustomEventSceneGuideOk, | ||
CameraSuiteCustomEventSceneGuideBack, | ||
} CameraSuiteCustomEvent; | ||
|
||
enum CameraSuiteCustomEventType { | ||
// Reserve first 100 events for button types and indexes, starting from 0. | ||
CameraSuiteCustomEventMenuVoid, | ||
CameraSuiteCustomEventMenuSelected, | ||
}; | ||
|
||
#pragma pack(push, 1) | ||
|
||
typedef union { | ||
uint32_t packed_value; | ||
struct { | ||
uint16_t type; | ||
int16_t value; | ||
} content; | ||
} CameraSuiteCustomEventMenu; | ||
|
||
#pragma pack(pop) | ||
|
||
static inline uint32_t camera_suite_custom_menu_event_pack(uint16_t type, int16_t value) { | ||
CameraSuiteCustomEventMenu event = {.content = {.type = type, .value = value}}; | ||
return event.packed_value; | ||
} | ||
|
||
static inline void | ||
camera_suite_custom_menu_event_unpack(uint32_t packed_value, uint16_t* type, int16_t* value) { | ||
CameraSuiteCustomEventMenu event = {.packed_value = packed_value}; | ||
if(type) *type = event.content.type; | ||
if(value) *value = event.content.value; | ||
} | ||
|
||
static inline uint16_t camera_suite_custom_menu_event_get_type(uint32_t packed_value) { | ||
uint16_t type; | ||
camera_suite_custom_menu_event_unpack(packed_value, &type, NULL); | ||
return type; | ||
} | ||
|
||
static inline int16_t camera_suite_custom_menu_event_get_value(uint32_t packed_value) { | ||
int16_t value; | ||
camera_suite_custom_menu_event_unpack(packed_value, NULL, &value); | ||
return value; | ||
} |
35 changes: 35 additions & 0 deletions
35
applications/external/camera-suite/helpers/camera_suite_haptic.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#include "camera_suite_haptic.h" | ||
#include "../camera-suite.h" | ||
|
||
void camera_suite_play_happy_bump(void* context) { | ||
CameraSuite* app = context; | ||
if(app->haptic != 1) { | ||
return; | ||
} | ||
notification_message(app->notification, &sequence_set_vibro_on); | ||
furi_thread_flags_wait(0, FuriFlagWaitAny, 20); | ||
notification_message(app->notification, &sequence_reset_vibro); | ||
} | ||
|
||
void camera_suite_play_bad_bump(void* context) { | ||
CameraSuite* app = context; | ||
if(app->haptic != 1) { | ||
return; | ||
} | ||
notification_message(app->notification, &sequence_set_vibro_on); | ||
furi_thread_flags_wait(0, FuriFlagWaitAny, 100); | ||
notification_message(app->notification, &sequence_reset_vibro); | ||
} | ||
|
||
void camera_suite_play_long_bump(void* context) { | ||
CameraSuite* app = context; | ||
if(app->haptic != 1) { | ||
return; | ||
} | ||
for(int i = 0; i < 4; i++) { | ||
notification_message(app->notification, &sequence_set_vibro_on); | ||
furi_thread_flags_wait(0, FuriFlagWaitAny, 50); | ||
notification_message(app->notification, &sequence_reset_vibro); | ||
furi_thread_flags_wait(0, FuriFlagWaitAny, 100); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
applications/external/camera-suite/helpers/camera_suite_haptic.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include <notification/notification_messages.h> | ||
|
||
void camera_suite_play_happy_bump(void* context); | ||
|
||
void camera_suite_play_bad_bump(void* context); | ||
|
||
void camera_suite_play_long_bump(void* context); |
38 changes: 38 additions & 0 deletions
38
applications/external/camera-suite/helpers/camera_suite_led.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#include "camera_suite_led.h" | ||
#include "../camera-suite.h" | ||
|
||
void camera_suite_led_set_rgb(void* context, int red, int green, int blue) { | ||
CameraSuite* app = context; | ||
if(app->led != 1) { | ||
return; | ||
} | ||
NotificationMessage notification_led_message_1; | ||
notification_led_message_1.type = NotificationMessageTypeLedRed; | ||
NotificationMessage notification_led_message_2; | ||
notification_led_message_2.type = NotificationMessageTypeLedGreen; | ||
NotificationMessage notification_led_message_3; | ||
notification_led_message_3.type = NotificationMessageTypeLedBlue; | ||
|
||
notification_led_message_1.data.led.value = red; | ||
notification_led_message_2.data.led.value = green; | ||
notification_led_message_3.data.led.value = blue; | ||
const NotificationSequence notification_sequence = { | ||
¬ification_led_message_1, | ||
¬ification_led_message_2, | ||
¬ification_led_message_3, | ||
&message_do_not_reset, | ||
NULL, | ||
}; | ||
notification_message(app->notification, ¬ification_sequence); | ||
//Delay, prevent removal from RAM before LED value set. | ||
furi_thread_flags_wait(0, FuriFlagWaitAny, 10); | ||
} | ||
|
||
void camera_suite_led_reset(void* context) { | ||
CameraSuite* app = context; | ||
notification_message(app->notification, &sequence_reset_red); | ||
notification_message(app->notification, &sequence_reset_green); | ||
notification_message(app->notification, &sequence_reset_blue); | ||
//Delay, prevent removal from RAM before LED value set. | ||
furi_thread_flags_wait(0, FuriFlagWaitAny, 300); | ||
} |
3 changes: 3 additions & 0 deletions
3
applications/external/camera-suite/helpers/camera_suite_led.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
void camera_suite_led_set_rgb(void* context, int red, int green, int blue); | ||
|
||
void camera_suite_led_reset(void* context); |
Oops, something went wrong.