diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index 632cce8f5..0c336843e 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -152,6 +152,7 @@ set(CPPSRC ${COMMON}/bch_code.cpp ctcss.cpp encoder.cpp + de_bruijn.cpp freqman.cpp ${COMMON}/lcd_ili9341.cpp ${COMMON}/ui.cpp diff --git a/firmware/application/de_bruijn.cpp b/firmware/application/de_bruijn.cpp new file mode 100644 index 000000000..e99fc4e40 --- /dev/null +++ b/firmware/application/de_bruijn.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2017 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 "de_bruijn.hpp" + +/* +How this works: +B(2,4): 2 states, 4 bits +Primitive poly with n=4: 1001 + + 0001 +xor 1001 = 0 ^ 1 = 1 + + 00011 +xor 1001 = 0 ^ 1 = 1 + + 000111 +xor 1001 = 0 ^ 1 = 1 + + 0001111 +xor 1001 = 1 ^ 1 = 0 + + 00011110 +xor 1001 = 1 ^ 0 = 1 + + 000111101 +xor 1001 = 1 ^ 1 = 0 + + 0001111010 +xor 1001 = 0 ^ 1 = 1 + + 00011110101 +xor 1001 = 0 ^ 1 = 1 + + 000111101011 +xor 1001 = 1 ^ 1 = 0 + + 0001111010110 +xor 1001 = 0 ^ 0 = 0 + + 00011110101100 +xor 1001 = 1 ^ 0 = 1 + + 000111101011001 +xor 1001 = 1 ^ 1 = 0 + + 0001111010110010 +xor 1001 = 0 ^ 0 = 0 +*/ + +void de_bruijn::init(const uint32_t n) { + if ((n < 3) || (n > 16)) + length = 3; + else + length = n; + + // k is 2 (binary sequence) + poly = de_bruijn_polys[length - 3]; + shift_register = 1; +} + +uint32_t de_bruijn::compute(const uint32_t step) { + uint32_t c, bits, masked; + uint8_t new_bit; + + for (c = 0; c < step; c++) { + masked = shift_register & poly; + new_bit = 0; + for (bits = 0; bits < length; bits++) { + new_bit ^= (masked & 1); + masked >>= 1; + } + shift_register <<= 1; + shift_register |= new_bit; + } + + return shift_register; +} diff --git a/firmware/application/de_bruijn.hpp b/firmware/application/de_bruijn.hpp new file mode 100644 index 000000000..0d487b0f8 --- /dev/null +++ b/firmware/application/de_bruijn.hpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2017 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 + +#ifndef __DE_BRUIJN_H__ +#define __DE_BRUIJN_H__ + +// Starts at n = 3 +const uint32_t de_bruijn_polys[14] { + 0b0000000000000101, + 0b0000000000001001, + 0b0000000000011011, + 0b0000000000110011, + 0b0000000001010011, + 0b0000000010001101, + 0b0000000100100001, + 0b0000001000100001, + 0b0000010001100001, + 0b0000110101000011, + 0b0001001001100101, + 0b0010101100000011, + 0b0101000000001001, + 0b1010000101000101 +}; + +struct de_bruijn { +public: + void init(const uint32_t n); + uint32_t compute(const uint32_t step); + +private: + uint32_t length { }; + uint32_t poly { }; + uint32_t shift_register { }; +}; + +#endif/*__DE_BRUIJN_H__*/ diff --git a/firmware/application/pocsag_app.cpp b/firmware/application/pocsag_app.cpp index 609af233f..369b69486 100644 --- a/firmware/application/pocsag_app.cpp +++ b/firmware/application/pocsag_app.cpp @@ -57,10 +57,7 @@ namespace ui { void POCSAGAppView::update_freq(rf::Frequency f) { set_target_frequency(f); - portapack::persistent_memory::set_tuned_frequency(f); // Maybe not ? - - button_setfreq.set_text(to_string_short_freq(f)); } POCSAGAppView::POCSAGAppView(NavigationView& nav) { @@ -71,11 +68,10 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) { add_children({ &rssi, &channel, - &options_freq, &field_rf_amp, &field_lna, &field_vga, - &button_setfreq, + &field_frequency, &options_bitrate, &check_log, &check_ignore, @@ -87,6 +83,20 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) { receiver_model.set_baseband_bandwidth(1750000); receiver_model.enable(); + field_frequency.set_value(receiver_model.tuning_frequency()); + field_frequency.set_step(receiver_model.frequency_step()); + field_frequency.on_change = [this](rf::Frequency f) { + update_freq(f); + }; + field_frequency.on_edit = [this, &nav]() { + // TODO: Provide separate modal method/scheme? + auto new_view = nav.push(receiver_model.tuning_frequency()); + new_view->on_changed = [this](rf::Frequency f) { + update_freq(f); + field_frequency.set_value(f); + }; + }; + check_log.set_value(logging); check_log.on_select = [this](Checkbox&, bool v) { logging = v; @@ -96,12 +106,6 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) { on_bitrate_changed(v); }; options_bitrate.set_selected_index(1); // 1200bps - - options_freq.on_change = [this](size_t, OptionsField::value_t v) { - set_target_frequency(v); - update_freq(v); - }; - options_freq.set_by_value(target_frequency()); check_ignore.set_value(ignore); check_ignore.on_select = [this](Checkbox&, bool v) { @@ -113,22 +117,13 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) { sym_ignore.set_sym(6 - c, ignore_address % 10); ignore_address /= 10; } - - button_setfreq.on_select = [this,&nav](Button&) { - auto new_view = nav.push(target_frequency_); - new_view->on_changed = [this](rf::Frequency f) { - options_freq.set_selected_index(0); // Automatically select "Entered" - update_freq(f); - }; - }; logger = std::make_unique(); if (logger) logger->append("pocsag.txt"); } -POCSAGAppView::~POCSAGAppView() { - +POCSAGAppView::~POCSAGAppView() { // Save ignored address persistent_memory::set_pocsag_ignore_address(sym_ignore.value_dec_u32()); @@ -137,7 +132,7 @@ POCSAGAppView::~POCSAGAppView() { } void POCSAGAppView::focus() { - options_freq.focus(); + field_frequency.focus(); } // Useless ? diff --git a/firmware/application/pocsag_app.hpp b/firmware/application/pocsag_app.hpp index 81e3fc43a..92488c2b9 100644 --- a/firmware/application/pocsag_app.hpp +++ b/firmware/application/pocsag_app.hpp @@ -75,46 +75,6 @@ private: static constexpr ui::Dim header_height = 1 * 16; - OptionsField options_freq { - { 0 * 8, 0 * 16 }, - 12, - { - { "Entered", 0 }, - { "BEL Fire", 169625000 }, - { "DEU Fire", 448425000 }, - { "DEU e-Msg1", 465970000 }, - { "DEU e-Msg2", 466075000 }, - { "FRA e-Msg1", 466025000 }, - { "FRA e-Msg2", 466050000 }, - { "FRA e-Msg3", 466075000 }, - { "FRA e-Msg4", 466175000 }, - { "FRA e-Msg5", 466206250 }, - { "FRA e-Msg6", 466231250 }, - { "FRA Fire *", 173512500 }, - { "FRA Fire HF", 85955000 }, - { "FRA Fire 1", 173550000 }, - { "FRA Fire 2", 173625000 }, - { "FRA Fire 3", 173550000 }, - { "FRA Fire 4", 173700000 }, - { "FRA Fire 5", 173875000 }, - { "FRA Fire 6", 173925000 }, - { "FRA Fire 7", 173550000 }, - { "FRA Fire 8", 168950000 }, - { "FRA Fire 9", 169025000 }, - { "FRA Fire 10", 169100000 }, - { "FRA Fire 11", 169275000 }, - { "FRA Fire 12", 169325000 }, - { "FRA Priv1", 446475000 }, - { "FRA Priv2", 446525000 }, * works near Paris - { "NL Medical", 169650000 }, - { "NL KPN3-Public", 172450000 }, - { "SWE Minicall1", 169800000 }, - { "SWE Minicall2", 161437500 }, - { "USA Medical1", 152007500 }, - { "USA Medical2", 157450000 }, - { "USA Medical3", 163250000 } - } - }; RFAmpField field_rf_amp { { 13 * 8, 0 * 16 } }; @@ -131,9 +91,8 @@ private: { 21 * 8, 5, 6 * 8, 4 }, }; - Button button_setfreq { - { 0, 19, 11 * 8, 20 }, - "----.----" + FrequencyField field_frequency { + { 0 * 8, 0 * 8 }, }; OptionsField options_bitrate { { 12 * 8, 21 }, diff --git a/firmware/application/ui_encoders.cpp b/firmware/application/ui_encoders.cpp index aa66a960f..5da7b6625 100644 --- a/firmware/application/ui_encoders.cpp +++ b/firmware/application/ui_encoders.cpp @@ -270,6 +270,7 @@ EncodersView::EncodersView(NavigationView& nav) { &numberfield_clk, &numberfield_bitduration, &numberfield_wordduration, + //&field_debug, &symfield_word, &text_format, //&text_format_a, // DEBUG @@ -296,6 +297,19 @@ EncodersView::EncodersView(NavigationView& nav) { this->generate_frame(); }; + // DEBUG + /*field_debug.on_change = [this](int32_t value) { + uint32_t l; + de_bruijn debruijn_seq; + debruijn_seq.init(value); + l = 1; + l <<= value; + l--; + if (l > 25) + l = 25; + text_format.set(to_string_bin(debruijn_seq.compute(l), 25)); + };*/ + // Selecting input clock changes symbol and word duration numberfield_clk.on_change = [this](int32_t value) { //int32_t new_value = 1000000 / (((float)value * 1000) / encoder_def->clk_per_symbol); diff --git a/firmware/application/ui_encoders.hpp b/firmware/application/ui_encoders.hpp index 14508630d..f50a38774 100644 --- a/firmware/application/ui_encoders.hpp +++ b/firmware/application/ui_encoders.hpp @@ -27,6 +27,7 @@ #include "ui_receiver.hpp" #include "ui_transmitter.hpp" #include "encoders.hpp" +#include "de_bruijn.hpp" #include "message.hpp" #include "transmitter_model.hpp" @@ -142,6 +143,15 @@ private: ' ' }; + // DEBUG + /*NumberField field_debug { + { 21 * 8, 10 * 8 }, + 2, + { 3, 16 }, + 1, + ' ' + };*/ + SymField symfield_word { { 2 * 8, 12 * 8 }, 20, diff --git a/firmware/application/ui_transmitter.hpp b/firmware/application/ui_transmitter.hpp index cbd581365..7090f7cc1 100644 --- a/firmware/application/ui_transmitter.hpp +++ b/firmware/application/ui_transmitter.hpp @@ -104,7 +104,7 @@ private: "BW: kHz" }; NumberField field_bw { - { 14 * 8, 2 * 8 }, + { 14 * 8, 1 * 8 }, 3, { 1, 150 }, 1, diff --git a/sdcard/FREQMAN/DPMR.TXT b/sdcard/FREQMAN/DPMR.TXT new file mode 100644 index 000000000..60cadc9a8 --- /dev/null +++ b/sdcard/FREQMAN/DPMR.TXT @@ -0,0 +1,16 @@ +f=446103125,d=dPMR CH1 +f=446109375,d=dPMR CH2 +f=446115625,d=dPMR CH3 +f=446121875,d=dPMR CH4 +f=446128125,d=dPMR CH5 +f=446134375,d=dPMR CH6 +f=446140625,d=dPMR CH7 +f=446146875,d=dPMR CH8 +f=446153125,d=dPMR CH9 +f=446159375,d=dPMR CH10 +f=446165625,d=dPMR CH11 +f=446171875,d=dPMR CH12 +f=446178125,d=dPMR CH13 +f=446184375,d=dPMR CH14 +f=446190625,d=dPMR CH15 +f=446196875,d=dPMR CH16 diff --git a/sdcard/FREQMAN/PMR446.TXT b/sdcard/FREQMAN/PMR446.TXT index c9dbfdcd8..ac9f41d6f 100644 --- a/sdcard/FREQMAN/PMR446.TXT +++ b/sdcard/FREQMAN/PMR446.TXT @@ -6,19 +6,3 @@ f=446056250,d=PMR CH5 f=446068750,d=PMR CH6 f=446081250,d=PMR CH7 f=446093750,d=PMR CH8 -f=446103125,d=dPMR CH1 -f=446109375,d=dPMR CH2 -f=446115625,d=dPMR CH3 -f=446121875,d=dPMR CH4 -f=446128125,d=dPMR CH5 -f=446134375,d=dPMR CH6 -f=446140625,d=dPMR CH7 -f=446146875,d=dPMR CH8 -f=446153125,d=dPMR CH9 -f=446159375,d=dPMR CH10 -f=446165625,d=dPMR CH11 -f=446171875,d=dPMR CH12 -f=446178125,d=dPMR CH13 -f=446184375,d=dPMR CH14 -f=446190625,d=dPMR CH15 -f=446196875,d=dPMR CH16 diff --git a/sdcard/FREQMAN/POCSAG.TXT b/sdcard/FREQMAN/POCSAG.TXT new file mode 100644 index 000000000..65038bd0a --- /dev/null +++ b/sdcard/FREQMAN/POCSAG.TXT @@ -0,0 +1,33 @@ +f=169625000,d=BEL Fire 2400 +f=466025000,d=FRA e-Msg1 1200 +f=466050000,d=FRA e-Msg2 1200 +f=466075000,d=FRA e-Msg3 1200 +f=466175000,d=FRA e-Msg4 1200 +f=466206250,d=FRA e-Msg5 1200 +f=466231250,d=FRA e-Msg6 1200 +f=173512500,d=FRA Fire * +f=85955000,d=FRA Fire HF +f=173550000,d=FRA Fire 1 +f=173625000,d=FRA Fire 2 +f=173550000,d=FRA Fire 3 +f=173700000,d=FRA Fire 4 +f=173875000,d=FRA Fire 5 +f=173925000,d=FRA Fire 6 +f=173550000,d=FRA Fire 7 +f=168950000,d=FRA Fire 8 +f=169025000,d=FRA Fire 9 +f=169100000,d=FRA Fire 10 +f=169275000,d=FRA Fire 11 +f=169325000,d=FRA Fire 12 +f=446475000,d=FRA Priv1 +f=446525000,d=FRA Priv2 +f=448425000,d=GER Fire 1200 +f=465970000,d=GER Skyper1 +f=466075000,d=GER Skyper2 +f=169650000,d=NL Medical +f=172450000,d=NL KPN3-Public +f=169800000,d=SWE Minicall1 +f=161437500,d=SWE Minicall2 +f=152007500,d=USA Medical1 +f=157450000,d=USA Medical2 +f=163250000,d=USA Medical3