Added De Bruijn sequence generator

Moved POCSAG frequency list to SD card file for FreqMan
This commit is contained in:
furrtek 2017-07-20 16:48:59 +01:00
parent 8364bfb2ce
commit 3005403b5e
11 changed files with 248 additions and 82 deletions

View File

@ -152,6 +152,7 @@ set(CPPSRC
${COMMON}/bch_code.cpp ${COMMON}/bch_code.cpp
ctcss.cpp ctcss.cpp
encoder.cpp encoder.cpp
de_bruijn.cpp
freqman.cpp freqman.cpp
${COMMON}/lcd_ili9341.cpp ${COMMON}/lcd_ili9341.cpp
${COMMON}/ui.cpp ${COMMON}/ui.cpp

View File

@ -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;
}

View File

@ -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 <string>
#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__*/

View File

@ -57,10 +57,7 @@ namespace ui {
void POCSAGAppView::update_freq(rf::Frequency f) { void POCSAGAppView::update_freq(rf::Frequency f) {
set_target_frequency(f); set_target_frequency(f);
portapack::persistent_memory::set_tuned_frequency(f); // Maybe not ? portapack::persistent_memory::set_tuned_frequency(f); // Maybe not ?
button_setfreq.set_text(to_string_short_freq(f));
} }
POCSAGAppView::POCSAGAppView(NavigationView& nav) { POCSAGAppView::POCSAGAppView(NavigationView& nav) {
@ -71,11 +68,10 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) {
add_children({ add_children({
&rssi, &rssi,
&channel, &channel,
&options_freq,
&field_rf_amp, &field_rf_amp,
&field_lna, &field_lna,
&field_vga, &field_vga,
&button_setfreq, &field_frequency,
&options_bitrate, &options_bitrate,
&check_log, &check_log,
&check_ignore, &check_ignore,
@ -87,6 +83,20 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) {
receiver_model.set_baseband_bandwidth(1750000); receiver_model.set_baseband_bandwidth(1750000);
receiver_model.enable(); 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<FrequencyKeypadView>(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.set_value(logging);
check_log.on_select = [this](Checkbox&, bool v) { check_log.on_select = [this](Checkbox&, bool v) {
logging = v; logging = v;
@ -97,12 +107,6 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) {
}; };
options_bitrate.set_selected_index(1); // 1200bps 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.set_value(ignore);
check_ignore.on_select = [this](Checkbox&, bool v) { check_ignore.on_select = [this](Checkbox&, bool v) {
ignore = v; ignore = v;
@ -114,21 +118,12 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) {
ignore_address /= 10; ignore_address /= 10;
} }
button_setfreq.on_select = [this,&nav](Button&) {
auto new_view = nav.push<FrequencyKeypadView>(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<POCSAGLogger>(); logger = std::make_unique<POCSAGLogger>();
if (logger) if (logger)
logger->append("pocsag.txt"); logger->append("pocsag.txt");
} }
POCSAGAppView::~POCSAGAppView() { POCSAGAppView::~POCSAGAppView() {
// Save ignored address // Save ignored address
persistent_memory::set_pocsag_ignore_address(sym_ignore.value_dec_u32()); persistent_memory::set_pocsag_ignore_address(sym_ignore.value_dec_u32());
@ -137,7 +132,7 @@ POCSAGAppView::~POCSAGAppView() {
} }
void POCSAGAppView::focus() { void POCSAGAppView::focus() {
options_freq.focus(); field_frequency.focus();
} }
// Useless ? // Useless ?

View File

@ -75,46 +75,6 @@ private:
static constexpr ui::Dim header_height = 1 * 16; 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 { RFAmpField field_rf_amp {
{ 13 * 8, 0 * 16 } { 13 * 8, 0 * 16 }
}; };
@ -131,9 +91,8 @@ private:
{ 21 * 8, 5, 6 * 8, 4 }, { 21 * 8, 5, 6 * 8, 4 },
}; };
Button button_setfreq { FrequencyField field_frequency {
{ 0, 19, 11 * 8, 20 }, { 0 * 8, 0 * 8 },
"----.----"
}; };
OptionsField options_bitrate { OptionsField options_bitrate {
{ 12 * 8, 21 }, { 12 * 8, 21 },

View File

@ -270,6 +270,7 @@ EncodersView::EncodersView(NavigationView& nav) {
&numberfield_clk, &numberfield_clk,
&numberfield_bitduration, &numberfield_bitduration,
&numberfield_wordduration, &numberfield_wordduration,
//&field_debug,
&symfield_word, &symfield_word,
&text_format, &text_format,
//&text_format_a, // DEBUG //&text_format_a, // DEBUG
@ -296,6 +297,19 @@ EncodersView::EncodersView(NavigationView& nav) {
this->generate_frame(); 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 // Selecting input clock changes symbol and word duration
numberfield_clk.on_change = [this](int32_t value) { numberfield_clk.on_change = [this](int32_t value) {
//int32_t new_value = 1000000 / (((float)value * 1000) / encoder_def->clk_per_symbol); //int32_t new_value = 1000000 / (((float)value * 1000) / encoder_def->clk_per_symbol);

View File

@ -27,6 +27,7 @@
#include "ui_receiver.hpp" #include "ui_receiver.hpp"
#include "ui_transmitter.hpp" #include "ui_transmitter.hpp"
#include "encoders.hpp" #include "encoders.hpp"
#include "de_bruijn.hpp"
#include "message.hpp" #include "message.hpp"
#include "transmitter_model.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 { SymField symfield_word {
{ 2 * 8, 12 * 8 }, { 2 * 8, 12 * 8 },
20, 20,

View File

@ -104,7 +104,7 @@ private:
"BW: kHz" "BW: kHz"
}; };
NumberField field_bw { NumberField field_bw {
{ 14 * 8, 2 * 8 }, { 14 * 8, 1 * 8 },
3, 3,
{ 1, 150 }, { 1, 150 },
1, 1,

16
sdcard/FREQMAN/DPMR.TXT Normal file
View File

@ -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

View File

@ -6,19 +6,3 @@ f=446056250,d=PMR CH5
f=446068750,d=PMR CH6 f=446068750,d=PMR CH6
f=446081250,d=PMR CH7 f=446081250,d=PMR CH7
f=446093750,d=PMR CH8 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

33
sdcard/FREQMAN/POCSAG.TXT Normal file
View File

@ -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