diff --git a/firmware/Makefile b/firmware/Makefile index 0def504ce..5bce1a9fc 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -65,7 +65,7 @@ modules: $(TARGET_BASEBAND).bin $(TARGET_BASEBAND_TX).bin cp $(PATH_BASEBAND_TX).bin ../sdcard/$(PATH_BASEBAND_TX).bin $(TARGET).bin: modules $(MAKE_SPI_IMAGE) $(TARGET_BOOTSTRAP).bin $(TARGET_HACKRF_FIRMWARE).dfu $(TARGET_BASEBAND_TX)_inc.bin $(TARGET_APPLICATION).bin - $(MAKE_SPI_IMAGE) $(TARGET_BOOTSTRAP).bin $(TARGET_HACKRF_FIRMWARE).dfu $(TARGET_BASEBAND_TX)_inc.bin $(TARGET_APPLICATION).bin $(TARGET).bin + $(MAKE_SPI_IMAGE) $(TARGET_BOOTSTRAP).bin $(TARGET_HACKRF_FIRMWARE).dfu $(TARGET_BASEBAND)_inc.bin $(TARGET_APPLICATION).bin $(TARGET).bin $(TARGET_BOOTSTRAP).bin: $(TARGET_BOOTSTRAP).elf $(CP) -O binary $(TARGET_BOOTSTRAP).elf $(TARGET_BOOTSTRAP).bin diff --git a/firmware/application/Makefile b/firmware/application/Makefile index d62a6588b..cbbdabd58 100755 --- a/firmware/application/Makefile +++ b/firmware/application/Makefile @@ -150,39 +150,40 @@ CPPSRC = main.cpp \ audio.cpp \ lcd_ili9341.cpp \ ui.cpp \ - ui_alphanum.cpp \ - ui_handwrite.cpp \ ui_about.cpp \ - ui_text.cpp \ - ui_widget.cpp \ - ui_painter.cpp \ - ui_focus.cpp \ - ui_navigation.cpp \ - ui_menu.cpp \ - ui_rssi.cpp \ - ui_channel.cpp \ - ui_audio.cpp \ - ui_audiotx.cpp \ - ui_soundboard.cpp \ - ui_lcr.cpp \ - ui_rds.cpp \ - ui_jammer.cpp \ - ui_font_fixed_8x16.cpp \ - ui_setup.cpp \ - ui_debug.cpp \ - ui_baseband_stats_view.cpp \ - ui_sd_card_status_view.cpp \ - ui_sd_card_debug.cpp \ - ui_console.cpp \ - ui_receiver.cpp \ - ui_record_view.cpp \ - ui_spectrum.cpp \ - ui_loadmodule.cpp \ ui_afskrx.cpp \ ui_afsksetup.cpp \ - ui_sigfrx.cpp \ - ui_xylos.cpp \ + ui_audio.cpp \ + ui_audiotx.cpp \ + ui_alphanum.cpp \ + ui_baseband_stats_view.cpp \ + ui_channel.cpp \ + ui_closecall.cpp \ + ui_console.cpp \ + ui_debug.cpp \ + ui_focus.cpp \ + ui_font_fixed_8x16.cpp \ + ui_handwrite.cpp \ + ui_jammer.cpp \ + ui_lcr.cpp \ + ui_loadmodule.cpp \ + ui_menu.cpp \ + ui_navigation.cpp \ ui_numbers.cpp \ + ui_painter.cpp \ + ui_rds.cpp \ + ui_receiver.cpp \ + ui_record_view.cpp \ + ui_rssi.cpp \ + ui_sd_card_debug.cpp \ + ui_sd_card_status_view.cpp \ + ui_setup.cpp \ + ui_sigfrx.cpp \ + ui_soundboard.cpp \ + ui_spectrum.cpp \ + ui_text.cpp \ + ui_widget.cpp \ + ui_xylos.cpp \ recent_entries.cpp \ receiver_model.cpp \ transmitter_model.cpp \ diff --git a/firmware/application/receiver_model.hpp b/firmware/application/receiver_model.hpp index ad6647002..3448f3691 100644 --- a/firmware/application/receiver_model.hpp +++ b/firmware/application/receiver_model.hpp @@ -38,6 +38,7 @@ public: WidebandFMAudio = 2, SpectrumAnalysis = 4, Capture = 7, + CloseCall = 10, }; rf::Frequency tuning_frequency() const; diff --git a/firmware/application/ui_audiotx.hpp b/firmware/application/ui_audiotx.hpp index d9074cf5a..c4c41e7ad 100644 --- a/firmware/application/ui_audiotx.hpp +++ b/firmware/application/ui_audiotx.hpp @@ -34,7 +34,7 @@ #include "transmitter_model.hpp" namespace ui { - + class AudioTXView : public View { public: AudioTXView(NavigationView& nav); diff --git a/firmware/application/ui_closecall.cpp b/firmware/application/ui_closecall.cpp new file mode 100644 index 000000000..8343e541a --- /dev/null +++ b/firmware/application/ui_closecall.cpp @@ -0,0 +1,323 @@ +/* + * 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 "ui_closecall.hpp" +#include "ui_receiver.hpp" + +#include "ch.h" +#include "evtimer.h" + +#include "event_m0.hpp" +#include "ff.h" +#include "hackrf_gpio.hpp" +#include "portapack.hpp" +#include "radio.hpp" +#include "baseband_api.hpp" +#include "string_format.hpp" + +#include "hackrf_hal.hpp" + +#include +#include +#include + +using namespace portapack; + +namespace ui { + +void CloseCallView::focus() { + button_exit.focus(); +} + +CloseCallView::~CloseCallView() { + receiver_model.disable(); +} + +void CloseCallView::do_detection() { + uint8_t xmax = 0; + uint16_t imax = 0; + uint8_t threshold; + size_t i; + + portapack::display.fill_rectangle({last_pos, 60, 1, 9}, Color::black()); + + mean /= (236 * (slices_max + 1)); + + for (i = 0; i < (slices_max + 1); i++) { + threshold = slicemax_db[i]; + if (threshold >= 40) { + if (((uint8_t)(threshold - 40) > mean) && (threshold > xmax)) { + xmax = threshold; + imax = slicemax_idx[i] + (i * 236); + } + } + } + + // Lock / release + if ((imax >= last_channel - 2) && (imax <= last_channel + 2)) { + if (detect_counter == 8) { + if (imax != last_channel) { + char finalstr[24] = {0}; + + // 236 steps = 10MHz + // Resolution = 42.4kHz + auto fstr = to_string_dec_int((slice_start + (42373 * (imax - 118))) / 1000); + + strcat(finalstr, "Locked: "); + strcat(finalstr, fstr.c_str()); + text_infos.set(finalstr); + } + + locked = true; + release_counter = 0; + } else { + detect_counter++; + } + } else { + if (locked == true) { + if (release_counter == 8) { + detect_counter = 0; + locked = false; + text_infos.set("Lost "); + } else { + release_counter++; + } + } + } + + last_channel = imax; + + last_pos = (ui::Coord)(imax + 2); + portapack::display.fill_rectangle({last_pos, 60, 1, 9}, Color::red()); +} + +void CloseCallView::on_channel_spectrum(const ChannelSpectrum& spectrum) { + uint8_t xmax = 0; + uint16_t imax = 0; + uint8_t threshold; + size_t i; + + if (!wait) { + // Spectrum line (for debug) + std::array pixel_row; + for(i = 0; i < 118; i++) { + const auto pixel_color = spectrum_rgb3_lut[spectrum.db[256 - 120 + i]]; + pixel_row[i + 2] = pixel_color; + } + + for(i = 122; i < 240; i++) { + const auto pixel_color = spectrum_rgb3_lut[spectrum.db[i - 120]]; + pixel_row[i - 2] = pixel_color; + } + + display.draw_pixels( + { { 0, 64 + slices_counter * 4 }, { pixel_row.size(), 1 } }, + pixel_row + ); + + // Find max for this slice + for (i = 0; i < 118; i++) { + threshold = spectrum.db[256 - 120 + i]; + if (threshold > xmax) { + xmax = threshold; + imax = i; + } + } + for (i = 122; i < 240; i++) { + threshold = spectrum.db[i - 120]; + if (threshold > xmax) { + xmax = threshold; + imax = i - 4; + } + } + slicemax_db[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) { + if (slices_counter >= slices_max) { + do_detection(); + mean = 0; + slices_counter = 0; + } else { + slices_counter++; + } + slice_frequency = slice_start + (slices_counter * CC_SLICE_WIDTH); + receiver_model.set_tuning_frequency(slice_frequency); + wait = 1; + } else { + do_detection(); + } + } else { + wait--; + } +} + +void CloseCallView::on_show() { + EventDispatcher::message_map().register_handler(Message::ID::ChannelSpectrumConfig, + [this](const Message* const p) { + const auto message = *reinterpret_cast(p); + this->fifo = message.fifo; + } + ); + EventDispatcher::message_map().register_handler(Message::ID::DisplayFrameSync, + [this](const Message* const) { + if( this->fifo ) { + ChannelSpectrum channel_spectrum; + while( fifo->out(channel_spectrum) ) { + this->on_channel_spectrum(channel_spectrum); + } + } + } + ); + + baseband::spectrum_streaming_start(); +} + +void CloseCallView::on_hide() { + baseband::spectrum_streaming_stop(); + + EventDispatcher::message_map().unregister_handler(Message::ID::DisplayFrameSync); + EventDispatcher::message_map().unregister_handler(Message::ID::ChannelSpectrumConfig); +} + +void CloseCallView::on_range_changed() { + rf::Frequency f_min, f_max; + rf::Frequency slices_span; + int64_t offset; + + f_max = field_frequency_max.value(); + f_min = field_frequency_min.value(); + scan_span = abs(f_max - f_min); + if (scan_span > CC_SLICE_WIDTH) { + // ex: 100~115 (15): 102.5(97.5~107.5) -> 112.5(107.5~117.5) = 2.5 lost left and right + slices_max = (scan_span + CC_SLICE_WIDTH - 1) / CC_SLICE_WIDTH; + // = 2 + slices_span = slices_max * CC_SLICE_WIDTH; + // = 20000000 + offset = (slices_span - scan_span) / 2; + // = (20000000 - 15000000) / 2 = 5000000 / 2 = 2500000 + slice_start = std::min(f_min, f_max) + offset; + + slices_max--; + slicing = true; + } else { + slice_frequency = (f_max + f_min) / 2; + //offset = (CC_SLICE_WIDTH - scan_span) / 2; + //slice_start = std::min(f_min, f_max) - offset; + slice_start = slice_frequency; + receiver_model.set_tuning_frequency(slice_frequency); + slices_max = 0; + slices_counter = 0; + slicing = false; + } + + text_slice.set(to_string_dec_int(slices_max + 1)); + slices_counter = 0; +} + +CloseCallView::CloseCallView( + NavigationView& nav +) +{ + add_children({ { + &field_frequency_min, + &field_frequency_max, + &text_slice, + &text_infos, + &button_exit + } }); + + field_frequency_min.set_value(receiver_model.tuning_frequency() - 2000000); + field_frequency_min.set_step(200000); + field_frequency_min.on_change = [this](rf::Frequency f) { + (void) f; + this->on_range_changed(); + }; + field_frequency_min.on_edit = [this, &nav]() { + auto new_view = nav.push(receiver_model.tuning_frequency()); + new_view->on_changed = [this](rf::Frequency f) { + this->on_range_changed(); + this->field_frequency_min.set_value(f); + }; + }; + + field_frequency_max.set_value(receiver_model.tuning_frequency() + 2000000); + field_frequency_max.set_step(200000); + field_frequency_max.on_change = [this](rf::Frequency f) { + (void) f; + this->on_range_changed(); + }; + field_frequency_max.on_edit = [this, &nav]() { + auto new_view = nav.push(receiver_model.tuning_frequency()); + new_view->on_changed = [this](rf::Frequency f) { + this->on_range_changed(); + this->field_frequency_max.set_value(f); + }; + }; + + on_range_changed(); + + button_exit.on_select = [&nav](Button&){ + nav.pop(); + }; + + /*field_lna.set_value(receiver_model.lna()); + field_lna.on_change = [this](int32_t v) { + this->on_lna_changed(v); + }; + + field_lna.on_show_options = [this]() { + this->on_show_options_rf_gain(); + }; + + field_vga.set_value(receiver_model.vga()); + field_vga.on_change = [this](int32_t v_db) { + this->on_vga_changed(v_db); + }; + field_vga.on_show_options = [this]() { + this->on_show_options_rf_gain(); + };*/ + + //receiver_model.set_lna(0); + //receiver_model.set_vga(0); + + + //audio::output::mute(); + receiver_model.set_baseband_configuration({ + .mode = toUType(ReceiverModel::Mode::CloseCall), + .sampling_rate = CC_SLICE_WIDTH, + .decimation_factor = 1, + }); + receiver_model.set_baseband_bandwidth(CC_SLICE_WIDTH); + receiver_model.enable(); + //audio::output::unmute(); + +} + +} /* namespace ui */ diff --git a/firmware/application/ui_closecall.hpp b/firmware/application/ui_closecall.hpp new file mode 100644 index 000000000..ad90f578f --- /dev/null +++ b/firmware/application/ui_closecall.hpp @@ -0,0 +1,102 @@ +/* + * 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 "ui.hpp" +#include "ui_widget.hpp" +#include "ui_painter.hpp" +#include "ui_menu.hpp" +#include "ui_navigation.hpp" +#include "clock_manager.hpp" +#include "message.hpp" +#include "rf_path.hpp" +#include "volume.hpp" +#include "receiver_model.hpp"*/ + +#include "receiver_model.hpp" + +#include "spectrum_color_lut.hpp" + +#include "ui_receiver.hpp" +#include "ui_spectrum.hpp" +#include "ui_record_view.hpp" + +#include "ui_font_fixed_8x16.hpp" + +namespace ui { + +#define CC_SLICE_WIDTH 10000000 + +class CloseCallView : public View { +public: + CloseCallView(NavigationView& nav); + ~CloseCallView(); + + void on_show() override; + void on_hide() override; + void focus() override; + std::string title() const override { return "Close call"; }; + +private: + Coord last_pos = 0; + ChannelSpectrumFIFO* fifo { nullptr }; + uint8_t detect_counter = 0, release_counter = 0; + uint8_t wait = 2; + uint32_t mean = 0; + rf::Frequency slice_start; + rf::Frequency slice_frequency; + uint8_t slices_max; + uint8_t slices_counter; + uint16_t last_channel; + rf::Frequency scan_span; + uint8_t slicemax_db[32]; // Todo: Cap max slices ! + uint8_t slicemax_idx[32]; + bool ignore = true; + bool slicing; + bool locked = false; + void on_channel_spectrum(const ChannelSpectrum& spectrum); + void on_range_changed(); + void do_detection(); + + FrequencyField field_frequency_min { + { 1 * 8, 0 * 16 }, + }; + FrequencyField field_frequency_max { + { 12 * 8, 0 * 16 }, + }; + + Text text_slice { + { 23 * 8, 0 * 16, 2 * 8, 16 }, + "--" + }; + + Text text_infos { + { 1 * 8, 1 * 16, 18 * 8, 16 }, + "..." + }; + + Button button_exit { + { 92, 264, 56, 32 }, + "Exit" + }; +}; + +} /* namespace ui */ diff --git a/firmware/application/ui_loadmodule.cpp b/firmware/application/ui_loadmodule.cpp index c6525ed69..4d782fce2 100644 --- a/firmware/application/ui_loadmodule.cpp +++ b/firmware/application/ui_loadmodule.cpp @@ -38,6 +38,7 @@ #include "analog_audio_app.hpp" #include "ui_soundboard.hpp" #include "ui_debug.hpp" +#include "ui_closecall.hpp" #include "ui_audiotx.hpp" #include @@ -51,10 +52,6 @@ void LoadModuleView::focus() { button_ok.focus(); } -void LoadModuleView::paint(Painter& painter) { - (void)painter; -} - void LoadModuleView::on_hide() { EventDispatcher::message_map().unregister_handler(Message::ID::ReadyForSwitch); EventDispatcher::message_map().unregister_handler(Message::ID::ModuleID); @@ -152,12 +149,10 @@ void LoadModuleView::loadmodule() { LoadModuleView::LoadModuleView( NavigationView& nav, const char * hash, - uint8_t ViewID, - bool loadplz + ViewID viewid ) { - if (loadplz == false) nav.pop(); // Useless, remove ! - + add_children({ { &text_info, &text_infob, @@ -165,17 +160,18 @@ LoadModuleView::LoadModuleView( } }); _hash = hash; - - button_ok.on_select = [this, &nav, ViewID](Button&){ + + button_ok.on_select = [this, &nav, viewid](Button&){ + nav.pop(); if (_mod_loaded == true) { - if (ViewID == 0) nav.push(); //nav.push(); - if (ViewID == 1) nav.push(); - if (ViewID == 2) nav.push(); - if (ViewID == 3) nav.push(); - - if (ViewID == 10) nav.push(); - } else { - nav.pop(); + if (viewid == AudioTX) nav.push(); + if (viewid == Xylos) nav.push(); + if (viewid == LCR) nav.push(); + if (viewid == SoundBoard) nav.push(); + if (viewid == AnalogAudio) nav.push(); + if (viewid == RDS) nav.push(); + if (viewid == CloseCall) nav.push(); + if (viewid == Receiver) nav.push(); } }; } diff --git a/firmware/application/ui_loadmodule.hpp b/firmware/application/ui_loadmodule.hpp index fa7c05a8e..d2d35e998 100644 --- a/firmware/application/ui_loadmodule.hpp +++ b/firmware/application/ui_loadmodule.hpp @@ -30,15 +30,25 @@ namespace ui { +enum ViewID { + Receiver, + AudioTX, + CloseCall, + Xylos, + LCR, + SoundBoard, + AnalogAudio, + RDS, +}; + class LoadModuleView : public View { public: - LoadModuleView(NavigationView& nav, const char * hash, uint8_t ViewID, bool loadplz); + LoadModuleView(NavigationView& nav, const char * hash, ViewID viewid); void loadmodule(); void on_show() override; void on_hide() override; void focus() override; - void paint(Painter& painter) override; private: int load_image(void); diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index f0712098f..f4130c68b 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -173,7 +173,7 @@ TranspondersMenuView::TranspondersMenuView(NavigationView& nav) { ReceiverMenuView::ReceiverMenuView(NavigationView& nav) { add_items<2>({ { - { "Audio", ui::Color::white(), [&nav](){ nav.push(md5_baseband, 10, true); } }, + { "Audio", ui::Color::white(), [&nav](){ nav.push(); } }, { "Transponders", ui::Color::white(), [&nav](){ nav.push(); } }, } }); on_left = [&nav](){ nav.pop(); }; @@ -182,19 +182,21 @@ ReceiverMenuView::ReceiverMenuView(NavigationView& nav) { /* SystemMenuView ********************************************************/ SystemMenuView::SystemMenuView(NavigationView& nav) { - add_items<10>({ { + add_items<12>({ { { "Play dead", ui::Color::red(), [&nav](){ nav.push(false); } }, - { "Receiver RX", ui::Color::cyan(), [&nav](){ nav.push(); } }, - { "Soundboard TX", ui::Color::orange(), [&nav](){ nav.push(md5_baseband_tx, 3, true); } }, - { "Audio TX TX", ui::Color::yellow(), [&nav](){ nav.push(md5_baseband_tx, 0, true); } }, - { "Xylos TX", ui::Color::yellow(), [&nav](){ nav.push(md5_baseband_tx, 1, true); } }, - { "TEDI/LCR TX", ui::Color::yellow(), [&nav](){ nav.push(md5_baseband_tx, 2, true); } }, + { "Receiver RX", ui::Color::cyan(), [&nav](){ nav.push(md5_baseband, Receiver); } }, + { "Close Call RX", ui::Color::cyan(), [&nav](){ nav.push(md5_baseband, CloseCall); } }, + { "Soundboard TX", ui::Color::yellow(), [&nav](){ nav.push(md5_baseband_tx, SoundBoard); } }, + { "Audio TX", ui::Color::yellow(), [&nav](){ nav.push(md5_baseband_tx, AudioTX); } }, + { "Xylos TX", ui::Color::orange(), [&nav](){ nav.push(md5_baseband_tx, Xylos); } }, + { "TEDI/LCR TX", ui::Color::orange(), [&nav](){ nav.push(md5_baseband_tx, LCR); } }, + { "RDS TX", ui::Color::yellow(), [&nav](){ nav.push(md5_baseband_tx, RDS); } }, //{ "Capture", ui::Color::white(), [&nav](){ nav.push(); } }, //{ "Analyze", ui::Color::white(), [&nav](){ nav.push(); } }, { "Setup", ui::Color::white(), [&nav](){ nav.push(); } }, - { "About", ui::Color::white(), [&nav](){ nav.push(); } }, { "Debug", ui::Color::white(), [&nav](){ nav.push(); } }, { "HackRF", ui::Color::white(), [&nav](){ nav.push(); } }, + { "About", ui::Color::white(), [&nav](){ nav.push(); } } } }); //{ "Nordic/BTLE RX", ui::Color::cyan(), [&nav](){ nav.push(new NotImplementedView { nav }); } }, @@ -225,7 +227,7 @@ SystemView::SystemView( { set_style(&style_default); - char debugtxt[21]; // DEBUG + //char debugtxt[21]; // DEBUG constexpr ui::Dim status_view_height = 16; diff --git a/firmware/application/ui_sigfrx.cpp b/firmware/application/ui_sigfrx.cpp index bc6c5f6e3..8ad9cd1e1 100644 --- a/firmware/application/ui_sigfrx.cpp +++ b/firmware/application/ui_sigfrx.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek * * This file is part of PortaPack. * diff --git a/firmware/application/ui_sigfrx.hpp b/firmware/application/ui_sigfrx.hpp index 3b83ac07b..15cd734a4 100644 --- a/firmware/application/ui_sigfrx.hpp +++ b/firmware/application/ui_sigfrx.hpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek * * This file is part of PortaPack. * diff --git a/firmware/baseband-tx.bin b/firmware/baseband-tx.bin index eed6adfe1..7ee70f4d5 100644 Binary files a/firmware/baseband-tx.bin and b/firmware/baseband-tx.bin differ diff --git a/firmware/baseband-tx/Makefile b/firmware/baseband-tx/Makefile index 48f288b78..cfe010f90 100755 --- a/firmware/baseband-tx/Makefile +++ b/firmware/baseband-tx/Makefile @@ -139,9 +139,9 @@ CPPSRC = main.cpp \ dsp_demodulate.cpp \ matched_filter.cpp \ proc_audiotx.cpp \ + proc_fsk_lcr.cpp \ proc_playaudio.cpp \ proc_xylos.cpp \ - proc_fsk_lcr.cpp \ dsp_squelch.cpp \ clock_recovery.cpp \ packet_builder.cpp \ diff --git a/firmware/baseband-tx/spectrum_collector.cpp b/firmware/baseband-tx/spectrum_collector.cpp deleted file mode 100644 index 0d288beee..000000000 --- a/firmware/baseband-tx/spectrum_collector.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. - * - * 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 "spectrum_collector.hpp" - -#include "dsp_fft.hpp" - -#include "utility.hpp" -#include "event_m4.hpp" -#include "portapack_shared_memory.hpp" - -#include "event_m4.hpp" - -#include - -void SpectrumCollector::on_message(const Message* const message) { - switch(message->id) { - case Message::ID::UpdateSpectrum: - update(); - break; - - case Message::ID::SpectrumStreamingConfig: - set_state(*reinterpret_cast(message)); - break; - - default: - break; - } -} - -void SpectrumCollector::set_state(const SpectrumStreamingConfigMessage& message) { - if( message.mode == SpectrumStreamingConfigMessage::Mode::Running ) { - start(); - } else { - stop(); - } -} - -void SpectrumCollector::start() { - streaming = true; - ChannelSpectrumConfigMessage message { &fifo }; - shared_memory.application_queue.push(message); -} - -void SpectrumCollector::stop() { - streaming = false; - fifo.reset_in(); -} - -void SpectrumCollector::set_decimation_factor( - const size_t decimation_factor -) { - channel_spectrum_decimator.set_factor(decimation_factor); -} - -/* TODO: Refactor to register task with idle thread? - * It's sad that the idle thread has to call all the way back here just to - * perform the deferred task on the buffer of data we prepared. - */ - -void SpectrumCollector::feed( - const buffer_c16_t& channel, - const uint32_t filter_pass_frequency, - const uint32_t filter_stop_frequency -) { - // Called from baseband processing thread. - channel_filter_pass_frequency = filter_pass_frequency; - channel_filter_stop_frequency = filter_stop_frequency; - - channel_spectrum_decimator.feed( - channel, - [this](const buffer_c16_t& data) { - this->post_message(data); - } - ); -} - -void SpectrumCollector::post_message(const buffer_c16_t& data) { - // Called from baseband processing thread. - if( streaming && !channel_spectrum_request_update ) { - fft_swap(data, channel_spectrum); - channel_spectrum_sampling_rate = data.sampling_rate; - channel_spectrum_request_update = true; - EventDispatcher::events_flag(EVT_MASK_SPECTRUM); - } -} - -void SpectrumCollector::update() { - // Called from idle thread (after EVT_MASK_SPECTRUM is flagged) - if( streaming && channel_spectrum_request_update ) { - /* Decimated buffer is full. Compute spectrum. */ - fft_c_preswapped(channel_spectrum); - - ChannelSpectrum spectrum; - spectrum.sampling_rate = channel_spectrum_sampling_rate; - spectrum.channel_filter_pass_frequency = channel_filter_pass_frequency; - spectrum.channel_filter_stop_frequency = channel_filter_stop_frequency; - for(size_t i=0; i -#include - -#include "message.hpp" - -class SpectrumCollector { -public: - constexpr SpectrumCollector( - ) : channel_spectrum_decimator { 1 }, - fifo { fifo_data, ChannelSpectrumConfigMessage::fifo_k } - { - } - - void on_message(const Message* const message); - - void set_decimation_factor(const size_t decimation_factor); - - void feed( - const buffer_c16_t& channel, - const uint32_t filter_pass_frequency, - const uint32_t filter_stop_frequency - ); - -private: - BlockDecimator channel_spectrum_decimator; - ChannelSpectrumFIFO fifo; - ChannelSpectrum fifo_data[1 << ChannelSpectrumConfigMessage::fifo_k]; - - volatile bool channel_spectrum_request_update { false }; - bool streaming { false }; - std::array, 256> channel_spectrum; - uint32_t channel_spectrum_sampling_rate { 0 }; - uint32_t channel_filter_pass_frequency { 0 }; - uint32_t channel_filter_stop_frequency { 0 }; - - void post_message(const buffer_c16_t& data); - - void set_state(const SpectrumStreamingConfigMessage& message); - void start(); - void stop(); - - void update(); -}; - -#endif/*__SPECTRUM_COLLECTOR_H__*/ diff --git a/firmware/baseband.bin b/firmware/baseband.bin index ec73e7d39..187b9c21d 100644 Binary files a/firmware/baseband.bin and b/firmware/baseband.bin differ diff --git a/firmware/baseband/baseband_thread.cpp b/firmware/baseband/baseband_thread.cpp index 88d77ef09..37f362758 100644 --- a/firmware/baseband/baseband_thread.cpp +++ b/firmware/baseband/baseband_thread.cpp @@ -132,6 +132,7 @@ BasebandProcessor* BasebandThread::create_processor(const int32_t mode) { case 5: return new TPMSProcessor(); case 6: return new ERTProcessor(); case 7: return new CaptureProcessor(); + case 10: return new WidebandSpectrum(); // Close call default: return nullptr; } } diff --git a/firmware/common/modules.h b/firmware/common/modules.h index 88a3a9ee2..38ca88d43 100644 --- a/firmware/common/modules.h +++ b/firmware/common/modules.h @@ -1,2 +1,2 @@ -const char md5_baseband[16] = {0x44,0xbd,0x72,0x34,0x68,0xd8,0xf1,0x97,0xd8,0xc0,0xd0,0x7a,0xfd,0x6a,0xc1,0xc5,}; -const char md5_baseband_tx[16] = {0x6c,0xfd,0x05,0x4c,0x96,0xdd,0xca,0x39,0xf9,0xab,0x57,0xfe,0x1a,0x49,0x36,0x15,}; +const char md5_baseband[16] = {0x1a,0x50,0xbc,0xc5,0xf4,0x5a,0x50,0x1b,0x3f,0x88,0x4c,0xb5,0xb3,0x95,0xa9,0x4d,}; +const char md5_baseband_tx[16] = {0xf6,0x31,0x51,0xa5,0x0a,0xb1,0x36,0xf8,0xbe,0x4e,0xe2,0x7b,0x84,0xfc,0x62,0xac,}; diff --git a/firmware/portapack-h1-firmware.bin b/firmware/portapack-h1-firmware.bin index adaf61ac2..71447fd78 100644 Binary files a/firmware/portapack-h1-firmware.bin and b/firmware/portapack-h1-firmware.bin differ diff --git a/firmware/tools/make_baseband_file.py b/firmware/tools/make_baseband_file.py index 50ac5031b..f0c96f1da 100755 --- a/firmware/tools/make_baseband_file.py +++ b/firmware/tools/make_baseband_file.py @@ -23,7 +23,7 @@ import struct import md5 usage_message = """ -Baseband processors modules package file generator +Baseband module package file generator Usage: ... """ diff --git a/sdcard/baseband-tx.bin b/sdcard/baseband-tx.bin index eed6adfe1..7ee70f4d5 100644 Binary files a/sdcard/baseband-tx.bin and b/sdcard/baseband-tx.bin differ diff --git a/sdcard/baseband.bin b/sdcard/baseband.bin index ec73e7d39..187b9c21d 100644 Binary files a/sdcard/baseband.bin and b/sdcard/baseband.bin differ