flashlight.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // by @xMasterX
  2. #include <furi.h>
  3. #include <furi_hal_power.h>
  4. #include <gui/gui.h>
  5. #include <input/input.h>
  6. #include <stdlib.h>
  7. #include <gui/elements.h>
  8. typedef enum {
  9. EventTypeTick,
  10. EventTypeKey,
  11. } EventType;
  12. typedef struct {
  13. EventType type;
  14. InputEvent input;
  15. } PluginEvent;
  16. typedef struct {
  17. bool is_on;
  18. } PluginState;
  19. static void render_callback(Canvas* const canvas, void* ctx) {
  20. const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25);
  21. if(plugin_state == NULL) {
  22. return;
  23. }
  24. canvas_set_font(canvas, FontPrimary);
  25. elements_multiline_text_aligned(canvas, 64, 2, AlignCenter, AlignTop, "Flashlight");
  26. canvas_set_font(canvas, FontSecondary);
  27. if(!plugin_state->is_on) {
  28. elements_multiline_text_aligned(
  29. canvas, 64, 28, AlignCenter, AlignTop, "Press OK button turn on");
  30. } else {
  31. elements_multiline_text_aligned(canvas, 64, 28, AlignCenter, AlignTop, "Light is on!");
  32. elements_multiline_text_aligned(
  33. canvas, 64, 40, AlignCenter, AlignTop, "Press OK button to off");
  34. }
  35. release_mutex((ValueMutex*)ctx, plugin_state);
  36. }
  37. static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
  38. furi_assert(event_queue);
  39. PluginEvent event = {.type = EventTypeKey, .input = *input_event};
  40. furi_message_queue_put(event_queue, &event, FuriWaitForever);
  41. }
  42. static void flash_toggle(PluginState* const plugin_state) {
  43. furi_hal_gpio_write(&gpio_ext_pc3, false);
  44. furi_hal_gpio_init(&gpio_ext_pc3, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
  45. if(plugin_state->is_on) {
  46. furi_hal_gpio_write(&gpio_ext_pc3, false);
  47. plugin_state->is_on = false;
  48. } else {
  49. furi_hal_gpio_write(&gpio_ext_pc3, true);
  50. plugin_state->is_on = true;
  51. }
  52. }
  53. int32_t flashlight_app() {
  54. FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
  55. PluginState* plugin_state = malloc(sizeof(PluginState));
  56. ValueMutex state_mutex;
  57. if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) {
  58. FURI_LOG_E("flashlight", "cannot create mutex\r\n");
  59. furi_message_queue_free(event_queue);
  60. free(plugin_state);
  61. return 255;
  62. }
  63. // Set system callbacks
  64. ViewPort* view_port = view_port_alloc();
  65. view_port_draw_callback_set(view_port, render_callback, &state_mutex);
  66. view_port_input_callback_set(view_port, input_callback, event_queue);
  67. // Open GUI and register view_port
  68. Gui* gui = furi_record_open(RECORD_GUI);
  69. gui_add_view_port(gui, view_port, GuiLayerFullscreen);
  70. PluginEvent event;
  71. for(bool processing = true; processing;) {
  72. FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
  73. PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex);
  74. if(event_status == FuriStatusOk) {
  75. // press events
  76. if(event.type == EventTypeKey) {
  77. if(event.input.type == InputTypePress) {
  78. switch(event.input.key) {
  79. case InputKeyUp:
  80. case InputKeyDown:
  81. case InputKeyRight:
  82. case InputKeyLeft:
  83. break;
  84. case InputKeyOk:
  85. flash_toggle(plugin_state);
  86. break;
  87. case InputKeyBack:
  88. processing = false;
  89. break;
  90. }
  91. }
  92. }
  93. }
  94. view_port_update(view_port);
  95. release_mutex(&state_mutex, plugin_state);
  96. }
  97. view_port_enabled_set(view_port, false);
  98. gui_remove_view_port(gui, view_port);
  99. furi_record_close(RECORD_GUI);
  100. view_port_free(view_port);
  101. furi_message_queue_free(event_queue);
  102. delete_mutex(&state_mutex);
  103. return 0;
  104. }