Skip to content

Commit 1fb9542

Browse files
committed
move base pack here
0 parents  commit 1fb9542

14 files changed

+823
-0
lines changed

application.fam

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
App(
2+
appid="signal_generator",
3+
name="Signal Generator",
4+
apptype=FlipperAppType.EXTERNAL,
5+
entry_point="signal_gen_app",
6+
requires=["gui"],
7+
stack_size=1 * 1024,
8+
order=50,
9+
fap_icon="signal_gen_10px.png",
10+
fap_category="GPIO",
11+
fap_icon_assets="icons",
12+
)

icons/SmallArrowDown_3x5.png

3.51 KB
Loading

icons/SmallArrowUp_3x5.png

7.79 KB
Loading

scenes/signal_gen_scene.c

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include "../signal_gen_app_i.h"
2+
3+
// Generate scene on_enter handlers array
4+
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
5+
void (*const signal_gen_scene_on_enter_handlers[])(void*) = {
6+
#include "signal_gen_scene_config.h"
7+
};
8+
#undef ADD_SCENE
9+
10+
// Generate scene on_event handlers array
11+
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
12+
bool (*const signal_gen_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
13+
#include "signal_gen_scene_config.h"
14+
};
15+
#undef ADD_SCENE
16+
17+
// Generate scene on_exit handlers array
18+
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
19+
void (*const signal_gen_scene_on_exit_handlers[])(void* context) = {
20+
#include "signal_gen_scene_config.h"
21+
};
22+
#undef ADD_SCENE
23+
24+
// Initialize scene handlers configuration structure
25+
const SceneManagerHandlers signal_gen_scene_handlers = {
26+
.on_enter_handlers = signal_gen_scene_on_enter_handlers,
27+
.on_event_handlers = signal_gen_scene_on_event_handlers,
28+
.on_exit_handlers = signal_gen_scene_on_exit_handlers,
29+
.scene_num = SignalGenSceneNum,
30+
};

scenes/signal_gen_scene.h

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#pragma once
2+
3+
#include <gui/scene_manager.h>
4+
5+
// Generate scene id and total number
6+
#define ADD_SCENE(prefix, name, id) SignalGenScene##id,
7+
typedef enum {
8+
#include "signal_gen_scene_config.h"
9+
SignalGenSceneNum,
10+
} SignalGenScene;
11+
#undef ADD_SCENE
12+
13+
extern const SceneManagerHandlers signal_gen_scene_handlers;
14+
15+
// Generate scene on_enter handlers declaration
16+
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
17+
#include "signal_gen_scene_config.h"
18+
#undef ADD_SCENE
19+
20+
// Generate scene on_event handlers declaration
21+
#define ADD_SCENE(prefix, name, id) \
22+
bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
23+
#include "signal_gen_scene_config.h"
24+
#undef ADD_SCENE
25+
26+
// Generate scene on_exit handlers declaration
27+
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
28+
#include "signal_gen_scene_config.h"
29+
#undef ADD_SCENE

scenes/signal_gen_scene_config.h

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ADD_SCENE(signal_gen, start, Start)
2+
ADD_SCENE(signal_gen, pwm, Pwm)
3+
ADD_SCENE(signal_gen, mco, Mco)

scenes/signal_gen_scene_mco.c

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#include "../signal_gen_app_i.h"
2+
3+
typedef enum {
4+
LineIndexPin,
5+
LineIndexSource,
6+
LineIndexDivision,
7+
} LineIndex;
8+
9+
static const char* const mco_pin_names[] = {
10+
"13(Tx)",
11+
};
12+
13+
static const char* const mco_source_names[] = {
14+
"32768Hz",
15+
"64MHz",
16+
"~100K",
17+
"~200K",
18+
"~400K",
19+
"~800K",
20+
"~1MHz",
21+
"~2MHz",
22+
"~4MHz",
23+
"~8MHz",
24+
"~16MHz",
25+
"~24MHz",
26+
"~32MHz",
27+
"~48MHz",
28+
};
29+
30+
static const FuriHalClockMcoSourceId mco_sources[] = {
31+
FuriHalClockMcoLse,
32+
FuriHalClockMcoSysclk,
33+
FuriHalClockMcoMsi100k,
34+
FuriHalClockMcoMsi200k,
35+
FuriHalClockMcoMsi400k,
36+
FuriHalClockMcoMsi800k,
37+
FuriHalClockMcoMsi1m,
38+
FuriHalClockMcoMsi2m,
39+
FuriHalClockMcoMsi4m,
40+
FuriHalClockMcoMsi8m,
41+
FuriHalClockMcoMsi16m,
42+
FuriHalClockMcoMsi24m,
43+
FuriHalClockMcoMsi32m,
44+
FuriHalClockMcoMsi48m,
45+
};
46+
47+
static const char* const mco_divisor_names[] = {
48+
"1",
49+
"2",
50+
"4",
51+
"8",
52+
"16",
53+
};
54+
55+
static const FuriHalClockMcoDivisorId mco_divisors[] = {
56+
FuriHalClockMcoDiv1,
57+
FuriHalClockMcoDiv2,
58+
FuriHalClockMcoDiv4,
59+
FuriHalClockMcoDiv8,
60+
FuriHalClockMcoDiv16,
61+
};
62+
63+
static void mco_source_list_change_callback(VariableItem* item) {
64+
SignalGenApp* app = variable_item_get_context(item);
65+
uint8_t index = variable_item_get_current_value_index(item);
66+
variable_item_set_current_value_text(item, mco_source_names[index]);
67+
68+
app->mco_src = mco_sources[index];
69+
70+
view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenMcoEventUpdate);
71+
}
72+
73+
static void mco_divisor_list_change_callback(VariableItem* item) {
74+
SignalGenApp* app = variable_item_get_context(item);
75+
uint8_t index = variable_item_get_current_value_index(item);
76+
variable_item_set_current_value_text(item, mco_divisor_names[index]);
77+
78+
app->mco_div = mco_divisors[index];
79+
80+
view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenMcoEventUpdate);
81+
}
82+
83+
void signal_gen_scene_mco_on_enter(void* context) {
84+
SignalGenApp* app = context;
85+
VariableItemList* var_item_list = app->var_item_list;
86+
87+
VariableItem* item;
88+
89+
item = variable_item_list_add(var_item_list, "GPIO Pin", COUNT_OF(mco_pin_names), NULL, NULL);
90+
variable_item_set_current_value_index(item, 0);
91+
variable_item_set_current_value_text(item, mco_pin_names[0]);
92+
93+
item = variable_item_list_add(
94+
var_item_list,
95+
"Frequency",
96+
COUNT_OF(mco_source_names),
97+
mco_source_list_change_callback,
98+
app);
99+
variable_item_set_current_value_index(item, 0);
100+
variable_item_set_current_value_text(item, mco_source_names[0]);
101+
102+
item = variable_item_list_add(
103+
var_item_list,
104+
"Freq. divider",
105+
COUNT_OF(mco_divisor_names),
106+
mco_divisor_list_change_callback,
107+
app);
108+
variable_item_set_current_value_index(item, 0);
109+
variable_item_set_current_value_text(item, mco_divisor_names[0]);
110+
111+
variable_item_list_set_selected_item(var_item_list, LineIndexSource);
112+
113+
view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewVarItemList);
114+
115+
app->mco_src = FuriHalClockMcoLse;
116+
app->mco_div = FuriHalClockMcoDiv1;
117+
furi_hal_clock_mco_enable(app->mco_src, app->mco_div);
118+
furi_hal_gpio_init_ex(
119+
&gpio_usart_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn0MCO);
120+
}
121+
122+
bool signal_gen_scene_mco_on_event(void* context, SceneManagerEvent event) {
123+
SignalGenApp* app = context;
124+
bool consumed = false;
125+
126+
if(event.type == SceneManagerEventTypeCustom) {
127+
if(event.event == SignalGenMcoEventUpdate) {
128+
consumed = true;
129+
furi_hal_clock_mco_enable(app->mco_src, app->mco_div);
130+
}
131+
}
132+
return consumed;
133+
}
134+
135+
void signal_gen_scene_mco_on_exit(void* context) {
136+
SignalGenApp* app = context;
137+
variable_item_list_reset(app->var_item_list);
138+
furi_hal_gpio_init_ex(
139+
&gpio_usart_tx,
140+
GpioModeAltFunctionPushPull,
141+
GpioPullUp,
142+
GpioSpeedVeryHigh,
143+
GpioAltFn7USART1);
144+
furi_hal_clock_mco_disable();
145+
}

scenes/signal_gen_scene_pwm.c

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#include "../signal_gen_app_i.h"
2+
3+
static const FuriHalPwmOutputId pwm_ch_id[] = {
4+
FuriHalPwmOutputIdTim1PA7,
5+
FuriHalPwmOutputIdLptim2PA4,
6+
};
7+
8+
#define DEFAULT_FREQ 1000
9+
#define DEFAULT_DUTY 50
10+
11+
static void
12+
signal_gen_pwm_callback(uint8_t channel_id, uint32_t freq, uint8_t duty, void* context) {
13+
SignalGenApp* app = context;
14+
15+
app->pwm_freq = freq;
16+
app->pwm_duty = duty;
17+
18+
if(app->pwm_ch != pwm_ch_id[channel_id]) { //-V1051
19+
app->pwm_ch_prev = app->pwm_ch;
20+
app->pwm_ch = pwm_ch_id[channel_id];
21+
view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenPwmEventChannelChange);
22+
} else {
23+
app->pwm_ch = pwm_ch_id[channel_id]; //-V1048
24+
view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenPwmEventUpdate);
25+
}
26+
}
27+
28+
void signal_gen_scene_pwm_on_enter(void* context) {
29+
SignalGenApp* app = context;
30+
31+
view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewPwm);
32+
33+
signal_gen_pwm_set_callback(app->pwm_view, signal_gen_pwm_callback, app);
34+
35+
signal_gen_pwm_set_params(app->pwm_view, 0, DEFAULT_FREQ, DEFAULT_DUTY);
36+
37+
if(!furi_hal_pwm_is_running(pwm_ch_id[0])) {
38+
furi_hal_pwm_start(pwm_ch_id[0], DEFAULT_FREQ, DEFAULT_DUTY);
39+
} else {
40+
furi_hal_pwm_stop(pwm_ch_id[0]);
41+
furi_hal_pwm_start(pwm_ch_id[0], DEFAULT_FREQ, DEFAULT_DUTY);
42+
}
43+
}
44+
45+
bool signal_gen_scene_pwm_on_event(void* context, SceneManagerEvent event) {
46+
SignalGenApp* app = context;
47+
bool consumed = false;
48+
49+
if(event.type == SceneManagerEventTypeCustom) {
50+
if(event.event == SignalGenPwmEventUpdate) {
51+
consumed = true;
52+
furi_hal_pwm_set_params(app->pwm_ch, app->pwm_freq, app->pwm_duty);
53+
} else if(event.event == SignalGenPwmEventChannelChange) {
54+
consumed = true;
55+
// Stop previous channel PWM
56+
if(furi_hal_pwm_is_running(app->pwm_ch_prev)) {
57+
furi_hal_pwm_stop(app->pwm_ch_prev);
58+
}
59+
60+
// Start PWM and restart if it was starter already
61+
if(furi_hal_pwm_is_running(app->pwm_ch)) {
62+
furi_hal_pwm_stop(app->pwm_ch);
63+
furi_hal_pwm_start(app->pwm_ch, app->pwm_freq, app->pwm_duty);
64+
} else {
65+
furi_hal_pwm_start(app->pwm_ch, app->pwm_freq, app->pwm_duty);
66+
}
67+
}
68+
}
69+
return consumed;
70+
}
71+
72+
void signal_gen_scene_pwm_on_exit(void* context) {
73+
SignalGenApp* app = context;
74+
variable_item_list_reset(app->var_item_list);
75+
76+
if(furi_hal_pwm_is_running(app->pwm_ch)) {
77+
furi_hal_pwm_stop(app->pwm_ch);
78+
}
79+
}

scenes/signal_gen_scene_start.c

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include "../signal_gen_app_i.h"
2+
3+
typedef enum {
4+
SubmenuIndexPwm,
5+
SubmenuIndexClockOutput,
6+
} SubmenuIndex;
7+
8+
void signal_gen_scene_start_submenu_callback(void* context, uint32_t index) {
9+
SignalGenApp* app = context;
10+
11+
view_dispatcher_send_custom_event(app->view_dispatcher, index);
12+
}
13+
14+
void signal_gen_scene_start_on_enter(void* context) {
15+
SignalGenApp* app = context;
16+
Submenu* submenu = app->submenu;
17+
18+
submenu_add_item(
19+
submenu, "PWM Generator", SubmenuIndexPwm, signal_gen_scene_start_submenu_callback, app);
20+
submenu_add_item(
21+
submenu,
22+
"Clock Generator",
23+
SubmenuIndexClockOutput,
24+
signal_gen_scene_start_submenu_callback,
25+
app);
26+
27+
submenu_set_selected_item(
28+
submenu, scene_manager_get_scene_state(app->scene_manager, SignalGenSceneStart));
29+
30+
view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewSubmenu);
31+
}
32+
33+
bool signal_gen_scene_start_on_event(void* context, SceneManagerEvent event) {
34+
SignalGenApp* app = context;
35+
bool consumed = false;
36+
37+
if(event.type == SceneManagerEventTypeCustom) {
38+
if(event.event == SubmenuIndexPwm) {
39+
scene_manager_next_scene(app->scene_manager, SignalGenScenePwm);
40+
consumed = true;
41+
} else if(event.event == SubmenuIndexClockOutput) {
42+
scene_manager_next_scene(app->scene_manager, SignalGenSceneMco);
43+
consumed = true;
44+
}
45+
scene_manager_set_scene_state(app->scene_manager, SignalGenSceneStart, event.event);
46+
}
47+
48+
return consumed;
49+
}
50+
51+
void signal_gen_scene_start_on_exit(void* context) {
52+
SignalGenApp* app = context;
53+
54+
submenu_reset(app->submenu);
55+
}

signal_gen_10px.png

5.94 KB
Loading

0 commit comments

Comments
 (0)