Skip to content

Commit b1850fd

Browse files
authored
Weather station: new external radio driver (#3)
* Weather station: new external radio driver
1 parent cb08b84 commit b1850fd

8 files changed

+135
-40
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include "radio_device_loader.h"
2+
3+
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
4+
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
5+
6+
static void radio_device_loader_power_on() {
7+
uint8_t attempts = 0;
8+
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
9+
furi_hal_power_enable_otg();
10+
//CC1101 power-up time
11+
furi_delay_ms(10);
12+
}
13+
}
14+
15+
static void radio_device_loader_power_off() {
16+
if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
17+
}
18+
19+
bool radio_device_loader_is_connect_external(const char* name) {
20+
bool is_connect = false;
21+
bool is_otg_enabled = furi_hal_power_is_otg_enabled();
22+
23+
if(!is_otg_enabled) {
24+
radio_device_loader_power_on();
25+
}
26+
27+
const SubGhzDevice* device = subghz_devices_get_by_name(name);
28+
if(device) {
29+
is_connect = subghz_devices_is_connect(device);
30+
}
31+
32+
if(!is_otg_enabled) {
33+
radio_device_loader_power_off();
34+
}
35+
return is_connect;
36+
}
37+
38+
const SubGhzDevice* radio_device_loader_set(
39+
const SubGhzDevice* current_radio_device,
40+
SubGhzRadioDeviceType radio_device_type) {
41+
const SubGhzDevice* radio_device;
42+
43+
if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 &&
44+
radio_device_loader_is_connect_external(SUBGHZ_DEVICE_CC1101_EXT_NAME)) {
45+
radio_device_loader_power_on();
46+
radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME);
47+
subghz_devices_begin(radio_device);
48+
} else if(current_radio_device == NULL) {
49+
radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
50+
} else {
51+
radio_device_loader_end(current_radio_device);
52+
radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
53+
}
54+
55+
return radio_device;
56+
}
57+
58+
bool radio_device_loader_is_external(const SubGhzDevice* radio_device) {
59+
furi_assert(radio_device);
60+
return (radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME));
61+
}
62+
63+
void radio_device_loader_end(const SubGhzDevice* radio_device) {
64+
furi_assert(radio_device);
65+
radio_device_loader_power_off();
66+
if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) {
67+
subghz_devices_end(radio_device);
68+
}
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
#include <lib/subghz/devices/devices.h>
4+
5+
/** SubGhzRadioDeviceType */
6+
typedef enum {
7+
SubGhzRadioDeviceTypeInternal,
8+
SubGhzRadioDeviceTypeExternalCC1101,
9+
} SubGhzRadioDeviceType;
10+
11+
const SubGhzDevice* radio_device_loader_set(
12+
const SubGhzDevice* current_radio_device,
13+
SubGhzRadioDeviceType radio_device_type);
14+
15+
bool radio_device_loader_is_external(const SubGhzDevice* radio_device);
16+
17+
void radio_device_loader_end(const SubGhzDevice* radio_device);

applications/external/weather_station/scenes/weather_station_receiver.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,18 @@ static void weather_station_scene_receiver_update_statusbar(void* context) {
4848
app->ws_receiver,
4949
furi_string_get_cstr(frequency_str),
5050
furi_string_get_cstr(modulation_str),
51-
furi_string_get_cstr(history_stat_str));
51+
furi_string_get_cstr(history_stat_str),
52+
radio_device_loader_is_external(app->txrx->radio_device));
5253

5354
furi_string_free(frequency_str);
5455
furi_string_free(modulation_str);
5556
} else {
5657
ws_view_receiver_add_data_statusbar(
57-
app->ws_receiver, furi_string_get_cstr(history_stat_str), "", "");
58+
app->ws_receiver,
59+
furi_string_get_cstr(history_stat_str),
60+
"",
61+
"",
62+
radio_device_loader_is_external(app->txrx->radio_device));
5863
}
5964
furi_string_free(history_stat_str);
6065
}
@@ -196,7 +201,7 @@ bool weather_station_scene_receiver_on_event(void* context, SceneManagerEvent ev
196201
weather_station_scene_receiver_update_statusbar(app);
197202
}
198203
// Get current RSSI
199-
float rssi = furi_hal_subghz_get_rssi();
204+
float rssi = subghz_devices_get_rssi(app->txrx->radio_device);
200205
ws_view_receiver_set_rssi(app->ws_receiver, rssi);
201206

202207
if(app->txrx->txrx_state == WSTxRxStateRx) {

applications/external/weather_station/views/weather_station_receiver.c

+9-4
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ typedef struct {
6161
uint16_t history_item;
6262
WSReceiverBarShow bar_show;
6363
uint8_t u_rssi;
64+
bool external_redio;
6465
} WSReceiverModel;
6566

6667
void ws_view_receiver_set_rssi(WSReceiver* instance, float rssi) {
@@ -154,7 +155,8 @@ void ws_view_receiver_add_data_statusbar(
154155
WSReceiver* ws_receiver,
155156
const char* frequency_str,
156157
const char* preset_str,
157-
const char* history_stat_str) {
158+
const char* history_stat_str,
159+
bool external) {
158160
furi_assert(ws_receiver);
159161
with_view_model(
160162
ws_receiver->view,
@@ -163,6 +165,7 @@ void ws_view_receiver_add_data_statusbar(
163165
furi_string_set_str(model->frequency_str, frequency_str);
164166
furi_string_set_str(model->preset_str, preset_str);
165167
furi_string_set_str(model->history_stat_str, history_stat_str);
168+
model->external_redio = external;
166169
},
167170
true);
168171
}
@@ -202,7 +205,7 @@ void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* model) {
202205
FuriString* str_buff;
203206
str_buff = furi_string_alloc();
204207

205-
bool ext_module = furi_hal_subghz_get_radio_type();
208+
// bool ext_module = furi_hal_subghz_get_radio_type();
206209

207210
WSReceiverMenuItem* item_menu;
208211

@@ -228,11 +231,12 @@ void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* model) {
228231
canvas_set_color(canvas, ColorBlack);
229232

230233
if(model->history_item == 0) {
231-
canvas_draw_icon(canvas, 0, 0, ext_module ? &I_Fishing_123x52 : &I_Scanning_123x52);
234+
canvas_draw_icon(
235+
canvas, 0, 0, model->external_redio ? &I_Fishing_123x52 : &I_Scanning_123x52);
232236
canvas_set_font(canvas, FontPrimary);
233237
canvas_draw_str(canvas, 63, 46, "Scanning...");
234238
canvas_set_font(canvas, FontSecondary);
235-
canvas_draw_str(canvas, 44, 10, ext_module ? "Ext" : "Int");
239+
canvas_draw_str(canvas, 44, 10, model->external_redio ? "Ext" : "Int");
236240
}
237241

238242
// Draw RSSI
@@ -408,6 +412,7 @@ WSReceiver* ws_view_receiver_alloc() {
408412
model->history_stat_str = furi_string_alloc();
409413
model->bar_show = WSReceiverBarShowDefault;
410414
model->history = malloc(sizeof(WSReceiverHistory));
415+
model->external_redio = false;
411416
WSReceiverMenuItemArray_init(model->history->data);
412417
},
413418
true);

applications/external/weather_station/views/weather_station_receiver.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ void ws_view_receiver_add_data_statusbar(
2727
WSReceiver* ws_receiver,
2828
const char* frequency_str,
2929
const char* preset_str,
30-
const char* history_stat_str);
30+
const char* history_stat_str,
31+
bool external);
3132

3233
void ws_view_receiver_add_item_to_menu(WSReceiver* ws_receiver, const char* name, uint8_t type);
3334

applications/external/weather_station/weather_station_app.c

+11-15
Original file line numberDiff line numberDiff line change
@@ -98,22 +98,21 @@ WeatherStationApp* weather_station_app_alloc() {
9898
app->txrx->environment, (void*)&weather_station_protocol_registry);
9999
app->txrx->receiver = subghz_receiver_alloc_init(app->txrx->environment);
100100

101+
subghz_devices_init();
102+
103+
app->txrx->radio_device =
104+
radio_device_loader_set(app->txrx->radio_device, SubGhzRadioDeviceTypeExternalCC1101);
105+
106+
subghz_devices_reset(app->txrx->radio_device);
107+
subghz_devices_idle(app->txrx->radio_device);
108+
101109
subghz_receiver_set_filter(app->txrx->receiver, SubGhzProtocolFlag_Decodable);
102110
subghz_worker_set_overrun_callback(
103111
app->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset);
104112
subghz_worker_set_pair_callback(
105113
app->txrx->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode);
106114
subghz_worker_set_context(app->txrx->worker, app->txrx->receiver);
107115

108-
// Enable power for External CC1101 if it is connected
109-
furi_hal_subghz_enable_ext_power();
110-
// Auto switch to internal radio if external radio is not available
111-
furi_delay_ms(15);
112-
if(!furi_hal_subghz_check_radio()) {
113-
furi_hal_subghz_select_radio_type(SubGhzRadioInternal);
114-
furi_hal_subghz_init_radio_type(SubGhzRadioInternal);
115-
}
116-
117116
furi_hal_power_suppress_charge_enter();
118117

119118
scene_manager_next_scene(app->scene_manager, WeatherStationSceneStart);
@@ -124,13 +123,10 @@ WeatherStationApp* weather_station_app_alloc() {
124123
void weather_station_app_free(WeatherStationApp* app) {
125124
furi_assert(app);
126125

127-
//CC1101 off
128-
ws_sleep(app);
126+
subghz_devices_sleep(app->txrx->radio_device);
127+
radio_device_loader_end(app->txrx->radio_device);
129128

130-
// Disable power for External CC1101 if it was enabled and module is connected
131-
furi_hal_subghz_disable_ext_power();
132-
// Reinit SPI handles for internal radio / nfc
133-
furi_hal_subghz_init_radio_type(SubGhzRadioInternal);
129+
subghz_devices_deinit();
134130

135131
// Submenu
136132
view_dispatcher_remove_view(app->view_dispatcher, WeatherStationViewSubmenu);

applications/external/weather_station/weather_station_app_i.c

+16-17
Original file line numberDiff line numberDiff line change
@@ -54,29 +54,28 @@ void ws_get_frequency_modulation(
5454

5555
void ws_begin(WeatherStationApp* app, uint8_t* preset_data) {
5656
furi_assert(app);
57-
UNUSED(preset_data);
58-
furi_hal_subghz_reset();
59-
furi_hal_subghz_idle();
60-
furi_hal_subghz_load_custom_preset(preset_data);
61-
furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);
57+
subghz_devices_reset(app->txrx->radio_device);
58+
subghz_devices_idle(app->txrx->radio_device);
59+
subghz_devices_load_preset(app->txrx->radio_device, FuriHalSubGhzPresetCustom, preset_data);
6260
app->txrx->txrx_state = WSTxRxStateIDLE;
6361
}
6462

6563
uint32_t ws_rx(WeatherStationApp* app, uint32_t frequency) {
6664
furi_assert(app);
67-
if(!furi_hal_subghz_is_frequency_valid(frequency)) {
65+
if(!subghz_devices_is_frequency_valid(app->txrx->radio_device, frequency)) {
6866
furi_crash("WeatherStation: Incorrect RX frequency.");
6967
}
7068
furi_assert(
7169
app->txrx->txrx_state != WSTxRxStateRx && app->txrx->txrx_state != WSTxRxStateSleep);
7270

73-
furi_hal_subghz_idle();
74-
uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency);
75-
furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow);
76-
furi_hal_subghz_flush_rx();
77-
furi_hal_subghz_rx();
71+
subghz_devices_idle(app->txrx->radio_device);
72+
uint32_t value = subghz_devices_set_frequency(app->txrx->radio_device, frequency);
73+
subghz_devices_flush_rx(app->txrx->radio_device);
74+
subghz_devices_set_rx(app->txrx->radio_device);
75+
76+
subghz_devices_start_async_rx(
77+
app->txrx->radio_device, subghz_worker_rx_callback, app->txrx->worker);
7878

79-
furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, app->txrx->worker);
8079
subghz_worker_start(app->txrx->worker);
8180
app->txrx->txrx_state = WSTxRxStateRx;
8281
return value;
@@ -85,7 +84,7 @@ uint32_t ws_rx(WeatherStationApp* app, uint32_t frequency) {
8584
void ws_idle(WeatherStationApp* app) {
8685
furi_assert(app);
8786
furi_assert(app->txrx->txrx_state != WSTxRxStateSleep);
88-
furi_hal_subghz_idle();
87+
subghz_devices_idle(app->txrx->radio_device);
8988
app->txrx->txrx_state = WSTxRxStateIDLE;
9089
}
9190

@@ -94,15 +93,15 @@ void ws_rx_end(WeatherStationApp* app) {
9493
furi_assert(app->txrx->txrx_state == WSTxRxStateRx);
9594
if(subghz_worker_is_running(app->txrx->worker)) {
9695
subghz_worker_stop(app->txrx->worker);
97-
furi_hal_subghz_stop_async_rx();
96+
subghz_devices_stop_async_rx(app->txrx->radio_device);
9897
}
99-
furi_hal_subghz_idle();
98+
subghz_devices_idle(app->txrx->radio_device);
10099
app->txrx->txrx_state = WSTxRxStateIDLE;
101100
}
102101

103102
void ws_sleep(WeatherStationApp* app) {
104103
furi_assert(app);
105-
furi_hal_subghz_sleep();
104+
subghz_devices_sleep(app->txrx->radio_device);
106105
app->txrx->txrx_state = WSTxRxStateSleep;
107106
}
108107

@@ -125,7 +124,7 @@ void ws_hopper_update(WeatherStationApp* app) {
125124
float rssi = -127.0f;
126125
if(app->txrx->hopper_state != WSHopperStateRSSITimeOut) {
127126
// See RSSI Calculation timings in CC1101 17.3 RSSI
128-
rssi = furi_hal_subghz_get_rssi();
127+
rssi = subghz_devices_get_rssi(app->txrx->radio_device);
129128

130129
// Stay if RSSI is high enough
131130
if(rssi > -90.0f) {

applications/external/weather_station/weather_station_app_i.h

+3
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@
2020
#include <lib/subghz/transmitter.h>
2121
#include <lib/subghz/registry.h>
2222

23+
#include "helpers/radio_device_loader.h"
24+
2325
typedef struct WeatherStationApp WeatherStationApp;
2426

2527
struct WeatherStationTxRx {
2628
SubGhzWorker* worker;
2729

30+
const SubGhzDevice* radio_device;
2831
SubGhzEnvironment* environment;
2932
SubGhzReceiver* receiver;
3033
SubGhzRadioPreset* preset;

0 commit comments

Comments
 (0)