diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index ed73b622..db2f2963 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -28,7 +28,7 @@ set(CHIBIOS_PORTAPACK ${PROJECT_SOURCE_DIR}/chibios-portapack) set(HACKRF_FIRMWARE_FILENAME hackrf_one_usb_ram.dfu) set(HACKRF_FIRMWARE_IMAGE ${PROJECT_SOURCE_DIR}/${HACKRF_FIRMWARE_FILENAME}) -set(HACKRF_CPLD_SVF_FILENAME hackrf_cpld_default.svf) +set(HACKRF_CPLD_SVF_FILENAME hackrf_cpld_portapack.svf) set(HACKRF_CPLD_SVF_PATH ${PROJECT_SOURCE_DIR}/${HACKRF_CPLD_SVF_FILENAME}) set(EXTRACT_CPLD_DATA ${PROJECT_SOURCE_DIR}/tools/extract_cpld_data.py) diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index 0f2c41f9..0863c21a 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -284,6 +284,10 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) { } baseband::run_image(image_tag); + + if (modulation == ReceiverModel::Mode::SpectrumAnalysis) { + baseband::set_spectrum(20000000, 127); + } const auto is_wideband_spectrum_mode = (modulation == ReceiverModel::Mode::SpectrumAnalysis); receiver_model.set_modulation(modulation); diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 0d2faf9f..db815fd9 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -171,14 +171,12 @@ void set_rds_data(const uint16_t message_length) { send_message(&message); } -/*void set_dtmf_data(const uint32_t bw, const uint32_t tone_length, const uint32_t pause_length) { - const DTMFTXConfigMessage message { - bw, - tone_length, - pause_length +void set_spectrum(const size_t sampling_rate, const size_t trigger) { + const WidebandSpectrumConfigMessage message { + sampling_rate, trigger }; send_message(&message); -}*/ +} static bool baseband_image_running = false; diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index e95add7c..1dcc75b5 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -67,7 +67,7 @@ void set_pocsag(const pocsag::BitRate bitrate); void set_adsb(); void set_jammer(const bool run, const uint32_t type, const uint32_t speed); void set_rds_data(const uint16_t message_length); -//void set_dtmf_data(const uint32_t bw, const uint32_t tone_length, const uint32_t pause_length); +void set_spectrum(const size_t sampling_rate, const size_t trigger); void run_image(const portapack::spi_flash::image_tag_t image_tag); void shutdown(); diff --git a/firmware/application/ui_alphanum.hpp b/firmware/application/ui_alphanum.hpp index 0542e210..74f5f91d 100644 --- a/firmware/application/ui_alphanum.hpp +++ b/firmware/application/ui_alphanum.hpp @@ -34,7 +34,7 @@ namespace ui { class AlphanumView : public View { public: - std::function on_changed; + std::function on_changed { }; AlphanumView(NavigationView& nav, char txt[], size_t max_length); @@ -55,8 +55,8 @@ private: const char * const keys_upper = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ. !<"; const char * const keys_lower = "0123456789abcdefghijklmnopqrstuvwxyz:=?<"; - size_t _max_length; - uint8_t txtidx; + size_t _max_length { }; + uint8_t txtidx { 0 }; bool _lowercase = false; char txtinput[29] = { 0 }; // 28 chars max diff --git a/firmware/application/ui_closecall.cpp b/firmware/application/ui_closecall.cpp index 271df700..3257f3c0 100644 --- a/firmware/application/ui_closecall.cpp +++ b/firmware/application/ui_closecall.cpp @@ -21,7 +21,6 @@ */ #include "ui_closecall.hpp" -#include "msgpack.hpp" #include "rtc_time.hpp" #include "event_m0.hpp" @@ -38,7 +37,7 @@ using namespace portapack; namespace ui { void CloseCallView::focus() { - button_exit.focus(); + field_frequency_min.focus(); } CloseCallView::~CloseCallView() { @@ -49,16 +48,16 @@ CloseCallView::~CloseCallView() { void CloseCallView::do_detection() { uint8_t xmax = 0; - int64_t imax = 0; + int16_t imax = 0; uint16_t iraw = 0, c; uint8_t power; rf::Frequency freq_low, freq_high; - mean /= (CC_BIN_NB * slices_max); + mean /= (CC_BIN_NB_NO_DC * slices_max); - // Find max value over threshold from all slices + // Find max value over threshold for all slices for (c = 0; c < slices_max; c++) { - power = slicemax_db[c]; + power = slicemax_pow[c]; if (power >= min_threshold) { if ((power - min_threshold >= mean) && (power > xmax)) { xmax = power; @@ -68,54 +67,42 @@ void CloseCallView::do_detection() { } } - // e-Message POCSAG FR: - // 466.025 MHz - 466.05 MHz - 466.075 MHz - 466.175 MHz - 466.20625 MHz - 466.23125 MHz - // 25 25 100 31 25 - - // Catches: - // 466.000 - // 466.021 21 - // 466.042 21 - // 466.148 106 - // 466.169 21 - // 466.190 21 - // Lock / release - if ((imax >= last_channel - 2) && (imax <= last_channel + 2) && imax) { - // Staying around the same frequency (+/- 25.4kHz) - if (detect_counter >= (5 / slices_max)) { + if ((imax >= last_channel - 2) && (imax <= last_channel + 2) && (imax)) { + // Staying around the same frequency + if (detect_counter >= (5 / slices_max)) { // Todo: ugly, change. Should depend on refresh rate. if ((imax != locked_imax) || (!locked)) { std::string finalstr; - // 236 steps = 3.072MHz - // Resolution = 13.1kHz if (locked) { - resolved_frequency = (resolved_frequency + slice_start + (CC_BIN_WIDTH * (imax - 118))) / 2; // Mean + // Already locked, adjust + if (weight < 16) { + frequency_acc += (slice_frequency + (CC_BIN_WIDTH * (imax - 120))); // Average + weight++; + } } else { - resolved_frequency = slice_start + (CC_BIN_WIDTH * (imax - 118)); // Init - if ((resolved_frequency >= f_min) && (resolved_frequency <= f_max)) { - // Correct according to DC spike mask width (8 for now) - if (iraw > 118) - resolved_frequency -= (4 * CC_BIN_WIDTH); - else - resolved_frequency += (4 * CC_BIN_WIDTH); + // Lost, locking + frequency_acc = slice_frequency + (CC_BIN_WIDTH * (imax - 120)); // Init + if ((frequency_acc >= f_min) && (frequency_acc <= f_max)) { text_infos.set("Locked !"); big_display.set_style(&style_locked); - big_display.set(resolved_frequency); // Approximation/error display - freq_low = (resolved_frequency - 6000) / 1000; - freq_high = (resolved_frequency + 6000) / 1000; - finalstr = "~12kHz: " + to_string_dec_uint(freq_low / 1000) + "." + to_string_dec_uint(freq_low % 1000); + freq_low = (frequency_acc - 4883) / 1000; + freq_high = (frequency_acc + 4883) / 1000; + finalstr = "~9.8kHz: " + to_string_dec_uint(freq_low / 1000) + "." + to_string_dec_uint(freq_low % 1000); finalstr += "/" + to_string_dec_uint(freq_high / 1000) + "." + to_string_dec_uint(freq_high % 1000); text_precision.set(finalstr); locked = true; + weight = 1; locked_imax = imax; } } - //text_debug.set(to_string_dec_int(CC_BIN_WIDTH * (imax - 118))); + + resolved_frequency = frequency_acc / weight; + big_display.set(resolved_frequency); } release_counter = 0; } else { @@ -128,7 +115,7 @@ void CloseCallView::do_detection() { locked = false; text_infos.set("Lost"); big_display.set_style(&style_grey); - big_display.set(resolved_frequency); + //big_display.set(resolved_frequency); } else { release_counter++; } @@ -138,28 +125,32 @@ void CloseCallView::do_detection() { last_channel = imax; scan_counter++; - portapack::display.fill_rectangle({last_pos, 90, 1, 13}, Color::black()); - last_pos = (ui::Coord)(iraw); - portapack::display.fill_rectangle({last_pos, 90, 1, 13}, Color::red()); + portapack::display.fill_rectangle({last_pos, 90, 1, 6}, Color::black()); + if (iraw < 120) + iraw += 2; + else + iraw -= 0; + last_pos = (ui::Coord)iraw; + portapack::display.fill_rectangle({last_pos, 90, 1, 6}, Color::red()); } void CloseCallView::on_channel_spectrum(const ChannelSpectrum& spectrum) { uint8_t xmax = 0; - uint16_t imax = 0; - uint8_t threshold; + int16_t imax = 0; + uint8_t power; size_t i, m; + std::array pixel_row; baseband::spectrum_streaming_stop(); - // Draw spectrum line (for debug), 2 black pixels left and right - std::array pixel_row; - for(i = 0; i < 118; i++) { - const auto pixel_color = spectrum_rgb3_lut[spectrum.db[256 - 120 + i]]; // 136~253 in 2~119 - pixel_row[i + 2] = pixel_color; + // Draw spectrum line (for debug) + for (i = 0; i < 120; i++) { + const auto pixel_color = spectrum_rgb3_lut[spectrum.db[134 + i]]; // 134~253 in 0~119 + pixel_row[i] = pixel_color; } - for(i = 122; i < 240; i++) { - const auto pixel_color = spectrum_rgb3_lut[spectrum.db[i - 120]]; // 2~119 in 120~237 - pixel_row[i - 2] = pixel_color; + for (i = 120; i < 240; i++) { + const auto pixel_color = spectrum_rgb3_lut[spectrum.db[i - 118]]; // 2~121 in 120~239 + pixel_row[i] = pixel_color; } display.draw_pixels( { { 0, 96 + slices_counter * 4 }, { pixel_row.size(), 1 } }, @@ -173,33 +164,30 @@ void CloseCallView::on_channel_spectrum(const ChannelSpectrum& spectrum) { // i = slice_trim; //else i = 0; - for ( ; i < 118; i++) { - threshold = spectrum.db[256 - 120 + i]; // 128+8 = 136~254 - if (threshold > xmax) { - xmax = threshold; - imax = i; + for ( ; i < 120; i++) { + power = spectrum.db[134 + i]; + mean += power; + if (power > xmax) { + xmax = power; + imax = i - 2; } } // Check if right of slice needs to be trimmed (masked) - if (slices_counter == (slices_max - 1)) - m = 240 - slice_trim; - else + //if (slices_counter == (slices_max - 1)) + // m = 240 - slice_trim; + //else m = 240; - for (i = 122 ; i < m; i++) { - threshold = spectrum.db[i - 120]; // 240-120 = 120 -> +8 = 128 - if (threshold > xmax) { // (0~2) 2~120 (120~136) 136~254 (254~256) - xmax = threshold; - imax = i - 4; + for (i = 120; i < m; i++) { + power = spectrum.db[i - 118]; + mean += power; + if (power > xmax) { + xmax = power; + imax = i + 2; } } - slicemax_db[slices_counter] = xmax; + + slicemax_pow[slices_counter] = xmax; slicemax_idx[slices_counter] = imax; - - // Add to mean - for (i = 136; i < 254; i++) - mean += spectrum.db[i]; - for (i = 2; i < 120; i++) - mean += spectrum.db[i]; // Slice update if (slicing) { @@ -229,7 +217,7 @@ void CloseCallView::on_hide() { void CloseCallView::on_range_changed() { rf::Frequency slices_span; - rf::Frequency resolved_frequency; + rf::Frequency slice_width; int64_t offset; f_max = field_frequency_max.value(); @@ -248,16 +236,14 @@ void CloseCallView::on_range_changed() { // Todo: trims } else { slice_frequency = (f_max + f_min) / 2; - slice_start = slice_frequency; receiver_model.set_tuning_frequency(slice_frequency); - //resolved_frequency = (CC_SLICE_WIDTH - scan_span) / 2; // Trim frequency span (for both sides) - //resolved_frequency /= CC_BIN_WIDTH; // Convert to bin span - //slice_trim = resolved_frequency; + slice_width = abs(f_max - f_min); + slice_trim = (240 - (slice_width * 240 / CC_SLICE_WIDTH)) / 2; - //portapack::display.fill_rectangle({0, 97, 240, 4}, Color::black()); - //portapack::display.fill_rectangle({0, 97, slice_trim, 4}, Color::orange()); - //portapack::display.fill_rectangle({240 - slice_trim, 97, slice_trim, 4}, Color::orange()); + portapack::display.fill_rectangle({0, 97, 240, 4}, Color::black()); + portapack::display.fill_rectangle({0, 97, slice_trim, 4}, Color::orange()); + portapack::display.fill_rectangle({240 - slice_trim, 97, slice_trim, 4}, Color::orange()); slices_max = 1; slices_counter = 0; @@ -299,7 +285,7 @@ CloseCallView::CloseCallView( NavigationView& nav ) { - baseband::run_image(portapack::spi_flash::image_tag_closecall); + baseband::run_image(portapack::spi_flash::image_tag_wideband_spectrum); add_children({ &text_labels_a, @@ -328,8 +314,7 @@ CloseCallView::CloseCallView( text_mhz.set_style(&style_grey); big_display.set_style(&style_grey); - // DEBUG - receiver_model.set_tuning_frequency(464400000); + baseband::set_spectrum(CC_SLICE_WIDTH, 32); field_threshold.set_value(80); field_threshold.on_change = [this](int32_t v) { @@ -338,8 +323,7 @@ CloseCallView::CloseCallView( field_frequency_min.set_value(receiver_model.tuning_frequency()); field_frequency_min.set_step(100000); - field_frequency_min.on_change = [this](rf::Frequency f) { - (void)f; + field_frequency_min.on_change = [this](rf::Frequency) { this->on_range_changed(); }; field_frequency_min.on_edit = [this, &nav]() { @@ -352,8 +336,7 @@ CloseCallView::CloseCallView( field_frequency_max.set_value(receiver_model.tuning_frequency() + 2000000); field_frequency_max.set_step(100000); - field_frequency_max.on_change = [this](rf::Frequency f) { - (void)f; + field_frequency_max.on_change = [this](rf::Frequency) { this->on_range_changed(); }; field_frequency_max.on_edit = [this, &nav]() { @@ -385,7 +368,7 @@ CloseCallView::CloseCallView( }; receiver_model.set_modulation(ReceiverModel::Mode::SpectrumAnalysis); - receiver_model.set_sampling_rate(3072000); + receiver_model.set_sampling_rate(CC_SLICE_WIDTH); receiver_model.set_baseband_bandwidth(2500000); receiver_model.enable(); } diff --git a/firmware/application/ui_closecall.hpp b/firmware/application/ui_closecall.hpp index 81919909..0827c8b7 100644 --- a/firmware/application/ui_closecall.hpp +++ b/firmware/application/ui_closecall.hpp @@ -29,9 +29,10 @@ namespace ui { -#define CC_SLICE_WIDTH 3072000 // Radio bandwidth -#define CC_BIN_NB 256 // Total power bins -#define CC_BIN_WIDTH CC_SLICE_WIDTH/CC_BIN_NB +#define CC_SLICE_WIDTH 2500000 // Radio bandwidth +#define CC_BIN_NB 256 // Total power bins (skip 4 at center, 2*6 on sides) +#define CC_BIN_NB_NO_DC (CC_BIN_NB - 16) +#define CC_BIN_WIDTH (CC_SLICE_WIDTH / CC_BIN_NB) class CloseCallView : public View { public: @@ -62,26 +63,28 @@ private: }; rf::Frequency f_min, f_max; - Coord last_pos = 0; + Coord last_pos { 0 }; ChannelSpectrumFIFO* fifo { nullptr }; - uint8_t detect_counter = 0, release_counter = 0; + uint8_t detect_counter { 0 }, release_counter { 0 }; uint8_t slice_trim; - uint32_t mean = 0; - uint32_t min_threshold = 80; // Todo: Put this in persistent / settings + uint32_t mean { 0 }; + uint32_t min_threshold { 80 }; // Todo: Put this in persistent / settings rf::Frequency slice_start; rf::Frequency slice_frequency; uint8_t slices_max; uint8_t slices_counter; - uint16_t last_channel; + int16_t last_channel; + uint32_t weight { 0 }; + uint64_t frequency_acc { 0 }; rf::Frequency scan_span, resolved_frequency; uint16_t locked_imax; - uint8_t slicemax_db[32]; // Todo: Cap max slices ! - uint8_t slicemax_idx[32]; + uint8_t slicemax_pow[32]; // Todo: Cap max slices ! + int16_t slicemax_idx[32]; uint8_t scan_counter; - SignalToken signal_token_tick_second; - bool ignore = true; - bool slicing; - bool locked = false; + SignalToken signal_token_tick_second { }; + bool ignore { true }; + bool slicing { false }; + bool locked { false }; void on_channel_spectrum(const ChannelSpectrum& spectrum); void on_range_changed(); diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index 730796dc..78e70eec 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -336,13 +336,6 @@ set(MODE_CPPSRC ) DeclareTargets(PSPE wideband_spectrum) -### Close Call - -set(MODE_CPPSRC - proc_closecall.cpp -) -DeclareTargets(PCLC closecall) - ### OOK set(MODE_CPPSRC diff --git a/firmware/baseband/baseband_thread.cpp b/firmware/baseband/baseband_thread.cpp index 7083e9f4..e6d7d034 100644 --- a/firmware/baseband/baseband_thread.cpp +++ b/firmware/baseband/baseband_thread.cpp @@ -64,6 +64,10 @@ BasebandThread::~BasebandThread() { thread = nullptr; } +void BasebandThread::set_sampling_rate(uint32_t new_sampling_rate) { + sampling_rate = new_sampling_rate; +} + void BasebandThread::run() { baseband_sgpio.init(); baseband::dma::init(); diff --git a/firmware/baseband/baseband_thread.hpp b/firmware/baseband/baseband_thread.hpp index 54fa9023..a168d045 100644 --- a/firmware/baseband/baseband_thread.hpp +++ b/firmware/baseband/baseband_thread.hpp @@ -48,6 +48,8 @@ public: baseband::Direction direction() const { return _direction; } + + void set_sampling_rate(uint32_t new_sampling_rate); private: static Thread* thread; diff --git a/firmware/baseband/proc_closecall.cpp b/firmware/baseband/proc_closecall.cpp deleted file mode 100644 index 9695d2fa..00000000 --- a/firmware/baseband/proc_closecall.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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 "proc_closecall.hpp" - -#include "event_m4.hpp" - -#include -#include - -#include - -void CloseCallProcessor::execute(const buffer_c8_t& buffer) { - if( phase == 0 ) { - std::fill(spectrum.begin(), spectrum.end(), 0); - } - - for(size_t i=0; iid) { - case Message::ID::UpdateSpectrum: - case Message::ID::SpectrumStreamingConfig: - channel_spectrum.on_message(message); - break; - - default: - break; - } -} - -int main() { - EventDispatcher event_dispatcher { std::make_unique() }; - event_dispatcher.run(); - return 0; -} diff --git a/firmware/baseband/proc_closecall.hpp b/firmware/baseband/proc_closecall.hpp deleted file mode 100644 index efdd9636..00000000 --- a/firmware/baseband/proc_closecall.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 __PROC_CLOSECALLPROCESSOR_H__ -#define __PROC_CLOSECALLPROCESSOR_H__ - -#include "baseband_processor.hpp" -#include "baseband_thread.hpp" -#include "spectrum_collector.hpp" - -#include "message.hpp" - -#include -#include -#include - -class CloseCallProcessor : public BasebandProcessor { -public: - void execute(const buffer_c8_t& buffer) override; - - void on_message(const Message* const message) override; - -private: - BasebandThread baseband_thread { 3072000, this, NORMALPRIO + 20, baseband::Direction::Receive }; - - SpectrumCollector channel_spectrum { }; - - std::array spectrum { }; - - size_t phase = 0; -}; - -#endif/*__PROC_CLOSECALLPROCESSOR_H__*/ diff --git a/firmware/baseband/proc_wfm_audio.cpp b/firmware/baseband/proc_wfm_audio.cpp index 1d375eb8..04270bda 100644 --- a/firmware/baseband/proc_wfm_audio.cpp +++ b/firmware/baseband/proc_wfm_audio.cpp @@ -69,7 +69,7 @@ void WidebandFMAudio::execute(const buffer_c8_t& buffer) { * -> FIR filter, <15kHz (0.156fs) pass, >19kHz (0.198fs) stop, gain of 1 * -> 48kHz int16_t[32] */ auto audio = audio_filter.execute(audio_2fs, work_audio_buffer); - + /* -> 48kHz int16_t[32] */ audio_output.write(audio); } else { diff --git a/firmware/baseband/proc_wfm_audio.hpp b/firmware/baseband/proc_wfm_audio.hpp index a5938907..2438720d 100644 --- a/firmware/baseband/proc_wfm_audio.hpp +++ b/firmware/baseband/proc_wfm_audio.hpp @@ -80,7 +80,7 @@ private: unsigned int c { 0 }, synth_acc { 0 }; uint32_t synth_div { 0 }; - bool pwmrssi_enabled = false; + bool pwmrssi_enabled { false }; uint32_t pwmrssi_avg { 0 }; bool configured { false }; diff --git a/firmware/baseband/proc_wideband_spectrum.cpp b/firmware/baseband/proc_wideband_spectrum.cpp index 76d627c2..f17ec245 100644 --- a/firmware/baseband/proc_wideband_spectrum.cpp +++ b/firmware/baseband/proc_wideband_spectrum.cpp @@ -33,6 +33,8 @@ void WidebandSpectrum::execute(const buffer_c8_t& buffer) { // 2048 complex8_t samples per buffer. // 102.4us per buffer. 20480 instruction cycles per buffer. + + if (!configured) return; if( phase == 0 ) { std::fill(spectrum.begin(), spectrum.end(), 0); @@ -45,7 +47,7 @@ void WidebandSpectrum::execute(const buffer_c8_t& buffer) { spectrum[i] += buffer.p[i + 1024]; } - if( phase == 127 ) { + if( phase == trigger ) { const buffer_c16_t buffer_c16 { spectrum.data(), spectrum.size(), @@ -61,11 +63,20 @@ void WidebandSpectrum::execute(const buffer_c8_t& buffer) { } } -void WidebandSpectrum::on_message(const Message* const message) { - switch(message->id) { +void WidebandSpectrum::on_message(const Message* const msg) { + const WidebandSpectrumConfigMessage message = *reinterpret_cast(msg); + + switch(msg->id) { case Message::ID::UpdateSpectrum: case Message::ID::SpectrumStreamingConfig: - channel_spectrum.on_message(message); + channel_spectrum.on_message(msg); + break; + + case Message::ID::WidebandSpectrumConfig: + baseband_fs = message.sampling_rate; + trigger = message.trigger; + baseband_thread.set_sampling_rate(baseband_fs); + configured = true; break; default: diff --git a/firmware/baseband/proc_wideband_spectrum.hpp b/firmware/baseband/proc_wideband_spectrum.hpp index 7d0b90ed..41637480 100644 --- a/firmware/baseband/proc_wideband_spectrum.hpp +++ b/firmware/baseband/proc_wideband_spectrum.hpp @@ -41,16 +41,18 @@ public: void on_message(const Message* const message) override; private: - static constexpr size_t baseband_fs = 20000000; + bool configured = false; + + size_t baseband_fs = 20000000; - BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Receive }; + BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 }; RSSIThread rssi_thread { NORMALPRIO + 10 }; SpectrumCollector channel_spectrum { }; std::array spectrum { }; - size_t phase = 0; + size_t phase = 0, trigger = 127; }; #endif/*__PROC_WIDEBAND_SPECTRUM_H__*/ diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index 4326ace1..3863820c 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -83,6 +83,7 @@ public: DTMFTXConfig = 39, ADSBConfigure = 40, JammerConfigure = 41, + WidebandSpectrumConfig = 42, POCSAGPacket = 50, @@ -232,6 +233,21 @@ public: Mode mode { Mode::Stopped }; }; +class WidebandSpectrumConfigMessage : public Message { +public: + constexpr WidebandSpectrumConfigMessage ( + size_t sampling_rate, + size_t trigger + ) : Message { ID::WidebandSpectrumConfig }, + sampling_rate { sampling_rate }, + trigger { trigger } + { + } + + size_t sampling_rate { 0 }; + size_t trigger { 0 }; +}; + struct ChannelSpectrum { std::array db { { 0 } }; uint32_t sampling_rate { 0 }; diff --git a/firmware/common/spi_image.hpp b/firmware/common/spi_image.hpp index c43de7c0..7c3079b9 100644 --- a/firmware/common/spi_image.hpp +++ b/firmware/common/spi_image.hpp @@ -72,7 +72,6 @@ constexpr image_tag_t image_tag_tpms { 'P', 'T', 'P', 'M' }; constexpr image_tag_t image_tag_pocsag { 'P', 'P', 'O', 'C' }; constexpr image_tag_t image_tag_wfm_audio { 'P', 'W', 'F', 'M' }; constexpr image_tag_t image_tag_wideband_spectrum { 'P', 'S', 'P', 'E' }; -constexpr image_tag_t image_tag_closecall { 'P', 'C', 'L', 'C' }; constexpr image_tag_t image_tag_jammer { 'P', 'J', 'A', 'M' }; constexpr image_tag_t image_tag_audio_tx { 'P', 'A', 'T', 'X' }; diff --git a/firmware/portapack-h1-havoc.bin b/firmware/portapack-h1-havoc.bin index 700b474c..5d990993 100644 Binary files a/firmware/portapack-h1-havoc.bin and b/firmware/portapack-h1-havoc.bin differ