From e751e10e4501b4b72cf27568267f85e461f4b837 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 27 Aug 2015 13:57:31 -0700 Subject: [PATCH] Add wideband spectrum processor. --- firmware/application/receiver_model.cpp | 24 +-- firmware/application/receiver_model.hpp | 6 +- firmware/application/ui_receiver.cpp | 34 +++- firmware/application/ui_receiver.hpp | 1 + firmware/baseband/Makefile | 1 + firmware/baseband/main.cpp | 5 + firmware/baseband/proc_wideband_spectrum.cpp | 197 +++++++++++++++++++ firmware/baseband/proc_wideband_spectrum.hpp | 37 ++++ 8 files changed, 278 insertions(+), 27 deletions(-) create mode 100644 firmware/baseband/proc_wideband_spectrum.cpp create mode 100644 firmware/baseband/proc_wideband_spectrum.hpp diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index 93090025..009ae829 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -92,20 +92,10 @@ uint32_t ReceiverModel::sampling_rate() const { return baseband_configuration.sampling_rate; } -void ReceiverModel::set_sampling_rate(uint32_t hz) { - baseband_configuration.sampling_rate = hz; - update_baseband_configuration(); -} - uint32_t ReceiverModel::modulation() const { return baseband_configuration.mode; } -void ReceiverModel::set_modulation(uint32_t v) { - baseband_configuration.mode = v; - update_modulation(); -} - volume_t ReceiverModel::headphone_volume() const { return headphone_volume_; } @@ -120,11 +110,6 @@ uint32_t ReceiverModel::baseband_oversampling() const { return baseband_configuration.decimation_factor; } -void ReceiverModel::set_baseband_oversampling(uint32_t v) { - baseband_configuration.decimation_factor = v; - update_baseband_configuration(); -} - void ReceiverModel::enable() { radio::set_direction(rf::Direction::Receive); update_tuning_frequency(); @@ -153,7 +138,11 @@ void ReceiverModel::disable() { } int32_t ReceiverModel::tuning_offset() { - return -(sampling_rate() / 4); + if( baseband_configuration.mode == 4 ) { + return 0; + } else { + return -(sampling_rate() / 4); + } } void ReceiverModel::update_tuning_frequency() { @@ -176,7 +165,8 @@ void ReceiverModel::update_vga() { radio::set_vga_gain(vga_gain_db_); } -void ReceiverModel::update_modulation() { +void ReceiverModel::set_baseband_configuration(const BasebandConfiguration config) { + baseband_configuration = config; update_baseband_configuration(); } diff --git a/firmware/application/receiver_model.hpp b/firmware/application/receiver_model.hpp index a6af119c..9fc7aefd 100644 --- a/firmware/application/receiver_model.hpp +++ b/firmware/application/receiver_model.hpp @@ -61,20 +61,19 @@ public: void set_vga(int32_t v_db); uint32_t sampling_rate() const; - void set_sampling_rate(uint32_t hz); uint32_t modulation() const; - void set_modulation(uint32_t v); volume_t headphone_volume() const; void set_headphone_volume(volume_t v); uint32_t baseband_oversampling() const; - void set_baseband_oversampling(uint32_t v); void enable(); void disable(); + void set_baseband_configuration(const BasebandConfiguration config); + private: rf::Frequency frequency_step_ { 25000 }; bool rf_amp_ { false }; @@ -96,7 +95,6 @@ private: void update_lna(); void update_baseband_bandwidth(); void update_vga(); - void update_modulation(); void update_baseband_configuration(); void update_headphone_volume(); diff --git a/firmware/application/ui_receiver.cpp b/firmware/application/ui_receiver.cpp index 7dfbb38e..2ff8c8f2 100644 --- a/firmware/application/ui_receiver.cpp +++ b/firmware/application/ui_receiver.cpp @@ -538,13 +538,35 @@ void ReceiverView::on_vga_changed(int32_t v_db) { } void ReceiverView::on_modulation_changed(int32_t modulation) { - if( modulation == 3 ) { - /* TODO: This is TERRIBLE!!! */ - receiver_model.set_sampling_rate(2457600); - } else { - receiver_model.set_sampling_rate(3072000); + /* TODO: This is TERRIBLE!!! */ + switch(modulation) { + case 3: + receiver_model.set_baseband_configuration({ + .mode = modulation, + .sampling_rate = 2457600, + .decimation_factor = 4, + }); + receiver_model.set_baseband_bandwidth(1750000); + break; + + case 4: + receiver_model.set_baseband_configuration({ + .mode = modulation, + .sampling_rate = 20000000, + .decimation_factor = 1, + }); + receiver_model.set_baseband_bandwidth(12000000); + break; + + default: + receiver_model.set_baseband_configuration({ + .mode = modulation, + .sampling_rate = 3072000, + .decimation_factor = 4, + }); + receiver_model.set_baseband_bandwidth(1750000); + break; } - receiver_model.set_modulation(modulation); } void ReceiverView::on_show_options_frequency() { diff --git a/firmware/application/ui_receiver.hpp b/firmware/application/ui_receiver.hpp index 3280ede6..01725aad 100644 --- a/firmware/application/ui_receiver.hpp +++ b/firmware/application/ui_receiver.hpp @@ -419,6 +419,7 @@ private: { "NFM ", 1 }, { "WFM ", 2 }, { "FSK ", 3 }, + { "SPEC", 4 }, } }; /* diff --git a/firmware/baseband/Makefile b/firmware/baseband/Makefile index 6331b798..b92cf0c8 100755 --- a/firmware/baseband/Makefile +++ b/firmware/baseband/Makefile @@ -137,6 +137,7 @@ CPPSRC = main.cpp \ proc_nfm_audio.cpp \ proc_wfm_audio.cpp \ proc_fsk.cpp \ + proc_wideband_spectrum.cpp \ dsp_squelch.cpp \ clock_recovery.cpp \ access_code_correlator.cpp \ diff --git a/firmware/baseband/main.cpp b/firmware/baseband/main.cpp index 3fa152a5..297d63c0 100755 --- a/firmware/baseband/main.cpp +++ b/firmware/baseband/main.cpp @@ -56,6 +56,7 @@ #include "proc_nfm_audio.hpp" #include "proc_wfm_audio.hpp" #include "proc_fsk.hpp" +#include "proc_wideband_spectrum.hpp" #include "clock_recovery.hpp" #include "access_code_correlator.hpp" @@ -296,6 +297,10 @@ int main(void) { baseband_processor = new FSKProcessor(message_handlers); break; + case 4: + baseband_processor = new WidebandSpectrum(); + break; + default: break; } diff --git a/firmware/baseband/proc_wideband_spectrum.cpp b/firmware/baseband/proc_wideband_spectrum.cpp new file mode 100644 index 00000000..39480981 --- /dev/null +++ b/firmware/baseband/proc_wideband_spectrum.cpp @@ -0,0 +1,197 @@ +/* + * 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 "proc_wideband_spectrum.hpp" + +#include "event_m4.hpp" + +#include "i2s.hpp" +using namespace lpc43xx; + +#include +#include + +#include + +// numpy.array(numpy.round(scipy.signal.windows.blackmanharris(1024) * 32767), dtype=numpy.int16) +static constexpr std::array window_blackmanharris_1024 { { + 2, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 4, 4, 5, 5, 5, 6, + 7, 7, 8, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, + 22, 23, 24, 26, 27, 29, 31, 32, + 34, 36, 38, 40, 42, 44, 46, 48, + 51, 53, 56, 58, 61, 64, 67, 70, + 73, 76, 79, 82, 86, 89, 93, 97, + 100, 104, 109, 113, 117, 122, 126, 131, + 136, 141, 146, 151, 156, 162, 168, 173, + 179, 186, 192, 198, 205, 212, 219, 226, + 233, 241, 249, 256, 265, 273, 281, 290, + 299, 308, 317, 327, 337, 347, 357, 367, + 378, 389, 400, 411, 423, 435, 447, 459, + 472, 485, 498, 512, 526, 540, 554, 569, + 584, 599, 614, 630, 646, 663, 680, 697, + 714, 732, 750, 769, 788, 807, 827, 846, + 867, 887, 908, 930, 952, 974, 996, 1019, + 1043, 1066, 1091, 1115, 1140, 1166, 1192, 1218, + 1245, 1272, 1299, 1327, 1356, 1385, 1414, 1444, + 1475, 1506, 1537, 1569, 1601, 1634, 1667, 1701, + 1735, 1770, 1805, 1841, 1878, 1915, 1952, 1990, + 2029, 2068, 2107, 2147, 2188, 2229, 2271, 2314, + 2357, 2400, 2444, 2489, 2534, 2580, 2627, 2674, + 2721, 2770, 2819, 2868, 2918, 2969, 3020, 3072, + 3125, 3178, 3232, 3287, 3342, 3398, 3454, 3511, + 3569, 3628, 3687, 3746, 3807, 3868, 3930, 3992, + 4055, 4119, 4183, 4249, 4314, 4381, 4448, 4516, + 4585, 4654, 4724, 4794, 4866, 4938, 5010, 5084, + 5158, 5233, 5308, 5385, 5462, 5539, 5618, 5697, + 5776, 5857, 5938, 6020, 6103, 6186, 6270, 6355, + 6440, 6526, 6613, 6700, 6789, 6878, 6967, 7058, + 7149, 7240, 7333, 7426, 7520, 7614, 7710, 7805, + 7902, 7999, 8097, 8196, 8295, 8395, 8496, 8597, + 8699, 8802, 8905, 9009, 9114, 9219, 9325, 9431, + 9539, 9646, 9755, 9864, 9974, 10084, 10195, 10306, +10419, 10531, 10645, 10759, 10873, 10988, 11104, 11220, +11337, 11454, 11572, 11691, 11810, 11929, 12049, 12170, +12291, 12412, 12534, 12657, 12780, 12903, 13027, 13152, +13277, 13402, 13528, 13654, 13781, 13908, 14035, 14163, +14291, 14420, 14549, 14678, 14808, 14938, 15068, 15199, +15330, 15461, 15593, 15725, 15857, 15989, 16122, 16255, +16388, 16522, 16655, 16789, 16923, 17058, 17192, 17327, +17461, 17596, 17731, 17867, 18002, 18137, 18273, 18408, +18544, 18680, 18815, 18951, 19087, 19223, 19358, 19494, +19630, 19765, 19901, 20037, 20172, 20308, 20443, 20578, +20713, 20848, 20983, 21118, 21252, 21386, 21520, 21654, +21788, 21921, 22054, 22187, 22320, 22452, 22584, 22716, +22847, 22978, 23109, 23239, 23369, 23499, 23628, 23757, +23885, 24013, 24140, 24267, 24394, 24520, 24645, 24770, +24894, 25018, 25142, 25264, 25386, 25508, 25629, 25749, +25869, 25988, 26106, 26224, 26341, 26457, 26573, 26688, +26802, 26915, 27028, 27139, 27251, 27361, 27470, 27579, +27687, 27794, 27900, 28005, 28109, 28213, 28315, 28417, +28518, 28617, 28716, 28814, 28911, 29007, 29102, 29196, +29288, 29380, 29471, 29561, 29650, 29737, 29824, 29909, +29994, 30077, 30159, 30240, 30320, 30399, 30477, 30553, +30628, 30702, 30775, 30847, 30918, 30987, 31055, 31122, +31188, 31252, 31315, 31377, 31438, 31497, 31555, 31612, +31667, 31721, 31774, 31826, 31876, 31925, 31972, 32019, +32064, 32107, 32149, 32190, 32230, 32268, 32304, 32340, +32374, 32406, 32438, 32467, 32496, 32523, 32548, 32573, +32595, 32617, 32637, 32655, 32672, 32688, 32702, 32715, +32727, 32737, 32745, 32753, 32758, 32763, 32765, 32767, +32767, 32765, 32763, 32758, 32753, 32745, 32737, 32727, +32715, 32702, 32688, 32672, 32655, 32637, 32617, 32595, +32573, 32548, 32523, 32496, 32467, 32438, 32406, 32374, +32340, 32304, 32268, 32230, 32190, 32149, 32107, 32064, +32019, 31972, 31925, 31876, 31826, 31774, 31721, 31667, +31612, 31555, 31497, 31438, 31377, 31315, 31252, 31188, +31122, 31055, 30987, 30918, 30847, 30775, 30702, 30628, +30553, 30477, 30399, 30320, 30240, 30159, 30077, 29994, +29909, 29824, 29737, 29650, 29561, 29471, 29380, 29288, +29196, 29102, 29007, 28911, 28814, 28716, 28617, 28518, +28417, 28315, 28213, 28109, 28005, 27900, 27794, 27687, +27579, 27470, 27361, 27251, 27139, 27028, 26915, 26802, +26688, 26573, 26457, 26341, 26224, 26106, 25988, 25869, +25749, 25629, 25508, 25386, 25264, 25142, 25018, 24894, +24770, 24645, 24520, 24394, 24267, 24140, 24013, 23885, +23757, 23628, 23499, 23369, 23239, 23109, 22978, 22847, +22716, 22584, 22452, 22320, 22187, 22054, 21921, 21788, +21654, 21520, 21386, 21252, 21118, 20983, 20848, 20713, +20578, 20443, 20308, 20172, 20037, 19901, 19765, 19630, +19494, 19358, 19223, 19087, 18951, 18815, 18680, 18544, +18408, 18273, 18137, 18002, 17867, 17731, 17596, 17461, +17327, 17192, 17058, 16923, 16789, 16655, 16522, 16388, +16255, 16122, 15989, 15857, 15725, 15593, 15461, 15330, +15199, 15068, 14938, 14808, 14678, 14549, 14420, 14291, +14163, 14035, 13908, 13781, 13654, 13528, 13402, 13277, +13152, 13027, 12903, 12780, 12657, 12534, 12412, 12291, +12170, 12049, 11929, 11810, 11691, 11572, 11454, 11337, +11220, 11104, 10988, 10873, 10759, 10645, 10531, 10419, +10306, 10195, 10084, 9974, 9864, 9755, 9646, 9539, + 9431, 9325, 9219, 9114, 9009, 8905, 8802, 8699, + 8597, 8496, 8395, 8295, 8196, 8097, 7999, 7902, + 7805, 7710, 7614, 7520, 7426, 7333, 7240, 7149, + 7058, 6967, 6878, 6789, 6700, 6613, 6526, 6440, + 6355, 6270, 6186, 6103, 6020, 5938, 5857, 5776, + 5697, 5618, 5539, 5462, 5385, 5308, 5233, 5158, + 5084, 5010, 4938, 4866, 4794, 4724, 4654, 4585, + 4516, 4448, 4381, 4314, 4249, 4183, 4119, 4055, + 3992, 3930, 3868, 3807, 3746, 3687, 3628, 3569, + 3511, 3454, 3398, 3342, 3287, 3232, 3178, 3125, + 3072, 3020, 2969, 2918, 2868, 2819, 2770, 2721, + 2674, 2627, 2580, 2534, 2489, 2444, 2400, 2357, + 2314, 2271, 2229, 2188, 2147, 2107, 2068, 2029, + 1990, 1952, 1915, 1878, 1841, 1805, 1770, 1735, + 1701, 1667, 1634, 1601, 1569, 1537, 1506, 1475, + 1444, 1414, 1385, 1356, 1327, 1299, 1272, 1245, + 1218, 1192, 1166, 1140, 1115, 1091, 1066, 1043, + 1019, 996, 974, 952, 930, 908, 887, 867, + 846, 827, 807, 788, 769, 750, 732, 714, + 697, 680, 663, 646, 630, 614, 599, 584, + 569, 554, 540, 526, 512, 498, 485, 472, + 459, 447, 435, 423, 411, 400, 389, 378, + 367, 357, 347, 337, 327, 317, 308, 299, + 290, 281, 273, 265, 256, 249, 241, 233, + 226, 219, 212, 205, 198, 192, 186, 179, + 173, 168, 162, 156, 151, 146, 141, 136, + 131, 126, 122, 117, 113, 109, 104, 100, + 97, 93, 89, 86, 82, 79, 76, 73, + 70, 67, 64, 61, 58, 56, 53, 51, + 48, 46, 44, 42, 40, 38, 36, 34, + 32, 31, 29, 27, 26, 24, 23, 22, + 20, 19, 18, 17, 16, 15, 14, 13, + 12, 11, 10, 9, 8, 8, 7, 7, + 6, 5, 5, 5, 4, 4, 3, 3, + 3, 3, 2, 2, 2, 2, 2, 2, +} }; + +void WidebandSpectrum::execute(buffer_c8_t buffer) { + sample_count += buffer.count; + if( sample_count > 400000 ) { + sample_count -= 400000; + + if( channel_spectrum_request_update == false ) { + channel_spectrum_request_update = true; + + for(size_t i=0; i + +class WidebandSpectrum : public BasebandProcessor { +public: + void execute(buffer_c8_t buffer) override; + +private: + size_t sample_count = 0; +}; + +#endif/*__PROC_WIDEBAND_SPECTRUM_H__*/