diff --git a/firmware/application/apps/capture_app.cpp b/firmware/application/apps/capture_app.cpp index e5b9a36c..07192556 100644 --- a/firmware/application/apps/capture_app.cpp +++ b/firmware/application/apps/capture_app.cpp @@ -35,6 +35,7 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { baseband::run_image(portapack::spi_flash::image_tag_capture); add_children({ + &labels, &rssi, &channel, &field_frequency, @@ -42,6 +43,7 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { &field_rf_amp, &field_lna, &field_vga, + &option_bandwidth, &record_view, &waterfall, }); @@ -65,6 +67,16 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { receiver_model.set_frequency_step(v); this->field_frequency.set_step(v); }; + + option_bandwidth.on_change = [this](size_t, uint32_t divider) { + sampling_rate = 4000000 / divider; + + waterfall.on_hide(); + set_target_frequency(target_frequency()); + record_view.set_sampling_rate(sampling_rate); + radio::set_baseband_rate(sampling_rate); + waterfall.on_show(); + }; radio::enable({ tuning_frequency(), @@ -75,8 +87,9 @@ CaptureAppView::CaptureAppView(NavigationView& nav) { static_cast(receiver_model.lna()), static_cast(receiver_model.vga()), }); + + option_bandwidth.set_selected_index(4); // 500k - record_view.set_sampling_rate(sampling_rate / 8); record_view.on_error = [&nav](std::string message) { nav.display_modal("Error", message); }; diff --git a/firmware/application/apps/capture_app.hpp b/firmware/application/apps/capture_app.hpp index 7764c76b..cadcb0fc 100644 --- a/firmware/application/apps/capture_app.hpp +++ b/firmware/application/apps/capture_app.hpp @@ -47,9 +47,9 @@ public: std::string title() const override { return "Capture"; }; private: - static constexpr ui::Dim header_height = 2 * 16; + static constexpr ui::Dim header_height = 3 * 16; - static constexpr uint32_t sampling_rate = 4000000; + uint32_t sampling_rate = 0; static constexpr uint32_t baseband_bandwidth = 2500000; void on_target_frequency_changed(rf::Frequency f); @@ -59,6 +59,10 @@ private: rf::Frequency tuning_frequency() const; + Labels labels { + { { 0 * 8, 1 * 16 }, "Rate:", Color::light_grey() }, + }; + RSSI rssi { { 24 * 8, 0, 6 * 8, 4 }, }; @@ -87,8 +91,20 @@ private: { 21 * 8, 0 * 16 } }; + OptionsField option_bandwidth { + { 5 * 8, 1 * 16 }, + 4, + { + { " 25k", 20 }, + { " 50k", 10 }, + { "100k", 5 }, + { "250k", 2 }, + { "500k", 1 } + } + }; + RecordView record_view { - { 0 * 8, 1 * 16, 30 * 8, 1 * 16 }, + { 0 * 8, 2 * 16, 30 * 8, 1 * 16 }, u"BBD_????", RecordView::FileType::RawS16, 16384, 3 }; diff --git a/firmware/application/apps/replay_app.cpp b/firmware/application/apps/replay_app.cpp index 43475f4c..be34e619 100644 --- a/firmware/application/apps/replay_app.cpp +++ b/firmware/application/apps/replay_app.cpp @@ -51,30 +51,40 @@ void ReplayAppView::on_file_changed(std::filesystem::path new_file_path) { file_path = new_file_path; - auto file_size = data_file.size(); - auto duration = (file_size * 1000) / (2 * 2 * sampling_rate / 8); - - progressbar.set_max(file_size); - text_filename.set(file_path.filename().string().substr(0, 19)); - text_duration.set(to_string_time_ms(duration)); - // Get original record frequency if available std::filesystem::path info_file_path = file_path; info_file_path.replace_extension(u".TXT"); + sample_rate = 500000; + auto info_open_error = info_file.open("/" + info_file_path.string()); if (!info_open_error.is_valid()) { memset(file_data, 0, 257); auto read_size = info_file.read(file_data, 256); if (!read_size.is_error()) { - auto pos = strstr(file_data, "center_frequency="); - if (pos) { - pos += 17; - field_frequency.set_value(strtoll(pos, nullptr, 10)); + auto pos1 = strstr(file_data, "center_frequency="); + if (pos1) { + pos1 += 17; + field_frequency.set_value(strtoll(pos1, nullptr, 10)); + } + + auto pos2 = strstr(file_data, "sample_rate="); + if (pos2) { + pos2 += 12; + sample_rate = strtoll(pos2, nullptr, 10); } } } + text_sample_rate.set(unit_auto_scale(sample_rate, 3, 0) + "Hz"); + + auto file_size = data_file.size(); + auto duration = (file_size * 1000) / (2 * 2 * sample_rate); + + progressbar.set_max(file_size); + text_filename.set(file_path.filename().string().substr(0, 12)); + text_duration.set(to_string_time_ms(duration)); + button_play.focus(); } @@ -117,6 +127,8 @@ void ReplayAppView::start() { if( reader ) { button_play.set_bitmap(&bitmap_stop); + baseband::set_sample_rate(sample_rate * 8); + replay_thread = std::make_unique( std::move(reader), read_size, buffer_count, @@ -130,7 +142,7 @@ void ReplayAppView::start() { radio::enable({ receiver_model.tuning_frequency(), - sampling_rate, + sample_rate * 8 , baseband_bandwidth, rf::Direction::Transmit, receiver_model.rf_amp(), @@ -172,6 +184,7 @@ ReplayAppView::ReplayAppView( &labels, &button_open, &text_filename, + &text_sample_rate, &text_duration, &progressbar, &field_frequency, diff --git a/firmware/application/apps/replay_app.hpp b/firmware/application/apps/replay_app.hpp index 30801f8b..9a25ffcf 100644 --- a/firmware/application/apps/replay_app.hpp +++ b/firmware/application/apps/replay_app.hpp @@ -50,7 +50,7 @@ private: static constexpr ui::Dim header_height = 3 * 16; - static constexpr uint32_t sampling_rate = 4000000; + uint32_t sample_rate = 0; static constexpr uint32_t baseband_bandwidth = 2500000; const size_t read_size { 16384 }; const size_t buffer_count { 3 }; @@ -76,7 +76,6 @@ private: Labels labels { { { 10 * 8, 2 * 16 }, "LNA: A:", Color::light_grey() } - //{ { 10 * 8, 2 * 16 }, "500ksps", Color::light_grey() } }; Button button_open { @@ -85,9 +84,14 @@ private: }; Text text_filename { - { 11 * 8, 0 * 16, 19 * 8, 16 }, + { 11 * 8, 0 * 16, 12 * 8, 16 }, "-" }; + Text text_sample_rate { + { 24 * 8, 0 * 16, 6 * 8, 16 }, + "-" + }; + Text text_duration { { 11 * 8, 1 * 16, 6 * 8, 16 }, "-" diff --git a/firmware/application/apps/ui_about.hpp b/firmware/application/apps/ui_about.hpp index 3e138c00..fd8a1cbc 100644 --- a/firmware/application/apps/ui_about.hpp +++ b/firmware/application/apps/ui_about.hpp @@ -97,7 +97,7 @@ private: { 1 * 8, " Windyoona Channels", 0 }, { 1 * 8, " F4GEV Pyr3x", 0 }, { 1 * 8, " HB3YOE", 24 }, - { 12 * 8, "MMXVII", -1 } + { 11 * 8, "MMXVIII", -1 } }; CreditsWidget credits_display { diff --git a/firmware/application/apps/ui_setup.cpp b/firmware/application/apps/ui_setup.cpp index 31a86d48..c358db48 100644 --- a/firmware/application/apps/ui_setup.cpp +++ b/firmware/application/apps/ui_setup.cpp @@ -135,9 +135,9 @@ SetRadioView::SetRadioView( form_init(model); - check_bias.set_value(receiver_model.antenna_bias()); + check_bias.set_value(portapack::get_antenna_bias()); check_bias.on_select = [this](Checkbox&, bool v) { - receiver_model.set_antenna_bias(v); + portapack::set_antenna_bias(v); StatusRefreshMessage message { }; EventDispatcher::send_message(message); }; diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 499c9887..ef03ac9d 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -296,6 +296,11 @@ void spectrum_streaming_stop() { send_message(&message); } +void set_sample_rate(const uint32_t sample_rate) { + SamplerateConfigMessage message { sample_rate }; + send_message(&message); +} + void capture_start(CaptureConfig* const config) { CaptureConfigMessage message { config }; send_message(&message); diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index 3f06b4d6..22f6ead6 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -87,6 +87,7 @@ void shutdown(); void spectrum_streaming_start(); void spectrum_streaming_stop(); +void set_sample_rate(const uint32_t sample_rate); void capture_start(CaptureConfig* const config); void capture_stop(); void replay_start(ReplayConfig* const config); diff --git a/firmware/application/portapack.cpp b/firmware/application/portapack.cpp index 98d97129..a3cf5f18 100644 --- a/firmware/application/portapack.cpp +++ b/firmware/application/portapack.cpp @@ -77,12 +77,20 @@ WM8731 audio_codec_wm8731 { i2c0, 0x1a }; AK4951 audio_codec_ak4951 { i2c0, 0x12 }; ReceiverModel receiver_model; +TransmitterModel transmitter_model; TemperatureLogger temperature_logger; -TransmitterModel transmitter_model; +bool antenna_bias { false }; +uint8_t bl_tick_counter { 0 }; -uint8_t bl_tick_counter = 0; +void set_antenna_bias(const bool v) { + antenna_bias = v; +} + +bool get_antenna_bias() { + return antenna_bias; +} class Power { public: diff --git a/firmware/application/portapack.hpp b/firmware/application/portapack.hpp index c105cdfb..359b1446 100644 --- a/firmware/application/portapack.hpp +++ b/firmware/application/portapack.hpp @@ -52,9 +52,13 @@ extern ReceiverModel receiver_model; extern TransmitterModel transmitter_model; extern uint8_t bl_tick_counter; +extern bool antenna_bias; extern TemperatureLogger temperature_logger; +void set_antenna_bias(const bool v); +bool get_antenna_bias(); + bool init(); void shutdown(); diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index 9b68bbe6..c8b49967 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -25,6 +25,7 @@ #include "portapack_persistent_memory.hpp" #include "hackrf_gpio.hpp" +#include "portapack.hpp" using namespace hackrf::one; using namespace portapack; @@ -72,12 +73,7 @@ void ReceiverModel::set_frequency_step(rf::Frequency f) { frequency_step_ = f; } -bool ReceiverModel::antenna_bias() const { - return antenna_bias_; -} - -void ReceiverModel::set_antenna_bias(bool enabled) { - antenna_bias_ = enabled; +void ReceiverModel::set_antenna_bias() { update_antenna_bias(); } @@ -180,7 +176,7 @@ void ReceiverModel::enable() { void ReceiverModel::disable() { enabled_ = false; - update_antenna_bias(); + radio::set_antenna_bias(false); // TODO: Responsibility for enabling/disabling the radio is muddy. // Some happens in ReceiverModel, some inside radio namespace. @@ -201,7 +197,8 @@ void ReceiverModel::update_tuning_frequency() { } void ReceiverModel::update_antenna_bias() { - radio::set_antenna_bias(antenna_bias_ && enabled_); + if (enabled_) + radio::set_antenna_bias(portapack::get_antenna_bias()); } void ReceiverModel::update_rf_amp() { diff --git a/firmware/application/receiver_model.hpp b/firmware/application/receiver_model.hpp index c3d993d1..139f0d67 100644 --- a/firmware/application/receiver_model.hpp +++ b/firmware/application/receiver_model.hpp @@ -45,9 +45,8 @@ public: rf::Frequency frequency_step() const; void set_frequency_step(rf::Frequency f); - bool antenna_bias() const; - void set_antenna_bias(bool enabled); - + void set_antenna_bias(); + bool rf_amp() const; void set_rf_amp(bool enabled); @@ -91,7 +90,6 @@ private: rf::Frequency frequency_step_ { 25000 }; bool enabled_ { false }; bool rf_amp_ { false }; - bool antenna_bias_ { false }; int32_t lna_gain_db_ { 32 }; uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum }; int32_t vga_gain_db_ { 32 }; diff --git a/firmware/application/transmitter_model.cpp b/firmware/application/transmitter_model.cpp index 16dab39a..1d5d402b 100644 --- a/firmware/application/transmitter_model.cpp +++ b/firmware/application/transmitter_model.cpp @@ -26,6 +26,7 @@ #include "portapack_persistent_memory.hpp" #include "hackrf_gpio.hpp" +#include "portapack.hpp" using namespace hackrf::one; using namespace portapack; @@ -43,6 +44,10 @@ void TransmitterModel::set_tuning_frequency(rf::Frequency f) { update_tuning_frequency(); } +void TransmitterModel::set_antenna_bias() { + update_antenna_bias(); +} + bool TransmitterModel::rf_amp() const { return rf_amp_; } @@ -114,6 +119,7 @@ void TransmitterModel::enable() { enabled_ = true; radio::set_direction(rf::Direction::Transmit); update_tuning_frequency(); + update_antenna_bias(); update_rf_amp(); update_lna(); update_vga(); @@ -132,6 +138,7 @@ void TransmitterModel::enable() { void TransmitterModel::disable() { enabled_ = false; + radio::set_antenna_bias(false); // TODO: Responsibility for enabling/disabling the radio is muddy. // Some happens in ReceiverModel, some inside radio namespace. @@ -145,6 +152,11 @@ void TransmitterModel::update_tuning_frequency() { radio::set_tuning_frequency(persistent_memory::tuned_frequency()); } +void TransmitterModel::update_antenna_bias() { + if (enabled_) + radio::set_antenna_bias(portapack::get_antenna_bias()); +} + void TransmitterModel::update_rf_amp() { radio::set_rf_amp(rf_amp_); } diff --git a/firmware/application/transmitter_model.hpp b/firmware/application/transmitter_model.hpp index 91176732..ef343218 100644 --- a/firmware/application/transmitter_model.hpp +++ b/firmware/application/transmitter_model.hpp @@ -38,6 +38,8 @@ public: rf::Frequency tuning_frequency() const; void set_tuning_frequency(rf::Frequency f); + void set_antenna_bias(); + bool rf_amp() const; void set_rf_amp(bool enabled); @@ -74,6 +76,7 @@ private: SignalToken signal_token_tick_second { }; void update_tuning_frequency(); + void update_antenna_bias(); void update_rf_amp(); void update_lna(); void update_baseband_bandwidth(); diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index c2ff7fdd..a166558f 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -77,6 +77,7 @@ #include "png_writer.hpp" using portapack::receiver_model; +using portapack::transmitter_model; namespace ui { @@ -145,7 +146,7 @@ SystemStatusView::SystemStatusView( } void SystemStatusView::refresh() { - if (receiver_model.antenna_bias()) { + if (portapack::get_antenna_bias()) { button_bias_tee.set_bitmap(&bitmap_icon_biast_on); button_bias_tee.set_foreground(ui::Color::yellow()); } else { @@ -171,28 +172,26 @@ void SystemStatusView::on_stealth() { bool mode = not portapack::persistent_memory::stealth_mode(); portapack::persistent_memory::set_stealth_mode(mode); - - if (mode) - button_stealth.set_foreground(ui::Color::green()); - else - button_stealth.set_foreground(ui::Color::light_grey()); + + button_stealth.set_foreground(mode ? ui::Color::green() : ui::Color::light_grey()); button_stealth.set_dirty(); } void SystemStatusView::on_bias_tee() { - bool antenna_bias = receiver_model.antenna_bias(); - - if (!antenna_bias) { + if (!portapack::antenna_bias) { nav_.display_modal("Bias voltage", "Enable DC voltage on\nantenna connector ?", YESNO, [this](bool v) { if (v) { - receiver_model.set_antenna_bias(true); + portapack::set_antenna_bias(true); + receiver_model.set_antenna_bias(); + transmitter_model.set_antenna_bias(); refresh(); } }); - } else { - receiver_model.set_antenna_bias(false); + portapack::set_antenna_bias(false); + receiver_model.set_antenna_bias(); + transmitter_model.set_antenna_bias(); refresh(); } } diff --git a/firmware/application/ui_record_view.cpp b/firmware/application/ui_record_view.cpp index aa8cea1c..be8c818e 100644 --- a/firmware/application/ui_record_view.cpp +++ b/firmware/application/ui_record_view.cpp @@ -27,8 +27,8 @@ using namespace portapack; #include "io_file.hpp" #include "io_wave.hpp" +#include "baseband_api.hpp" #include "rtc_time.hpp" - #include "string_format.hpp" #include "utility.hpp" @@ -36,7 +36,7 @@ using namespace portapack; namespace ui { -void RecordView::toggle_pitch_rssi() { +/*void RecordView::toggle_pitch_rssi() { pitch_rssi_enabled = !pitch_rssi_enabled; // Send to RSSI widget @@ -51,7 +51,7 @@ void RecordView::toggle_pitch_rssi() { } else { button_pitch_rssi.set_foreground(Color::green()); } -} +}*/ RecordView::RecordView( const Rect parent_rect, @@ -67,18 +67,18 @@ RecordView::RecordView( { add_children({ &rect_background, - &button_pitch_rssi, + //&button_pitch_rssi, &button_record, &text_record_filename, &text_record_dropped, &text_time_available, }); - + rect_background.set_parent_rect({ { 0, 0 }, size() }); - button_pitch_rssi.on_select = [this](ImageButton&) { + /*button_pitch_rssi.on_select = [this](ImageButton&) { this->toggle_pitch_rssi(); - }; + };*/ button_record.on_select = [this](ImageButton&) { this->toggle(); @@ -100,7 +100,9 @@ void RecordView::focus() { void RecordView::set_sampling_rate(const size_t new_sampling_rate) { if( new_sampling_rate != sampling_rate ) { stop(); + sampling_rate = new_sampling_rate; + baseband::set_sample_rate(sampling_rate); button_record.hidden(sampling_rate == 0); text_record_filename.hidden(sampling_rate == 0); @@ -214,7 +216,7 @@ Optional RecordView::write_metadata_file(const std::filesystem::pat if( create_error.is_valid() ) { return create_error; } else { - const auto error_line1 = file.write_line("sample_rate=" + to_string_dec_uint(sampling_rate)); + const auto error_line1 = file.write_line("sample_rate=" + to_string_dec_uint(sampling_rate / 8)); if( error_line1.is_valid() ) { return error_line1; } @@ -237,13 +239,13 @@ void RecordView::update_status_display() { text_record_dropped.set(s); } - if (pitch_rssi_enabled) { + /*if (pitch_rssi_enabled) { button_pitch_rssi.invert_colors(); - } + }*/ if( sampling_rate ) { const auto space_info = std::filesystem::space(u""); - const uint32_t bytes_per_second = file_type == FileType::WAV ? (sampling_rate * 2) : (sampling_rate * 4); + const uint32_t bytes_per_second = file_type == FileType::WAV ? (sampling_rate * 2) : (sampling_rate / 8 * 4); const uint32_t available_seconds = space_info.free / bytes_per_second; const uint32_t seconds = available_seconds % 60; const uint32_t available_minutes = available_seconds / 60; diff --git a/firmware/application/ui_record_view.hpp b/firmware/application/ui_record_view.hpp index 72603570..d1911d1d 100644 --- a/firmware/application/ui_record_view.hpp +++ b/firmware/application/ui_record_view.hpp @@ -64,7 +64,7 @@ public: private: void toggle(); - void toggle_pitch_rssi(); + //void toggle_pitch_rssi(); Optional write_metadata_file(const std::filesystem::path& filename); void on_tick_second(); @@ -73,7 +73,7 @@ private: void handle_capture_thread_done(const File::Error error); void handle_error(const File::Error error); - bool pitch_rssi_enabled = false; + //bool pitch_rssi_enabled = false; const std::filesystem::path filename_stem_pattern; const FileType file_type; const size_t write_size; @@ -85,15 +85,16 @@ private: Color::black() }; - ImageButton button_pitch_rssi { + /*ImageButton button_pitch_rssi { { 2, 0 * 16, 3 * 8, 1 * 16 }, &bitmap_rssipwm, Color::orange(), Color::black() - }; + };*/ ImageButton button_record { - { 4 * 8, 0 * 16, 2 * 8, 1 * 16 }, + //{ 4 * 8, 0 * 16, 2 * 8, 1 * 16 }, + { 0 * 8, 0 * 16, 2 * 8, 1 * 16 }, &bitmap_record, Color::red(), Color::black() diff --git a/firmware/baseband/proc_capture.cpp b/firmware/baseband/proc_capture.cpp index 04edf70a..1d50cd7c 100644 --- a/firmware/baseband/proc_capture.cpp +++ b/firmware/baseband/proc_capture.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2018 Furrtek * * This file is part of PortaPack. * @@ -28,23 +29,9 @@ #include "utility.hpp" CaptureProcessor::CaptureProcessor() { - const auto& decim_0_filter = taps_200k_decim_0; - constexpr size_t decim_0_input_fs = baseband_fs; - constexpr size_t decim_0_output_fs = decim_0_input_fs / decim_0.decimation_factor; - - const auto& decim_1_filter = taps_200k_decim_1; - constexpr size_t decim_1_input_fs = decim_0_output_fs; - constexpr size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor; - - decim_0.configure(decim_0_filter.taps, 33554432); - decim_1.configure(decim_1_filter.taps, 131072); - - channel_filter_pass_f = decim_1_filter.pass_frequency_normalized * decim_1_input_fs; // 162760.416666667 - channel_filter_stop_f = decim_1_filter.stop_frequency_normalized * decim_1_input_fs; // 337239.583333333 - - spectrum_interval_samples = decim_1_output_fs / spectrum_rate_hz; - spectrum_samples = 0; - + decim_0.configure(taps_200k_decim_0.taps, 33554432); + decim_1.configure(taps_200k_decim_1.taps, 131072); + channel_spectrum.set_decimation_factor(1); } @@ -76,6 +63,10 @@ void CaptureProcessor::on_message(const Message* const message) { channel_spectrum.on_message(message); break; + case Message::ID::SamplerateConfig: + samplerate_config(*reinterpret_cast(message)); + break; + case Message::ID::CaptureConfig: capture_config(*reinterpret_cast(message)); break; @@ -85,6 +76,22 @@ void CaptureProcessor::on_message(const Message* const message) { } } +void CaptureProcessor::samplerate_config(const SamplerateConfigMessage& message) { + baseband_fs = message.sample_rate; + baseband_thread.set_sampling_rate(baseband_fs); + + size_t decim_0_output_fs = baseband_fs / decim_0.decimation_factor; + + size_t decim_1_input_fs = decim_0_output_fs; + size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor; + + channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * decim_1_input_fs; // 162760.416666667 + channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * decim_1_input_fs; // 337239.583333333 + + spectrum_interval_samples = decim_1_output_fs / spectrum_rate_hz; + spectrum_samples = 0; +} + void CaptureProcessor::capture_config(const CaptureConfigMessage& message) { if( message.config ) { stream = std::make_unique(message.config); diff --git a/firmware/baseband/proc_capture.hpp b/firmware/baseband/proc_capture.hpp index db0a2945..9dd02d9b 100644 --- a/firmware/baseband/proc_capture.hpp +++ b/firmware/baseband/proc_capture.hpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2018 Furrtek * * This file is part of PortaPack. * @@ -45,7 +46,7 @@ public: private: // TODO: Repeated value needs to be transmitted from application side. - static constexpr size_t baseband_fs = 4000000; + size_t baseband_fs = 0; static constexpr auto spectrum_rate_hz = 50.0f; BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Receive }; @@ -68,6 +69,7 @@ private: size_t spectrum_interval_samples = 0; size_t spectrum_samples = 0; + void samplerate_config(const SamplerateConfigMessage& message); void capture_config(const CaptureConfigMessage& message); }; diff --git a/firmware/baseband/proc_replay.cpp b/firmware/baseband/proc_replay.cpp index 3b8593b1..edb93469 100644 --- a/firmware/baseband/proc_replay.cpp +++ b/firmware/baseband/proc_replay.cpp @@ -32,7 +32,6 @@ ReplayProcessor::ReplayProcessor() { channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * 1000000; // 162760.416666667 channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * 1000000; // 337239.583333333 - spectrum_interval_samples = baseband_fs / spectrum_rate_hz; spectrum_samples = 0; channel_spectrum.set_decimation_factor(1); @@ -86,6 +85,10 @@ void ReplayProcessor::on_message(const Message* const message) { channel_spectrum.on_message(message); break; + case Message::ID::SamplerateConfig: + samplerate_config(*reinterpret_cast(message)); + break; + case Message::ID::ReplayConfig: configured = false; bytes_read = 0; @@ -102,8 +105,15 @@ void ReplayProcessor::on_message(const Message* const message) { } } +void ReplayProcessor::samplerate_config(const SamplerateConfigMessage& message) { + baseband_fs = message.sample_rate; + baseband_thread.set_sampling_rate(baseband_fs); + spectrum_interval_samples = baseband_fs / spectrum_rate_hz; +} + void ReplayProcessor::replay_config(const ReplayConfigMessage& message) { if( message.config ) { + stream = std::make_unique(message.config); // Tell application that the buffers and FIFO pointers are ready, prefill diff --git a/firmware/baseband/proc_replay.hpp b/firmware/baseband/proc_replay.hpp index 1ab220f7..9edb82f7 100644 --- a/firmware/baseband/proc_replay.hpp +++ b/firmware/baseband/proc_replay.hpp @@ -42,7 +42,7 @@ public: void on_message(const Message* const message) override; private: - static constexpr size_t baseband_fs = 4000000; + size_t baseband_fs = 0; static constexpr auto spectrum_rate_hz = 50.0f; BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Transmit }; @@ -66,6 +66,7 @@ private: bool configured { false }; uint32_t bytes_read { 0 }; + void samplerate_config(const SamplerateConfigMessage& message); void replay_config(const ReplayConfigMessage& message); TXProgressMessage txprogress_message { }; diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index cf848234..be1d7e21 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -75,6 +75,7 @@ public: ReplayThreadDone = 21, AFSKRxConfigure = 22, StatusRefresh = 23, + SamplerateConfig = 24, TXProgress = 30, Retune = 31, @@ -751,6 +752,18 @@ public: uint32_t range = 0; }; +class SamplerateConfigMessage : public Message { +public: + constexpr SamplerateConfigMessage( + const uint32_t sample_rate + ) : Message { ID::SamplerateConfig }, + sample_rate(sample_rate) + { + } + + const uint32_t sample_rate = 0; +}; + class AudioLevelReportMessage : public Message { public: constexpr AudioLevelReportMessage( diff --git a/firmware/portapack-h1-havoc.bin b/firmware/portapack-h1-havoc.bin index 927e2613..8b44f7ca 100644 Binary files a/firmware/portapack-h1-havoc.bin and b/firmware/portapack-h1-havoc.bin differ