make siggen ext (#2917)

This commit is contained in:
Totoo
2026-01-10 14:25:41 +01:00
committed by GitHub
parent 133b2d2065
commit 2884bb9ab7
8 changed files with 107 additions and 16 deletions
+6
View File
@@ -276,6 +276,11 @@ set(EXTCPPSRC
#subcarrx
external/subcarrx/main.cpp
external/subcarrx/ui_subcar.cpp
#siggen
external/siggen/main.cpp
external/siggen/ui_siggen.cpp
)
set(EXTAPPLIST
@@ -345,4 +350,5 @@ set(EXTAPPLIST
adult_toys_controller
flex_rx
subcarrx
siggen
)
+7
View File
@@ -89,6 +89,7 @@ MEMORY
ram_external_app_flex_rx (rwx) : org = 0xADF00000, len = 32k
ram_external_app_sstvrx (rwx) : org = 0xADF10000, len = 32k
ram_external_app_subcarrx (rwx) : org = 0xADF20000, len = 32k
ram_external_app_siggen (rwx) : org = 0xADF30000, len = 32k
}
@@ -492,6 +493,12 @@ SECTIONS
*(*ui*external_app*subcarrx*);
} > ram_external_app_subcarrx
.external_app_siggen : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_siggen.application_information));
*(*ui*external_app*siggen*);
} > ram_external_app_siggen
}
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright (C) 2023 Bernd Herzog
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui.hpp"
#include "ui_siggen.hpp"
#include "ui_navigation.hpp"
#include "external_app.hpp"
namespace ui::external_app::siggen {
void initialize_app(ui::NavigationView& nav) {
nav.push<SigGenView>();
}
} // namespace ui::external_app::siggen
extern "C" {
__attribute__((section(".external_app.app_siggen.application_information"), used)) application_information_t _application_information_siggen = {
/*.memory_location = */ (uint8_t*)0x00000000,
/*.externalAppEntry = */ ui::external_app::siggen::initialize_app,
/*.header_version = */ CURRENT_HEADER_VERSION,
/*.app_version = */ VERSION_MD5,
/*.app_name = */ "Signal gen",
/*.bitmap_data = */ {
0x18,
0x00,
0x24,
0x00,
0x42,
0x00,
0x42,
0x00,
0x42,
0x00,
0x42,
0x00,
0x81,
0x00,
0xAB,
0x6A,
0x80,
0x40,
0x00,
0x21,
0x00,
0x21,
0x00,
0x21,
0x00,
0x21,
0x00,
0x12,
0x00,
0x0C,
0x00,
0x00,
},
/*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::TX,
/*.desired_menu_position = */ -1,
/*.m4_app_tag = portapack::spi_flash::image_tag_siggen */ {'P', 'S', 'I', 'G'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
};
}
+175
View File
@@ -0,0 +1,175 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui_siggen.hpp"
#include "tonesets.hpp"
#include "portapack.hpp"
#include "baseband_api.hpp"
#include <cstring>
#include <stdio.h>
using namespace portapack;
namespace ui::external_app::siggen {
void SigGenView::focus() {
options_shape.focus();
}
SigGenView::~SigGenView() {
transmitter_model.disable();
baseband::shutdown();
}
void SigGenView::update_config() {
if (checkbox_stop.value())
baseband::set_siggen_config(transmitter_model.channel_bandwidth(), (options_mod.selected_index_value() << 4) + options_shape.selected_index_value(), field_stop.value());
else
baseband::set_siggen_config(transmitter_model.channel_bandwidth(), (options_mod.selected_index_value() << 4) + options_shape.selected_index_value(), 0);
}
void SigGenView::update_tone() {
baseband::set_siggen_tone(symfield_tone.to_integer());
}
void SigGenView::start_tx() {
transmitter_model.enable();
update_tone();
/*auto duration = field_stop.value();
if (!checkbox_auto.value())
duration = 0;*/
update_config();
}
void SigGenView::on_tx_progress(const uint32_t progress, const bool done) {
(void)progress;
if (done) {
transmitter_model.disable();
tx_view.set_transmitting(false);
}
}
SigGenView::SigGenView(
NavigationView& nav) {
baseband::run_prepared_image(portapack::memory::map::m4_code.base());
add_children({&labels,
&options_mod,
&options_shape,
&text_shape,
&symfield_tone,
&button_update,
&checkbox_auto,
&checkbox_stop,
&field_stop,
&tx_view});
symfield_tone.hidden(true); // At first launch , by default we are in CW: Shape ignored, we are not using Tone modulation.
options_shape.hidden(true);
text_shape.hidden(true);
symfield_tone.set_value(1000); // Default: 1000 Hz
options_shape.on_change = [this](size_t, OptionsField::value_t v) {
text_shape.set(shape_strings[v]);
if (auto_update)
update_config();
if (v == 5) { // In Shape Pseudo Random Noise we are not using Tone modulation freq.
symfield_tone.hidden(true);
} else {
symfield_tone.hidden(false);
}
set_dirty();
};
options_shape.set_selected_index(0);
text_shape.set(shape_strings[0]);
options_mod.on_change = [this](size_t, OptionsField::value_t v) {
if (auto_update)
update_config();
if (v == 0) { // In Modulation Options CW we are not using Tone modulation freq.
symfield_tone.hidden(true);
} else {
symfield_tone.hidden(false);
}
if ((v == 0) || (v == 2) || (v == 3) || (v == 7)) { // In Modulation Options CW, QPSK, BPSK, Pulsed CW we are not using Shapes.
options_shape.hidden(true);
text_shape.hidden(true);
} else {
options_shape.hidden(false);
text_shape.hidden(false);
}
set_dirty();
};
options_mod.set_selected_index(0);
field_stop.set_value(1);
symfield_tone.set_value(1000); // Default: 1000 Hz
symfield_tone.on_change = [this](SymField&) {
if (auto_update)
update_tone();
};
button_update.on_select = [this](Button&) {
update_tone();
update_config();
};
checkbox_auto.on_select = [this](Checkbox&, bool v) {
auto_update = v;
};
tx_view.on_edit_frequency = [this, &nav]() {
auto new_view = nav.push<FrequencyKeypadView>(transmitter_model.target_frequency());
new_view->on_changed = [this](rf::Frequency f) {
transmitter_model.set_target_frequency(f);
};
};
tx_view.on_bandwidth_changed = [this]() {
// we don't protect here with auto_update because other field of tx_view obj isn't protected too
// to remains the design logic same
update_config();
};
tx_view.on_start = [this]() {
start_tx();
tx_view.set_transmitting(true);
};
tx_view.on_stop = [this]() {
transmitter_model.disable();
tx_view.set_transmitting(false);
};
}
} // namespace ui::external_app::siggen
+144
View File
@@ -0,0 +1,144 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __SIGGEN_H__
#define __SIGGEN_H__
#include "app_settings.hpp"
#include "radio_state.hpp"
#include "ui.hpp"
#include "ui_widget.hpp"
#include "ui_navigation.hpp"
#include "ui_transmitter.hpp"
#include "portapack.hpp"
#include "message.hpp"
namespace ui::external_app::siggen {
class SigGenView : public View {
public:
SigGenView(NavigationView& nav);
~SigGenView();
void focus() override;
std::string title() const override { return "Signal gen"; };
private:
void start_tx();
void update_config();
void update_tone();
void on_tx_progress(const uint32_t progress, const bool done);
TxRadioState radio_state_{
0 /* frequency */,
1750000 /* bandwidth */,
1536000 /* sampling rate */
};
app_settings::SettingsManager settings_{
"tx_siggen", app_settings::Mode::TX};
const std::string shape_strings[6] = {// max 15 character text space.
"Sine",
"Triangle",
"Saw up",
"Saw down",
"Square",
"Pseudo Noise"};
bool auto_update{false};
Labels labels{
{{3 * 8, 2 * 8}, "Modulation:", Theme::getInstance()->fg_light->foreground},
{{3 * 8, 3 * 8 + 8 + 10}, "Shape:", Theme::getInstance()->fg_light->foreground},
{{6 * 8, 2 * 8 + 7 * 8}, "Tone: Hz", Theme::getInstance()->fg_light->foreground},
{{22 * 8, 2 * 8 + 15 * 8 + 4}, "s.", Theme::getInstance()->fg_light->foreground}};
ImageOptionsField options_shape{
{10 * 8, 3 * 8 + 8, 32, 32},
Theme::getInstance()->bg_darkest->foreground,
Theme::getInstance()->bg_darkest->background,
{{&bitmap_sig_sine, 0},
{&bitmap_sig_tri, 1},
{&bitmap_sig_saw_up, 2},
{&bitmap_sig_saw_down, 3},
{&bitmap_sig_square, 4},
{&bitmap_sig_noise, 5}}};
Text text_shape{
{15 * 8, 3 * 8 + 8 + 10, 15 * 8, 16},
""};
SymField symfield_tone{
{12 * 8, 2 * 8 + 7 * 8},
5};
Button button_update{
{5 * 8, 2 * 8 + 10 * 8, 8 * 8, 3 * 8},
"Update"};
Checkbox checkbox_auto{
{15 * 8, 2 * 8 + 10 * 8},
4,
"Auto"};
Checkbox checkbox_stop{
{5 * 8, 2 * 8 + 15 * 8},
10,
"Stop after"};
NumberField field_stop{
{20 * 8, 2 * 8 + 15 * 8 + 4},
2,
{1, 99},
1,
' '};
OptionsField options_mod{
{15 * 8, 2 * 8},
12,
{{"CW (No mod.)", 0},
{"FM", 1},
{"BPSK", 2},
{"QPSK", 3},
{"DSB", 4},
{"AM 100% dep.", 5},
{"AM 50% depth", 6},
{"Pulse CW 25%", 7}}};
TransmitterView tx_view{
(int16_t)UI_POS_Y_BOTTOM(4),
10000,
12};
MessageHandlerRegistration message_handler_tx_progress{
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}};
};
} // namespace ui::external_app::siggen
#endif /*__SIGGEN_H__*/