Skip to content

Commit

Permalink
Migrated existing state to a new repo.
Browse files Browse the repository at this point in the history
- Dialer semi-functional - DTMF is untuned, code needs refactor
- There is definitely a memory leak.
- Bluebox and redbox functionality awaiting code refactor.
  • Loading branch information
litui committed Sep 16, 2022
0 parents commit 4754832
Show file tree
Hide file tree
Showing 24 changed files with 1,293 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## DTMF Dolphin

Dialer, and future Bluebox and Redbox for the Flipper Zero.

Documentation and code completion pending. This is a work in progress.
13 changes: 13 additions & 0 deletions application.fam
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
App(
appid="dtmf_dolphin",
name="DTMF Dolphin",
apptype=FlipperAppType.EXTERNAL,
entry_point="dtmf_dolphin_app",
cdefines=["DTMF_DOLPHIN"],
requires=[
"gui",
"dialogs",
],
stack_size=4 * 1024,
order=20,
)
136 changes: 136 additions & 0 deletions dtmf_dolphin.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#include "dtmf_dolphin_i.h"

#include <furi.h>
#include <furi_hal.h>

static bool dtmf_dolphin_app_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
DTMFDolphinApp* app = context;
return scene_manager_handle_custom_event(app->scene_manager, event);
}

static bool dtmf_dolphin_app_back_event_callback(void* context) {
furi_assert(context);
DTMFDolphinApp* app = context;
return scene_manager_handle_back_event(app->scene_manager);
}

static void dtmf_dolphin_app_tick_event_callback(void* context) {
furi_assert(context);
DTMFDolphinApp* app = context;

// Needed to handle queueing to ISR and prioritization of audio
if (app->player.playing) {
dtmf_dolphin_player_handle_tick();
} else {
scene_manager_handle_tick_event(app->scene_manager);
}
}

static DTMFDolphinApp* app_alloc() {
DTMFDolphinApp* app = malloc(sizeof(DTMFDolphinApp));
app->player.half_samples = 4 * 1024;
app->player.sample_count = 8 * 1024;
app->player.sample_buffer = malloc(sizeof(uint16_t) * app->player.sample_count);
app->player.buffer_buffer = malloc(sizeof(uint8_t) * app->player.sample_count);
app->player.wf1_period = 0;
app->player.wf2_period = 0;
app->player.wf1_freq = 0;
app->player.wf2_freq = 0;
app->player.wf1_pos = 0;
app->player.wf2_pos = 0;
app->player.queue = furi_message_queue_alloc(10, sizeof(DTMFDolphinEvent));
app->player.volume = 2.0f;
app->player.playing = false;

app->gui = furi_record_open(RECORD_GUI);
app->view_dispatcher = view_dispatcher_alloc();
app->scene_manager = scene_manager_alloc(&dtmf_dolphin_scene_handlers, app);
view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);

view_dispatcher_set_custom_event_callback(
app->view_dispatcher, dtmf_dolphin_app_custom_event_callback);
view_dispatcher_set_navigation_event_callback(
app->view_dispatcher, dtmf_dolphin_app_back_event_callback);
view_dispatcher_set_tick_event_callback(
app->view_dispatcher, dtmf_dolphin_app_tick_event_callback, 100);

view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);

app->main_menu_list = variable_item_list_alloc();
view_dispatcher_add_view(
app->view_dispatcher,
DTMFDolphinViewMainMenu,
variable_item_list_get_view(app->main_menu_list));

app->dtmf_dolphin_dialer = dtmf_dolphin_dialer_alloc();
view_dispatcher_add_view(
app->view_dispatcher,
DTMFDolphinViewDialer,
dtmf_dolphin_dialer_get_view(app->dtmf_dolphin_dialer));

app->dtmf_dolphin_bluebox = dtmf_dolphin_bluebox_alloc();
view_dispatcher_add_view(
app->view_dispatcher,
DTMFDolphinViewBluebox,
dtmf_dolphin_bluebox_get_view(app->dtmf_dolphin_bluebox));

app->dtmf_dolphin_play = widget_alloc();
view_dispatcher_add_view(
app->view_dispatcher,
DTMFDolphinViewPlay,
widget_get_view(app->dtmf_dolphin_play));

// app->dialer_button_panel = button_panel_alloc();
// app->bluebox_button_panel = button_panel_alloc();
// app->redbox_button_panel = button_panel_alloc();

app->notification = furi_record_open(RECORD_NOTIFICATION);
notification_message(app->notification, &sequence_display_backlight_enforce_on);

scene_manager_next_scene(app->scene_manager, DTMFDolphinSceneStart);

return app;
}

static void app_free(DTMFDolphinApp* app) {
furi_assert(app);
view_dispatcher_remove_view(app->view_dispatcher, DTMFDolphinViewMainMenu);
view_dispatcher_remove_view(app->view_dispatcher, DTMFDolphinViewBluebox);
view_dispatcher_remove_view(app->view_dispatcher, DTMFDolphinViewDialer);
view_dispatcher_remove_view(app->view_dispatcher, DTMFDolphinViewPlay);
variable_item_list_free(app->main_menu_list);

dtmf_dolphin_bluebox_free(app->dtmf_dolphin_bluebox);
dtmf_dolphin_dialer_free(app->dtmf_dolphin_dialer);
widget_free(app->dtmf_dolphin_play);

view_dispatcher_free(app->view_dispatcher);
scene_manager_free(app->scene_manager);

furi_message_queue_free(app->player.queue);
free(app->player.sample_buffer);

// button_panel_free(app->dialer_button_panel);
// button_panel_free(app->bluebox_button_panel);
// button_panel_free(app->redbox_button_panel);

notification_message(app->notification, &sequence_display_backlight_enforce_auto);

furi_record_close(RECORD_GUI);
furi_record_close(RECORD_NOTIFICATION);
free(app);
}

int32_t dtmf_dolphin_app(void *p) {
UNUSED(p);
DTMFDolphinApp* app = app_alloc();

dtmf_dolphin_player_init(&(app->player));

view_dispatcher_run(app->view_dispatcher);

app_free(app);
return 0;
}
14 changes: 14 additions & 0 deletions dtmf_dolphin_event.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

typedef enum {
DTMFDolphinEventVolumeUp = 0,
DTMFDolphinEventVolumeDown,
DTMFDolphinBlueboxOkCB,
DTMFDolphinEventStartDialer,
DTMFDolphinEventStartBluebox,
DTMFDolphinEventStartRedbox,
DTMFDolphinEventPlayTones,
DTMFDolphinEventStopTones,
DTMFDolphinPlayerEventHalfTransfer,
DTMFDolphinPlayerEventFullTransfer,
} DTMFDolphinEvent;
52 changes: 52 additions & 0 deletions dtmf_dolphin_hal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "dtmf_dolphin_hal.h"

void dtmf_dolphin_speaker_init() {
LL_TIM_InitTypeDef TIM_InitStruct = {0};
TIM_InitStruct.Prescaler = 4;
TIM_InitStruct.Autoreload = 255;
LL_TIM_Init(FURI_HAL_SPEAKER_TIMER, &TIM_InitStruct);

LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE;
TIM_OC_InitStruct.CompareValue = 127;
LL_TIM_OC_Init(FURI_HAL_SPEAKER_TIMER, FURI_HAL_SPEAKER_CHANNEL, &TIM_OC_InitStruct);
}

void dtmf_dolphin_speaker_start() {
LL_TIM_EnableAllOutputs(FURI_HAL_SPEAKER_TIMER);
LL_TIM_EnableCounter(FURI_HAL_SPEAKER_TIMER);
}

void dtmf_dolphin_speaker_stop() {
LL_TIM_DisableAllOutputs(FURI_HAL_SPEAKER_TIMER);
LL_TIM_DisableCounter(FURI_HAL_SPEAKER_TIMER);
}

void dtmf_dolphin_dma_init(uint32_t address, size_t size) {
uint32_t dma_dst = (uint32_t) & (FURI_HAL_SPEAKER_TIMER->CCR1);

LL_DMA_ConfigAddresses(DMA_INSTANCE, address, dma_dst, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
LL_DMA_SetDataLength(DMA_INSTANCE, size);

LL_DMA_SetPeriphRequest(DMA_INSTANCE, LL_DMAMUX_REQ_TIM16_UP);
LL_DMA_SetDataTransferDirection(DMA_INSTANCE, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
LL_DMA_SetChannelPriorityLevel(DMA_INSTANCE, LL_DMA_PRIORITY_VERYHIGH);
LL_DMA_SetMode(DMA_INSTANCE, LL_DMA_MODE_CIRCULAR);
LL_DMA_SetPeriphIncMode(DMA_INSTANCE, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA_INSTANCE, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA_INSTANCE, LL_DMA_PDATAALIGN_HALFWORD);
LL_DMA_SetMemorySize(DMA_INSTANCE, LL_DMA_MDATAALIGN_HALFWORD);

LL_DMA_EnableIT_TC(DMA_INSTANCE);
LL_DMA_EnableIT_HT(DMA_INSTANCE);
}

void dtmf_dolphin_dma_start() {
LL_DMA_EnableChannel(DMA_INSTANCE);
LL_TIM_EnableDMAReq_UPDATE(FURI_HAL_SPEAKER_TIMER);
}

void dtmf_dolphin_dma_stop() {
LL_DMA_DisableChannel(DMA_INSTANCE);
}
32 changes: 32 additions & 0 deletions dtmf_dolphin_hal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once
#include <furi.h>
#include <furi_hal.h>
#include <stdint.h>
#include <stddef.h>
#include <stm32wb55xx.h>
#include <stm32wbxx_ll_tim.h>
#include <stm32wbxx_ll_dma.h>

#define FURI_HAL_SPEAKER_TIMER TIM16
#define FURI_HAL_SPEAKER_CHANNEL LL_TIM_CHANNEL_CH1
#define DMA_INSTANCE DMA1, LL_DMA_CHANNEL_1

#ifdef __cplusplus
extern "C" {
#endif

void dtmf_dolphin_speaker_init();

void dtmf_dolphin_speaker_start();

void dtmf_dolphin_speaker_stop();

void dtmf_dolphin_dma_init(uint32_t address, size_t size);

void dtmf_dolphin_dma_start();

void dtmf_dolphin_dma_stop();

#ifdef __cplusplus
}
#endif
52 changes: 52 additions & 0 deletions dtmf_dolphin_i.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

#include "scenes/dtmf_dolphin_scene.h"

#include <gui/gui.h>
#include <gui/view_dispatcher.h>
#include <gui/scene_manager.h>
#include <gui/modules/submenu.h>
#include <gui/modules/widget.h>
#include <gui/modules/variable_item_list.h>
#include <notification/notification_messages.h>
#include <input/input.h>

#include "dtmf_dolphin_event.h"
#include "dtmf_dolphin_player.h"

#include "views/dtmf_dolphin_dialer.h"
#include "views/dtmf_dolphin_bluebox.h"

#define TAG "DTMFDolphin"


enum DTMFDolphinItem {
DTMFDolphinItemDialer,
DTMFDolphinItemBluebox,
DTMFDolphinItemRedbox,
DTMFDolphinItemPlay
};

typedef struct {
ViewDispatcher* view_dispatcher;
SceneManager* scene_manager;
VariableItemList* main_menu_list;
DTMFDolphinDialer* dtmf_dolphin_dialer;
DTMFDolphinBluebox* dtmf_dolphin_bluebox;
DTMFDolphinPlayer player;
Widget* dtmf_dolphin_play;

Gui* gui;
// ButtonPanel* dialer_button_panel;
// ButtonPanel* bluebox_button_panel;
// ButtonPanel* redbox_button_panel;
NotificationApp* notification;
} DTMFDolphinApp;

typedef enum {
DTMFDolphinViewMainMenu,
DTMFDolphinViewDialer,
DTMFDolphinViewBluebox,
DTMFDolphinViewRedbox,
DTMFDolphinViewPlay,
} DTMFDolphinView;
Loading

0 comments on commit 4754832

Please sign in to comment.