Skip to content

Commit

Permalink
Merge pull request #535 from gid9798/cc1101_ext_pocsag
Browse files Browse the repository at this point in the history
POCSAG Pager: cc1101 ext
  • Loading branch information
xMasterX authored Jul 10, 2023
2 parents f91a731 + 1e8a58c commit 88391c8
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 39 deletions.
66 changes: 66 additions & 0 deletions applications/external/pocsag_pager/helpers/radio_device_loader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "radio_device_loader.h"

#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>

static void radio_device_loader_power_on() {
uint8_t attempts = 0;
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
furi_hal_power_enable_otg();
//CC1101 power-up time
furi_delay_ms(10);
}
}

static void radio_device_loader_power_off() {
if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
}

bool radio_device_loader_is_connect_external(const char* name) {
bool is_connect = false;
bool is_otg_enabled = furi_hal_power_is_otg_enabled();

if(!is_otg_enabled) {
radio_device_loader_power_on();
}

is_connect = subghz_devices_is_connect(subghz_devices_get_by_name(name));

if(!is_otg_enabled) {
radio_device_loader_power_off();
}
return is_connect;
}

const SubGhzDevice* radio_device_loader_set(
const SubGhzDevice* current_radio_device,
SubGhzRadioDeviceType radio_device_type) {
const SubGhzDevice* radio_device;

if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 &&
radio_device_loader_is_connect_external(SUBGHZ_DEVICE_CC1101_EXT_NAME)) {
radio_device_loader_power_on();
radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME);
subghz_devices_begin(radio_device);
} else if(current_radio_device == NULL) {
radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
} else {
radio_device_loader_end(current_radio_device);
radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
}

return radio_device;
}

bool radio_device_loader_is_external(const SubGhzDevice* radio_device) {
furi_assert(radio_device);
return (radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME));
}

void radio_device_loader_end(const SubGhzDevice* radio_device) {
furi_assert(radio_device);
radio_device_loader_power_off();
if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) {
subghz_devices_end(radio_device);
}
}
17 changes: 17 additions & 0 deletions applications/external/pocsag_pager/helpers/radio_device_loader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include <lib/subghz/devices/devices.h>

/** SubGhzRadioDeviceType */
typedef enum {
SubGhzRadioDeviceTypeInternal,
SubGhzRadioDeviceTypeExternalCC1101,
} SubGhzRadioDeviceType;

const SubGhzDevice* radio_device_loader_set(
const SubGhzDevice* current_radio_device,
SubGhzRadioDeviceType radio_device_type);

bool radio_device_loader_is_external(const SubGhzDevice* radio_device);

void radio_device_loader_end(const SubGhzDevice* radio_device);
29 changes: 13 additions & 16 deletions applications/external/pocsag_pager/pocsag_pager_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ POCSAGPagerApp* pocsag_pager_app_alloc() {
app->txrx->preset = malloc(sizeof(SubGhzRadioPreset));
app->txrx->preset->name = furi_string_alloc();

furi_hal_power_suppress_charge_enter();

// Radio Devices init & load
subghz_devices_init();
app->txrx->radio_device =
radio_device_loader_set(app->txrx->radio_device, SubGhzRadioDeviceTypeExternalCC1101);

subghz_devices_reset(app->txrx->radio_device);
subghz_devices_idle(app->txrx->radio_device);

// Custom Presets load without using config file

FlipperFormat* temp_fm_preset = flipper_format_string_alloc();
Expand Down Expand Up @@ -122,17 +132,6 @@ POCSAGPagerApp* pocsag_pager_app_alloc() {
app->txrx->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode);
subghz_worker_set_context(app->txrx->worker, app->txrx->receiver);

// Enable power for External CC1101 if it is connected
furi_hal_subghz_enable_ext_power();
// Auto switch to internal radio if external radio is not available
furi_delay_ms(15);
if(!furi_hal_subghz_check_radio()) {
furi_hal_subghz_select_radio_type(SubGhzRadioInternal);
furi_hal_subghz_init_radio_type(SubGhzRadioInternal);
}

furi_hal_power_suppress_charge_enter();

scene_manager_next_scene(app->scene_manager, POCSAGPagerSceneStart);

return app;
Expand All @@ -141,13 +140,11 @@ POCSAGPagerApp* pocsag_pager_app_alloc() {
void pocsag_pager_app_free(POCSAGPagerApp* app) {
furi_assert(app);

//CC1101 off
// Radio Devices sleep & off
pcsg_sleep(app);
radio_device_loader_end(app->txrx->radio_device);

// Disable power for External CC1101 if it was enabled and module is connected
furi_hal_subghz_disable_ext_power();
// Reinit SPI handles for internal radio / nfc
furi_hal_subghz_init_radio_type(SubGhzRadioInternal);
subghz_devices_deinit();

// Submenu
view_dispatcher_remove_view(app->view_dispatcher, POCSAGPagerViewSubmenu);
Expand Down
39 changes: 22 additions & 17 deletions applications/external/pocsag_pager/pocsag_pager_app_i.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,29 +36,34 @@ void pcsg_get_frequency_modulation(

void pcsg_begin(POCSAGPagerApp* app, uint8_t* preset_data) {
furi_assert(app);
UNUSED(preset_data);
furi_hal_subghz_reset();
furi_hal_subghz_idle();
furi_hal_subghz_load_custom_preset(preset_data);
furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);

subghz_devices_reset(app->txrx->radio_device);
subghz_devices_idle(app->txrx->radio_device);
subghz_devices_load_preset(app->txrx->radio_device, FuriHalSubGhzPresetCustom, preset_data);

// furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);
app->txrx->txrx_state = PCSGTxRxStateIDLE;
}

uint32_t pcsg_rx(POCSAGPagerApp* app, uint32_t frequency) {
furi_assert(app);
if(!furi_hal_subghz_is_frequency_valid(frequency)) {
if(!subghz_devices_is_frequency_valid(app->txrx->radio_device, frequency)) {
furi_crash("POCSAGPager: Incorrect RX frequency.");
}
furi_assert(
app->txrx->txrx_state != PCSGTxRxStateRx && app->txrx->txrx_state != PCSGTxRxStateSleep);

furi_hal_subghz_idle();
uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency);
furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);
furi_hal_subghz_flush_rx();
furi_hal_subghz_rx();
subghz_devices_idle(app->txrx->radio_device);
uint32_t value = subghz_devices_set_frequency(app->txrx->radio_device, frequency);

// Not need. init in subghz_devices_start_async_tx
// furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);

subghz_devices_flush_rx(app->txrx->radio_device);
subghz_devices_set_rx(app->txrx->radio_device);

furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, app->txrx->worker);
subghz_devices_start_async_rx(
app->txrx->radio_device, subghz_worker_rx_callback, app->txrx->worker);
subghz_worker_start(app->txrx->worker);
app->txrx->txrx_state = PCSGTxRxStateRx;
return value;
Expand All @@ -67,7 +72,7 @@ uint32_t pcsg_rx(POCSAGPagerApp* app, uint32_t frequency) {
void pcsg_idle(POCSAGPagerApp* app) {
furi_assert(app);
furi_assert(app->txrx->txrx_state != PCSGTxRxStateSleep);
furi_hal_subghz_idle();
subghz_devices_idle(app->txrx->radio_device);
app->txrx->txrx_state = PCSGTxRxStateIDLE;
}

Expand All @@ -76,15 +81,15 @@ void pcsg_rx_end(POCSAGPagerApp* app) {
furi_assert(app->txrx->txrx_state == PCSGTxRxStateRx);
if(subghz_worker_is_running(app->txrx->worker)) {
subghz_worker_stop(app->txrx->worker);
furi_hal_subghz_stop_async_rx();
subghz_devices_stop_async_rx(app->txrx->radio_device);
}
furi_hal_subghz_idle();
subghz_devices_idle(app->txrx->radio_device);
app->txrx->txrx_state = PCSGTxRxStateIDLE;
}

void pcsg_sleep(POCSAGPagerApp* app) {
furi_assert(app);
furi_hal_subghz_sleep();
subghz_devices_sleep(app->txrx->radio_device);
app->txrx->txrx_state = PCSGTxRxStateSleep;
}

Expand All @@ -110,7 +115,7 @@ void pcsg_hopper_update(POCSAGPagerApp* app) {
float rssi = -127.0f;
if(app->txrx->hopper_state != PCSGHopperStateRSSITimeOut) {
// See RSSI Calculation timings in CC1101 17.3 RSSI
rssi = furi_hal_subghz_get_rssi();
rssi = subghz_devices_get_rssi(app->txrx->radio_device);

// Stay if RSSI is high enough
if(rssi > -90.0f) {
Expand Down
4 changes: 4 additions & 0 deletions applications/external/pocsag_pager/pocsag_pager_app_i.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "helpers/pocsag_pager_types.h"
#include "helpers/radio_device_loader.h"

#include "scenes/pocsag_pager_scene.h"
#include <gui/gui.h>
Expand All @@ -19,6 +20,7 @@
#include <lib/subghz/receiver.h>
#include <lib/subghz/transmitter.h>
#include <lib/subghz/registry.h>
#include <lib/subghz/devices/devices.h>

typedef struct POCSAGPagerApp POCSAGPagerApp;

Expand All @@ -35,6 +37,8 @@ struct POCSAGPagerTxRx {
uint8_t hopper_timeout;
uint8_t hopper_idx_frequency;
PCSGRxKeyState rx_key_state;

const SubGhzDevice* radio_device;
};

typedef struct POCSAGPagerTxRx POCSAGPagerTxRx;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ void pocsag_pager_scene_receiver_on_enter(void* context) {
}

pcsg_view_receiver_set_lock(app->pcsg_receiver, app->lock);
pcsg_view_receiver_set_ext_module_state(
app->pcsg_receiver, radio_device_loader_is_external(app->txrx->radio_device));

//Load history to receiver
pcsg_view_receiver_exit(app->pcsg_receiver);
Expand All @@ -136,6 +138,7 @@ void pocsag_pager_scene_receiver_on_enter(void* context) {
};
if((app->txrx->txrx_state == PCSGTxRxStateIDLE) ||
(app->txrx->txrx_state == PCSGTxRxStateSleep)) {
// Start RX
pcsg_begin(
app,
subghz_setting_get_preset_data_by_name(
Expand All @@ -157,7 +160,7 @@ bool pocsag_pager_scene_receiver_on_event(void* context, SceneManagerEvent event
// Stop CC1101 Rx
if(app->txrx->txrx_state == PCSGTxRxStateRx) {
pcsg_rx_end(app);
pcsg_sleep(app);
pcsg_idle(app);
};
app->txrx->hopper_state = PCSGHopperStateOFF;
app->txrx->idx_menu_chosen = 0;
Expand Down Expand Up @@ -196,7 +199,7 @@ bool pocsag_pager_scene_receiver_on_event(void* context, SceneManagerEvent event
pocsag_pager_scene_receiver_update_statusbar(app);
}
// Get current RSSI
float rssi = furi_hal_subghz_get_rssi();
float rssi = subghz_devices_get_rssi(app->txrx->radio_device);
pcsg_receiver_rssi(app->pcsg_receiver, rssi);

if(app->txrx->txrx_state == PCSGTxRxStateRx) {
Expand Down
13 changes: 9 additions & 4 deletions applications/external/pocsag_pager/views/pocsag_pager_receiver.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ typedef struct {
uint16_t history_item;
PCSGReceiverBarShow bar_show;
uint8_t u_rssi;
bool ext_module;
} PCSGReceiverModel;

void pcsg_receiver_rssi(PCSGReceiver* instance, float rssi) {
Expand Down Expand Up @@ -98,6 +99,12 @@ void pcsg_view_receiver_set_lock(PCSGReceiver* pcsg_receiver, PCSGLock lock) {
}
}

void pcsg_view_receiver_set_ext_module_state(PCSGReceiver* pcsg_receiver, bool is_external) {
furi_assert(pcsg_receiver);
with_view_model(
pcsg_receiver->view, PCSGReceiverModel * model, { model->ext_module = is_external; }, true);
}

void pcsg_view_receiver_set_callback(
PCSGReceiver* pcsg_receiver,
PCSGReceiverCallback callback,
Expand Down Expand Up @@ -207,8 +214,6 @@ void pcsg_view_receiver_draw(Canvas* canvas, PCSGReceiverModel* model) {
FuriString* str_buff;
str_buff = furi_string_alloc();

bool ext_module = furi_hal_subghz_get_radio_type();

PCSGReceiverMenuItem* item_menu;

for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) {
Expand All @@ -234,11 +239,11 @@ void pcsg_view_receiver_draw(Canvas* canvas, PCSGReceiverModel* model) {
canvas_set_color(canvas, ColorBlack);

if(model->history_item == 0) {
canvas_draw_icon(canvas, 0, 0, ext_module ? &I_Fishing_123x52 : &I_Scanning_123x52);
canvas_draw_icon(canvas, 0, 0, model->ext_module ? &I_Fishing_123x52 : &I_Scanning_123x52);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 63, 46, "Scanning...");
canvas_set_font(canvas, FontSecondary);
canvas_draw_str(canvas, 44, 10, ext_module ? "Ext" : "Int");
canvas_draw_str(canvas, 44, 10, model->ext_module ? "Ext" : "Int");
}

// Draw RSSI
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ void pcsg_receiver_rssi(PCSGReceiver* instance, float rssi);

void pcsg_view_receiver_set_lock(PCSGReceiver* pcsg_receiver, PCSGLock keyboard);

void pcsg_view_receiver_set_ext_module_state(PCSGReceiver* pcsg_receiver, bool is_external);

void pcsg_view_receiver_set_callback(
PCSGReceiver* pcsg_receiver,
PCSGReceiverCallback callback,
Expand Down

0 comments on commit 88391c8

Please sign in to comment.