Skip to content

Commit 4754832

Browse files
committed
Migrated existing state to a new repo.
- Dialer semi-functional - DTMF is untuned, code needs refactor - There is definitely a memory leak. - Bluebox and redbox functionality awaiting code refactor.
0 parents  commit 4754832

24 files changed

+1293
-0
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## DTMF Dolphin
2+
3+
Dialer, and future Bluebox and Redbox for the Flipper Zero.
4+
5+
Documentation and code completion pending. This is a work in progress.

application.fam

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
App(
2+
appid="dtmf_dolphin",
3+
name="DTMF Dolphin",
4+
apptype=FlipperAppType.EXTERNAL,
5+
entry_point="dtmf_dolphin_app",
6+
cdefines=["DTMF_DOLPHIN"],
7+
requires=[
8+
"gui",
9+
"dialogs",
10+
],
11+
stack_size=4 * 1024,
12+
order=20,
13+
)

dtmf_dolphin.c

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#include "dtmf_dolphin_i.h"
2+
3+
#include <furi.h>
4+
#include <furi_hal.h>
5+
6+
static bool dtmf_dolphin_app_custom_event_callback(void* context, uint32_t event) {
7+
furi_assert(context);
8+
DTMFDolphinApp* app = context;
9+
return scene_manager_handle_custom_event(app->scene_manager, event);
10+
}
11+
12+
static bool dtmf_dolphin_app_back_event_callback(void* context) {
13+
furi_assert(context);
14+
DTMFDolphinApp* app = context;
15+
return scene_manager_handle_back_event(app->scene_manager);
16+
}
17+
18+
static void dtmf_dolphin_app_tick_event_callback(void* context) {
19+
furi_assert(context);
20+
DTMFDolphinApp* app = context;
21+
22+
// Needed to handle queueing to ISR and prioritization of audio
23+
if (app->player.playing) {
24+
dtmf_dolphin_player_handle_tick();
25+
} else {
26+
scene_manager_handle_tick_event(app->scene_manager);
27+
}
28+
}
29+
30+
static DTMFDolphinApp* app_alloc() {
31+
DTMFDolphinApp* app = malloc(sizeof(DTMFDolphinApp));
32+
app->player.half_samples = 4 * 1024;
33+
app->player.sample_count = 8 * 1024;
34+
app->player.sample_buffer = malloc(sizeof(uint16_t) * app->player.sample_count);
35+
app->player.buffer_buffer = malloc(sizeof(uint8_t) * app->player.sample_count);
36+
app->player.wf1_period = 0;
37+
app->player.wf2_period = 0;
38+
app->player.wf1_freq = 0;
39+
app->player.wf2_freq = 0;
40+
app->player.wf1_pos = 0;
41+
app->player.wf2_pos = 0;
42+
app->player.queue = furi_message_queue_alloc(10, sizeof(DTMFDolphinEvent));
43+
app->player.volume = 2.0f;
44+
app->player.playing = false;
45+
46+
app->gui = furi_record_open(RECORD_GUI);
47+
app->view_dispatcher = view_dispatcher_alloc();
48+
app->scene_manager = scene_manager_alloc(&dtmf_dolphin_scene_handlers, app);
49+
view_dispatcher_enable_queue(app->view_dispatcher);
50+
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
51+
52+
view_dispatcher_set_custom_event_callback(
53+
app->view_dispatcher, dtmf_dolphin_app_custom_event_callback);
54+
view_dispatcher_set_navigation_event_callback(
55+
app->view_dispatcher, dtmf_dolphin_app_back_event_callback);
56+
view_dispatcher_set_tick_event_callback(
57+
app->view_dispatcher, dtmf_dolphin_app_tick_event_callback, 100);
58+
59+
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
60+
61+
app->main_menu_list = variable_item_list_alloc();
62+
view_dispatcher_add_view(
63+
app->view_dispatcher,
64+
DTMFDolphinViewMainMenu,
65+
variable_item_list_get_view(app->main_menu_list));
66+
67+
app->dtmf_dolphin_dialer = dtmf_dolphin_dialer_alloc();
68+
view_dispatcher_add_view(
69+
app->view_dispatcher,
70+
DTMFDolphinViewDialer,
71+
dtmf_dolphin_dialer_get_view(app->dtmf_dolphin_dialer));
72+
73+
app->dtmf_dolphin_bluebox = dtmf_dolphin_bluebox_alloc();
74+
view_dispatcher_add_view(
75+
app->view_dispatcher,
76+
DTMFDolphinViewBluebox,
77+
dtmf_dolphin_bluebox_get_view(app->dtmf_dolphin_bluebox));
78+
79+
app->dtmf_dolphin_play = widget_alloc();
80+
view_dispatcher_add_view(
81+
app->view_dispatcher,
82+
DTMFDolphinViewPlay,
83+
widget_get_view(app->dtmf_dolphin_play));
84+
85+
// app->dialer_button_panel = button_panel_alloc();
86+
// app->bluebox_button_panel = button_panel_alloc();
87+
// app->redbox_button_panel = button_panel_alloc();
88+
89+
app->notification = furi_record_open(RECORD_NOTIFICATION);
90+
notification_message(app->notification, &sequence_display_backlight_enforce_on);
91+
92+
scene_manager_next_scene(app->scene_manager, DTMFDolphinSceneStart);
93+
94+
return app;
95+
}
96+
97+
static void app_free(DTMFDolphinApp* app) {
98+
furi_assert(app);
99+
view_dispatcher_remove_view(app->view_dispatcher, DTMFDolphinViewMainMenu);
100+
view_dispatcher_remove_view(app->view_dispatcher, DTMFDolphinViewBluebox);
101+
view_dispatcher_remove_view(app->view_dispatcher, DTMFDolphinViewDialer);
102+
view_dispatcher_remove_view(app->view_dispatcher, DTMFDolphinViewPlay);
103+
variable_item_list_free(app->main_menu_list);
104+
105+
dtmf_dolphin_bluebox_free(app->dtmf_dolphin_bluebox);
106+
dtmf_dolphin_dialer_free(app->dtmf_dolphin_dialer);
107+
widget_free(app->dtmf_dolphin_play);
108+
109+
view_dispatcher_free(app->view_dispatcher);
110+
scene_manager_free(app->scene_manager);
111+
112+
furi_message_queue_free(app->player.queue);
113+
free(app->player.sample_buffer);
114+
115+
// button_panel_free(app->dialer_button_panel);
116+
// button_panel_free(app->bluebox_button_panel);
117+
// button_panel_free(app->redbox_button_panel);
118+
119+
notification_message(app->notification, &sequence_display_backlight_enforce_auto);
120+
121+
furi_record_close(RECORD_GUI);
122+
furi_record_close(RECORD_NOTIFICATION);
123+
free(app);
124+
}
125+
126+
int32_t dtmf_dolphin_app(void *p) {
127+
UNUSED(p);
128+
DTMFDolphinApp* app = app_alloc();
129+
130+
dtmf_dolphin_player_init(&(app->player));
131+
132+
view_dispatcher_run(app->view_dispatcher);
133+
134+
app_free(app);
135+
return 0;
136+
}

dtmf_dolphin_event.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
3+
typedef enum {
4+
DTMFDolphinEventVolumeUp = 0,
5+
DTMFDolphinEventVolumeDown,
6+
DTMFDolphinBlueboxOkCB,
7+
DTMFDolphinEventStartDialer,
8+
DTMFDolphinEventStartBluebox,
9+
DTMFDolphinEventStartRedbox,
10+
DTMFDolphinEventPlayTones,
11+
DTMFDolphinEventStopTones,
12+
DTMFDolphinPlayerEventHalfTransfer,
13+
DTMFDolphinPlayerEventFullTransfer,
14+
} DTMFDolphinEvent;

dtmf_dolphin_hal.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include "dtmf_dolphin_hal.h"
2+
3+
void dtmf_dolphin_speaker_init() {
4+
LL_TIM_InitTypeDef TIM_InitStruct = {0};
5+
TIM_InitStruct.Prescaler = 4;
6+
TIM_InitStruct.Autoreload = 255;
7+
LL_TIM_Init(FURI_HAL_SPEAKER_TIMER, &TIM_InitStruct);
8+
9+
LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
10+
TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
11+
TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE;
12+
TIM_OC_InitStruct.CompareValue = 127;
13+
LL_TIM_OC_Init(FURI_HAL_SPEAKER_TIMER, FURI_HAL_SPEAKER_CHANNEL, &TIM_OC_InitStruct);
14+
}
15+
16+
void dtmf_dolphin_speaker_start() {
17+
LL_TIM_EnableAllOutputs(FURI_HAL_SPEAKER_TIMER);
18+
LL_TIM_EnableCounter(FURI_HAL_SPEAKER_TIMER);
19+
}
20+
21+
void dtmf_dolphin_speaker_stop() {
22+
LL_TIM_DisableAllOutputs(FURI_HAL_SPEAKER_TIMER);
23+
LL_TIM_DisableCounter(FURI_HAL_SPEAKER_TIMER);
24+
}
25+
26+
void dtmf_dolphin_dma_init(uint32_t address, size_t size) {
27+
uint32_t dma_dst = (uint32_t) & (FURI_HAL_SPEAKER_TIMER->CCR1);
28+
29+
LL_DMA_ConfigAddresses(DMA_INSTANCE, address, dma_dst, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
30+
LL_DMA_SetDataLength(DMA_INSTANCE, size);
31+
32+
LL_DMA_SetPeriphRequest(DMA_INSTANCE, LL_DMAMUX_REQ_TIM16_UP);
33+
LL_DMA_SetDataTransferDirection(DMA_INSTANCE, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
34+
LL_DMA_SetChannelPriorityLevel(DMA_INSTANCE, LL_DMA_PRIORITY_VERYHIGH);
35+
LL_DMA_SetMode(DMA_INSTANCE, LL_DMA_MODE_CIRCULAR);
36+
LL_DMA_SetPeriphIncMode(DMA_INSTANCE, LL_DMA_PERIPH_NOINCREMENT);
37+
LL_DMA_SetMemoryIncMode(DMA_INSTANCE, LL_DMA_MEMORY_INCREMENT);
38+
LL_DMA_SetPeriphSize(DMA_INSTANCE, LL_DMA_PDATAALIGN_HALFWORD);
39+
LL_DMA_SetMemorySize(DMA_INSTANCE, LL_DMA_MDATAALIGN_HALFWORD);
40+
41+
LL_DMA_EnableIT_TC(DMA_INSTANCE);
42+
LL_DMA_EnableIT_HT(DMA_INSTANCE);
43+
}
44+
45+
void dtmf_dolphin_dma_start() {
46+
LL_DMA_EnableChannel(DMA_INSTANCE);
47+
LL_TIM_EnableDMAReq_UPDATE(FURI_HAL_SPEAKER_TIMER);
48+
}
49+
50+
void dtmf_dolphin_dma_stop() {
51+
LL_DMA_DisableChannel(DMA_INSTANCE);
52+
}

dtmf_dolphin_hal.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#pragma once
2+
#include <furi.h>
3+
#include <furi_hal.h>
4+
#include <stdint.h>
5+
#include <stddef.h>
6+
#include <stm32wb55xx.h>
7+
#include <stm32wbxx_ll_tim.h>
8+
#include <stm32wbxx_ll_dma.h>
9+
10+
#define FURI_HAL_SPEAKER_TIMER TIM16
11+
#define FURI_HAL_SPEAKER_CHANNEL LL_TIM_CHANNEL_CH1
12+
#define DMA_INSTANCE DMA1, LL_DMA_CHANNEL_1
13+
14+
#ifdef __cplusplus
15+
extern "C" {
16+
#endif
17+
18+
void dtmf_dolphin_speaker_init();
19+
20+
void dtmf_dolphin_speaker_start();
21+
22+
void dtmf_dolphin_speaker_stop();
23+
24+
void dtmf_dolphin_dma_init(uint32_t address, size_t size);
25+
26+
void dtmf_dolphin_dma_start();
27+
28+
void dtmf_dolphin_dma_stop();
29+
30+
#ifdef __cplusplus
31+
}
32+
#endif

dtmf_dolphin_i.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#pragma once
2+
3+
#include "scenes/dtmf_dolphin_scene.h"
4+
5+
#include <gui/gui.h>
6+
#include <gui/view_dispatcher.h>
7+
#include <gui/scene_manager.h>
8+
#include <gui/modules/submenu.h>
9+
#include <gui/modules/widget.h>
10+
#include <gui/modules/variable_item_list.h>
11+
#include <notification/notification_messages.h>
12+
#include <input/input.h>
13+
14+
#include "dtmf_dolphin_event.h"
15+
#include "dtmf_dolphin_player.h"
16+
17+
#include "views/dtmf_dolphin_dialer.h"
18+
#include "views/dtmf_dolphin_bluebox.h"
19+
20+
#define TAG "DTMFDolphin"
21+
22+
23+
enum DTMFDolphinItem {
24+
DTMFDolphinItemDialer,
25+
DTMFDolphinItemBluebox,
26+
DTMFDolphinItemRedbox,
27+
DTMFDolphinItemPlay
28+
};
29+
30+
typedef struct {
31+
ViewDispatcher* view_dispatcher;
32+
SceneManager* scene_manager;
33+
VariableItemList* main_menu_list;
34+
DTMFDolphinDialer* dtmf_dolphin_dialer;
35+
DTMFDolphinBluebox* dtmf_dolphin_bluebox;
36+
DTMFDolphinPlayer player;
37+
Widget* dtmf_dolphin_play;
38+
39+
Gui* gui;
40+
// ButtonPanel* dialer_button_panel;
41+
// ButtonPanel* bluebox_button_panel;
42+
// ButtonPanel* redbox_button_panel;
43+
NotificationApp* notification;
44+
} DTMFDolphinApp;
45+
46+
typedef enum {
47+
DTMFDolphinViewMainMenu,
48+
DTMFDolphinViewDialer,
49+
DTMFDolphinViewBluebox,
50+
DTMFDolphinViewRedbox,
51+
DTMFDolphinViewPlay,
52+
} DTMFDolphinView;

0 commit comments

Comments
 (0)