mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-21 12:21:49 +03:00
Weather station: new external radio driver (#3)
* Weather station: new external radio driver
This commit is contained in:
parent
cb08b84197
commit
b1850fd700
69
applications/external/weather_station/helpers/radio_device_loader.c
vendored
Normal file
69
applications/external/weather_station/helpers/radio_device_loader.c
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
#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();
|
||||
}
|
||||
|
||||
const SubGhzDevice* device = subghz_devices_get_by_name(name);
|
||||
if(device) {
|
||||
is_connect = subghz_devices_is_connect(device);
|
||||
}
|
||||
|
||||
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
applications/external/weather_station/helpers/radio_device_loader.h
vendored
Normal file
17
applications/external/weather_station/helpers/radio_device_loader.h
vendored
Normal file
@ -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);
|
@ -48,13 +48,18 @@ static void weather_station_scene_receiver_update_statusbar(void* context) {
|
||||
app->ws_receiver,
|
||||
furi_string_get_cstr(frequency_str),
|
||||
furi_string_get_cstr(modulation_str),
|
||||
furi_string_get_cstr(history_stat_str));
|
||||
furi_string_get_cstr(history_stat_str),
|
||||
radio_device_loader_is_external(app->txrx->radio_device));
|
||||
|
||||
furi_string_free(frequency_str);
|
||||
furi_string_free(modulation_str);
|
||||
} else {
|
||||
ws_view_receiver_add_data_statusbar(
|
||||
app->ws_receiver, furi_string_get_cstr(history_stat_str), "", "");
|
||||
app->ws_receiver,
|
||||
furi_string_get_cstr(history_stat_str),
|
||||
"",
|
||||
"",
|
||||
radio_device_loader_is_external(app->txrx->radio_device));
|
||||
}
|
||||
furi_string_free(history_stat_str);
|
||||
}
|
||||
@ -196,7 +201,7 @@ bool weather_station_scene_receiver_on_event(void* context, SceneManagerEvent ev
|
||||
weather_station_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);
|
||||
ws_view_receiver_set_rssi(app->ws_receiver, rssi);
|
||||
|
||||
if(app->txrx->txrx_state == WSTxRxStateRx) {
|
||||
|
@ -61,6 +61,7 @@ typedef struct {
|
||||
uint16_t history_item;
|
||||
WSReceiverBarShow bar_show;
|
||||
uint8_t u_rssi;
|
||||
bool external_redio;
|
||||
} WSReceiverModel;
|
||||
|
||||
void ws_view_receiver_set_rssi(WSReceiver* instance, float rssi) {
|
||||
@ -154,7 +155,8 @@ void ws_view_receiver_add_data_statusbar(
|
||||
WSReceiver* ws_receiver,
|
||||
const char* frequency_str,
|
||||
const char* preset_str,
|
||||
const char* history_stat_str) {
|
||||
const char* history_stat_str,
|
||||
bool external) {
|
||||
furi_assert(ws_receiver);
|
||||
with_view_model(
|
||||
ws_receiver->view,
|
||||
@ -163,6 +165,7 @@ void ws_view_receiver_add_data_statusbar(
|
||||
furi_string_set_str(model->frequency_str, frequency_str);
|
||||
furi_string_set_str(model->preset_str, preset_str);
|
||||
furi_string_set_str(model->history_stat_str, history_stat_str);
|
||||
model->external_redio = external;
|
||||
},
|
||||
true);
|
||||
}
|
||||
@ -202,7 +205,7 @@ void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* model) {
|
||||
FuriString* str_buff;
|
||||
str_buff = furi_string_alloc();
|
||||
|
||||
bool ext_module = furi_hal_subghz_get_radio_type();
|
||||
// bool ext_module = furi_hal_subghz_get_radio_type();
|
||||
|
||||
WSReceiverMenuItem* item_menu;
|
||||
|
||||
@ -228,11 +231,12 @@ void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* 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->external_redio ? &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->external_redio ? "Ext" : "Int");
|
||||
}
|
||||
|
||||
// Draw RSSI
|
||||
@ -408,6 +412,7 @@ WSReceiver* ws_view_receiver_alloc() {
|
||||
model->history_stat_str = furi_string_alloc();
|
||||
model->bar_show = WSReceiverBarShowDefault;
|
||||
model->history = malloc(sizeof(WSReceiverHistory));
|
||||
model->external_redio = false;
|
||||
WSReceiverMenuItemArray_init(model->history->data);
|
||||
},
|
||||
true);
|
||||
|
@ -27,7 +27,8 @@ void ws_view_receiver_add_data_statusbar(
|
||||
WSReceiver* ws_receiver,
|
||||
const char* frequency_str,
|
||||
const char* preset_str,
|
||||
const char* history_stat_str);
|
||||
const char* history_stat_str,
|
||||
bool external);
|
||||
|
||||
void ws_view_receiver_add_item_to_menu(WSReceiver* ws_receiver, const char* name, uint8_t type);
|
||||
|
||||
|
@ -98,6 +98,14 @@ WeatherStationApp* weather_station_app_alloc() {
|
||||
app->txrx->environment, (void*)&weather_station_protocol_registry);
|
||||
app->txrx->receiver = subghz_receiver_alloc_init(app->txrx->environment);
|
||||
|
||||
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);
|
||||
|
||||
subghz_receiver_set_filter(app->txrx->receiver, SubGhzProtocolFlag_Decodable);
|
||||
subghz_worker_set_overrun_callback(
|
||||
app->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset);
|
||||
@ -105,15 +113,6 @@ WeatherStationApp* weather_station_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, WeatherStationSceneStart);
|
||||
@ -124,13 +123,10 @@ WeatherStationApp* weather_station_app_alloc() {
|
||||
void weather_station_app_free(WeatherStationApp* app) {
|
||||
furi_assert(app);
|
||||
|
||||
//CC1101 off
|
||||
ws_sleep(app);
|
||||
subghz_devices_sleep(app->txrx->radio_device);
|
||||
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, WeatherStationViewSubmenu);
|
||||
|
@ -54,29 +54,28 @@ void ws_get_frequency_modulation(
|
||||
|
||||
void ws_begin(WeatherStationApp* 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);
|
||||
app->txrx->txrx_state = WSTxRxStateIDLE;
|
||||
}
|
||||
|
||||
uint32_t ws_rx(WeatherStationApp* 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("WeatherStation: Incorrect RX frequency.");
|
||||
}
|
||||
furi_assert(
|
||||
app->txrx->txrx_state != WSTxRxStateRx && app->txrx->txrx_state != WSTxRxStateSleep);
|
||||
|
||||
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);
|
||||
subghz_devices_flush_rx(app->txrx->radio_device);
|
||||
subghz_devices_set_rx(app->txrx->radio_device);
|
||||
|
||||
subghz_devices_start_async_rx(
|
||||
app->txrx->radio_device, subghz_worker_rx_callback, app->txrx->worker);
|
||||
|
||||
furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, app->txrx->worker);
|
||||
subghz_worker_start(app->txrx->worker);
|
||||
app->txrx->txrx_state = WSTxRxStateRx;
|
||||
return value;
|
||||
@ -85,7 +84,7 @@ uint32_t ws_rx(WeatherStationApp* app, uint32_t frequency) {
|
||||
void ws_idle(WeatherStationApp* app) {
|
||||
furi_assert(app);
|
||||
furi_assert(app->txrx->txrx_state != WSTxRxStateSleep);
|
||||
furi_hal_subghz_idle();
|
||||
subghz_devices_idle(app->txrx->radio_device);
|
||||
app->txrx->txrx_state = WSTxRxStateIDLE;
|
||||
}
|
||||
|
||||
@ -94,15 +93,15 @@ void ws_rx_end(WeatherStationApp* app) {
|
||||
furi_assert(app->txrx->txrx_state == WSTxRxStateRx);
|
||||
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 = WSTxRxStateIDLE;
|
||||
}
|
||||
|
||||
void ws_sleep(WeatherStationApp* app) {
|
||||
furi_assert(app);
|
||||
furi_hal_subghz_sleep();
|
||||
subghz_devices_sleep(app->txrx->radio_device);
|
||||
app->txrx->txrx_state = WSTxRxStateSleep;
|
||||
}
|
||||
|
||||
@ -125,7 +124,7 @@ void ws_hopper_update(WeatherStationApp* app) {
|
||||
float rssi = -127.0f;
|
||||
if(app->txrx->hopper_state != WSHopperStateRSSITimeOut) {
|
||||
// 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) {
|
||||
|
@ -20,11 +20,14 @@
|
||||
#include <lib/subghz/transmitter.h>
|
||||
#include <lib/subghz/registry.h>
|
||||
|
||||
#include "helpers/radio_device_loader.h"
|
||||
|
||||
typedef struct WeatherStationApp WeatherStationApp;
|
||||
|
||||
struct WeatherStationTxRx {
|
||||
SubGhzWorker* worker;
|
||||
|
||||
const SubGhzDevice* radio_device;
|
||||
SubGhzEnvironment* environment;
|
||||
SubGhzReceiver* receiver;
|
||||
SubGhzRadioPreset* preset;
|
||||
|
Loading…
Reference in New Issue
Block a user