-
Notifications
You must be signed in to change notification settings - Fork 0
/
lasercat.c
158 lines (142 loc) · 7.5 KB
/
lasercat.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//подключаем модули
#include <stdio.h>
#include <furi.h>
#include <furi_hal.h> // подключается когда 5 вольт
#include <gui/gui.h>
#include <input/input.h>
#include <notification/notification_messages.h>
#include <furi_hal_power.h> //подключается когда используется GPO
#include "lasercat_icons.h" //подключаем когда есть images именно так idприложения_icons.h
// (*1) Это будет метка, указывающая вам, какая кнопка клавиатуры нажата.
char* currentKeyPressed;
int BUFFER = 10;
bool keyonoff = false;
// Эта функция предназначена для рисования графического интерфейса экрана каждый раз, когда
// flip обновляет дисплей
static void draw_callback(Canvas* canvas, void* ctx) {
UNUSED(ctx);
// очистка дисплея
canvas_clear(canvas);
// Код с lopaka.app
canvas_set_bitmap_mode(canvas, true);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 69, 12, "LaserCat");
canvas_set_font(canvas, FontKeyboard);
canvas_draw_str(canvas, 60, 30, "Click");
canvas_draw_str(canvas, 60, 38, "");
canvas_draw_icon(canvas, -11, 0, &I_cat);
canvas_set_font(canvas, FontSecondary);
canvas_draw_str(canvas, 65, 43, currentKeyPressed);
canvas_draw_line(canvas, 59, 15, 127, 15);
canvas_draw_line(canvas, 60, 47, 127, 47);
canvas_set_font(canvas, FontSecondary);
canvas_draw_str(canvas, 110, 30, "to");
canvas_draw_str(canvas, 37, 60, "GitHub.com/DroWez");
canvas_draw_frame(canvas, 35, 50, 92, 13);
if(keyonoff == true) {
canvas_draw_icon(canvas, 44, 0, &I_lamp_on);
} else {
canvas_draw_icon(canvas, 44, 0, &I_lamp_off);
}
canvas_draw_icon(canvas, 93, 20, &I_Ok_btn_pressed);
}
// (*2) Здесь мы можем определить обратный вызов для таймера: каждые 2 секунды
// система furi-timer будет вызывать наш определенный обратный вызов
static void timer_callback(void* context) {
FuriMessageQueue* event_queue = (FuriMessageQueue*)context;
furi_assert(event_queue);
if(keyonoff == true) {
currentKeyPressed = "turn off laser ";
furi_hal_gpio_write(&gpio_ext_pc3, true);
} else {
currentKeyPressed = "turn on laser ";
furi_hal_gpio_write(&gpio_ext_pc3, false);
}
}
// Эта функция является обработчиком пользовательского ввода (кнопки справа
// на Flip используются для навигации, подтверждения и возврата назад)
static void input_callback(InputEvent* input_event, void* ctx) {
furi_assert(ctx);
FuriMessageQueue* event_queue = ctx;
furi_message_queue_put(event_queue, input_event, FuriWaitForever);
}
// Основная запись приложения, как определено внутри application.fam
int32_t main_fap(void* p) {
UNUSED(p);
// Инициализация (*1)
keyonoff = false;
// включаем 5 вольт при запуске
uint8_t attempts = 0;
if(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
furi_hal_power_enable_otg();
furi_delay_ms(10);
}
// конец
//отключим порт при запуске
furi_hal_gpio_write(&gpio_ext_pc3, false);
// Текущее событие типа InputEvent
InputEvent event;
// Очередь событий для 8 элементов размера InputEvent
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
// ViewPort нужен для рисования графического интерфейса пользователя
ViewPort* view_port = view_port_alloc();
// мы даем этому [view_port_draw_callback_set] функцию, определенную
// before (draw_callback) для рисования графического интерфейса на дисплее Flip
view_port_draw_callback_set(view_port, draw_callback, NULL);
// Та же концепция применима к [view_port_input_callback_set], связанному с функцией (input_callback)
//определенной ранее
view_port_input_callback_set(view_port, input_callback, event_queue);
// Cоздаем структуру графического интерфейса пользователя и связать ее с ранее определенным окном просмотра
Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
// Создает furi-таймер и связывает соответствующий обратный вызов, определенный в (*2)
FuriTimer* timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, event_queue);
// Запускает таймер - время истечения в миллисекундах (в данном случае 0.5 секунды)
furi_timer_start(timer, 500);
//проверем И подключаем GPO
furi_hal_gpio_write(&gpio_ext_pc3, false);
furi_hal_gpio_init(&gpio_ext_pc3, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
// Бесконечный цикл... (как у arduino)
while(1) {
// Продолжаем (бесконечно) выводить из очереди все события, накопленные внутри
furi_check(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk);
// Если событием из очереди является нажатие кнопки кнопок и запись значений currentKeyPressed, мы выходим из цикла
if(event.key == InputKeyOk) {
if(keyonoff == true) {
currentKeyPressed = "turn on laser ";
keyonoff = false;
} else {
currentKeyPressed = "turn off laser ";
keyonoff = true;
}
}
if(event.key == InputKeyBack) {
//отключим порт
furi_hal_gpio_write(&gpio_ext_pc3, false);
// на всякий отключим 5 вольт
if(furi_hal_power_is_otg_enabled()) {
furi_hal_power_disable_otg();
furi_delay_ms(10);
}
break;
}
}
// Когда вы используете таймер, не забудьте остановить его
furi_timer_stop(timer);
// и освободите память, выделенную для таймера
furi_timer_free(timer);
// после выхода из цикла нам нужно освободить ресурсы:
// очистить все элементы внутри очереди
furi_message_queue_free(event_queue);
// Мы удаляем графический интерфейс из связанного порта просмотра
gui_remove_view_port(gui, view_port);
//отключить 5 вольт
if(furi_hal_power_is_otg_enabled()) {
furi_hal_power_disable_otg();
}
// Освобождаем память, удаляем view_port и закрываем
// Запись GUI
view_port_free(view_port);
furi_record_close(RECORD_GUI);
return 0;
}