New approach to support RX-only mode more cleanly (#2908)

* Add enabled checks in ReceiverModel and TransmitterModel

* Move TX limit logic to TransmitterModel from radio API

* Add TX disable functionality and UI
This commit is contained in:
Harin Lee
2026-01-07 13:29:56 +09:00
committed by GitHub
parent 3d979a613a
commit 93799bde6d
10 changed files with 103 additions and 39 deletions
+5 -2
View File
@@ -315,17 +315,20 @@ SetTXLimitView::SetTXLimitView(NavigationView& nav) {
add_children({
&labels,
&tx_gain_max_db,
&tx_disable_switch,
&tx_amp_disable_switch,
&button_save,
&button_cancel,
});
tx_gain_max_db.set_value(pmem::config_tx_gain_max_db());
tx_disable_switch.set_value(pmem::config_tx_disabled());
tx_amp_disable_switch.set_value(pmem::config_tx_amp_disabled());
tx_gain_max_db.set_value(pmem::config_tx_gain_max_db());
button_save.on_select = [&nav, this](Button&) {
pmem::set_config_tx_gain_max_db(tx_gain_max_db.value());
pmem::set_config_tx_disabled(tx_disable_switch.value());
pmem::set_config_tx_amp_disabled(tx_amp_disable_switch.value());
pmem::set_config_tx_gain_max_db(tx_gain_max_db.value());
send_system_refresh();
nav.pop();
};
+12 -7
View File
@@ -277,23 +277,28 @@ class SetTXLimitView : public View {
{{1 * 8, 1 * 16}, "Limits RF TX Gain", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "(This may affect", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 3 * 16}, "all applications.)", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 8 * 16}, "TX Gain (Max):", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 12 * 16}, "TX Max Gain:", Theme::getInstance()->fg_light->foreground},
};
Checkbox tx_disable_switch{
{1 * 8, 6 * 16},
23,
"Disable TX"};
Checkbox tx_amp_disable_switch{
{1 * 8, 8 * 16},
23,
"Disable TX Amp"};
NumberField tx_gain_max_db{
{20 * 8, 8 * 16},
{20 * 8, 12 * 16},
6,
{0, 47},
1,
' ',
};
Checkbox tx_amp_disable_switch{
{1 * 8, 12 * 16},
23,
"Disable TX Amp"};
Button button_save{
{UI_POS_X_CENTER(12) - UI_POS_WIDTH(8), UI_POS_Y_BOTTOM(4), UI_POS_WIDTH(12), UI_POS_HEIGHT(2)},
"Save"};
+4 -10
View File
@@ -42,8 +42,6 @@ using namespace hackrf::one;
#include "portapack.hpp"
#include "portapack_persistent_memory.hpp"
#include <algorithm>
/* Direct access to the radio. Setting values incorrectly can damage
* the device. Applications should use ReceiverModel or TransmitterModel
* instead of calling these functions directly. */
@@ -152,14 +150,10 @@ void set_direction(const rf::Direction new_direction) {
baseband_codec.set_mode((direction == rf::Direction::Transmit) ? max5864::Mode::Transmit : max5864::Mode::Receive);
if (direction == rf::Direction::Receive) {
if (direction == rf::Direction::Receive)
led_rx.on();
} else {
if (portapack::persistent_memory::config_tx_amp_disabled())
rf_path.set_rf_amp(false);
else
led_tx.on();
}
}
bool set_tuning_frequency(const rf::Frequency frequency) {
@@ -211,7 +205,7 @@ bool set_tuning_frequency(const rf::Frequency frequency) {
}
void set_rf_amp(const bool rf_amp) {
rf_path.set_rf_amp(rf_amp && (direction != rf::Direction::Transmit || !portapack::persistent_memory::config_tx_amp_disabled()));
rf_path.set_rf_amp(rf_amp);
}
void set_lna_gain(const int_fast8_t db) {
@@ -223,7 +217,7 @@ void set_vga_gain(const int_fast8_t db) {
}
void set_tx_gain(const int_fast8_t db) {
second_if->set_tx_vga_gain(std::min(static_cast<int8_t>(db), portapack::persistent_memory::config_tx_gain_max_db()));
second_if->set_tx_vga_gain(db);
}
void set_baseband_filter_bandwidth_rx(const uint32_t bandwidth_minimum) {
+18 -7
View File
@@ -303,7 +303,8 @@ int32_t ReceiverModel::tuning_offset() {
void ReceiverModel::update_tuning_frequency() {
// TODO: use positive offset if freq < offset.
radio::set_tuning_frequency(target_frequency() + hidden_offset + tuning_offset());
if (enabled_)
radio::set_tuning_frequency(target_frequency() + hidden_offset + tuning_offset());
}
void ReceiverModel::set_hidden_offset(rf::Frequency offset) {
@@ -312,7 +313,8 @@ void ReceiverModel::set_hidden_offset(rf::Frequency offset) {
}
void ReceiverModel::update_baseband_bandwidth() {
radio::set_baseband_filter_bandwidth_rx(baseband_bandwidth());
if (enabled_)
radio::set_baseband_filter_bandwidth_rx(baseband_bandwidth());
}
void ReceiverModel::update_sampling_rate() {
@@ -321,23 +323,31 @@ void ReceiverModel::update_sampling_rate() {
// protocols that need quick RX/TX turn-around.
// Disabling baseband while changing sampling rates seems like a good idea...
radio::set_baseband_rate(sampling_rate());
if (enabled_)
radio::set_baseband_rate(sampling_rate());
update_tuning_frequency();
}
void ReceiverModel::update_lna() {
radio::set_lna_gain(lna());
if (enabled_)
radio::set_lna_gain(lna());
}
void ReceiverModel::update_vga() {
radio::set_vga_gain(vga());
if (enabled_)
radio::set_vga_gain(vga());
}
void ReceiverModel::update_rf_amp() {
radio::set_rf_amp(rf_amp());
if (enabled_)
radio::set_rf_amp(rf_amp());
}
void ReceiverModel::update_modulation() {
if (!enabled_)
return;
switch (modulation()) {
default:
case Mode::AMAudio:
@@ -392,5 +402,6 @@ void ReceiverModel::update_antenna_bias() {
}
void ReceiverModel::update_headphone_volume() {
audio::headphone::set_volume(headphone_volume());
if (enabled_)
audio::headphone::set_volume(headphone_volume());
}
+23 -7
View File
@@ -31,6 +31,8 @@
#include "portapack_persistent_memory.hpp"
#include "radio.hpp"
#include <algorithm>
using namespace hackrf::one;
using namespace portapack;
@@ -70,7 +72,7 @@ void TransmitterModel::set_channel_bandwidth(uint32_t v) {
}
uint8_t TransmitterModel::tx_gain() const {
return settings_.tx_gain_db;
return std::min(settings_.tx_gain_db, portapack::persistent_memory::config_tx_gain_max_db());
}
void TransmitterModel::set_tx_gain(uint8_t v_db) {
@@ -79,7 +81,7 @@ void TransmitterModel::set_tx_gain(uint8_t v_db) {
}
bool TransmitterModel::rf_amp() const {
return settings_.rf_amp;
return settings_.rf_amp && !portapack::persistent_memory::config_tx_amp_disabled();
}
void TransmitterModel::set_rf_amp(bool enabled) {
@@ -92,6 +94,15 @@ void TransmitterModel::set_antenna_bias() {
}
void TransmitterModel::enable() {
if (portapack::persistent_memory::config_tx_disabled()) {
radio::disable();
TXDisabledMessage message;
EventDispatcher::send_message(message);
return;
}
enabled_ = true;
radio::set_direction(rf::Direction::Transmit);
update_tuning_frequency();
@@ -133,11 +144,13 @@ void TransmitterModel::configure_from_app_settings(
}
void TransmitterModel::update_tuning_frequency() {
radio::set_tuning_frequency(target_frequency());
if (enabled_)
radio::set_tuning_frequency(target_frequency());
}
void TransmitterModel::update_baseband_bandwidth() {
radio::set_baseband_filter_bandwidth_tx(baseband_bandwidth());
if (enabled_)
radio::set_baseband_filter_bandwidth_tx(baseband_bandwidth());
}
void TransmitterModel::update_sampling_rate() {
@@ -146,17 +159,20 @@ void TransmitterModel::update_sampling_rate() {
// protocols that need quick RX/TX turn-around.
// Disabling baseband while changing sampling rates seems like a good idea...
if (enabled_)
radio::set_baseband_rate(sampling_rate());
radio::set_baseband_rate(sampling_rate());
update_tuning_frequency();
}
void TransmitterModel::update_tx_gain() {
radio::set_tx_gain(tx_gain());
if (enabled_)
radio::set_tx_gain(tx_gain());
}
void TransmitterModel::update_rf_amp() {
radio::set_rf_amp(rf_amp());
if (enabled_)
radio::set_rf_amp(rf_amp());
}
void TransmitterModel::update_antenna_bias() {
+8
View File
@@ -320,6 +320,14 @@ SystemStatusView::SystemStatusView(
refresh();
}
void SystemStatusView::on_tx_disabled() {
if (!nav_.is_valid())
return;
nav_.pop();
nav_.display_modal("Error", "RF transmit disabled.\nApplication closed.");
}
// when battery icon / text is clicked
void SystemStatusView::on_battery_details() {
if (!nav_.is_valid()) return;
+8
View File
@@ -303,6 +303,7 @@ class SystemStatusView : public View {
void on_title();
void refresh();
void on_clk();
void on_tx_disabled();
void rtc_battery_workaround();
void on_battery_data(const BatteryStateMessage* msg);
void on_battery_details();
@@ -314,6 +315,13 @@ class SystemStatusView : public View {
this->refresh();
}};
MessageHandlerRegistration message_handler_tx_disabled{
Message::ID::TXDisabled,
[this](const Message* const p) {
(void)p;
this->on_tx_disabled();
}};
MessageHandlerRegistration message_handler_battery{
Message::ID::BatteryStateData,
[this](const Message* const p) {
+8
View File
@@ -146,6 +146,7 @@ class Message {
SSTVRXPhaseSlant = 88,
SSTVRXCalibration = 89,
SubCarData = 90,
TXDisabled = 91,
MAX
};
@@ -1699,4 +1700,11 @@ class SubCarDataMessage : public Message {
uint64_t data2 = 0;
};
class TXDisabledMessage : public Message {
public:
constexpr TXDisabledMessage()
: Message{ID::TXDisabled} {
}
};
#endif /*__MESSAGE_H__*/
@@ -152,10 +152,10 @@ struct misc_config_t {
bool config_sdcard_high_speed_io : 1;
bool config_disable_config_mode : 1;
bool beep_on_packets : 1;
bool tx_disabled : 1;
bool tx_amp_disabled : 1;
bool UNUSED_7 : 1;
int8_t tx_gain_max_db;
uint8_t tx_gain_max_db;
uint8_t PLACEHOLDER_1;
uint8_t PLACEHOLDER_2;
};
@@ -442,6 +442,7 @@ void defaults() {
set_config_sdcard_high_speed_io(false, true);
set_config_tx_disabled(false);
set_config_tx_amp_disabled(false);
set_config_tx_gain_max_db(47);
}
@@ -652,11 +653,15 @@ bool config_sdcard_high_speed_io() {
return data->misc_config.config_sdcard_high_speed_io;
}
bool config_tx_disabled() {
return data->misc_config.tx_disabled;
}
bool config_tx_amp_disabled() {
return data->misc_config.tx_amp_disabled;
}
int8_t config_tx_gain_max_db() {
uint8_t config_tx_gain_max_db() {
return data->misc_config.tx_gain_max_db;
}
@@ -754,11 +759,15 @@ void set_config_sdcard_high_speed_io(bool v, bool save) {
data->misc_config.config_sdcard_high_speed_io = v;
}
void set_config_tx_disabled(bool v) {
data->misc_config.tx_disabled = v;
}
void set_config_tx_amp_disabled(bool v) {
data->misc_config.tx_amp_disabled = v;
}
void set_config_tx_gain_max_db(int8_t v) {
void set_config_tx_gain_max_db(uint8_t v) {
data->misc_config.tx_gain_max_db = v;
}
@@ -203,8 +203,9 @@ bool config_disable_external_tcxo();
bool config_sdcard_high_speed_io();
bool config_disable_config_mode();
bool beep_on_packets();
bool config_tx_disabled();
bool config_tx_amp_disabled();
int8_t config_tx_gain_max_db();
uint8_t config_tx_gain_max_db();
bool config_splash();
bool config_converter();
@@ -228,8 +229,9 @@ void set_config_disable_external_tcxo(bool v);
void set_config_sdcard_high_speed_io(bool v, bool save);
void set_config_disable_config_mode(bool v);
void set_beep_on_packets(bool v);
void set_config_tx_disabled(bool v);
void set_config_tx_amp_disabled(bool v);
void set_config_tx_gain_max_db(int8_t v);
void set_config_tx_gain_max_db(uint8_t v);
void set_config_splash(bool v);
bool config_converter();