Remove broken \ unworking plugins
Remove unworking Flappy Bird, JukeBox and Universa_RF apps (didnt found way to use) and non-working Spectrum Analyzer.
@@ -39,8 +39,6 @@ extern int32_t passport_app(void* p);
|
||||
extern int32_t scened_app(void* p);
|
||||
extern int32_t storage_test_app(void* p);
|
||||
extern int32_t subghz_app(void* p);
|
||||
extern int32_t jukebox_app(void *p);
|
||||
extern int32_t universal_rf_remote_app(void *p);
|
||||
extern int32_t usb_mouse_app(void* p);
|
||||
extern int32_t usb_test_app(void* p);
|
||||
extern int32_t vibro_test_app(void* p);
|
||||
@@ -54,10 +52,6 @@ extern int32_t music_player_app(void* p);
|
||||
extern int32_t snake_game_app(void* p);
|
||||
extern int32_t tetris_game_app(void *p);
|
||||
extern int32_t clock_app(void *p);
|
||||
// extern int32_t floopper_bloopper(void* p);
|
||||
// extern int32_t raycast_game_app(void* p);
|
||||
extern int32_t spectrum_analyzer_app(void* p);
|
||||
extern int32_t flappy_game_app(void* p);
|
||||
|
||||
// On system start hooks declaration
|
||||
extern void bt_on_system_start();
|
||||
@@ -231,22 +225,6 @@ const FlipperApplication FLIPPER_APPS[] = {
|
||||
.flags = FlipperApplicationFlagDefault},
|
||||
#endif
|
||||
|
||||
#ifdef APP_UNIVERSALRF
|
||||
{.app = universal_rf_remote_app,
|
||||
.name = "Universal SubGHz",
|
||||
.stack_size = 2048,
|
||||
.icon = &A_UniversalRemote_14,
|
||||
.flags = FlipperApplicationFlagDefault},
|
||||
#endif
|
||||
|
||||
#ifdef APP_JUKEBOX
|
||||
{.app = jukebox_app,
|
||||
.name = "Jukebox",
|
||||
.stack_size = 2048,
|
||||
.icon = &A_TouchTunes_14,
|
||||
.flags = FlipperApplicationFlagDefault},
|
||||
#endif
|
||||
|
||||
#ifdef APP_LF_RFID
|
||||
{.app = lfrfid_app,
|
||||
.name = "125 kHz RFID",
|
||||
@@ -367,14 +345,6 @@ const FlipperApplication FLIPPER_PLUGINS[] = {
|
||||
.flags = FlipperApplicationFlagDefault},
|
||||
#endif
|
||||
|
||||
#ifdef APP_FLAPPY_GAME
|
||||
{.app = flappy_game_app,
|
||||
.name = "Flipper Flappy Bird",
|
||||
.stack_size = 1024,
|
||||
.icon = &A_Plugins_14
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef APP_MUSIC_PLAYER
|
||||
{.app = music_player_app,
|
||||
.name = "Music Player",
|
||||
@@ -391,14 +361,6 @@ const FlipperApplication FLIPPER_PLUGINS[] = {
|
||||
.flags = FlipperApplicationFlagDefault},
|
||||
#endif
|
||||
|
||||
#ifdef APP_SPECTRUM_ANALYZER
|
||||
{.app = spectrum_analyzer_app,
|
||||
.name = "Spectrum Analyzer",
|
||||
.stack_size = 1024,
|
||||
.icon = &A_Plugins_14,
|
||||
.flags = FlipperApplicationFlagDefault},
|
||||
#endif
|
||||
|
||||
#ifdef APP_TETRIS_GAME
|
||||
{.app = tetris_game_app, .name = "Tetris Game", .stack_size = 1024, .icon = NULL},
|
||||
#endif
|
||||
@@ -408,19 +370,6 @@ const FlipperApplication FLIPPER_PLUGINS[] = {
|
||||
.stack_size = 4096,
|
||||
.icon = &A_MusicPlayer_14,
|
||||
.flags = FlipperApplicationFlagDefault},
|
||||
|
||||
// #ifdef APP_RAYCAST_GAME
|
||||
// {.app = raycast_game_app, .name = "Raycast Game", .stack_size = 4096, .icon = NULL},
|
||||
// #endif
|
||||
|
||||
// #ifdef FLOOPPER_BLOOPPER
|
||||
// {.app = floopper_bloopper,
|
||||
// .name = "Floopper Bloopper",
|
||||
// .stack_size = 1024,
|
||||
// .icon = &A_Plugins_14,
|
||||
// .flags = FlipperApplicationFlagDefault},
|
||||
// #endif
|
||||
|
||||
};
|
||||
|
||||
const size_t FLIPPER_PLUGINS_COUNT = COUNT_OF(FLIPPER_PLUGINS);
|
||||
|
||||
@@ -40,8 +40,6 @@ APP_INFRARED = 1
|
||||
APP_LF_RFID = 1
|
||||
APP_NFC = 1
|
||||
APP_SUBGHZ = 1
|
||||
APP_UNIVERSALRF = 1
|
||||
APP_JUKEBOX = 1
|
||||
APP_ABOUT = 1
|
||||
APP_PASSPORT = 1
|
||||
APP_UPDATER = 1
|
||||
@@ -50,11 +48,7 @@ APP_UPDATER = 1
|
||||
APP_MUSIC_PLAYER = 1
|
||||
APP_SNAKE_GAME = 1
|
||||
APP_TETRIS_GAME = 1
|
||||
# APP_RAYCAST_GAME = 1
|
||||
APP_CLOCK = 1
|
||||
APP_SPECTRUM_ANALYZER = 1
|
||||
APP_FLAPPY_GAME = 1
|
||||
|
||||
|
||||
# Debug
|
||||
APP_ACCESSOR = 1
|
||||
@@ -113,19 +107,6 @@ SRV_GUI = 1
|
||||
SRV_CLI = 1
|
||||
endif
|
||||
|
||||
APP_UNIVERSALRF ?= 0
|
||||
ifeq ($(APP_UNIVERSALRF), 1)
|
||||
CFLAGS += -DAPP_UNIVERSALRF
|
||||
SRV_GUI = 1
|
||||
SRV_CLI = 1
|
||||
endif
|
||||
|
||||
APP_JUKEBOX ?= 0
|
||||
ifeq ($(APP_JUKEBOX), 1)
|
||||
CFLAGS += -DAPP_JUKEBOX
|
||||
SRV_GUI = 1
|
||||
SRV_CLI = 1
|
||||
endif
|
||||
|
||||
APP_ABOUT ?= 0
|
||||
ifeq ($(APP_ABOUT), 1)
|
||||
@@ -255,11 +236,6 @@ CFLAGS += -DAPP_MUSIC_PLAYER
|
||||
SRV_GUI = 1
|
||||
endif
|
||||
|
||||
APP_FLAPPY_GAME ?= 0
|
||||
ifeq ($(APP_FLAPPY_GAME), 1)
|
||||
CFLAGS += -DAPP_FLAPPY_GAME
|
||||
SRV_GUI = 1
|
||||
endif
|
||||
|
||||
APP_SNAKE_GAME ?= 0
|
||||
ifeq ($(APP_SNAKE_GAME), 1)
|
||||
@@ -267,11 +243,6 @@ CFLAGS += -DAPP_SNAKE_GAME
|
||||
SRV_GUI = 1
|
||||
endif
|
||||
|
||||
APP_SPECTRUM_ANALYZER ?= 0
|
||||
ifeq ($(APP_SPECTRUM_ANALYZER), 1)
|
||||
CFLAGS += -DAPP_SPECTRUM_ANALYZER
|
||||
SRV_GUI = 1
|
||||
endif
|
||||
|
||||
APP_TETRIS_GAME ?= 0
|
||||
ifeq ($(APP_TETRIS_GAME), 1)
|
||||
@@ -279,12 +250,6 @@ CFLAGS += -DAPP_TETRIS_GAME
|
||||
SRV_GUI = 1
|
||||
endif
|
||||
|
||||
# APP_RAYCAST_GAME ?= 0
|
||||
# ifeq ($(APP_RAYCAST_GAME), 1)
|
||||
# CFLAGS += -DAPP_RAYCAST_GAME
|
||||
# SRV_GUI = 1
|
||||
# endif
|
||||
|
||||
|
||||
APP_CLOCK ?= 0
|
||||
ifeq ($(APP_CLOCK), 1)
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
#include <furi.h>
|
||||
|
||||
uint8_t bird_array[3][15][11] = {
|
||||
{
|
||||
{0,0,0,0,0,0,1,1,0,0,0},
|
||||
{0,0,0,0,0,1,0,0,1,0,0},
|
||||
{0,0,0,0,0,1,0,0,0,1,0},
|
||||
{0,0,1,1,1,1,0,0,0,1,0},
|
||||
{0,1,0,0,0,1,0,0,0,1,0},
|
||||
{0,1,0,0,0,0,1,0,1,0,1},
|
||||
{1,0,0,0,0,0,0,1,0,0,1},
|
||||
{1,0,1,1,1,0,0,1,0,0,1},
|
||||
{1,1,0,0,0,0,1,0,1,0,1},
|
||||
{1,0,0,0,0,1,0,1,0,1,0},
|
||||
{1,0,0,0,0,1,0,1,0,1,0},
|
||||
{0,1,0,1,1,1,0,1,0,1,0},
|
||||
{0,0,1,0,0,1,0,1,0,1,0},
|
||||
{0,0,0,1,1,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,0,1,1,1,0,0},
|
||||
}, {
|
||||
{0,0,0,0,0,1,1,0,0,0,0},
|
||||
{0,0,0,0,1,0,0,1,0,0,0},
|
||||
{0,0,0,0,1,0,0,0,1,0,0},
|
||||
{0,0,1,1,1,0,0,0,1,0,0},
|
||||
{0,1,0,0,1,0,0,0,1,1,0},
|
||||
{0,1,0,0,0,1,0,1,0,0,1},
|
||||
{1,0,0,0,0,0,1,0,0,0,1},
|
||||
{1,0,1,1,1,0,0,1,0,0,1},
|
||||
{1,1,0,0,0,0,1,0,1,0,1},
|
||||
{1,0,0,0,0,1,0,1,0,1,0},
|
||||
{1,0,0,0,0,1,0,1,0,1,0},
|
||||
{0,1,0,1,1,1,0,1,0,1,0},
|
||||
{0,0,1,0,0,1,0,1,0,1,0},
|
||||
{0,0,0,1,1,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,0,1,1,1,0,0},
|
||||
}, {
|
||||
{0,0,0,0,1,1,0,0,0,0,0},
|
||||
{0,0,0,1,0,0,1,0,0,0,0},
|
||||
{0,0,0,1,0,0,0,1,1,0,0},
|
||||
{0,0,1,1,0,0,0,1,0,1,0},
|
||||
{0,1,0,1,0,0,0,1,0,1,0},
|
||||
{0,1,0,0,1,0,1,0,0,0,1},
|
||||
{1,0,0,0,0,1,0,0,0,0,1},
|
||||
{1,0,1,1,1,0,0,1,0,0,1},
|
||||
{1,1,0,0,0,0,1,0,1,0,1},
|
||||
{1,0,0,0,0,1,0,1,0,1,0},
|
||||
{1,0,0,0,0,1,0,1,0,1,0},
|
||||
{0,1,0,1,1,1,0,1,0,1,0},
|
||||
{0,0,1,0,0,1,0,1,0,1,0},
|
||||
{0,0,0,1,1,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,0,1,1,1,0,0},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,256 +0,0 @@
|
||||
#include <furi.h>
|
||||
#include <gui/gui.h>
|
||||
#include <input/input.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bird.h"
|
||||
|
||||
#define TAG "Flappy"
|
||||
|
||||
#define FLAPPY_BIRD_HEIGHT 15
|
||||
#define FLAPPY_BIRD_WIDTH 10
|
||||
|
||||
#define FLAPPY_PILAR_MAX 6
|
||||
#define FLAPPY_PILAR_DIST 45
|
||||
|
||||
#define FLAPPY_GAB_HEIGHT 25
|
||||
#define FLAPPY_GAB_WIDTH 5
|
||||
|
||||
#define FLAPPY_GRAVITY_JUMP -1.1
|
||||
#define FLAPPY_GRAVITY_TICK 0.10
|
||||
|
||||
#define FLIPPER_LCD_WIDTH 128
|
||||
#define FLIPPER_LCD_HEIGHT 64
|
||||
|
||||
typedef enum {
|
||||
EventTypeTick,
|
||||
EventTypeKey,
|
||||
} EventType;
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
} POINT;
|
||||
|
||||
typedef struct {
|
||||
float gravity;
|
||||
POINT point;
|
||||
}BIRD;
|
||||
|
||||
typedef struct {
|
||||
POINT point;
|
||||
int height;
|
||||
int visible;
|
||||
int passed;
|
||||
} PILAR;
|
||||
|
||||
typedef struct {
|
||||
BIRD bird;
|
||||
|
||||
int points;
|
||||
int pilars_count;
|
||||
PILAR pilars[FLAPPY_PILAR_MAX];
|
||||
} GameState;
|
||||
|
||||
typedef struct {
|
||||
EventType type;
|
||||
InputEvent input;
|
||||
} GameEvent;
|
||||
|
||||
typedef enum {
|
||||
DirectionUp,
|
||||
DirectionRight,
|
||||
DirectionDown,
|
||||
DirectionLeft,
|
||||
} Direction;
|
||||
|
||||
static void flappy_game_random_pilar(GameState* const game_state) {
|
||||
PILAR pilar;
|
||||
|
||||
pilar.visible = 1;
|
||||
pilar.height = random() % (FLIPPER_LCD_HEIGHT - FLAPPY_GAB_HEIGHT) + 1;
|
||||
pilar.point.y = 0;
|
||||
pilar.point.x = FLIPPER_LCD_WIDTH + FLAPPY_GAB_WIDTH + 1;
|
||||
|
||||
game_state->pilars_count++;
|
||||
game_state->pilars[game_state->pilars_count % FLAPPY_PILAR_MAX] = pilar;
|
||||
}
|
||||
|
||||
static void flappy_game_tick(GameState* const game_state) {
|
||||
game_state->bird.gravity += FLAPPY_GRAVITY_TICK;
|
||||
game_state->bird.point.y += game_state->bird.gravity;
|
||||
|
||||
// Checking the location of the last respawned pilar.
|
||||
PILAR * pilar = &game_state->pilars[game_state->pilars_count % FLAPPY_PILAR_MAX];
|
||||
if (pilar->point.x == (FLIPPER_LCD_WIDTH - FLAPPY_PILAR_DIST))
|
||||
flappy_game_random_pilar(game_state);
|
||||
|
||||
// Updating the position/status of the pilars (visiblity, posotion, game points)
|
||||
for (int i = 0; i < FLAPPY_PILAR_MAX; i++) {
|
||||
PILAR * pilar = &game_state->pilars[i];
|
||||
pilar->point.x--;
|
||||
|
||||
if (pilar != NULL && pilar->visible && pilar->point.x > 0) {
|
||||
if (game_state->bird.point.x >= pilar->point.x + FLAPPY_GAB_WIDTH &&
|
||||
pilar->passed == 0) {
|
||||
pilar->passed = 1;
|
||||
game_state->points++;
|
||||
}
|
||||
if (pilar->point.x < -FLAPPY_PILAR_DIST)
|
||||
pilar->visible = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void flappy_game_flap(GameState* const game_state) {
|
||||
game_state->bird.gravity = FLAPPY_GRAVITY_JUMP;
|
||||
}
|
||||
|
||||
static void flappy_game_state_init(GameState* const game_state) {
|
||||
BIRD bird;
|
||||
bird.gravity = 0.0f;
|
||||
bird.point.x = 5;
|
||||
bird.point.y = 32;
|
||||
|
||||
game_state->bird = bird;
|
||||
game_state->pilars_count = 0;
|
||||
memset(game_state->pilars, 0, sizeof(game_state->pilars));
|
||||
|
||||
flappy_game_random_pilar(game_state);
|
||||
}
|
||||
|
||||
static void flappy_game_render_callback(Canvas* const canvas, void* ctx) {
|
||||
const GameState* game_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(game_state == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||
|
||||
// Pilars
|
||||
for (int i = 0; i < FLAPPY_PILAR_MAX; i++) {
|
||||
const PILAR * pilar = &game_state->pilars[i];
|
||||
if (pilar != NULL && pilar->visible) {
|
||||
canvas_draw_dot(canvas, pilar->point.x, pilar->point.y + 10);
|
||||
canvas_draw_frame(canvas, pilar->point.x, pilar->point.y,
|
||||
FLAPPY_GAB_WIDTH, pilar->height);
|
||||
|
||||
canvas_draw_frame(canvas, pilar->point.x, pilar->point.y + pilar->height + FLAPPY_GAB_HEIGHT,
|
||||
FLAPPY_GAB_WIDTH, FLIPPER_LCD_HEIGHT - pilar->height - FLAPPY_GAB_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
// Flappy
|
||||
for (int h = 0; h < FLAPPY_BIRD_HEIGHT; h++) {
|
||||
for (int w = 0; w < FLAPPY_BIRD_WIDTH; w++) {
|
||||
// Switch animation
|
||||
int bird = 0;
|
||||
if (game_state->bird.gravity < -0.5)
|
||||
bird = 1;
|
||||
else
|
||||
bird = 2;
|
||||
|
||||
// Draw bird pixels
|
||||
if (bird_array[bird][h][w] == 1) {
|
||||
int x = game_state->bird.point.x + h;
|
||||
int y = game_state->bird.point.y + w;
|
||||
|
||||
canvas_draw_dot(canvas, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, game_state);
|
||||
}
|
||||
|
||||
|
||||
static void flappy_game_input_callback(InputEvent* input_event, osMessageQueueId_t event_queue) {
|
||||
furi_assert(event_queue);
|
||||
|
||||
GameEvent event = {.type = EventTypeKey, .input = *input_event};
|
||||
osMessageQueuePut(event_queue, &event, 0, osWaitForever);
|
||||
}
|
||||
|
||||
static void flappy_game_update_timer_callback(osMessageQueueId_t event_queue) {
|
||||
furi_assert(event_queue);
|
||||
|
||||
GameEvent event = {.type = EventTypeTick};
|
||||
osMessageQueuePut(event_queue, &event, 0, 0);
|
||||
}
|
||||
|
||||
int32_t flappy_game_app(void* p) {
|
||||
osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(GameEvent), NULL);
|
||||
|
||||
GameState* game_state = malloc(sizeof(GameState));
|
||||
flappy_game_state_init(game_state);
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if (!init_mutex(&state_mutex, game_state, sizeof(GameState))) {
|
||||
FURI_LOG_E(TAG, "cannot create mutex\r\n");
|
||||
free(game_state);
|
||||
return 255;
|
||||
}
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, flappy_game_render_callback, &state_mutex);
|
||||
view_port_input_callback_set(view_port, flappy_game_input_callback, event_queue);
|
||||
|
||||
osTimerId_t timer =
|
||||
osTimerNew(flappy_game_update_timer_callback, osTimerPeriodic, event_queue, NULL);
|
||||
osTimerStart(timer, osKernelGetTickFreq() / 22);
|
||||
|
||||
// Open GUI and register view_port
|
||||
Gui* gui = furi_record_open("gui");
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
GameEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 100);
|
||||
GameState* game_state = (GameState*)acquire_mutex_block(&state_mutex);
|
||||
|
||||
if(event_status == osOK) {
|
||||
// press events
|
||||
if(event.type == EventTypeKey) {
|
||||
if(event.input.type == InputTypePress) {
|
||||
switch(event.input.key) {
|
||||
case InputKeyUp:
|
||||
game_state->bird.point.y--;
|
||||
break;
|
||||
case InputKeyDown:
|
||||
game_state->bird.point.y++;
|
||||
break;
|
||||
case InputKeyRight:
|
||||
game_state->bird.point.x++;
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
game_state->bird.point.x--;
|
||||
break;
|
||||
case InputKeyOk:
|
||||
flappy_game_flap(game_state);
|
||||
break;
|
||||
case InputKeyBack:
|
||||
processing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(event.type == EventTypeTick) {
|
||||
flappy_game_tick(game_state);
|
||||
}
|
||||
} else {
|
||||
FURI_LOG_D(TAG, "osMessageQueue: event timeout");
|
||||
// event timeout
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, game_state);
|
||||
}
|
||||
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close("gui");
|
||||
view_port_free(view_port);
|
||||
osMessageQueueDelete(event_queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,276 +0,0 @@
|
||||
#include <furi.h>
|
||||
#include <gui/gui.h>
|
||||
#include <input/input.h>
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
#include <string.h>
|
||||
#include <lib/subghz/receiver.h>
|
||||
#include <lib/subghz/transmitter.h>
|
||||
#include <lib/subghz/subghz_file_encoder_worker.h>
|
||||
#include <lib/toolbox/path.h>
|
||||
#include <notification/notification_messages.h>
|
||||
|
||||
#define TAG "JukeBox"
|
||||
|
||||
typedef struct {
|
||||
bool press[5];
|
||||
} RemoteAppState;
|
||||
|
||||
static void jukebox_reset_state(RemoteAppState* state) {
|
||||
state->press[0] = 0;
|
||||
state->press[1] = 0;
|
||||
state->press[2] = 0;
|
||||
state->press[3] = 0;
|
||||
state->press[4] = 0;
|
||||
}
|
||||
static string_t up_file;
|
||||
static string_t down_file;
|
||||
static string_t left_file;
|
||||
static string_t right_file;
|
||||
static string_t ok_file;
|
||||
|
||||
static char* subString(char* someString, int n) {
|
||||
char* new = malloc(sizeof(char) * n + 1);
|
||||
strncpy(new, someString, n);
|
||||
new[n] = '\0';
|
||||
return(new);
|
||||
}
|
||||
|
||||
static char* file_stub(const char* file_name) {
|
||||
string_t filename;
|
||||
string_init(filename);
|
||||
// string_init(file_name);
|
||||
path_extract_filename_no_ext(file_name, filename);
|
||||
|
||||
return(subString((char*)string_get_cstr(filename), 8));
|
||||
}
|
||||
|
||||
static void jukebox_send_signal(uint32_t frequency, string_t signal, string_t protocol) {
|
||||
uint32_t repeat = 1;
|
||||
frequency = frequency ? frequency : 433920000;
|
||||
FURI_LOG_D(TAG, "file to send: %s", string_get_cstr(signal));
|
||||
|
||||
if(strlen(string_get_cstr(signal)) < 10) {
|
||||
return;
|
||||
}
|
||||
|
||||
string_t flipper_format_string;
|
||||
if(strcmp(string_get_cstr(protocol), "RAW") == 0) {
|
||||
string_init_printf(flipper_format_string, "File_name: %s", string_get_cstr(signal));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
NotificationApp* notification = furi_record_open("notification");
|
||||
FlipperFormat* flipper_format = flipper_format_string_alloc();
|
||||
Stream* stream = flipper_format_get_raw_stream(flipper_format);
|
||||
stream_clean(stream);
|
||||
stream_write_cstring(stream, string_get_cstr(flipper_format_string));
|
||||
|
||||
SubGhzEnvironment* environment = subghz_environment_alloc();
|
||||
|
||||
SubGhzTransmitter* transmitter =
|
||||
subghz_transmitter_alloc_init(environment, string_get_cstr(protocol));
|
||||
subghz_transmitter_deserialize(transmitter, flipper_format);
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok270Async);
|
||||
furi_hal_subghz_set_frequency_and_path(frequency);
|
||||
FURI_LOG_D(
|
||||
TAG, "Transmitting at %lu, repeat %lu. Press CTRL+C to stop\r\n", frequency, repeat);
|
||||
|
||||
furi_hal_power_suppress_charge_enter();
|
||||
notification_message(notification, &sequence_set_vibro_on);
|
||||
|
||||
furi_hal_subghz_start_async_tx(subghz_transmitter_yield, transmitter);
|
||||
|
||||
while(!(furi_hal_subghz_is_async_tx_complete())) {
|
||||
FURI_LOG_D(TAG, ".");
|
||||
fflush(stdout);
|
||||
osDelay(333);
|
||||
}
|
||||
notification_message(notification, &sequence_reset_vibro);
|
||||
|
||||
furi_record_close("notification");
|
||||
furi_hal_subghz_stop_async_tx();
|
||||
furi_hal_subghz_sleep();
|
||||
|
||||
furi_hal_power_suppress_charge_exit();
|
||||
|
||||
flipper_format_free(flipper_format);
|
||||
subghz_transmitter_free(transmitter);
|
||||
subghz_environment_free(environment);
|
||||
}
|
||||
|
||||
static void jukebox_render_callback(Canvas* canvas, void* ctx) {
|
||||
RemoteAppState* state = (RemoteAppState*)acquire_mutex((ValueMutex*)ctx, 25);
|
||||
canvas_clear(canvas);
|
||||
char strings[5][20];
|
||||
string_t signal;
|
||||
string_init(signal);
|
||||
sprintf(strings[0], "Ok: %s", file_stub(string_get_cstr(ok_file)));
|
||||
sprintf(strings[1], "L: %s", file_stub(string_get_cstr(left_file)));
|
||||
sprintf(strings[2], "R: %s", file_stub(string_get_cstr(right_file)));
|
||||
sprintf(strings[3], "U: %s", file_stub(string_get_cstr(up_file)));
|
||||
sprintf(strings[4], "D: %s", file_stub(string_get_cstr(down_file)));
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 0, 10, "Univeral Remote");
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(canvas, 0, 24, strings[1]);
|
||||
canvas_draw_str(canvas, 85, 24, strings[2]);
|
||||
canvas_draw_str(canvas, 0, 36, strings[3]);
|
||||
canvas_draw_str(canvas, 85, 36, strings[4]);
|
||||
canvas_draw_str(canvas, 0, 48, strings[0]);
|
||||
// canvas_draw_circle(canvas, 100, 26, 25);
|
||||
|
||||
if(state->press[0]) {
|
||||
string_cat_printf(signal, "%s", string_get_cstr(right_file));
|
||||
}
|
||||
|
||||
else if(state->press[1]) {
|
||||
string_cat_printf(signal, "%s", string_get_cstr(left_file));
|
||||
|
||||
} else if(state->press[2]) {
|
||||
string_cat_printf(signal, "%s", string_get_cstr(up_file));
|
||||
|
||||
} else if(state->press[3]) {
|
||||
string_cat_printf(signal, "%s", string_get_cstr(down_file));
|
||||
|
||||
}
|
||||
|
||||
else if(state->press[4]) {
|
||||
string_cat_printf(signal, "%s", string_get_cstr(ok_file));
|
||||
}
|
||||
FURI_LOG_D(TAG, "signal = %s", string_get_cstr(signal));
|
||||
|
||||
if(strlen(string_get_cstr(signal)) > 12) {
|
||||
string_t file_name;
|
||||
string_init(file_name);
|
||||
string_t protocol;
|
||||
string_init(protocol);
|
||||
string_set(file_name, string_get_cstr(signal));
|
||||
Storage* storage = furi_record_open("storage");
|
||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
||||
uint32_t frequency_str;
|
||||
flipper_format_file_open_existing(fff_data_file, string_get_cstr(file_name));
|
||||
flipper_format_read_uint32(fff_data_file, "Frequency", (uint32_t*)&frequency_str, 1);
|
||||
if(!flipper_format_read_string(fff_data_file, "Protocol", protocol)) {
|
||||
FURI_LOG_D(TAG, "Could not read Protocol");
|
||||
string_set(protocol, "RAW");
|
||||
}
|
||||
flipper_format_free(fff_data_file);
|
||||
furi_record_close("storage");
|
||||
FURI_LOG_D(TAG, "%lu", frequency_str);
|
||||
jukebox_send_signal(frequency_str, signal, protocol);
|
||||
}
|
||||
|
||||
canvas_draw_str(canvas, 10, 63, "[back] - skip, hold to exit");
|
||||
jukebox_reset_state(state);
|
||||
release_mutex((ValueMutex*)ctx, state);
|
||||
}
|
||||
|
||||
static void jukebox_input_callback(InputEvent* input_event, void* ctx) {
|
||||
if (input_event->type == InputTypeRelease) {
|
||||
osMessageQueueId_t event_queue = ctx;
|
||||
osMessageQueuePut(event_queue, input_event, 0, osWaitForever);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t jukebox_app(void* p) {
|
||||
UNUSED(p);
|
||||
osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL);
|
||||
furi_check(event_queue);
|
||||
string_init(up_file);
|
||||
string_init(down_file);
|
||||
string_init(left_file);
|
||||
string_init(right_file);
|
||||
string_init(ok_file);
|
||||
|
||||
string_t file_name;
|
||||
string_init(file_name);
|
||||
string_set(file_name, "/ext/subghz/assets/touchtunes_map");
|
||||
Storage* storage = furi_record_open("storage");
|
||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
||||
if(!flipper_format_file_open_existing(fff_data_file, string_get_cstr(file_name))) {
|
||||
FURI_LOG_D(TAG, "Could not open file %s", string_get_cstr(file_name));
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(fff_data_file, "UP", up_file)) {
|
||||
FURI_LOG_D(TAG, "Could not read UP string");
|
||||
}
|
||||
if(!flipper_format_read_string(fff_data_file, "DOWN", down_file)) {
|
||||
FURI_LOG_D(TAG, "Could not read DOWN string");
|
||||
}
|
||||
if(!flipper_format_read_string(fff_data_file, "LEFT", left_file)) {
|
||||
FURI_LOG_D(TAG, "Could not read LEFT string");
|
||||
}
|
||||
if(!flipper_format_read_string(fff_data_file, "RIGHT", right_file)) {
|
||||
FURI_LOG_D(TAG, "Could not read RIGHT string");
|
||||
}
|
||||
if(!flipper_format_read_string(fff_data_file, "OK", ok_file)) {
|
||||
FURI_LOG_D(TAG, "Could not read OK string");
|
||||
}
|
||||
flipper_format_free(fff_data_file);
|
||||
furi_record_close("storage");
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"%s %s %s %s %s ",
|
||||
string_get_cstr(up_file),
|
||||
string_get_cstr(down_file),
|
||||
string_get_cstr(left_file),
|
||||
string_get_cstr(right_file),
|
||||
string_get_cstr(ok_file));
|
||||
|
||||
RemoteAppState _state = {{false, false, false, false, false}};
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, &_state, sizeof(RemoteAppState))) {
|
||||
FURI_LOG_D(TAG, "cannot create mutex");
|
||||
return(0);
|
||||
}
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
|
||||
view_port_draw_callback_set(view_port, jukebox_render_callback, &state_mutex);
|
||||
view_port_input_callback_set(view_port, jukebox_input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
Gui* gui = furi_record_open("gui");
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
InputEvent event;
|
||||
while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) {
|
||||
RemoteAppState* state = (RemoteAppState*)acquire_mutex_block(&state_mutex);
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
"key: %s type: %s",
|
||||
input_get_key_name(event.key),
|
||||
input_get_type_name(event.type));
|
||||
|
||||
if(event.key == InputKeyRight) {
|
||||
state->press[0] = true;
|
||||
} else if(event.key == InputKeyLeft) {
|
||||
state->press[1] = true;
|
||||
} else if(event.key == InputKeyUp) {
|
||||
state->press[2] = true;
|
||||
} else if(event.key == InputKeyDown) {
|
||||
state->press[3] = true;
|
||||
} else if(event.key == InputKeyOk) {
|
||||
state->press[4] = true;
|
||||
} else if(event.key == InputKeyBack) {
|
||||
release_mutex(&state_mutex, state);
|
||||
break;
|
||||
}
|
||||
release_mutex(&state_mutex, state);
|
||||
view_port_update(view_port);
|
||||
}
|
||||
// remove & free all stuff created by app
|
||||
gui_remove_view_port(gui, view_port);
|
||||
view_port_free(view_port);
|
||||
osMessageQueueDelete(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
|
||||
furi_record_close("gui");
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1,459 +0,0 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <input/input.h>
|
||||
#include <stdlib.h>
|
||||
#include "spectrum_analyzer.h"
|
||||
|
||||
#include <gui/gui.h>
|
||||
|
||||
#include <lib/drivers/cc1101_regs.h>
|
||||
#include "spectrum_analyzer_worker.h"
|
||||
|
||||
typedef struct {
|
||||
uint16_t center_freq;
|
||||
uint8_t width;
|
||||
uint8_t band;
|
||||
uint8_t vscroll;
|
||||
|
||||
uint32_t channel0_frequency;
|
||||
uint32_t spacing;
|
||||
|
||||
float max_rssi;
|
||||
uint8_t max_rssi_dec;
|
||||
uint8_t max_rssi_channel;
|
||||
uint8_t channel_ss[NUM_CHANNELS];
|
||||
} SpectrumAnalyzerModel;
|
||||
|
||||
typedef struct {
|
||||
SpectrumAnalyzerModel* model;
|
||||
osMutexId_t* model_mutex;
|
||||
|
||||
osMessageQueueId_t event_queue;
|
||||
|
||||
ViewPort* view_port;
|
||||
Gui* gui;
|
||||
|
||||
SpectrumAnalyzerWorker* worker;
|
||||
} SpectrumAnalyzer;
|
||||
|
||||
void spectrum_analyzer_draw_scale(Canvas* canvas, const SpectrumAnalyzerModel* model) {
|
||||
// Draw line
|
||||
canvas_draw_line(
|
||||
canvas, FREQ_START_X, FREQ_BOTTOM_Y, FREQ_START_X + FREQ_LENGTH_X, FREQ_BOTTOM_Y);
|
||||
// Draw minor scale
|
||||
for(int i = FREQ_START_X; i < FREQ_START_X + FREQ_LENGTH_X; i += 5) {
|
||||
canvas_draw_line(canvas, i, FREQ_BOTTOM_Y, i, FREQ_BOTTOM_Y + 2);
|
||||
}
|
||||
// Draw major scale
|
||||
for(int i = FREQ_START_X; i < FREQ_START_X + FREQ_LENGTH_X; i += 25) {
|
||||
canvas_draw_line(canvas, i, FREQ_BOTTOM_Y, i, FREQ_BOTTOM_Y + 4);
|
||||
}
|
||||
|
||||
// Draw scale tags
|
||||
uint16_t tag_left;
|
||||
uint16_t tag_center;
|
||||
uint16_t tag_right;
|
||||
char temp_str[18];
|
||||
|
||||
tag_center = model->center_freq;
|
||||
|
||||
switch(model->width) {
|
||||
case NARROW:
|
||||
tag_left = model->center_freq - 2;
|
||||
tag_right = model->center_freq + 2;
|
||||
break;
|
||||
case ULTRAWIDE:
|
||||
tag_left = model->center_freq - 40;
|
||||
tag_right = model->center_freq + 40;
|
||||
break;
|
||||
default:
|
||||
tag_left = model->center_freq - 10;
|
||||
tag_right = model->center_freq + 10;
|
||||
}
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
snprintf(temp_str, 18, "%u", tag_left);
|
||||
canvas_draw_str_aligned(canvas, FREQ_START_X, 63, AlignCenter, AlignBottom, temp_str);
|
||||
snprintf(temp_str, 18, "%u", tag_center);
|
||||
canvas_draw_str_aligned(canvas, 128 / 2, 63, AlignCenter, AlignBottom, temp_str);
|
||||
snprintf(temp_str, 18, "%u", tag_right);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, FREQ_START_X + FREQ_LENGTH_X - 1, 63, AlignCenter, AlignBottom, temp_str);
|
||||
}
|
||||
|
||||
static void spectrum_analyzer_render_callback(Canvas* const canvas, void* ctx) {
|
||||
SpectrumAnalyzer* spectrum_analyzer = ctx;
|
||||
furi_check(osMutexAcquire(spectrum_analyzer->model_mutex, osWaitForever) == osOK);
|
||||
|
||||
SpectrumAnalyzerModel* model = spectrum_analyzer->model;
|
||||
|
||||
spectrum_analyzer_draw_scale(canvas, model);
|
||||
|
||||
for(uint8_t column = 0; column < 128; column++) {
|
||||
uint8_t ss = model->channel_ss[column + 2];
|
||||
// Compress height to max of 64 values (255>>2)
|
||||
uint8_t s = MAX((ss - model->vscroll) >> 2, 0);
|
||||
uint8_t y = FREQ_BOTTOM_Y - s; // bar height
|
||||
|
||||
// Draw each bar
|
||||
canvas_draw_line(canvas, column, FREQ_BOTTOM_Y, column, y);
|
||||
}
|
||||
|
||||
// Draw cross and label
|
||||
if(model->max_rssi > PEAK_THRESHOLD) {
|
||||
// Compress height to max of 64 values (255>>2)
|
||||
uint8_t max_y = MAX((model->max_rssi_dec - model->vscroll) >> 2, 0);
|
||||
max_y = (FREQ_BOTTOM_Y - max_y);
|
||||
|
||||
// Cross
|
||||
int16_t x1, x2, y1, y2;
|
||||
x1 = model->max_rssi_channel - 2 - 2;
|
||||
if(x1 < 0) x1 = 0;
|
||||
y1 = max_y - 2;
|
||||
if(y1 < 0) y1 = 0;
|
||||
x2 = model->max_rssi_channel - 2 + 2;
|
||||
if(x2 > 127) x2 = 127;
|
||||
y2 = max_y + 2;
|
||||
if(y2 > 63) y2 = 63; // SHOULD NOT HAPPEN CHECK!
|
||||
canvas_draw_line(canvas, x1, y1, x2, y2);
|
||||
|
||||
x1 = model->max_rssi_channel - 2 + 2;
|
||||
if(x1 > 127) x1 = 127;
|
||||
y1 = max_y - 2;
|
||||
if(y1 < 0) y1 = 0;
|
||||
x2 = model->max_rssi_channel - 2 - 2;
|
||||
if(x2 < 0) x2 = 0;
|
||||
y2 = max_y + 2;
|
||||
if(y2 > 63) y2 = 63; // SHOULD NOT HAPPEN CHECK!
|
||||
canvas_draw_line(canvas, (uint8_t)x1, (uint8_t)y1, (uint8_t)x2, (uint8_t)y2);
|
||||
|
||||
// Label
|
||||
char temp_str[36];
|
||||
snprintf(
|
||||
temp_str,
|
||||
36,
|
||||
"Peak: %3.2f Mhz %3.1f dbm",
|
||||
((float)(model->channel0_frequency + (model->max_rssi_channel * model->spacing)) /
|
||||
1000000),
|
||||
model->max_rssi);
|
||||
canvas_draw_str_aligned(canvas, 127, 0, AlignRight, AlignTop, temp_str);
|
||||
}
|
||||
|
||||
osMutexRelease(spectrum_analyzer->model_mutex);
|
||||
|
||||
// FURI_LOG_D("Spectrum", "model->vscroll %u", model->vscroll);
|
||||
}
|
||||
|
||||
static void spectrum_analyzer_input_callback(InputEvent* input_event, void* ctx) {
|
||||
SpectrumAnalyzer* spectrum_analyzer = ctx;
|
||||
// Only handle short presses
|
||||
if(input_event->type == InputTypeShort) {
|
||||
osMessageQueuePut(spectrum_analyzer->event_queue, input_event, 0, osWaitForever);
|
||||
}
|
||||
}
|
||||
|
||||
static void spectrum_analyzer_worker_callback(
|
||||
void* channel_ss,
|
||||
float max_rssi,
|
||||
uint8_t max_rssi_dec,
|
||||
uint8_t max_rssi_channel,
|
||||
void* context) {
|
||||
SpectrumAnalyzer* spectrum_analyzer = context;
|
||||
furi_check(osMutexAcquire(spectrum_analyzer->model_mutex, osWaitForever) == osOK);
|
||||
|
||||
SpectrumAnalyzerModel* model = (SpectrumAnalyzerModel*)spectrum_analyzer->model;
|
||||
memcpy(model->channel_ss, (uint8_t*)channel_ss, sizeof(uint8_t) * NUM_CHANNELS);
|
||||
model->max_rssi = max_rssi;
|
||||
model->max_rssi_dec = max_rssi_dec;
|
||||
model->max_rssi_channel = max_rssi_channel;
|
||||
|
||||
osMutexRelease(spectrum_analyzer->model_mutex);
|
||||
view_port_update(spectrum_analyzer->view_port);
|
||||
}
|
||||
|
||||
void spectrum_analyzer_calculate_frequencies(SpectrumAnalyzerModel* model) {
|
||||
// REDO ALL THIS. CALCULATE ONLY WITH SPACING!
|
||||
|
||||
uint8_t new_band;
|
||||
uint32_t min_hz;
|
||||
uint32_t max_hz;
|
||||
uint8_t margin;
|
||||
uint8_t step;
|
||||
uint16_t upper_limit;
|
||||
uint16_t lower_limit;
|
||||
uint16_t next_up;
|
||||
uint16_t next_down;
|
||||
uint8_t next_band_up;
|
||||
uint8_t next_band_down;
|
||||
|
||||
switch(model->width) {
|
||||
case NARROW:
|
||||
margin = NARROW_MARGIN;
|
||||
step = NARROW_STEP;
|
||||
model->spacing = NARROW_SPACING;
|
||||
break;
|
||||
case ULTRAWIDE:
|
||||
margin = ULTRAWIDE_MARGIN;
|
||||
step = ULTRAWIDE_STEP;
|
||||
model->spacing = ULTRAWIDE_SPACING;
|
||||
/* nearest 20 MHz step */
|
||||
model->center_freq = ((model->center_freq + 10) / 20) * 20;
|
||||
break;
|
||||
default:
|
||||
margin = WIDE_MARGIN;
|
||||
step = WIDE_STEP;
|
||||
model->spacing = WIDE_SPACING;
|
||||
/* nearest 5 MHz step */
|
||||
model->center_freq = ((model->center_freq + 2) / 5) * 5;
|
||||
break;
|
||||
}
|
||||
|
||||
/* handle cases near edges of bands */
|
||||
if(model->center_freq > EDGE_900) {
|
||||
new_band = BAND_900;
|
||||
upper_limit = UPPER(MAX_900, margin, step);
|
||||
lower_limit = LOWER(MIN_900, margin, step);
|
||||
next_up = LOWER(MIN_300, margin, step);
|
||||
next_down = UPPER(MAX_400, margin, step);
|
||||
next_band_up = BAND_300;
|
||||
next_band_down = BAND_400;
|
||||
} else if(model->center_freq > EDGE_400) {
|
||||
new_band = BAND_400;
|
||||
upper_limit = UPPER(MAX_400, margin, step);
|
||||
lower_limit = LOWER(MIN_400, margin, step);
|
||||
next_up = LOWER(MIN_900, margin, step);
|
||||
next_down = UPPER(MAX_300, margin, step);
|
||||
next_band_up = BAND_900;
|
||||
next_band_down = BAND_300;
|
||||
} else {
|
||||
new_band = BAND_300;
|
||||
upper_limit = UPPER(MAX_300, margin, step);
|
||||
lower_limit = LOWER(MIN_300, margin, step);
|
||||
next_up = LOWER(MIN_400, margin, step);
|
||||
next_down = UPPER(MAX_900, margin, step);
|
||||
next_band_up = BAND_400;
|
||||
next_band_down = BAND_900;
|
||||
}
|
||||
|
||||
if(model->center_freq > upper_limit) {
|
||||
model->center_freq = upper_limit;
|
||||
if(new_band == model->band) {
|
||||
new_band = next_band_up;
|
||||
model->center_freq = next_up;
|
||||
}
|
||||
} else if(model->center_freq < lower_limit) {
|
||||
model->center_freq = lower_limit;
|
||||
if(new_band == model->band) {
|
||||
new_band = next_band_down;
|
||||
model->center_freq = next_down;
|
||||
}
|
||||
}
|
||||
|
||||
model->band = new_band;
|
||||
/* doing everything in Hz from here on */
|
||||
switch(model->band) {
|
||||
case BAND_400:
|
||||
min_hz = MIN_400 * 1000000;
|
||||
max_hz = MAX_400 * 1000000;
|
||||
break;
|
||||
case BAND_300:
|
||||
min_hz = MIN_300 * 1000000;
|
||||
max_hz = MAX_300 * 1000000;
|
||||
break;
|
||||
default:
|
||||
min_hz = MIN_900 * 1000000;
|
||||
max_hz = MAX_900 * 1000000;
|
||||
break;
|
||||
}
|
||||
|
||||
model->channel0_frequency =
|
||||
model->center_freq * 1000000 - (model->spacing * ((NUM_CHANNELS / 2) + 1));
|
||||
|
||||
// /* calibrate upper channels */
|
||||
// hz = model->center_freq * 1000000;
|
||||
// max_chan = NUM_CHANNELS / 2;
|
||||
// while (hz <= max_hz && max_chan < NUM_CHANNELS) {
|
||||
// instance->chan_table[max_chan].frequency = hz;
|
||||
// FURI_LOG_T("Spectrum", "calibrate_freq ch[%u]: %lu", max_chan, hz);
|
||||
// hz += model->spacing;
|
||||
// max_chan++;
|
||||
// }
|
||||
|
||||
// /* calibrate lower channels */
|
||||
// hz = instance->freq * 1000000 - model->spacing;
|
||||
// min_chan = NUM_CHANNELS / 2;
|
||||
// while (hz >= min_hz && min_chan > 0) {
|
||||
// min_chan--;
|
||||
// instance->chan_table[min_chan].frequency = hz;
|
||||
// FURI_LOG_T("Spectrum", "calibrate_freq ch[%u]: %lu", min_chan, hz);
|
||||
// hz -= model->spacing;
|
||||
// }
|
||||
|
||||
model->max_rssi = -200.0;
|
||||
model->max_rssi_dec = 0;
|
||||
|
||||
FURI_LOG_D("Spectrum", "setup_frequencies - max_hz: %u - min_hz: %u", max_hz, min_hz);
|
||||
FURI_LOG_D("Spectrum", "center_freq: %u", model->center_freq);
|
||||
FURI_LOG_D(
|
||||
"Spectrum",
|
||||
"ch[0]: %lu - ch[%u]: %lu",
|
||||
model->channel0_frequency,
|
||||
NUM_CHANNELS - 1,
|
||||
model->channel0_frequency + ((NUM_CHANNELS - 1) * model->spacing));
|
||||
}
|
||||
|
||||
SpectrumAnalyzer* spectrum_analyzer_alloc() {
|
||||
SpectrumAnalyzer* instance = malloc(sizeof(SpectrumAnalyzer));
|
||||
instance->model = malloc(sizeof(SpectrumAnalyzerModel));
|
||||
|
||||
SpectrumAnalyzerModel* model = instance->model;
|
||||
|
||||
for(uint8_t ch = 0; ch < NUM_CHANNELS - 1; ch++) {
|
||||
model->channel_ss[ch] = 0;
|
||||
}
|
||||
model->max_rssi_dec = 0;
|
||||
model->max_rssi_channel = 0;
|
||||
model->max_rssi = PEAK_THRESHOLD - 1; // Should initializar to < PEAK_THRESHOLD
|
||||
|
||||
model->center_freq = DEFAULT_FREQ;
|
||||
model->width = WIDE;
|
||||
model->band = BAND_400;
|
||||
|
||||
model->vscroll = DEFAULT_VSCROLL;
|
||||
|
||||
instance->model_mutex = osMutexNew(NULL);
|
||||
instance->event_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL);
|
||||
|
||||
instance->worker = spectrum_analyzer_worker_alloc();
|
||||
|
||||
spectrum_analyzer_worker_set_callback(
|
||||
instance->worker, spectrum_analyzer_worker_callback, instance);
|
||||
|
||||
// Set system callbacks
|
||||
instance->view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(instance->view_port, spectrum_analyzer_render_callback, instance);
|
||||
view_port_input_callback_set(instance->view_port, spectrum_analyzer_input_callback, instance);
|
||||
|
||||
// Open GUI and register view_port
|
||||
instance->gui = furi_record_open("gui");
|
||||
gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void spectrum_analyzer_free(SpectrumAnalyzer* instance) {
|
||||
// view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(instance->gui, instance->view_port);
|
||||
furi_record_close("gui");
|
||||
view_port_free(instance->view_port);
|
||||
|
||||
spectrum_analyzer_worker_free(instance->worker);
|
||||
|
||||
osMessageQueueDelete(instance->event_queue);
|
||||
|
||||
osMutexDelete(instance->model_mutex);
|
||||
|
||||
free(instance->model);
|
||||
free(instance);
|
||||
|
||||
furi_hal_subghz_idle();
|
||||
furi_hal_subghz_sleep();
|
||||
}
|
||||
|
||||
int32_t spectrum_analyzer_app(void* p) {
|
||||
UNUSED(p);
|
||||
|
||||
SpectrumAnalyzer* spectrum_analyzer = spectrum_analyzer_alloc();
|
||||
InputEvent input;
|
||||
|
||||
FURI_LOG_D("Spectrum", "Main Loop - Starting worker");
|
||||
furi_hal_delay_ms(50);
|
||||
|
||||
spectrum_analyzer_worker_start(spectrum_analyzer->worker);
|
||||
|
||||
FURI_LOG_D("Spectrum", "Main Loop - Wait on queue");
|
||||
furi_hal_delay_ms(50);
|
||||
|
||||
while(osMessageQueueGet(spectrum_analyzer->event_queue, &input, NULL, osWaitForever) == osOK) {
|
||||
furi_check(osMutexAcquire(spectrum_analyzer->model_mutex, osWaitForever) == osOK);
|
||||
|
||||
FURI_LOG_D("Spectrum", "Main Loop - Input: %u", input.key);
|
||||
|
||||
SpectrumAnalyzerModel* model = spectrum_analyzer->model;
|
||||
|
||||
uint8_t vstep = VERTICAL_SHORT_STEP;
|
||||
uint8_t hstep;
|
||||
|
||||
bool exit_loop = false;
|
||||
|
||||
switch(model->width) {
|
||||
case NARROW:
|
||||
hstep = NARROW_STEP;
|
||||
break;
|
||||
case ULTRAWIDE:
|
||||
hstep = ULTRAWIDE_STEP;
|
||||
break;
|
||||
default:
|
||||
hstep = WIDE_STEP;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(input.key) {
|
||||
case InputKeyUp:
|
||||
model->vscroll = MAX(model->vscroll - vstep, MIN_VSCROLL);
|
||||
FURI_LOG_D("Spectrum", "Vscroll: %u", model->vscroll);
|
||||
break;
|
||||
case InputKeyDown:
|
||||
model->vscroll = MIN(model->vscroll + vstep, MAX_VSCROLL);
|
||||
FURI_LOG_D("Spectrum", "Vscroll: %u", model->vscroll);
|
||||
break;
|
||||
case InputKeyRight:
|
||||
model->center_freq += hstep;
|
||||
FURI_LOG_D("Spectrum", "center_freq: %lu", model->center_freq);
|
||||
spectrum_analyzer_calculate_frequencies(model);
|
||||
spectrum_analyzer_worker_set_frequencies(
|
||||
spectrum_analyzer->worker, model->channel0_frequency, model->spacing, model->width);
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
model->center_freq -= hstep;
|
||||
spectrum_analyzer_calculate_frequencies(model);
|
||||
spectrum_analyzer_worker_set_frequencies(
|
||||
spectrum_analyzer->worker, model->channel0_frequency, model->spacing, model->width);
|
||||
FURI_LOG_D("Spectrum", "center_freq: %lu", model->center_freq);
|
||||
break;
|
||||
case InputKeyOk: {
|
||||
switch(model->width) {
|
||||
case WIDE:
|
||||
model->width = NARROW;
|
||||
break;
|
||||
case NARROW:
|
||||
model->width = ULTRAWIDE;
|
||||
break;
|
||||
case ULTRAWIDE:
|
||||
default:
|
||||
model->width = WIDE;
|
||||
}
|
||||
}
|
||||
spectrum_analyzer_calculate_frequencies(model);
|
||||
spectrum_analyzer_worker_set_frequencies(
|
||||
spectrum_analyzer->worker, model->channel0_frequency, model->spacing, model->width);
|
||||
FURI_LOG_D("Spectrum", "Width: %u", model->width);
|
||||
break;
|
||||
case InputKeyBack:
|
||||
exit_loop = true;
|
||||
break;
|
||||
}
|
||||
|
||||
osMutexRelease(spectrum_analyzer->model_mutex);
|
||||
view_port_update(spectrum_analyzer->view_port);
|
||||
if(exit_loop == true) break;
|
||||
}
|
||||
|
||||
spectrum_analyzer_worker_stop(spectrum_analyzer->worker);
|
||||
|
||||
spectrum_analyzer_free(spectrum_analyzer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
#define NUM_CHANNELS 132
|
||||
|
||||
// Screen coordinates
|
||||
#define FREQ_BOTTOM_Y 50
|
||||
#define FREQ_START_X 14
|
||||
// How many channels displayed on the scale (On screen still 218)
|
||||
#define FREQ_LENGTH_X 102
|
||||
// dBm threshold to show peak value
|
||||
#define PEAK_THRESHOLD -85
|
||||
|
||||
/*
|
||||
* ultrawide mode: 80 MHz on screen, 784 kHz per channel
|
||||
* wide mode (default): 20 MHz on screen, 196 kHz per channel
|
||||
* narrow mode: 4 MHz on screen, 39 kHz per channel
|
||||
*/
|
||||
#define WIDE 0
|
||||
#define NARROW 1
|
||||
#define ULTRAWIDE 2
|
||||
|
||||
/* channel spacing in Hz */
|
||||
#define WIDE_SPACING 196078
|
||||
#define NARROW_SPACING 39215
|
||||
#define ULTRAWIDE_SPACING 784313
|
||||
|
||||
/* vertical scrolling */
|
||||
#define VERTICAL_SHORT_STEP 16
|
||||
#define MAX_VSCROLL 120
|
||||
#define MIN_VSCROLL 0
|
||||
#define DEFAULT_VSCROLL 48
|
||||
|
||||
/* frequencies in MHz */
|
||||
#define DEFAULT_FREQ 440
|
||||
#define WIDE_STEP 5
|
||||
#define NARROW_STEP 1
|
||||
#define ULTRAWIDE_STEP 20
|
||||
#define WIDE_MARGIN 13
|
||||
#define NARROW_MARGIN 3
|
||||
#define ULTRAWIDE_MARGIN 42
|
||||
|
||||
/* frequency bands supported by device */
|
||||
#define BAND_300 0
|
||||
#define BAND_400 1
|
||||
#define BAND_900 2
|
||||
|
||||
/* band limits in MHz */
|
||||
#define MIN_300 281
|
||||
#define CEN_300 315
|
||||
#define MAX_300 361
|
||||
#define MIN_400 378
|
||||
#define CEN_400 435
|
||||
#define MAX_400 481
|
||||
#define MIN_900 749
|
||||
#define CEN_900 855
|
||||
#define MAX_900 962
|
||||
|
||||
/* band transition points in MHz */
|
||||
#define EDGE_400 369
|
||||
#define EDGE_900 615
|
||||
|
||||
/* VCO transition points in Hz */
|
||||
#define MID_300 318000000
|
||||
#define MID_400 424000000
|
||||
#define MID_900 848000000
|
||||
|
||||
#define UPPER(a, b, c) ((((a) - (b) + ((c) / 2)) / (c)) * (c))
|
||||
#define LOWER(a, b, c) ((((a) + (b)) / (c)) * (c))
|
||||
@@ -1,195 +0,0 @@
|
||||
#include "spectrum_analyzer.h"
|
||||
#include "spectrum_analyzer_worker.h"
|
||||
|
||||
#include <furi_hal.h>
|
||||
#include <furi.h>
|
||||
|
||||
#include <lib/drivers/cc1101_regs.h>
|
||||
|
||||
struct SpectrumAnalyzerWorker {
|
||||
FuriThread* thread;
|
||||
bool should_work;
|
||||
|
||||
SpectrumAnalyzerWorkerCallback callback;
|
||||
void* callback_context;
|
||||
|
||||
uint32_t channel0_frequency;
|
||||
uint32_t spacing;
|
||||
uint8_t width;
|
||||
float max_rssi;
|
||||
uint8_t max_rssi_dec;
|
||||
uint8_t max_rssi_channel;
|
||||
|
||||
uint8_t channel_ss[NUM_CHANNELS];
|
||||
};
|
||||
|
||||
/* set the channel bandwidth */
|
||||
void spectrum_analyzer_worker_set_filter(SpectrumAnalyzerWorker* instance) {
|
||||
uint8_t filter_config[2][2] = {
|
||||
{CC1101_MDMCFG4, 0},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
// FURI_LOG_D("SpectrumWorker", "spectrum_analyzer_worker_set_filter: width = %u", instance->width);
|
||||
|
||||
/* channel spacing should fit within 80% of channel filter bandwidth */
|
||||
switch(instance->width) {
|
||||
case NARROW:
|
||||
filter_config[0][1] = 0xFC; /* 39.2 kHz / .8 = 49 kHz --> 58 kHz */
|
||||
break;
|
||||
case ULTRAWIDE:
|
||||
filter_config[0][1] = 0x0C; /* 784 kHz / .8 = 980 kHz --> 812 kHz */
|
||||
break;
|
||||
default:
|
||||
filter_config[0][1] = 0x6C; /* 196 kHz / .8 = 245 kHz --> 270 kHz */
|
||||
break;
|
||||
}
|
||||
furi_hal_subghz_load_registers(filter_config);
|
||||
}
|
||||
|
||||
static int32_t spectrum_analyzer_worker_thread(void* context) {
|
||||
furi_assert(context);
|
||||
SpectrumAnalyzerWorker* instance = context;
|
||||
|
||||
FURI_LOG_D("SpectrumWorker", "spectrum_analyzer_worker_thread: Start");
|
||||
|
||||
// Start CC1101
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||
furi_hal_subghz_set_frequency(433920000);
|
||||
furi_hal_subghz_flush_rx();
|
||||
furi_hal_subghz_rx();
|
||||
|
||||
static const uint8_t radio_config[][2] = {
|
||||
{CC1101_FSCTRL1, 0x12},
|
||||
{CC1101_FSCTRL0, 0x00},
|
||||
|
||||
{CC1101_AGCCTRL2, 0xC0},
|
||||
|
||||
{CC1101_MDMCFG4, 0x6C},
|
||||
{CC1101_TEST2, 0x88},
|
||||
{CC1101_TEST1, 0x31},
|
||||
{CC1101_TEST0, 0x09},
|
||||
/* End */
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
while(instance->should_work) {
|
||||
furi_hal_delay_ms(50);
|
||||
|
||||
// FURI_LOG_T("SpectrumWorker", "spectrum_analyzer_worker_thread: Worker Loop");
|
||||
furi_hal_subghz_idle();
|
||||
furi_hal_subghz_load_registers(radio_config);
|
||||
|
||||
// TODO: Check filter!
|
||||
// spectrum_analyzer_worker_set_filter(instance);
|
||||
|
||||
instance->max_rssi_dec = 0;
|
||||
|
||||
for(uint8_t ch = 0; ch < NUM_CHANNELS - 1; ch++) {
|
||||
furi_hal_subghz_set_frequency(instance->channel0_frequency + (ch * instance->spacing));
|
||||
|
||||
furi_hal_subghz_rx();
|
||||
furi_hal_delay_ms(3);
|
||||
|
||||
// dec dBm
|
||||
//max_ss = 127 -> -10.5
|
||||
//max_ss = 0 -> -74.0
|
||||
//max_ss = 255 -> -74.5
|
||||
//max_ss = 128 -> -138.0
|
||||
instance->channel_ss[ch] = (furi_hal_subghz_get_rssi() + 138) * 2;
|
||||
|
||||
if(instance->channel_ss[ch] > instance->max_rssi_dec) {
|
||||
instance->max_rssi_dec = instance->channel_ss[ch];
|
||||
instance->max_rssi = (instance->channel_ss[ch] / 2) - 138;
|
||||
instance->max_rssi_channel = ch;
|
||||
}
|
||||
|
||||
furi_hal_subghz_idle();
|
||||
}
|
||||
|
||||
// FURI_LOG_T("SpectrumWorker", "channel_ss[0]: %u", instance->channel_ss[0]);
|
||||
|
||||
// Report results back to main thread
|
||||
if(instance->callback) {
|
||||
instance->callback(
|
||||
(void*)&(instance->channel_ss),
|
||||
instance->max_rssi,
|
||||
instance->max_rssi_dec,
|
||||
instance->max_rssi_channel,
|
||||
instance->callback_context);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SpectrumAnalyzerWorker* spectrum_analyzer_worker_alloc() {
|
||||
FURI_LOG_D("Spectrum", "spectrum_analyzer_worker_alloc: Start");
|
||||
|
||||
SpectrumAnalyzerWorker* instance = malloc(sizeof(SpectrumAnalyzerWorker));
|
||||
|
||||
instance->thread = furi_thread_alloc();
|
||||
furi_thread_set_name(instance->thread, "SpectrumWorker");
|
||||
furi_thread_set_stack_size(instance->thread, 2048);
|
||||
furi_thread_set_context(instance->thread, instance);
|
||||
furi_thread_set_callback(instance->thread, spectrum_analyzer_worker_thread);
|
||||
|
||||
FURI_LOG_D("Spectrum", "spectrum_analyzer_worker_alloc: End");
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void spectrum_analyzer_worker_free(SpectrumAnalyzerWorker* instance) {
|
||||
FURI_LOG_D("Spectrum", "spectrum_analyzer_worker_free");
|
||||
furi_assert(instance);
|
||||
furi_thread_free(instance->thread);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
void spectrum_analyzer_worker_set_callback(
|
||||
SpectrumAnalyzerWorker* instance,
|
||||
SpectrumAnalyzerWorkerCallback callback,
|
||||
void* context) {
|
||||
furi_assert(instance);
|
||||
instance->callback = callback;
|
||||
instance->callback_context = context;
|
||||
}
|
||||
|
||||
void spectrum_analyzer_worker_set_frequencies(
|
||||
SpectrumAnalyzerWorker* instance,
|
||||
uint32_t channel0_frequency,
|
||||
uint32_t spacing,
|
||||
uint8_t width) {
|
||||
furi_assert(instance);
|
||||
|
||||
FURI_LOG_D(
|
||||
"SpectrumWorker",
|
||||
"spectrum_analyzer_worker_set_frequencies - channel0_frequency= %u - spacing = %u - width = %u",
|
||||
channel0_frequency,
|
||||
spacing,
|
||||
width);
|
||||
|
||||
instance->channel0_frequency = channel0_frequency;
|
||||
instance->spacing = spacing;
|
||||
instance->width = width;
|
||||
}
|
||||
|
||||
void spectrum_analyzer_worker_start(SpectrumAnalyzerWorker* instance) {
|
||||
FURI_LOG_D("Spectrum", "spectrum_analyzer_worker_start");
|
||||
|
||||
furi_assert(instance);
|
||||
furi_assert(instance->should_work == false);
|
||||
|
||||
instance->should_work = true;
|
||||
furi_thread_start(instance->thread);
|
||||
}
|
||||
|
||||
void spectrum_analyzer_worker_stop(SpectrumAnalyzerWorker* instance) {
|
||||
FURI_LOG_D("Spectrum", "spectrum_analyzer_worker_stop");
|
||||
furi_assert(instance);
|
||||
furi_assert(instance->should_work == true);
|
||||
|
||||
instance->should_work = false;
|
||||
furi_thread_join(instance->thread);
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef void (*SpectrumAnalyzerWorkerCallback)(
|
||||
void* chan_table,
|
||||
float max_rssi,
|
||||
uint8_t max_rssi_dec,
|
||||
uint8_t max_rssi_channel,
|
||||
void* context);
|
||||
|
||||
typedef struct SpectrumAnalyzerWorker SpectrumAnalyzerWorker;
|
||||
|
||||
SpectrumAnalyzerWorker* spectrum_analyzer_worker_alloc();
|
||||
|
||||
void spectrum_analyzer_worker_free(SpectrumAnalyzerWorker* instance);
|
||||
|
||||
void spectrum_analyzer_worker_set_callback(
|
||||
SpectrumAnalyzerWorker* instance,
|
||||
SpectrumAnalyzerWorkerCallback callback,
|
||||
void* context);
|
||||
|
||||
void spectrum_analyzer_worker_set_filter(SpectrumAnalyzerWorker* instance);
|
||||
|
||||
void spectrum_analyzer_worker_set_frequencies(
|
||||
SpectrumAnalyzerWorker* instance,
|
||||
uint32_t channel0_frequency,
|
||||
uint32_t spacing,
|
||||
uint8_t width);
|
||||
|
||||
void spectrum_analyzer_worker_start(SpectrumAnalyzerWorker* instance);
|
||||
|
||||
void spectrum_analyzer_worker_stop(SpectrumAnalyzerWorker* instance);
|
||||
@@ -1,274 +0,0 @@
|
||||
#include <furi.h>
|
||||
#include <gui/gui.h>
|
||||
#include <input/input.h>
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
#include <string.h>
|
||||
#include <lib/subghz/receiver.h>
|
||||
#include <lib/subghz/transmitter.h>
|
||||
#include <lib/subghz/subghz_file_encoder_worker.h>
|
||||
#include <lib/toolbox/path.h>
|
||||
#include <notification/notification_messages.h>
|
||||
|
||||
#define TAG "UniveralRFRemote"
|
||||
|
||||
typedef struct {
|
||||
bool press[5];
|
||||
} RemoteAppState;
|
||||
|
||||
static void remote_reset_state(RemoteAppState* state) {
|
||||
state->press[0] = 0;
|
||||
state->press[1] = 0;
|
||||
state->press[2] = 0;
|
||||
state->press[3] = 0;
|
||||
state->press[4] = 0;
|
||||
}
|
||||
static string_t up_file;
|
||||
static string_t down_file;
|
||||
static string_t left_file;
|
||||
static string_t right_file;
|
||||
static string_t ok_file;
|
||||
|
||||
static char* subString(char* someString, int n) {
|
||||
char* new = malloc(sizeof(char) * n + 1);
|
||||
strncpy(new, someString, n);
|
||||
new[n] = '\0';
|
||||
return(new);
|
||||
}
|
||||
|
||||
static char* file_stub(const char* file_name) {
|
||||
string_t filename;
|
||||
string_init(filename);
|
||||
path_extract_filename_no_ext(file_name, filename);
|
||||
|
||||
return(subString((char*)string_get_cstr(filename), 8));
|
||||
}
|
||||
|
||||
static void remote_send_signal(uint32_t frequency, string_t signal, string_t protocol) {
|
||||
uint32_t repeat = 1;
|
||||
frequency = frequency ? frequency : 433920000;
|
||||
FURI_LOG_D(TAG, "file to send: %s", string_get_cstr(signal));
|
||||
|
||||
if(strlen(string_get_cstr(signal)) < 10) {
|
||||
return;
|
||||
}
|
||||
|
||||
string_t flipper_format_string;
|
||||
if(strcmp(string_get_cstr(protocol), "RAW") == 0) {
|
||||
string_init_printf(flipper_format_string, "File_name: %s", string_get_cstr(signal));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
NotificationApp* notification = furi_record_open("notification");
|
||||
FlipperFormat* flipper_format = flipper_format_string_alloc();
|
||||
Stream* stream = flipper_format_get_raw_stream(flipper_format);
|
||||
stream_clean(stream);
|
||||
stream_write_cstring(stream, string_get_cstr(flipper_format_string));
|
||||
|
||||
SubGhzEnvironment* environment = subghz_environment_alloc();
|
||||
|
||||
SubGhzTransmitter* transmitter =
|
||||
subghz_transmitter_alloc_init(environment, string_get_cstr(protocol));
|
||||
subghz_transmitter_deserialize(transmitter, flipper_format);
|
||||
|
||||
furi_hal_subghz_reset();
|
||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok270Async);
|
||||
furi_hal_subghz_set_frequency_and_path(frequency);
|
||||
FURI_LOG_D(
|
||||
TAG, "Transmitting at %lu, repeat %lu. Press CTRL+C to stop\r\n", frequency, repeat);
|
||||
|
||||
furi_hal_power_suppress_charge_enter();
|
||||
notification_message(notification, &sequence_set_vibro_on);
|
||||
|
||||
furi_hal_subghz_start_async_tx(subghz_transmitter_yield, transmitter);
|
||||
|
||||
while(!(furi_hal_subghz_is_async_tx_complete())) {
|
||||
FURI_LOG_D(TAG, ".");
|
||||
fflush(stdout);
|
||||
osDelay(333);
|
||||
}
|
||||
notification_message(notification, &sequence_reset_vibro);
|
||||
|
||||
furi_record_close("notification");
|
||||
|
||||
furi_hal_subghz_stop_async_tx();
|
||||
furi_hal_subghz_sleep();
|
||||
|
||||
furi_hal_power_suppress_charge_exit();
|
||||
|
||||
flipper_format_free(flipper_format);
|
||||
subghz_transmitter_free(transmitter);
|
||||
subghz_environment_free(environment);
|
||||
}
|
||||
|
||||
static void remote_render_callback(Canvas* canvas, void* ctx) {
|
||||
RemoteAppState* state = (RemoteAppState*)acquire_mutex((ValueMutex*)ctx, 25);
|
||||
canvas_clear(canvas);
|
||||
char strings[5][20];
|
||||
string_t signal;
|
||||
string_init(signal);
|
||||
sprintf(strings[0], "Ok: %s", file_stub(string_get_cstr(ok_file)));
|
||||
sprintf(strings[1], "L: %s", file_stub(string_get_cstr(left_file)));
|
||||
sprintf(strings[2], "R: %s", file_stub(string_get_cstr(right_file)));
|
||||
sprintf(strings[3], "U: %s", file_stub(string_get_cstr(up_file)));
|
||||
sprintf(strings[4], "D: %s", file_stub(string_get_cstr(down_file)));
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 0, 10, "Univeral Remote");
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(canvas, 0, 24, strings[1]);
|
||||
canvas_draw_str(canvas, 85, 24, strings[2]);
|
||||
canvas_draw_str(canvas, 0, 36, strings[3]);
|
||||
canvas_draw_str(canvas, 85, 36, strings[4]);
|
||||
canvas_draw_str(canvas, 0, 48, strings[0]);
|
||||
|
||||
if(state->press[0]) {
|
||||
string_cat_printf(signal, "%s", string_get_cstr(right_file));
|
||||
}
|
||||
|
||||
else if(state->press[1]) {
|
||||
string_cat_printf(signal, "%s", string_get_cstr(left_file));
|
||||
|
||||
} else if(state->press[2]) {
|
||||
string_cat_printf(signal, "%s", string_get_cstr(up_file));
|
||||
|
||||
} else if(state->press[3]) {
|
||||
string_cat_printf(signal, "%s", string_get_cstr(down_file));
|
||||
|
||||
}
|
||||
|
||||
else if(state->press[4]) {
|
||||
string_cat_printf(signal, "%s", string_get_cstr(ok_file));
|
||||
}
|
||||
FURI_LOG_D(TAG, "signal = %s", string_get_cstr(signal));
|
||||
|
||||
if(strlen(string_get_cstr(signal)) > 12) {
|
||||
string_t file_name;
|
||||
string_init(file_name);
|
||||
string_t protocol;
|
||||
string_init(protocol);
|
||||
string_set(file_name, string_get_cstr(signal));
|
||||
Storage* storage = furi_record_open("storage");
|
||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
||||
uint32_t frequency_str;
|
||||
flipper_format_file_open_existing(fff_data_file, string_get_cstr(file_name));
|
||||
flipper_format_read_uint32(fff_data_file, "Frequency", (uint32_t*)&frequency_str, 1);
|
||||
if(!flipper_format_read_string(fff_data_file, "Protocol", protocol)) {
|
||||
FURI_LOG_D(TAG, "Could not read Protocol");
|
||||
string_set(protocol, "RAW");
|
||||
}
|
||||
flipper_format_free(fff_data_file);
|
||||
furi_record_close("storage");
|
||||
FURI_LOG_D(TAG, "%lu", frequency_str);
|
||||
remote_send_signal(frequency_str, signal, protocol);
|
||||
}
|
||||
|
||||
canvas_draw_str(canvas, 10, 63, "[back] - skip, hold to exit");
|
||||
remote_reset_state(state);
|
||||
release_mutex((ValueMutex*)ctx, state);
|
||||
}
|
||||
|
||||
static void remote_input_callback(InputEvent* input_event, void* ctx) {
|
||||
if (input_event->type == InputTypeRelease) {
|
||||
osMessageQueueId_t event_queue = ctx;
|
||||
osMessageQueuePut(event_queue, input_event, 0, osWaitForever);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t universal_rf_remote_app(void* p) {
|
||||
UNUSED(p);
|
||||
osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL);
|
||||
furi_check(event_queue);
|
||||
string_init(up_file);
|
||||
string_init(down_file);
|
||||
string_init(left_file);
|
||||
string_init(right_file);
|
||||
string_init(ok_file);
|
||||
|
||||
string_t file_name;
|
||||
string_init(file_name);
|
||||
string_set(file_name, "/ext/subghz/assets/universal_rf_map");
|
||||
Storage* storage = furi_record_open("storage");
|
||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
||||
if(!flipper_format_file_open_existing(fff_data_file, string_get_cstr(file_name))) {
|
||||
FURI_LOG_D(TAG, "Could not open file %s", string_get_cstr(file_name));
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(fff_data_file, "UP", up_file)) {
|
||||
FURI_LOG_D(TAG, "Could not read UP string");
|
||||
}
|
||||
if(!flipper_format_read_string(fff_data_file, "DOWN", down_file)) {
|
||||
FURI_LOG_D(TAG, "Could not read DOWN string");
|
||||
}
|
||||
if(!flipper_format_read_string(fff_data_file, "LEFT", left_file)) {
|
||||
FURI_LOG_D(TAG, "Could not read LEFT string");
|
||||
}
|
||||
if(!flipper_format_read_string(fff_data_file, "RIGHT", right_file)) {
|
||||
FURI_LOG_D(TAG, "Could not read RIGHT string");
|
||||
}
|
||||
if(!flipper_format_read_string(fff_data_file, "OK", ok_file)) {
|
||||
FURI_LOG_D(TAG, "Could not read OK string");
|
||||
}
|
||||
flipper_format_free(fff_data_file);
|
||||
furi_record_close("storage");
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"%s %s %s %s %s ",
|
||||
string_get_cstr(up_file),
|
||||
string_get_cstr(down_file),
|
||||
string_get_cstr(left_file),
|
||||
string_get_cstr(right_file),
|
||||
string_get_cstr(ok_file));
|
||||
|
||||
RemoteAppState _state = {{false, false, false, false, false}};
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, &_state, sizeof(RemoteAppState))) {
|
||||
FURI_LOG_D(TAG, "cannot create mutex");
|
||||
return(0);
|
||||
}
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
|
||||
view_port_draw_callback_set(view_port, remote_render_callback, &state_mutex);
|
||||
view_port_input_callback_set(view_port, remote_input_callback, event_queue);
|
||||
|
||||
Gui* gui = furi_record_open("gui");
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
InputEvent event;
|
||||
while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) {
|
||||
RemoteAppState* state = (RemoteAppState*)acquire_mutex_block(&state_mutex);
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
"key: %s type: %s",
|
||||
input_get_key_name(event.key),
|
||||
input_get_type_name(event.type));
|
||||
|
||||
if(event.key == InputKeyRight) {
|
||||
state->press[0] = true;
|
||||
} else if(event.key == InputKeyLeft) {
|
||||
state->press[1] = true;
|
||||
} else if(event.key == InputKeyUp) {
|
||||
state->press[2] = true;
|
||||
} else if(event.key == InputKeyDown) {
|
||||
state->press[3] = true;
|
||||
} else if(event.key == InputKeyOk) {
|
||||
state->press[4] = true;
|
||||
} else if(event.key == InputKeyBack) {
|
||||
release_mutex(&state_mutex, state);
|
||||
break;
|
||||
}
|
||||
release_mutex(&state_mutex, state);
|
||||
view_port_update(view_port);
|
||||
}
|
||||
|
||||
gui_remove_view_port(gui, view_port);
|
||||
view_port_free(view_port);
|
||||
osMessageQueueDelete(event_queue);
|
||||
delete_mutex(&state_mutex);
|
||||
|
||||
furi_record_close("gui");
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -484,16 +484,6 @@ const uint8_t _A_U2F_14_2[] = {0x00,0xE0,0x01,0x10,0x02,0x08,0x04,0x08,0x04,0x08
|
||||
const uint8_t _A_U2F_14_3[] = {0x00,0x00,0x00,0xE0,0x01,0x10,0x02,0x08,0x04,0x08,0x04,0xFE,0x1F,0x01,0x20,0xD5,0x2D,0x55,0x25,0x15,0x2D,0x95,0x24,0xDD,0x25,0x01,0x20,0xFE,0x1F,};
|
||||
const uint8_t* const _A_U2F_14[] = {_A_U2F_14_0,_A_U2F_14_1,_A_U2F_14_2,_A_U2F_14_3};
|
||||
|
||||
const uint8_t _A_UniversalRemote_14_0[] = {0x01,0x00,0x17,0x00,0xe0,0x40,0x24,0x10,0x1f,0x04,0x04,0x0e,0x20,0x31,0x8b,0x46,0xa2,0xb2,0xa0,0x08,0x81,0x44,0x1a,0xa1,0x51,0x0c,0x88,};
|
||||
const uint8_t _A_UniversalRemote_14_1[] = {0x01,0x00,0x17,0x00,0xe0,0x40,0x3c,0x10,0x10,0x08,0x81,0xc4,0x06,0x31,0x68,0xd4,0x56,0x54,0x01,0x10,0x28,0x83,0x56,0x41,0x01,0x0c,0x88,};
|
||||
const uint8_t _A_UniversalRemote_14_2[] = {0x01,0x00,0x17,0x00,0xe0,0x40,0x24,0x10,0x1f,0x04,0x04,0x0e,0x20,0x31,0x8b,0x46,0xa2,0xb3,0xa0,0x08,0x81,0x44,0x1a,0xa1,0x51,0x0c,0x88,};
|
||||
const uint8_t _A_UniversalRemote_14_3[] = {0x01,0x00,0x17,0x00,0xe0,0x40,0x24,0x10,0x1f,0x04,0x04,0x0e,0x20,0x31,0x8b,0x46,0xa2,0xb2,0xa0,0x08,0x81,0x44,0x1a,0xa0,0x11,0x0c,0x88,};
|
||||
const uint8_t _A_UniversalRemote_14_4[] = {0x01,0x00,0x17,0x00,0xe0,0x40,0x24,0x10,0x1f,0x04,0x04,0x0e,0x20,0x31,0x8b,0x46,0xa2,0xf2,0xa0,0x08,0x81,0x44,0x1a,0xa1,0x51,0x0c,0x88,};
|
||||
const uint8_t _A_UniversalRemote_14_5[] = {0x01,0x00,0x17,0x00,0xe0,0x40,0x3c,0x10,0x10,0x08,0x81,0xc4,0x06,0x31,0x68,0xd4,0x56,0x54,0x01,0x10,0x28,0x83,0x56,0x41,0x01,0x0c,0x88,};
|
||||
const uint8_t _A_UniversalRemote_14_6[] = {0x01,0x00,0x17,0x00,0xe0,0x40,0x24,0x10,0x1f,0x04,0x04,0x0e,0x20,0x31,0xfb,0x46,0xfe,0xb2,0xb0,0x08,0x81,0x44,0x1a,0xa1,0x51,0x0c,0x88,};
|
||||
const uint8_t* const _A_UniversalRemote_14[] = {_A_UniversalRemote_14_0,_A_UniversalRemote_14_1,_A_UniversalRemote_14_2,_A_UniversalRemote_14_3,_A_UniversalRemote_14_4,_A_UniversalRemote_14_5,_A_UniversalRemote_14_6};
|
||||
|
||||
|
||||
const uint8_t _A_iButton_14_0[] = {0x00,0x00,0x1C,0x00,0x3E,0x00,0x35,0x80,0x3A,0x78,0x15,0x84,0x0A,0x32,0x05,0x49,0x02,0x85,0x02,0x85,0x02,0x49,0x02,0x32,0x01,0x84,0x00,0x78,0x00,};
|
||||
const uint8_t _A_iButton_14_1[] = {0x00,0x00,0x00,0x00,0x38,0x00,0x26,0x80,0x21,0xE0,0x10,0x38,0x0D,0x6C,0x03,0x56,0x01,0x2B,0x01,0x97,0x00,0x4D,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,};
|
||||
const uint8_t _A_iButton_14_2[] = {0x01,0x00,0x1a,0x00,0x00,0x24,0xc2,0x01,0x2c,0x80,0x48,0xfb,0x11,0x89,0x64,0x1b,0x2d,0x01,0xa5,0xc0,0x24,0xb0,0x08,0x94,0x02,0x13,0x00,0x83,0x85,0x88,};
|
||||
@@ -815,7 +805,6 @@ const Icon A_Sub1ghz_14 = {.width=14,.height=14,.frame_count=6,.frame_rate=3,.fr
|
||||
const Icon A_Tamagotchi_14 = {.width=14,.height=14,.frame_count=6,.frame_rate=3,.frames=_A_Tamagotchi_14};
|
||||
const Icon A_TouchTunes_14 = {.width=14,.height=14,.frame_count=30,.frame_rate=3,.frames=_A_TouchTunes_14};
|
||||
const Icon A_U2F_14 = {.width=14,.height=14,.frame_count=4,.frame_rate=3,.frames=_A_U2F_14};
|
||||
const Icon A_UniversalRemote_14 = {.width=14,.height=14,.frame_count=7,.frame_rate=3,.frames=_A_UniversalRemote_14};
|
||||
const Icon A_iButton_14 = {.width=14,.height=14,.frame_count=7,.frame_rate=3,.frames=_A_iButton_14};
|
||||
const Icon I_Detailed_chip_17x13 = {.width=17,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_Detailed_chip_17x13};
|
||||
const Icon I_Medium_chip_22x21 = {.width=22,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_Medium_chip_22x21};
|
||||
|
||||
@@ -109,7 +109,6 @@ extern const Icon A_Sub1ghz_14;
|
||||
extern const Icon A_Tamagotchi_14;
|
||||
extern const Icon A_TouchTunes_14;
|
||||
extern const Icon A_U2F_14;
|
||||
extern const Icon A_UniversalRemote_14;
|
||||
extern const Icon A_iButton_14;
|
||||
extern const Icon I_Detailed_chip_17x13;
|
||||
extern const Icon I_Medium_chip_22x21;
|
||||
|
||||
|
Before Width: | Height: | Size: 470 B |
|
Before Width: | Height: | Size: 411 B |
|
Before Width: | Height: | Size: 411 B |
|
Before Width: | Height: | Size: 411 B |
|
Before Width: | Height: | Size: 401 B |
|
Before Width: | Height: | Size: 397 B |
|
Before Width: | Height: | Size: 400 B |
|
Before Width: | Height: | Size: 404 B |
|
Before Width: | Height: | Size: 414 B |
|
Before Width: | Height: | Size: 427 B |
|
Before Width: | Height: | Size: 170 B |
|
Before Width: | Height: | Size: 427 B |
|
Before Width: | Height: | Size: 426 B |
|
Before Width: | Height: | Size: 431 B |
|
Before Width: | Height: | Size: 424 B |
|
Before Width: | Height: | Size: 424 B |
|
Before Width: | Height: | Size: 424 B |
|
Before Width: | Height: | Size: 424 B |
|
Before Width: | Height: | Size: 426 B |
|
Before Width: | Height: | Size: 418 B |
|
Before Width: | Height: | Size: 419 B |
|
Before Width: | Height: | Size: 165 B |
|
Before Width: | Height: | Size: 425 B |
|
Before Width: | Height: | Size: 415 B |
|
Before Width: | Height: | Size: 405 B |
|
Before Width: | Height: | Size: 394 B |
|
Before Width: | Height: | Size: 401 B |
|
Before Width: | Height: | Size: 401 B |
|
Before Width: | Height: | Size: 404 B |
|
Before Width: | Height: | Size: 410 B |
|
Before Width: | Height: | Size: 411 B |
|
Before Width: | Height: | Size: 411 B |
|
Before Width: | Height: | Size: 171 B |
|
Before Width: | Height: | Size: 168 B |
|
Before Width: | Height: | Size: 169 B |
|
Before Width: | Height: | Size: 165 B |
|
Before Width: | Height: | Size: 166 B |
@@ -1 +0,0 @@
|
||||
3
|
||||