diff --git a/firmware/application/apps/ui_mictx.cpp b/firmware/application/apps/ui_mictx.cpp index c7b47c35..e72e63a0 100644 --- a/firmware/application/apps/ui_mictx.cpp +++ b/firmware/application/apps/ui_mictx.cpp @@ -130,9 +130,9 @@ void MicTXView::set_tx(bool enable) { portapack::pin_i2s0_rx_sda.mode(3); // This is already done in audio::init but gets changed by the CPLD overlay reprogramming } else { if (transmitting && rogerbeep_enabled) { - baseband::request_beep(); // Transmit the roger beep - transmitting = false; // And flag the end of the transmission so ... - } else { // (if roger beep was enabled, this will be executed after the beep ends transmitting. + baseband::request_roger_beep(); // Transmit the roger beep + transmitting = false; // Flag the end of the transmission (transmitter will be disabled after the beep) + } else { transmitting = false; configure_baseband(); transmitter_model.disable(); diff --git a/firmware/application/apps/ui_sonde.cpp b/firmware/application/apps/ui_sonde.cpp index 25bac356..499bd39e 100644 --- a/firmware/application/apps/ui_sonde.cpp +++ b/firmware/application/apps/ui_sonde.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. * Copyright (C) 2017 Furrtek + * Copyright (C) 2024 Mark Thompson * * This file is part of PortaPack. * @@ -70,16 +71,19 @@ SondeView::SondeView(NavigationView& nav) geopos.set_read_only(true); + check_beep.set_value(beep); check_beep.on_select = [this](Checkbox&, bool v) { beep = v; - if (v) - baseband::request_beep(); + if (beep) + baseband::request_audio_beep(1000, 60); // 1khz tone for 60ms to acknowledge enablement }; + check_log.set_value(logging); check_log.on_select = [this](Checkbox&, bool v) { logging = v; }; + check_crc.set_value(use_crc); check_crc.on_select = [this](Checkbox&, bool v) { use_crc = v; }; @@ -222,7 +226,7 @@ void SondeView::on_packet(const sonde::Packet& packet) { } if (beep) { - baseband::request_beep(); + baseband::request_rssi_beep(); } } } diff --git a/firmware/application/apps/ui_sonde.hpp b/firmware/application/apps/ui_sonde.hpp index aa5e3e34..718a8dc9 100644 --- a/firmware/application/apps/ui_sonde.hpp +++ b/firmware/application/apps/ui_sonde.hpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. * Copyright (C) 2017 Furrtek + * Copyright (C) 2024 Mark Thompson * * This file is part of PortaPack. * @@ -74,13 +75,19 @@ class SondeView : public View { 1750000 /* bandwidth */, 2457600 /* sampling rate */ }; - app_settings::SettingsManager settings_{ - "rx_sonde", app_settings::Mode::RX}; - - std::unique_ptr logger{}; + bool beep{false}; bool logging{false}; bool use_crc{false}; - bool beep{false}; + app_settings::SettingsManager settings_{ + "rx_sonde", + app_settings::Mode::RX, + { + {"beep"sv, &beep}, + {"logging"sv, &logging}, + {"use_crc"sv, &use_crc}, + }}; + + std::unique_ptr logger{}; char geo_uri[32] = {}; diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 45289125..0095189d 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -428,8 +428,25 @@ void replay_stop() { send_message(&message); } -void request_beep() { - RequestSignalMessage message{RequestSignalMessage::Signal::BeepRequest}; +void request_beep(RequestSignalMessage::Signal beep_type) { + RequestSignalMessage message{beep_type}; + send_message(&message); +} + +void request_roger_beep() { + request_beep(RequestSignalMessage::Signal::RogerBeepRequest); +} + +void request_rssi_beep() { + request_beep(RequestSignalMessage::Signal::RSSIBeepRequest); +} + +void request_beep_stop() { + request_beep(RequestSignalMessage::Signal::BeepStopRequest); +} + +void request_audio_beep(uint32_t freq, uint32_t duration_ms) { + AudioBeepMessage message{freq, duration_ms}; send_message(&message); } diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index 48428f7e..50e2282e 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -89,7 +89,11 @@ void set_siggen_tone(const uint32_t tone); void set_siggen_config(const uint32_t bw, const uint32_t shape, const uint32_t duration); void set_spectrum_painter_config(const uint16_t width, const uint16_t height, bool update, int32_t bw); void set_subghzd_config(uint8_t modulation, uint32_t sampling_rate); -void request_beep(); + +void request_roger_beep(); +void request_rssi_beep(); +void request_beep_stop(); +void request_audio_beep(uint32_t freq, uint32_t duration_ms); void run_image(const portapack::spi_flash::image_tag_t image_tag); void run_prepared_image(const uint32_t m4_code); diff --git a/firmware/baseband/proc_mictx.cpp b/firmware/baseband/proc_mictx.cpp index 9f0d3771..b2705d03 100644 --- a/firmware/baseband/proc_mictx.cpp +++ b/firmware/baseband/proc_mictx.cpp @@ -155,7 +155,7 @@ void MicTXProcessor::on_message(const Message* const msg) { break; case Message::ID::RequestSignal: - if (request_message.signal == RequestSignalMessage::Signal::BeepRequest) { + if (request_message.signal == RequestSignalMessage::Signal::RogerBeepRequest) { beep_index = 0; beep_timer = 0; play_beep = true; diff --git a/firmware/baseband/proc_sonde.cpp b/firmware/baseband/proc_sonde.cpp index 1f43be2e..a40359d7 100644 --- a/firmware/baseband/proc_sonde.cpp +++ b/firmware/baseband/proc_sonde.cpp @@ -57,24 +57,15 @@ void SondeProcessor::execute(const buffer_c8_t& buffer) { void SondeProcessor::on_message(const Message* const msg) { switch (msg->id) { case Message::ID::RequestSignal: - if ((*reinterpret_cast(msg)).signal == RequestSignalMessage::Signal::BeepRequest) { - float rssi_ratio = (float)last_rssi / (float)RSSI_CEILING; - uint32_t beep_duration = 0; + on_signal_message(*reinterpret_cast(msg)); + break; - if (rssi_ratio <= PROPORTIONAL_BEEP_THRES) { - beep_duration = BEEP_MIN_DURATION; - } else if (rssi_ratio < 1) { - beep_duration = (int)rssi_ratio * BEEP_DURATION_RANGE + BEEP_MIN_DURATION; - } else { - beep_duration = BEEP_DURATION_RANGE + BEEP_MIN_DURATION; - } - - audio::dma::beep_start(beep_freq, AUDIO_SAMPLE_RATE, beep_duration); - } + case Message::ID::AudioBeep: + on_beep_message(*reinterpret_cast(msg)); break; case Message::ID::PitchRSSIConfigure: - pitch_rssi_config(*reinterpret_cast(msg)); + on_pitch_rssi_config(*reinterpret_cast(msg)); break; default: @@ -82,10 +73,31 @@ void SondeProcessor::on_message(const Message* const msg) { } } -void SondeProcessor::pitch_rssi_config(const PitchRSSIConfigureMessage& message) { +void SondeProcessor::on_signal_message(const RequestSignalMessage& message) { + if (message.signal == RequestSignalMessage::Signal::RSSIBeepRequest) { + float rssi_ratio = (float)last_rssi / RSSI_CEILING; + uint32_t beep_duration = 0; + + if (rssi_ratio <= PROPORTIONAL_BEEP_THRES) { + beep_duration = BEEP_MIN_DURATION; + } else if (rssi_ratio < 1) { + beep_duration = rssi_ratio * BEEP_DURATION_RANGE + BEEP_MIN_DURATION; + } else { + beep_duration = BEEP_DURATION_RANGE + BEEP_MIN_DURATION; + } + + audio::dma::beep_start(beep_freq, AUDIO_SAMPLE_RATE, beep_duration); + } +} + +void SondeProcessor::on_beep_message(const AudioBeepMessage& message) { + audio::dma::beep_start(message.freq, AUDIO_SAMPLE_RATE, message.duration_ms); +} + +void SondeProcessor::on_pitch_rssi_config(const PitchRSSIConfigureMessage& message) { pitch_rssi_enabled = message.enabled; - beep_freq = (int)((float)message.rssi * (float)RSSI_PITCH_WEIGHT + (float)BEEP_BASE_FREQ); + beep_freq = message.rssi * RSSI_PITCH_WEIGHT + BEEP_BASE_FREQ; last_rssi = message.rssi; } diff --git a/firmware/baseband/proc_sonde.hpp b/firmware/baseband/proc_sonde.hpp index 8f9283e3..7b678413 100644 --- a/firmware/baseband/proc_sonde.hpp +++ b/firmware/baseband/proc_sonde.hpp @@ -97,10 +97,12 @@ #define BEEP_MIN_DURATION 60 #define BEEP_DURATION_RANGE 100 -#define BEEP_BASE_FREQ 200 +#define BEEP_BASE_FREQ 400 // Lowest audible freq for some PortaPack speakers +#define BEEP_MAX_FREQ 8000 // Highest audible freq for some PortaPack speakers +#define BEEP_SIMPLE_FREQ 1000 #define RSSI_CEILING 1000 #define PROPORTIONAL_BEEP_THRES 0.8 -#define RSSI_PITCH_WEIGHT 0.5 +#define RSSI_PITCH_WEIGHT (float(BEEP_MAX_FREQ - BEEP_BASE_FREQ) / RSSI_CEILING) #define AUDIO_SAMPLE_RATE 24000 class SondeProcessor : public BasebandProcessor { @@ -168,7 +170,9 @@ class SondeProcessor : public BasebandProcessor { baseband_fs, this, baseband::Direction::Receive, /*auto_start*/ false}; RSSIThread rssi_thread{}; - void pitch_rssi_config(const PitchRSSIConfigureMessage& message); + void on_signal_message(const RequestSignalMessage& message); + void on_beep_message(const AudioBeepMessage& message); + void on_pitch_rssi_config(const PitchRSSIConfigureMessage& message); }; #endif /*__PROC_ERT_H__*/ diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index 717fb50b..1bf4e12d 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -121,6 +121,7 @@ class Message { GPSPosData = 63, OrientationData = 64, EnvironmentData = 65, + AudioBeep = 66, MAX }; @@ -1165,8 +1166,10 @@ class RequestSignalMessage : public Message { public: enum class Signal : char { FillRequest = 1, - BeepRequest = 2, - Squelched = 3 + RogerBeepRequest = 2, + RSSIBeepRequest = 3, + BeepStopRequest = 4, + Squelched = 5, }; constexpr RequestSignalMessage( @@ -1361,4 +1364,16 @@ class EnvironmentDataMessage : public Message { uint16_t light = 0; // lux }; +class AudioBeepMessage : public Message { + public: + constexpr AudioBeepMessage( + uint32_t freq = 1000, + uint32_t duration_ms = 100) + : Message{ID::AudioBeep}, + freq{freq}, + duration_ms{duration_ms} { + } + uint32_t freq = 1000; + uint32_t duration_ms = 100; +}; #endif /*__MESSAGE_H__*/