Compare commits

...

4 Commits

Author SHA1 Message Date
Netro 175e5e2e8c BLE: Minor improvements to fix occasional not start on tx app first time. (#1605) 2023-11-27 21:59:29 +01:00
Mark Thompson 7bc27038be Save Morse app settings (#1602) 2023-11-26 12:17:23 +01:00
Brumi-2021 609bf3219f solve Morse_TX_App latch up in r9 (#1601) 2023-11-25 01:01:52 +01:00
Mark Thompson bdbd616a84 added a frequency field to the ERT app 2023-11-24 09:25:50 +01:00
6 changed files with 113 additions and 71 deletions
+26 -19
View File
@@ -167,6 +167,9 @@ void BLETxView::toggle() {
}
void BLETxView::start() {
baseband::run_image(portapack::spi_flash::image_tag_btle_tx);
transmitter_model.enable();
int randomChannel = channel_number;
if (auto_channel) {
@@ -192,27 +195,19 @@ void BLETxView::start() {
return;
}
transmitter_model.enable();
button_play.set_bitmap(&bitmap_stop);
is_running = true;
}
// Send next packet.
// Setup next packet configuration.
progressbar.set_max(packets[current_packet].packet_count);
baseband::set_btletx(randomChannel, random_mac ? randomMac : packets[current_packet].macAddress, packets[current_packet].advertisementData, pduType);
is_sending = true;
if ((packet_counter % 10) == 0) {
text_packets_sent.set(to_string_dec_uint(packet_counter));
}
packet_counter--;
progressbar.set_value(packets[current_packet].packet_count - packet_counter);
}
void BLETxView::stop() {
transmitter_model.disable();
baseband::shutdown();
progressbar.set_value(0);
button_play.set_bitmap(&bitmap_play);
check_loop.set_value(false);
@@ -222,30 +217,39 @@ void BLETxView::stop() {
is_running = false;
}
void BLETxView::reset() {
transmitter_model.disable();
baseband::shutdown();
start();
}
// called each 1/60th of second, so 6 = 100ms
void BLETxView::on_timer() {
if (++mscounter == timer_period) {
mscounter = 0;
if (is_active() && !is_sending) {
if (is_active()) {
// Reached end of current packet repeats.
if (packet_counter == 0) {
// Done sending all packets.
if (current_packet == (num_packets - 1)) {
current_packet = 0;
// If looping, restart from beginning.
if (check_loop.value()) {
update_current_packet(packets[current_packet], 0);
start();
update_current_packet(packets[current_packet], current_packet);
reset();
} else {
stop();
}
} else {
current_packet++;
update_current_packet(packets[current_packet], current_packet);
start();
reset();
}
} else {
start();
reset();
}
}
}
@@ -254,15 +258,18 @@ void BLETxView::on_timer() {
void BLETxView::on_tx_progress(const bool done) {
if (done) {
if (is_active()) {
is_sending = false;
if ((packet_counter % 10) == 0) {
text_packets_sent.set(to_string_dec_uint(packet_counter));
}
packet_counter--;
progressbar.set_value(packets[current_packet].packet_count - packet_counter);
}
}
}
BLETxView::BLETxView(NavigationView& nav)
: nav_{nav} {
baseband::run_image(portapack::spi_flash::image_tag_btle_tx);
add_children({&button_open,
&text_filename,
&progressbar,
+1 -1
View File
@@ -108,6 +108,7 @@ class BLETxView : public View {
void toggle();
void start();
void stop();
void reset();
void handle_replay_thread_done(const uint32_t return_code);
void file_error();
bool saveFile(const std::filesystem::path& path);
@@ -142,7 +143,6 @@ class BLETxView : public View {
char randomMac[13] = "010203040506";
bool is_running = false;
bool is_sending = false;
uint64_t timer_count{0};
int16_t timer_period{1};
bool repeatLoop = false;
+12 -4
View File
@@ -65,9 +65,13 @@ std::string commodity_type(CommodityType value) {
} /* namespace ert */
void ERTLogger::on_packet(const ert::Packet& packet) {
void ERTLogger::on_packet(const ert::Packet& packet, const uint32_t target_frequency) {
const auto formatted = packet.symbols_formatted();
std::string entry = ert::format::type(packet.type()) + " " + formatted.data + "/" + formatted.errors;
// TODO: function doesn't take uint64_t, so when >= 1<<32, weirdness will ensue!
const auto target_frequency_str = to_string_dec_uint(target_frequency, 10);
std::string entry = target_frequency_str + " " + ert::format::type(packet.type()) + " " + formatted.data + "/" + formatted.errors;
log_file.write_entry(packet.received_at(), entry);
}
@@ -99,10 +103,12 @@ void RecentEntriesTable<ERTRecentEntries>::draw(
painter.draw_string(target_rect.location(), style, line);
}
ERTAppView::ERTAppView(NavigationView&) {
ERTAppView::ERTAppView(NavigationView& nav)
: nav_{nav} {
baseband::run_image(portapack::spi_flash::image_tag_ert);
add_children({
&field_frequency,
&field_rf_amp,
&field_lna,
&field_vga,
@@ -110,6 +116,8 @@ ERTAppView::ERTAppView(NavigationView&) {
&recent_entries_view,
});
field_frequency.set_step(1000000);
receiver_model.enable();
logger = std::make_unique<ERTLogger>();
@@ -134,7 +142,7 @@ void ERTAppView::set_parent_rect(const Rect new_parent_rect) {
void ERTAppView::on_packet(const ert::Packet& packet) {
if (logger) {
logger->on_packet(packet);
logger->on_packet(packet, receiver_model.target_frequency());
}
if (packet.crc_ok()) {
+7 -1
View File
@@ -24,6 +24,7 @@
#include "ui_navigation.hpp"
#include "ui_receiver.hpp"
#include "ui_freq_field.hpp"
#include "ui_rssi.hpp"
#include "ui_channel.hpp"
@@ -95,7 +96,7 @@ class ERTLogger {
return log_file.append(filename);
}
void on_packet(const ert::Packet& packet);
void on_packet(const ert::Packet& packet, const uint32_t target_frequency);
private:
LogFile log_file{};
@@ -126,6 +127,7 @@ class ERTAppView : public View {
ERTRecentEntries recent{};
std::unique_ptr<ERTLogger> logger{};
NavigationView& nav_;
RxRadioState radio_state_{
911600000 /* frequency */,
2500000 /* bandwidth */,
@@ -143,6 +145,10 @@ class ERTAppView : public View {
static constexpr auto header_height = 1 * 16;
RxFrequencyField field_frequency{
{5 * 8, 0 * 16},
nav_};
RFAmpField field_rf_amp{
{13 * 8, 0 * 16}};
+42 -22
View File
@@ -56,13 +56,23 @@ static msg_t ookthread_fn(void* arg) {
v = (symbol < 2) ? 1 : 0; // TX on for dot or dash, off for pause
delay = morse_symbols[symbol];
gpio_og_tx.write(v);
if (hackrf_r9) { // r9 has a common PIN 54 for MODE CONTROL TX / RX, <=r6 has two independent MODE CONTROL pins (TX and RX)
gpio_r9_rx.write(!v); // in hackrf r9 opposite logic "0" means tx , "1" rx = no tx)
} else {
gpio_og_tx.write(v); // in hackrf <=r6, "1" means tx , "0" no tx.
}
arg_c->on_tx_progress(i, false);
chThdSleepMilliseconds(delay * arg_c->time_unit_ms);
}
gpio_og_tx.write(0); // Ensure TX is off
if (hackrf_r9) { // r9 has a common PIN 54 for MODE CONTROL TX / RX, <=r6 has two independent MODE CONTROL pins (TX and RX)
gpio_r9_rx.write(1); // Hackrf_r9 , common pin, rx="1" (we ensure TX is off) / tx="0"
} else {
gpio_og_tx.write(0); // Hackrf <=r6 independent TX / RX pins ,now touching the tx pin ==> Ensure TX is off
}
arg_c->on_tx_progress(0, true);
chThdExit(0);
@@ -121,9 +131,9 @@ bool MorseView::start_tx() {
transmitter_model.set_baseband_bandwidth(1'750'000); // Min TX LPF .already tested in FM morse max tone 9,999k , max dev 150khz
transmitter_model.enable();
if (modulation == CW) {
if (mode_cw) {
ookthread = chThdCreateStatic(ookthread_wa, sizeof(ookthread_wa), NORMALPRIO + 10, ookthread_fn, this);
} else if (modulation == FM) {
} else {
baseband::set_tones_config(transmitter_model.channel_bandwidth(), 0, symbol_count, false, false);
}
@@ -133,8 +143,8 @@ bool MorseView::start_tx() {
void MorseView::update_tx_duration() {
uint32_t duration_ms;
time_unit_ms = 1200 / field_speed.value();
symbol_count = morse_encode(message, time_unit_ms, field_tone.value(), &time_units);
time_unit_ms = 1200 / speed;
symbol_count = morse_encode(message, time_unit_ms, tone, &time_units);
if (symbol_count) {
duration_ms = time_units * time_unit_ms;
@@ -175,7 +185,7 @@ void MorseView::on_loop_progress(const uint32_t progress, const bool done) {
}
void MorseView::set_foxhunt(size_t i) {
message = foxhunt_codes[i];
message = foxhunt_codes[i - 1];
buffer = message.c_str();
text_message.set(message);
update_tx_duration();
@@ -188,7 +198,7 @@ MorseView::MorseView(
add_children({&labels,
&checkbox_foxhunt,
&options_foxhunt,
&field_foxhunt,
&field_speed,
&field_tone,
&options_modulation,
@@ -200,36 +210,46 @@ MorseView::MorseView(
&tx_view});
// Default settings
field_speed.set_value(15); // 15wps
field_tone.set_value(700); // 700Hz FM tone
options_modulation.set_selected_index(0); // CW mode
options_loop.set_selected_index(0); // Off
field_speed.set_value(speed);
field_tone.set_value(tone);
options_modulation.set_by_value(mode_cw);
options_loop.set_by_value(loop);
checkbox_foxhunt.set_value(foxhunt_mode);
field_foxhunt.set_value(foxhunt_code);
checkbox_foxhunt.on_select = [this](Checkbox&, bool value) {
foxhunt_mode = value;
if (foxhunt_mode)
set_foxhunt(options_foxhunt.selected_index_value());
set_foxhunt(foxhunt_code);
};
options_foxhunt.on_change = [this](size_t i, int32_t) {
field_foxhunt.on_change = [this](int32_t value) {
foxhunt_code = value;
if (foxhunt_mode)
set_foxhunt(i);
set_foxhunt(foxhunt_code);
};
options_modulation.on_change = [this](size_t i, int32_t) {
modulation = (modulation_t)i;
};
options_loop.on_change = [this](size_t i, uint32_t n) {
options_modulation.on_change = [this](size_t i, int32_t value) {
(void)i; // avoid unused warning
loop = n;
mode_cw = (bool)value;
};
field_speed.on_change = [this](int32_t) {
options_loop.on_change = [this](size_t i, uint32_t value) {
(void)i; // avoid unused warning
loop = value;
};
field_speed.on_change = [this](int32_t value) {
speed = value;
update_tx_duration();
};
field_tone.on_change = [this](int32_t value) {
tone = value;
};
button_message.on_select = [this, &nav](Button&) {
this->on_set_text(nav);
};
+25 -24
View File
@@ -65,7 +65,6 @@ class MorseView : public View {
private:
NavigationView& nav_;
std::string buffer{"PORTAPACK"};
std::string message{};
uint32_t time_units{0};
@@ -74,14 +73,25 @@ class MorseView : public View {
1750000 /* bandwidth */,
1536000 /* sampling rate */
};
app_settings::SettingsManager settings_{
"tx_morse", app_settings::Mode::TX};
enum modulation_t {
CW = 0,
FM = 1
};
modulation_t modulation{CW};
std::string buffer{"PORTAPACK"};
bool mode_cw{true};
bool foxhunt_mode{false};
uint32_t foxhunt_code{1};
uint32_t speed{15};
uint32_t tone{700};
app_settings::SettingsManager settings_{
"tx_morse",
app_settings::Mode::TX,
{
{"message"sv, &buffer},
{"foxhunt"sv, &foxhunt_mode},
{"foxhunt_code"sv, &foxhunt_code},
{"speed"sv, &speed},
{"tone"sv, &tone},
{"mode_cw"sv, &mode_cw},
{"loop"sv, &loop},
}};
bool start_tx();
void update_tx_duration();
@@ -90,7 +100,6 @@ class MorseView : public View {
Thread* ookthread{nullptr};
Thread* loopthread{nullptr};
bool foxhunt_mode{false};
bool run{false};
Labels labels{
@@ -104,20 +113,12 @@ class MorseView : public View {
{4 * 8, 16},
8,
"Foxhunt:"};
OptionsField options_foxhunt{
NumberField field_foxhunt{
{17 * 8, 16 + 4},
7,
{{"1 (MOE)", 0},
{"2 (MOI)", 1},
{"3 (MOS)", 2},
{"4 (MOH)", 3},
{"5 (MO5)", 4},
{"6 (MON)", 5},
{"7 (MOD)", 6},
{"8 (MOB)", 7},
{"9 (MO6)", 8},
{"X (MO) ", 9},
{"T (S) ", 10}}};
2,
{1, 11},
1,
' '};
NumberField field_speed{
{10 * 8, 6 * 8},
@@ -136,8 +137,8 @@ class MorseView : public View {
OptionsField options_modulation{
{15 * 8, 10 * 8},
2,
{{"CW", 0},
{"FM", 1}}};
{{"CW", true},
{"FM", false}}};
OptionsField options_loop{
{9 * 8, 12 * 8},