From c27192bdbbba93e3fa26819294acc16973aa6af7 Mon Sep 17 00:00:00 2001 From: Totoo Date: Fri, 6 Feb 2026 09:48:20 +0100 Subject: [PATCH] Flipper fsk tx support (#2964) --- firmware/application/baseband_api.cpp | 5 ++ firmware/application/baseband_api.hpp | 1 + .../external/flippertx/ui_flippertx.cpp | 7 ++- .../external/flippertx/ui_flippertx.hpp | 2 + firmware/baseband/CMakeLists.txt | 6 +-- ..._stream_tx.cpp => proc_bint_stream_tx.cpp} | 47 +++++++++++++------ ..._stream_tx.hpp => proc_bint_stream_tx.hpp} | 10 +++- firmware/common/message.hpp | 12 +++++ 8 files changed, 70 insertions(+), 20 deletions(-) rename firmware/baseband/{proc_ook_stream_tx.cpp => proc_bint_stream_tx.cpp} (71%) rename firmware/baseband/{proc_ook_stream_tx.hpp => proc_bint_stream_tx.hpp} (84%) diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 838968bbc..3dae14a9c 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -383,6 +383,11 @@ void set_morsetx_key(bool key_down) { send_message(&message); } +void set_bitstream_config(uint32_t deviation, uint8_t mode) { + const StreamTXConfigurationMessage message{deviation, mode}; + send_message(&message); +} + static bool baseband_image_running = false; void run_image(const spi_flash::image_tag_t image_tag) { diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index cab673b7c..c0e0b8760 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -108,6 +108,7 @@ void set_morsetx_key(bool key_down); void set_wefax_config(uint8_t lpm, uint8_t ioc); void set_noaaapt_config(); void set_flex_config(); +void set_bitstream_config(uint32_t deviation, uint8_t mode); // mode 0 for am, 1 for 2fsk void request_roger_beep(); void request_rssi_beep(); diff --git a/firmware/application/external/flippertx/ui_flippertx.cpp b/firmware/application/external/flippertx/ui_flippertx.cpp index 03572ed00..45165c380 100644 --- a/firmware/application/external/flippertx/ui_flippertx.cpp +++ b/firmware/application/external/flippertx/ui_flippertx.cpp @@ -80,7 +80,7 @@ bool FlipperTxView::on_file_changed(std::filesystem::path new_file_path) { return false; } preset = submeta.value().preset; - if (preset != FLIPPER_PRESET_OOK) { + if (preset != FLIPPER_PRESET_OOK && preset != FLIPPER_PRESET_2FSK) { field_filename.set_text("File: err, not supp. preset"); return false; } @@ -108,8 +108,13 @@ void FlipperTxView::stop() { bool FlipperTxView::start() { if (filename.empty()) return false; baseband::run_prepared_image(portapack::memory::map::m4_code.base()); + transmitter_model.set_sampling_rate(OOK_SAMPLERATE); transmitter_model.enable(); button_startstop.set_text(LanguageHelper::currentMessages[LANG_STOP]); + uint8_t mode = 0; + if (preset == FLIPPER_PRESET_2FSK) + mode = 1; + baseband::set_bitstream_config(FM_DEVIATION, mode); // start thread replay_thread = std::make_unique( filename, diff --git a/firmware/application/external/flippertx/ui_flippertx.hpp b/firmware/application/external/flippertx/ui_flippertx.hpp index 0f30ab342..9775c5ffa 100644 --- a/firmware/application/external/flippertx/ui_flippertx.hpp +++ b/firmware/application/external/flippertx/ui_flippertx.hpp @@ -28,6 +28,8 @@ using namespace ui; namespace ui::external_app::flippertx { #define OOK_SAMPLERATE 2280000U +#define FM_DEVIATION 60000U + class FlipperPlayThread; class FlipperTxView : public View { public: diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index 363a1eeaa..d4ba69c5d 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -618,12 +618,12 @@ set(MODE_CPPSRC ) DeclareTargets(PADT adsbtx) -### OOKStream +### Binary Timed stream TX set(MODE_CPPSRC - proc_ook_stream_tx.cpp + proc_bint_stream_tx.cpp ) -DeclareTargets(POSK ookstream) +DeclareTargets(POSK bintstream) ### Signal generator diff --git a/firmware/baseband/proc_ook_stream_tx.cpp b/firmware/baseband/proc_bint_stream_tx.cpp similarity index 71% rename from firmware/baseband/proc_ook_stream_tx.cpp rename to firmware/baseband/proc_bint_stream_tx.cpp index a82f413c4..244451aca 100644 --- a/firmware/baseband/proc_ook_stream_tx.cpp +++ b/firmware/baseband/proc_bint_stream_tx.cpp @@ -19,7 +19,7 @@ * Boston, MA 02110-1301, USA. */ -#include "proc_ook_stream_tx.hpp" +#include "proc_bint_stream_tx.hpp" #include "sine_table_int8.hpp" #include "portapack_shared_memory.hpp" @@ -27,27 +27,35 @@ #include "utility.hpp" -OOKProcessorStreamed::OOKProcessorStreamed() { +BinaryTimedProcessorStreamed::BinaryTimedProcessorStreamed() { configured = false; baseband_thread.start(); } -inline void OOKProcessorStreamed::write_sample(const buffer_c8_t& buffer, bool bit_value, size_t i) { - int8_t re, im; - - if (bit_value) { - phase = (phase + 200); // What ? +inline void BinaryTimedProcessorStreamed::write_sample(const buffer_c8_t& buffer, bool bit_value, size_t i) { + int8_t re = 0, im = 0; + if (mode == 0) { + if (bit_value) { + phase = (phase + 200); + sphase = phase + (64 << 18); + re = (sine_table_i8[(sphase & 0x03FC0000) >> 18]); + im = (sine_table_i8[(phase & 0x03FC0000) >> 18]); + } + } else if (mode == 1) { + // calculate the re, im based on the deviation uint32_t variable to get the re, im, to send out 2fsk signal. based on the bit_value + if (bit_value) { + phase += deviation_delta; + } else { + phase -= deviation_delta; + } sphase = phase + (64 << 18); re = (sine_table_i8[(sphase & 0x03FC0000) >> 18]); im = (sine_table_i8[(phase & 0x03FC0000) >> 18]); - } else { - re = 0; - im = 0; } buffer.p[i] = {re, im}; } -void OOKProcessorStreamed::execute(const buffer_c8_t& buffer) { +void BinaryTimedProcessorStreamed::execute(const buffer_c8_t& buffer) { if (!configured || !stream) return; for (size_t i = 0; i < buffer.count; i++) { @@ -87,7 +95,7 @@ void OOKProcessorStreamed::execute(const buffer_c8_t& buffer) { } } -void OOKProcessorStreamed::on_message(const Message* const message) { +void BinaryTimedProcessorStreamed::on_message(const Message* const message) { switch (message->id) { case Message::ID::ReplayConfig: configured = false; @@ -100,12 +108,23 @@ void OOKProcessorStreamed::on_message(const Message* const message) { shared_memory.application_queue.push(txprogress_message); break; + case Message::ID::StreamTXConfiguration: + streamtx_config(*reinterpret_cast(message)); + break; + default: break; } } -void OOKProcessorStreamed::replay_config(const ReplayConfigMessage& message) { +void BinaryTimedProcessorStreamed::streamtx_config(const StreamTXConfigurationMessage& message) { + mode = message.mode; + deviation = message.deviation; + uint64_t big_calc = (uint64_t)message.deviation << 26; + deviation_delta = (uint32_t)(big_calc / OOK_SAMPLERATE); +} + +void BinaryTimedProcessorStreamed::replay_config(const ReplayConfigMessage& message) { if (message.config) { txprogress_message.progress = -2; shared_memory.application_queue.push(txprogress_message); @@ -121,7 +140,7 @@ void OOKProcessorStreamed::replay_config(const ReplayConfigMessage& message) { } int main() { - EventDispatcher event_dispatcher{std::make_unique()}; + EventDispatcher event_dispatcher{std::make_unique()}; event_dispatcher.run(); return 0; } diff --git a/firmware/baseband/proc_ook_stream_tx.hpp b/firmware/baseband/proc_bint_stream_tx.hpp similarity index 84% rename from firmware/baseband/proc_ook_stream_tx.hpp rename to firmware/baseband/proc_bint_stream_tx.hpp index 44c1629e7..09ad51092 100644 --- a/firmware/baseband/proc_ook_stream_tx.hpp +++ b/firmware/baseband/proc_bint_stream_tx.hpp @@ -34,10 +34,11 @@ #include #define OOK_SAMPLERATE 2280000U +#define FM_DEVIATION 60000U -class OOKProcessorStreamed : public BasebandProcessor { +class BinaryTimedProcessorStreamed : public BasebandProcessor { public: - OOKProcessorStreamed(); + BinaryTimedProcessorStreamed(); void execute(const buffer_c8_t& buffer) override; void on_message(const Message* const message) override; @@ -53,6 +54,11 @@ class OOKProcessorStreamed : public BasebandProcessor { std::unique_ptr stream{}; bool configured{false}; void replay_config(const ReplayConfigMessage& message); + void streamtx_config(const StreamTXConfigurationMessage& message); + + uint8_t mode = 0; // am = 0, 2fsk = 1 + uint32_t deviation = FM_DEVIATION; // used in 2fsk + uint32_t deviation_delta = (FM_DEVIATION * 4294967296ULL) / OOK_SAMPLERATE; int32_t endsignals[3] = {0, 42069, 613379}; // 0 is skipped, count from 1, don't ask... uint8_t readerrs = 0; // to count in the array diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index 6e10417cd..376a3e40b 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -152,6 +152,7 @@ class Message { TXDisabled = 94, MorseTXConfigure = 95, MorseTXkey = 96, + StreamTXConfiguration = 97, MAX }; @@ -1758,4 +1759,15 @@ class MorseTXkeyMessage : public Message { bool key_down = false; }; +class StreamTXConfigurationMessage : public Message { + public: + constexpr StreamTXConfigurationMessage(uint32_t deviation, uint8_t mode) + : Message{ID::StreamTXConfiguration}, + deviation{deviation}, + mode{mode} {} + + uint32_t deviation = 60000; // used in 2fsk + uint8_t mode = 0; // am = 0, 2fsk = 1 +}; + #endif /*__MESSAGE_H__*/