mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-08-22 07:29:03 +00:00
Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2a38f386ab | |||
| 079a0506a4 | |||
| e8ad86cc94 | |||
| e69c9bbc7b | |||
| 25c267a3d9 | |||
| efbcd2aa9b | |||
| f32b55f66f | |||
| e9adc32421 | |||
| a120a6344d | |||
| e3cea4c68b | |||
| 0631f5d5ab | |||
| 8986b65f94 | |||
| 7f64606fb2 | |||
| 7bfb54eee9 | |||
| e0c1f7b45e | |||
| 734f315266 | |||
| 7f6aebbe53 | |||
| 5f62926af3 | |||
| 17f6475506 | |||
| 17d3cb387e | |||
| 1e4c93b979 | |||
| 25dfa96257 | |||
| 400cccdcc1 | |||
| f59437cf71 | |||
| 5577ec82ed | |||
| da98e7739e | |||
| b5b5bf42af | |||
| 587fbfbbb1 | |||
| c54e382db2 | |||
| 22de89c879 | |||
| aa778e5797 | |||
| e8e98475e2 | |||
| 95d1bca9fd | |||
| 1a5c360efe | |||
| 560c7143bf | |||
| 6fc03a2651 | |||
| f31ee1172d | |||
| 996e648a64 | |||
| ca4f68d24a | |||
| 2c3f8e9b3d | |||
| a591ba572f | |||
| c9657bc92b | |||
| b8d98e4f45 | |||
| e0309b13e5 | |||
| c2117b2c5b | |||
| 2b78f9e907 | |||
| 6cd4eb0358 | |||
| 8ec69d7c95 | |||
| efe8d82fae | |||
| 32697d1c73 | |||
| 11558b9843 | |||
| e5d1308560 | |||
| 62968e6009 | |||
| a9b4abc07e | |||
| 05f3793213 | |||
| ae8633c569 | |||
| 480f492740 | |||
| dd2e23f901 | |||
| 3ca57f634c | |||
| 29ac3192cb |
@@ -1 +1 @@
|
||||
v1.5.3
|
||||
v1.5.4
|
||||
|
||||
@@ -1 +1 @@
|
||||
v1.5.4
|
||||
v1.6.0
|
||||
|
||||
@@ -49,6 +49,8 @@ You can write [documentation](https://github.com/eried/portapack-mayhem/wiki), f
|
||||
|
||||
Consider that the hardware and firmware has been created and maintain by a [lot](https://github.com/mossmann/hackrf/graphs/contributors) of [people](https://github.com/eried/portapack-mayhem/graphs/contributors), so always try colaborating your time and effort first. For coding related questions, if something does not fit as an issue, please join our Discord by clicking the chat badge on [top](#portapack-mayhem).
|
||||
|
||||
[](https://github.com/eried/portapack-mayhem/graphs/contributors)
|
||||
|
||||
As a last option, if you want to send money directly to me for getting more boards, antennas and such:
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CBPQA4HRRPJQ6&source=url)
|
||||
|
||||
@@ -53,12 +53,13 @@ private:
|
||||
|
||||
OptionsField options_config {
|
||||
{ 3 * 8, 0 * 16 },
|
||||
4,
|
||||
5,
|
||||
{
|
||||
{ "DSB ", 0 },
|
||||
{ "USB ", 0 },
|
||||
{ "LSB ", 0 },
|
||||
{ "CW ", 0 },
|
||||
{ "DSB 9k ", 0 },
|
||||
{ "DSB 6k ", 0 },
|
||||
{ "USB+3k ", 0 },
|
||||
{ "LSB-3k ", 0 },
|
||||
{ "CW ", 0 },
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "ui_fileman.hpp"
|
||||
#include "io_file.hpp"
|
||||
|
||||
#include "cpld_update.hpp"
|
||||
#include "baseband_api.hpp"
|
||||
#include "portapack.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
@@ -258,7 +258,12 @@ ReplayAppView::ReplayAppView(
|
||||
|
||||
ReplayAppView::~ReplayAppView() {
|
||||
radio::disable();
|
||||
baseband::shutdown();
|
||||
|
||||
display.fill_rectangle({ 0,0,240, 320 },Color::black()); //Solving sometimes visible bottom waterfall artifacts, clearing all LCD pixels.
|
||||
chThdSleepMilliseconds(40); // (that happened sometimes if we interrupt the waterfall play at the beggining of the play around 25% and exit )
|
||||
hackrf::cpld::load_sram_no_verify(); // to leave all RX reception ok, without "ghost interference signal problem" at the exit .
|
||||
|
||||
baseband::shutdown(); // better this function at the end, after load_sram(). If not , sometimes produced hang up (now not , it is ok).
|
||||
}
|
||||
|
||||
void ReplayAppView::on_hide() {
|
||||
|
||||
@@ -36,16 +36,17 @@ EncodersConfigView::EncodersConfigView(
|
||||
using option_t = std::pair<std::string, int32_t>;
|
||||
std::vector<option_t> enc_options;
|
||||
size_t i;
|
||||
|
||||
|
||||
set_parent_rect(parent_rect);
|
||||
hidden(true);
|
||||
|
||||
|
||||
// Default encoder def
|
||||
encoder_def = &encoder_defs[0];
|
||||
|
||||
|
||||
add_children({
|
||||
&labels,
|
||||
&options_enctype,
|
||||
&field_repeat_min,
|
||||
&field_clk,
|
||||
&field_clk_step,
|
||||
&field_frameduration,
|
||||
@@ -58,18 +59,18 @@ EncodersConfigView::EncodersConfigView(
|
||||
// Load encoder types in option field
|
||||
for (i = 0; i < ENC_TYPES_COUNT; i++)
|
||||
enc_options.emplace_back(std::make_pair(encoder_defs[i].name, i));
|
||||
|
||||
|
||||
options_enctype.on_change = [this](size_t index, int32_t) {
|
||||
on_type_change(index);
|
||||
};
|
||||
|
||||
|
||||
options_enctype.set_options(enc_options);
|
||||
options_enctype.set_selected_index(0);
|
||||
|
||||
|
||||
symfield_word.on_change = [this]() {
|
||||
generate_frame();
|
||||
};
|
||||
|
||||
|
||||
// Selecting input clock changes symbol and word duration
|
||||
field_clk.on_change = [this](int32_t value) {
|
||||
// value is in kHz, new_value is in us
|
||||
@@ -81,7 +82,7 @@ EncodersConfigView::EncodersConfigView(
|
||||
field_clk_step.on_change = [this](size_t, int32_t value) {
|
||||
field_clk.set_step(value);
|
||||
};
|
||||
|
||||
|
||||
// Selecting word duration changes input clock and symbol duration
|
||||
field_frameduration.on_change = [this](int32_t value) {
|
||||
// value is in us, new_value is in kHz
|
||||
@@ -107,7 +108,8 @@ void EncodersConfigView::on_type_change(size_t index) {
|
||||
encoder_def = &encoder_defs[index];
|
||||
|
||||
field_clk.set_value(encoder_def->default_speed / 1000);
|
||||
|
||||
field_repeat_min.set_value(encoder_def->repeat_min);
|
||||
|
||||
// SymField setup
|
||||
word_length = encoder_def->word_length;
|
||||
symfield_word.set_length(word_length);
|
||||
@@ -122,10 +124,10 @@ void EncodersConfigView::on_type_change(size_t index) {
|
||||
format_string += 'D';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Ugly :( Pad to erase
|
||||
format_string.append(24 - format_string.size(), ' ');
|
||||
|
||||
|
||||
text_format.set(format_string);
|
||||
|
||||
generate_frame();
|
||||
@@ -141,28 +143,28 @@ void EncodersConfigView::draw_waveform() {
|
||||
|
||||
for (size_t n = 0; n < length; n++)
|
||||
waveform_buffer[n] = (frame_fragments[n] == '0') ? 0 : 1;
|
||||
|
||||
|
||||
waveform.set_length(length);
|
||||
waveform.set_dirty();
|
||||
}
|
||||
|
||||
void EncodersConfigView::generate_frame() {
|
||||
size_t i = 0;
|
||||
|
||||
|
||||
frame_fragments.clear();
|
||||
|
||||
|
||||
for (auto c : encoder_def->word_format) {
|
||||
if (c == 'S')
|
||||
frame_fragments += encoder_def->sync;
|
||||
else
|
||||
frame_fragments += encoder_def->bit_format[symfield_word.get_sym(i++)];
|
||||
}
|
||||
|
||||
|
||||
draw_waveform();
|
||||
}
|
||||
|
||||
uint8_t EncodersConfigView::repeat_min() {
|
||||
return encoder_def->repeat_min;
|
||||
return field_repeat_min.value();
|
||||
}
|
||||
|
||||
uint32_t EncodersConfigView::samples_per_bit() {
|
||||
@@ -174,7 +176,7 @@ uint32_t EncodersConfigView::pause_symbols() {
|
||||
}
|
||||
|
||||
void EncodersScanView::focus() {
|
||||
field_debug.focus();
|
||||
field_length.focus();
|
||||
}
|
||||
|
||||
EncodersScanView::EncodersScanView(
|
||||
@@ -182,31 +184,17 @@ EncodersScanView::EncodersScanView(
|
||||
) {
|
||||
set_parent_rect(parent_rect);
|
||||
hidden(true);
|
||||
|
||||
|
||||
add_children({
|
||||
&labels,
|
||||
&field_debug,
|
||||
&text_debug,
|
||||
&text_length
|
||||
&field_length,
|
||||
&bit_length_10,
|
||||
&bit_length
|
||||
});
|
||||
|
||||
// DEBUG
|
||||
field_debug.on_change = [this](int32_t value) {
|
||||
uint32_t l;
|
||||
size_t length;
|
||||
|
||||
de_bruijn debruijn_seq;
|
||||
length = debruijn_seq.init(value);
|
||||
|
||||
l = 1;
|
||||
l <<= value;
|
||||
l--;
|
||||
if (l > 25)
|
||||
l = 25;
|
||||
text_debug.set(to_string_bin(debruijn_seq.compute(l), 25));
|
||||
|
||||
text_length.set(to_string_dec_uint(length));
|
||||
};
|
||||
|
||||
field_length.set_value(8);
|
||||
bit_length_10.set_value(40);
|
||||
bit_length.set_value(0);
|
||||
}
|
||||
|
||||
void EncodersView::focus() {
|
||||
@@ -215,7 +203,7 @@ void EncodersView::focus() {
|
||||
|
||||
EncodersView::~EncodersView() {
|
||||
// save app settings
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||
settings.save("tx_ook", &app_settings);
|
||||
|
||||
transmitter_model.disable();
|
||||
@@ -225,24 +213,11 @@ EncodersView::~EncodersView() {
|
||||
|
||||
void EncodersView::update_progress() {
|
||||
std::string str_buffer;
|
||||
|
||||
// text_status.set(" ");
|
||||
|
||||
if (tx_mode == SINGLE) {
|
||||
|
||||
if (tx_mode == SINGLE || tx_mode == SCAN) {
|
||||
str_buffer = to_string_dec_uint(repeat_index) + "/" + to_string_dec_uint(repeat_min);
|
||||
text_status.set(str_buffer);
|
||||
progressbar.set_value(repeat_index);
|
||||
|
||||
/*} else if (tx_mode == SCAN) {
|
||||
strcpy(str, to_string_dec_uint(repeat_index).c_str());
|
||||
strcat(str, "/");
|
||||
strcat(str, to_string_dec_uint(portapack::persistent_memory::afsk_repeats()).c_str());
|
||||
strcat(str, " ");
|
||||
strcat(str, to_string_dec_uint(scan_index + 1).c_str());
|
||||
strcat(str, "/");
|
||||
strcat(str, to_string_dec_uint(scan_count).c_str());
|
||||
text_status.set(str);
|
||||
progress.set_value(scan_progress);*/
|
||||
} else {
|
||||
text_status.set("Ready");
|
||||
progressbar.set_value(0);
|
||||
@@ -250,89 +225,58 @@ void EncodersView::update_progress() {
|
||||
}
|
||||
|
||||
void EncodersView::on_tx_progress(const uint32_t progress, const bool done) {
|
||||
//char str[16];
|
||||
|
||||
if (!done) {
|
||||
// Repeating...
|
||||
repeat_index = progress + 1;
|
||||
|
||||
/*if (tx_mode == SCAN) {
|
||||
scan_progress++;
|
||||
update_progress();
|
||||
} else {*/
|
||||
update_progress();
|
||||
//}
|
||||
update_progress();
|
||||
} else {
|
||||
// make sure all samples are transmitted before disabling radio
|
||||
chThdSleepMilliseconds(10);
|
||||
|
||||
// Done transmitting
|
||||
/*if ((tx_mode == SCAN) && (scan_index < (scan_count - 1))) {
|
||||
transmitter_model.disable();
|
||||
if (abort_scan) {
|
||||
// Kill scan process
|
||||
strcpy(str, "Abort @");
|
||||
strcat(str, rgsb);
|
||||
text_status.set(str);
|
||||
progress.set_value(0);
|
||||
tx_mode = IDLE;
|
||||
abort_scan = false;
|
||||
button_scan.set_style(&style_val);
|
||||
button_scan.set_text("SCAN");
|
||||
} else {
|
||||
// Next address
|
||||
scan_index++;
|
||||
strcpy(rgsb, &scan_list[options_scanlist.selected_index()].addresses[scan_index * 5]);
|
||||
scan_progress++;
|
||||
repeat_index = 1;
|
||||
update_progress();
|
||||
start_tx(true);
|
||||
}
|
||||
} else {*/
|
||||
transmitter_model.disable();
|
||||
tx_mode = IDLE;
|
||||
text_status.set("Done");
|
||||
progressbar.set_value(0);
|
||||
tx_view.set_transmitting(false);
|
||||
//}
|
||||
transmitter_model.disable();
|
||||
tx_mode = IDLE;
|
||||
text_status.set("Done");
|
||||
progressbar.set_value(0);
|
||||
tx_view.set_transmitting(false);
|
||||
}
|
||||
}
|
||||
|
||||
void EncodersView::start_tx(const bool scan) {
|
||||
(void)scan;
|
||||
size_t bitstream_length = 0;
|
||||
|
||||
repeat_min = view_config.repeat_min();
|
||||
|
||||
/*if (scan) {
|
||||
if (tx_mode != SCAN) {
|
||||
scan_index = 0;
|
||||
scan_count = scan_list[options_scanlist.selected_index()].count;
|
||||
scan_progress = 1;
|
||||
repeat_index = 1;
|
||||
tx_mode = SCAN;
|
||||
strcpy(rgsb, &scan_list[options_scanlist.selected_index()].addresses[0]);
|
||||
progress.set_max(scan_count * afsk_repeats);
|
||||
update_progress();
|
||||
}
|
||||
} else {*/
|
||||
int scan_width = 0;
|
||||
uint32_t samples_per_bit;
|
||||
|
||||
if (scan) {
|
||||
tx_mode = SCAN;
|
||||
scan_width = view_scan.field_length.value();
|
||||
samples_per_bit =
|
||||
((view_scan.bit_length_10.value() * 10 + view_scan.bit_length.value()) * OOK_SAMPLERATE) / 1000000UL;
|
||||
const uint32_t seq_len = ((1 << (scan_width - 1)) * 2) * ((uint64_t) samples_per_bit) / 2048UL;
|
||||
progressbar.set_max(seq_len);
|
||||
repeat_min = seq_len;
|
||||
} else {
|
||||
tx_mode = SINGLE;
|
||||
repeat_index = 1;
|
||||
samples_per_bit = view_config.samples_per_bit();
|
||||
view_config.generate_frame();
|
||||
bitstream_length = make_bitstream(view_config.frame_fragments);
|
||||
progressbar.set_max(repeat_min);
|
||||
update_progress();
|
||||
//}
|
||||
|
||||
view_config.generate_frame();
|
||||
|
||||
bitstream_length = make_bitstream(view_config.frame_fragments);
|
||||
repeat_min = view_config.repeat_min();
|
||||
}
|
||||
|
||||
repeat_index = 1;
|
||||
update_progress();
|
||||
|
||||
transmitter_model.set_sampling_rate(OOK_SAMPLERATE);
|
||||
transmitter_model.set_rf_amp(true);
|
||||
transmitter_model.set_baseband_bandwidth(1750000);
|
||||
transmitter_model.enable();
|
||||
|
||||
|
||||
baseband::set_ook_data(
|
||||
bitstream_length,
|
||||
view_config.samples_per_bit(),
|
||||
samples_per_bit,
|
||||
repeat_min,
|
||||
view_config.pause_symbols()
|
||||
view_config.pause_symbols(),
|
||||
scan_width
|
||||
);
|
||||
}
|
||||
|
||||
@@ -350,14 +294,14 @@ EncodersView::EncodersView(
|
||||
&progressbar,
|
||||
&tx_view
|
||||
});
|
||||
|
||||
|
||||
// load app settings
|
||||
auto rc = settings.load("tx_ook", &app_settings);
|
||||
if(rc == SETTINGS_OK) {
|
||||
if (rc == SETTINGS_OK) {
|
||||
transmitter_model.set_rf_amp(app_settings.tx_amp);
|
||||
transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth);
|
||||
transmitter_model.set_tuning_frequency(app_settings.tx_frequency);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
transmitter_model.set_tx_gain(app_settings.tx_gain);
|
||||
}
|
||||
|
||||
tx_view.on_edit_frequency = [this, &nav]() {
|
||||
@@ -366,14 +310,16 @@ EncodersView::EncodersView(
|
||||
transmitter_model.set_tuning_frequency(f);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
tx_view.on_start = [this]() {
|
||||
tx_view.set_transmitting(true);
|
||||
start_tx(false);
|
||||
start_tx(tab_view.selected());
|
||||
};
|
||||
|
||||
|
||||
tx_view.on_stop = [this]() {
|
||||
tx_view.set_transmitting(false);
|
||||
baseband::kill_ook();
|
||||
transmitter_model.disable();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -35,43 +35,39 @@ namespace ui {
|
||||
class EncodersConfigView : public View {
|
||||
public:
|
||||
EncodersConfigView(NavigationView& nav, Rect parent_rect);
|
||||
|
||||
|
||||
EncodersConfigView(const EncodersConfigView&) = delete;
|
||||
EncodersConfigView(EncodersConfigView&&) = delete;
|
||||
EncodersConfigView& operator=(const EncodersConfigView&) = delete;
|
||||
EncodersConfigView& operator=(EncodersConfigView&&) = delete;
|
||||
|
||||
|
||||
void focus() override;
|
||||
void on_show() override;
|
||||
|
||||
|
||||
uint8_t repeat_min();
|
||||
uint32_t samples_per_bit();
|
||||
uint32_t pause_symbols();
|
||||
void generate_frame();
|
||||
|
||||
|
||||
std::string frame_fragments = "0";
|
||||
|
||||
private:
|
||||
//bool abort_scan = false;
|
||||
//uint8_t scan_count;
|
||||
//double scan_progress;
|
||||
//unsigned int scan_index;
|
||||
int16_t waveform_buffer[550];
|
||||
const encoder_def_t * encoder_def { };
|
||||
//uint8_t enc_type = 0;
|
||||
|
||||
void draw_waveform();
|
||||
void on_bitfield();
|
||||
void on_type_change(size_t index);
|
||||
|
||||
|
||||
Labels labels {
|
||||
{ { 1 * 8, 0 }, "Type:", Color::light_grey() },
|
||||
{ { 17 * 8, 0 }, "Repeat:", Color::light_grey() },
|
||||
{ { 1 * 8, 2 * 8 }, "Clk:", Color::light_grey() },
|
||||
{ { 10 * 8, 2 * 8 }, "kHz", Color::light_grey() },
|
||||
{ { 17 * 8, 2 * 8 }, "Step:", Color::light_grey() },
|
||||
{ { 17 * 8, 2 * 8 }, "Step:", Color::light_grey() },
|
||||
{ { 1 * 8, 4 * 8 }, "Frame:", Color::light_grey() },
|
||||
{ { 13 * 8, 4 * 8 }, "us", Color::light_grey() },
|
||||
{ { 17 * 8, 4 * 8 }, "Step", Color::light_grey() },
|
||||
{ { 13 * 8, 4 * 8 }, "us", Color::light_grey() },
|
||||
{ { 17 * 8, 4 * 8 }, "Step:", Color::light_grey() },
|
||||
{ { 2 * 8, 7 * 8 }, "Symbols:", Color::light_grey() },
|
||||
{ { 1 * 8, 14 * 8 }, "Waveform:", Color::light_grey() }
|
||||
};
|
||||
@@ -91,6 +87,14 @@ private:
|
||||
' '
|
||||
};
|
||||
|
||||
NumberField field_repeat_min {
|
||||
{ 24 * 8, 0 },
|
||||
2,
|
||||
{ 1, 99 },
|
||||
1,
|
||||
' '
|
||||
};
|
||||
|
||||
OptionsField field_clk_step {
|
||||
{ 22 * 8, 2 * 8 },
|
||||
7,
|
||||
@@ -119,18 +123,18 @@ private:
|
||||
{ "1000", 1000 }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
SymField symfield_word {
|
||||
{ 2 * 8, 9 * 8 },
|
||||
20,
|
||||
SymField::SYMFIELD_DEF
|
||||
};
|
||||
|
||||
|
||||
Text text_format {
|
||||
{ 2 * 8, 11 * 8, 24 * 8, 16 },
|
||||
""
|
||||
};
|
||||
|
||||
|
||||
Waveform waveform {
|
||||
{ 0, 17 * 8, 240, 32 },
|
||||
waveform_buffer,
|
||||
@@ -145,33 +149,38 @@ private:
|
||||
class EncodersScanView : public View {
|
||||
public:
|
||||
EncodersScanView(NavigationView& nav, Rect parent_rect);
|
||||
|
||||
|
||||
NumberField field_length {
|
||||
{ 8 * 8, 0 },
|
||||
2,
|
||||
{ 3, 24 },
|
||||
1,
|
||||
' '
|
||||
};
|
||||
|
||||
NumberField bit_length_10 {
|
||||
{ 12 * 8, 2 * 8 },
|
||||
2,
|
||||
{ 1, 88 },
|
||||
1,
|
||||
' '
|
||||
};
|
||||
|
||||
NumberField bit_length {
|
||||
{ 14 * 8, 2 * 8 },
|
||||
1,
|
||||
{ 0, 9 },
|
||||
1,
|
||||
' '
|
||||
};
|
||||
|
||||
void focus() override;
|
||||
|
||||
private:
|
||||
Labels labels {
|
||||
{ { 1 * 8, 1 * 8 }, "Coming soon...", Color::light_grey() }
|
||||
};
|
||||
|
||||
// DEBUG
|
||||
NumberField field_debug {
|
||||
{ 1 * 8, 6 * 8 },
|
||||
2,
|
||||
{ 3, 16 },
|
||||
1,
|
||||
' '
|
||||
};
|
||||
|
||||
// DEBUG
|
||||
Text text_debug {
|
||||
{ 1 * 8, 8 * 8, 24 * 8, 16 },
|
||||
""
|
||||
};
|
||||
|
||||
// DEBUG
|
||||
Text text_length {
|
||||
{ 1 * 8, 10 * 8, 24 * 8, 16 },
|
||||
""
|
||||
{ { 1 * 8, 0 * 8 }, "Length:", Color::light_grey() },
|
||||
{ { 1 * 8, 2 * 8 }, "Bit length:", Color::light_grey() },
|
||||
{ { 16 * 8, 2 * 8 }, "us", Color::light_grey() },
|
||||
};
|
||||
};
|
||||
|
||||
@@ -179,9 +188,9 @@ class EncodersView : public View {
|
||||
public:
|
||||
EncodersView(NavigationView& nav);
|
||||
~EncodersView();
|
||||
|
||||
|
||||
void focus() override;
|
||||
|
||||
|
||||
std::string title() const override { return "OOK TX"; };
|
||||
|
||||
private:
|
||||
@@ -192,19 +201,19 @@ private:
|
||||
SINGLE,
|
||||
SCAN
|
||||
};
|
||||
|
||||
|
||||
// app save settings
|
||||
std::app_settings settings { };
|
||||
std::app_settings settings { };
|
||||
std::app_settings::AppSettings app_settings { };
|
||||
|
||||
tx_modes tx_mode = IDLE;
|
||||
uint8_t repeat_index { 0 };
|
||||
uint8_t repeat_min { 0 };
|
||||
|
||||
uint32_t repeat_index { 0 };
|
||||
uint32_t repeat_min { 0 };
|
||||
|
||||
void update_progress();
|
||||
void start_tx(const bool scan);
|
||||
void on_tx_progress(const uint32_t progress, const bool done);
|
||||
|
||||
|
||||
/*const Style style_address {
|
||||
.font = font::fixed_8x16,
|
||||
.background = Color::black(),
|
||||
@@ -215,32 +224,32 @@ private:
|
||||
.background = Color::black(),
|
||||
.foreground = Color::blue(),
|
||||
};*/
|
||||
|
||||
|
||||
Rect view_rect = { 0, 4 * 8, 240, 168 };
|
||||
|
||||
|
||||
EncodersConfigView view_config { nav_, view_rect };
|
||||
EncodersScanView view_scan { nav_, view_rect };
|
||||
|
||||
|
||||
TabView tab_view {
|
||||
{ "Config", Color::cyan(), &view_config },
|
||||
{ "Scan", Color::green(), &view_scan },
|
||||
{ "de Bruijn", Color::green(), &view_scan },
|
||||
};
|
||||
|
||||
Text text_status {
|
||||
{ 2 * 8, 13 * 16, 128, 16 },
|
||||
"Ready"
|
||||
};
|
||||
|
||||
|
||||
ProgressBar progressbar {
|
||||
{ 2 * 8, 13 * 16 + 20, 208, 16 }
|
||||
};
|
||||
|
||||
|
||||
TransmitterView tx_view {
|
||||
16 * 16,
|
||||
50000,
|
||||
9
|
||||
};
|
||||
|
||||
|
||||
MessageHandlerRegistration message_handler_tx_progress {
|
||||
Message::ID::TXProgress,
|
||||
[this](const Message* const p) {
|
||||
|
||||
@@ -270,9 +270,9 @@ void JammerView::start_tx() {
|
||||
button_transmit.set_text("STOP");
|
||||
|
||||
transmitter_model.set_sampling_rate(3072000U);
|
||||
transmitter_model.set_rf_amp(true);
|
||||
transmitter_model.set_rf_amp(field_amp.value());
|
||||
transmitter_model.set_baseband_bandwidth(3500000U);
|
||||
transmitter_model.set_tx_gain(47);
|
||||
transmitter_model.set_tx_gain(field_gain.value());
|
||||
transmitter_model.enable();
|
||||
|
||||
baseband::set_jammer(true, (JammerType)options_type.selected_index(), options_speed.selected_index_value());
|
||||
@@ -368,6 +368,8 @@ JammerView::JammerView(
|
||||
&field_timetx,
|
||||
&field_timepause,
|
||||
&field_jitter,
|
||||
&field_gain,
|
||||
&field_amp,
|
||||
&button_transmit
|
||||
});
|
||||
|
||||
@@ -382,6 +384,8 @@ JammerView::JammerView(
|
||||
|
||||
field_timetx.set_value(30);
|
||||
field_timepause.set_value(1);
|
||||
field_gain.set_value(transmitter_model.tx_gain());
|
||||
field_amp.set_value(transmitter_model.rf_amp());
|
||||
|
||||
button_transmit.on_select = [this](Button&) {
|
||||
if (jamming || cooling)
|
||||
|
||||
@@ -156,7 +156,9 @@ private:
|
||||
{ { 0 * 8, 33 * 8 }, "Jitter:", Color::light_grey() }, //Maybe the repository curator can keep the "mystype" for some versions.
|
||||
{ { 11 * 8, 29 * 8 }, "Secs.", Color::light_grey() },
|
||||
{ { 11 * 8, 31 * 8 }, "Secs.", Color::light_grey() },
|
||||
{ { 11 * 8, 33 * 8 }, "/60", Color::light_grey() }
|
||||
{ { 11 * 8, 33 * 8 }, "/60", Color::light_grey() },
|
||||
{ { 2 * 8, 35 * 8 }, "Gain:", Color::light_grey() },
|
||||
{ { 11 * 8, 35 * 8 }, "A:", Color::light_grey() }
|
||||
};
|
||||
|
||||
OptionsField options_type {
|
||||
@@ -229,8 +231,24 @@ private:
|
||||
' ',
|
||||
};
|
||||
|
||||
NumberField field_gain {
|
||||
{ 8 * 8, 35 * 8 },
|
||||
2,
|
||||
{ 0, 47 },
|
||||
1,
|
||||
' ',
|
||||
};
|
||||
|
||||
NumberField field_amp {
|
||||
{ 13 * 8, 35 * 8 },
|
||||
1,
|
||||
{ 0, 1 },
|
||||
1,
|
||||
' ',
|
||||
};
|
||||
|
||||
Button button_transmit {
|
||||
{ 148, 212, 80, 80},
|
||||
{ 148, 216, 80, 80},
|
||||
"START"
|
||||
};
|
||||
|
||||
|
||||
@@ -159,19 +159,24 @@ void MicTXView::rxaudio(bool is_on) {
|
||||
audio::input::stop();
|
||||
baseband::shutdown();
|
||||
|
||||
if (enable_am || enable_usb || enable_lsb || enable_dsb) {
|
||||
if (enable_am || enable_usb || enable_lsb || enable_dsb) { // "NFM/FM",0 ," WFM ",1 , " AM ",2, " USB ", 3, " LSB ",4, " DSB-SC", 5
|
||||
baseband::run_image(portapack::spi_flash::image_tag_am_audio);
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::AMAudio);
|
||||
if (options_mode.selected_index() < 4)
|
||||
receiver_model.set_am_configuration(options_mode.selected_index() - 1);
|
||||
else
|
||||
receiver_model.set_am_configuration(0);
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::AMAudio); // that AM demodulation engine is common to all Amplitude mod : AM/USB/LSB/DSB (2,3,4,5)
|
||||
if (options_mode.selected_index() < 5) // We will be called here with 2,3,4,5 . We treat here demod. filter 2,3,4; (excluding DSB-C case (5) it is treated more down).
|
||||
receiver_model.set_am_configuration(options_mode.selected_index() - 1); // selecting proper filter(2,3,4). 2-1=1=>6k-AM(1) , 3-1=2=>+3k-USB(2), 4-1=3=>-3K-LSB(3),
|
||||
}
|
||||
else {
|
||||
baseband::run_image(portapack::spi_flash::image_tag_nfm_audio);
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
|
||||
else { // We are in NFM/FM or WFM (NFM BW:8k5 or 11k / FM BW 16k / WFM BW:200k)
|
||||
|
||||
}
|
||||
if (enable_wfm) { // WFM , BW 200Khz aprox ,
|
||||
baseband::run_image(portapack::spi_flash::image_tag_wfm_audio);
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
|
||||
receiver_model.set_wfm_configuration(0); // there are only 1 x config filters 200k WFM . (not like 8k5/11k/16k)
|
||||
} else { // NFM BW:8k5 or 11k / FM BW 16k
|
||||
baseband::run_image(portapack::spi_flash::image_tag_nfm_audio);
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); //
|
||||
// receiver_model.set_nbfm_configuration(n); is called above , depending 8k5, 11k, 16k
|
||||
}
|
||||
}
|
||||
receiver_model.set_sampling_rate(3072000);
|
||||
receiver_model.set_baseband_bandwidth(1750000);
|
||||
// receiver_model.set_tuning_frequency(field_frequency.value()); //probably this too can be commented out.
|
||||
@@ -346,7 +351,8 @@ MicTXView::MicTXView(
|
||||
field_bw.on_change = [this](uint32_t v) {
|
||||
transmitter_model.set_channel_bandwidth(v * 1000);
|
||||
};
|
||||
field_bw.set_value(10);
|
||||
field_bw.set_value(10); // pre-default first time, TX deviation FM for NFM / FM
|
||||
|
||||
|
||||
tx_gain = transmitter_model.tx_gain();
|
||||
field_rfgain.on_change = [this](int32_t v) {
|
||||
@@ -361,50 +367,102 @@ MicTXView::MicTXView(
|
||||
};
|
||||
field_rfamp.set_value(rf_amp ? 14 : 0);
|
||||
|
||||
options_mode.on_change = [this](size_t, int32_t v) {
|
||||
enable_am = false;
|
||||
options_mode.on_change = [this](size_t, int32_t v) { //{ "NFM/FM", 0 }, { " WFM ", 1 },{ "AM", 2 },{ "USB", 3 },{ "LSB", 4 },{ "DSB", 5 }
|
||||
enable_am = false;
|
||||
enable_usb = false;
|
||||
enable_lsb = false;
|
||||
enable_dsb = false;
|
||||
enable_wfm = false;
|
||||
|
||||
using option_t = std::pair<std::string, int32_t>;
|
||||
using options_t = std::vector<option_t>;
|
||||
options_t rxbw; // Aux structure to change dynamically field_rxbw contents,
|
||||
|
||||
switch(v) {
|
||||
case 0:
|
||||
enable_am = false;
|
||||
case 0: //{ "FM", 0 }
|
||||
enable_am = false;
|
||||
enable_usb = false;
|
||||
enable_lsb = false;
|
||||
enable_dsb = false;
|
||||
field_bw.set_value(transmitter_model.channel_bandwidth() / 1000);
|
||||
field_bw.set_value(10); // pre-default deviation FM for WFM
|
||||
// field_bw.set_value(transmitter_model.channel_bandwidth() / 1000);
|
||||
//if (rx_enabled)
|
||||
rxaudio(rx_enabled); //Update now if we have RX audio on
|
||||
options_tone_key.hidden(0); // we are in FM mode , we should have active the Key-tones & CTCSS option.
|
||||
|
||||
rxbw.emplace_back(" NFM1:8k5 ", 0); // restore the original dynamic field_rxbw value.
|
||||
rxbw.emplace_back(" NFM2:11k ", 1);
|
||||
rxbw.emplace_back(" FM :16k ", 2);
|
||||
field_rxbw.set_options(rxbw); // store that aux GUI option to the field_rxbw.
|
||||
|
||||
field_rxbw.hidden(0); // we are in FM mode, we need to allow the user set up of the RX NFM BW selection (8K5, 11K, 16K)
|
||||
field_bw.hidden(0); // we are in FM mode, we need to allow FM deviation parameter , in non FM mode.
|
||||
break;
|
||||
case 1:
|
||||
case 1: //{ "WFM", 1 }
|
||||
enable_am = false;
|
||||
enable_usb = false;
|
||||
enable_lsb = false;
|
||||
enable_dsb = false;
|
||||
enable_wfm = true;
|
||||
field_bw.set_value(75); // pre-default deviation FM for WFM
|
||||
// field_bw.set_value(transmitter_model.channel_bandwidth() / 1000);
|
||||
//if (rx_enabled)
|
||||
rxaudio(rx_enabled); //Update now if we have RX audio on
|
||||
options_tone_key.hidden(0); // we are in WFM mode , we should have active the Key-tones & CTCSS option.
|
||||
|
||||
rxbw.emplace_back(" 200k-WFM ", 0); // locked a fixed option , to display it .
|
||||
field_rxbw.set_options(rxbw); // store that aux GUI option to the field_rxbw.
|
||||
|
||||
field_rxbw.hidden(0); // we are in WFM mode, we need to show to the user the selected BW WFM filer .
|
||||
field_bw.hidden(0); // we are in WFM mode, we need to allow WFM deviation parameter , in non FM mode.
|
||||
break;
|
||||
case 2: //{ "AM", 2 }
|
||||
enable_am = true;
|
||||
rxaudio(rx_enabled); //Update now if we have RX audio on
|
||||
options_tone_key.set_selected_index(0); // we are NOT in FM mode , we reset the possible previous key-tones &CTCSS selection.
|
||||
set_dirty(); // Refresh display
|
||||
options_tone_key.hidden(1); // we hide that Key-tones & CTCSS input selecction, (no meaning in AM/DSB/SSB).
|
||||
field_rxbw.hidden(1); // we hide the NFM BW selection in other modes non_FM (no meaning in AM/DSB/SSB)
|
||||
check_rogerbeep.hidden(0); // make visible again the "rogerbeep" selection.
|
||||
|
||||
rxbw.emplace_back(" DSB1-9k ", 0); // we offer in AM DSB two audio BW 9k / 6k .
|
||||
rxbw.emplace_back(" DSB2-6k ", 1);
|
||||
field_rxbw.set_options(rxbw); // store that aux GUI option to the field_rxbw.
|
||||
|
||||
field_rxbw.hidden(0); // we show fixed RX AM BW 6Khz
|
||||
field_bw.hidden(1); // we hide the FM TX deviation parameter , in non FM mode.
|
||||
check_rogerbeep.hidden(0); // make visible again the "rogerbeep" selection.
|
||||
break;
|
||||
case 2:
|
||||
case 3: //{ "USB", 3 }
|
||||
enable_usb = true;
|
||||
rxaudio(rx_enabled); //Update now if we have RX audio on
|
||||
check_rogerbeep.set_value(false); // reset the possible activation of roger beep, because it is not compatible with SSB , by now.
|
||||
check_rogerbeep.hidden(1); // hide that roger beep selection.
|
||||
|
||||
rxbw.emplace_back(" USB+3k ", 0); // locked a fixed option , to display it .
|
||||
field_rxbw.set_options(rxbw); // store that aux GUI option to the field_rxbw.
|
||||
|
||||
set_dirty(); // Refresh display
|
||||
break;
|
||||
case 3:
|
||||
case 4: //{ "LSB", 4 }
|
||||
enable_lsb = true;
|
||||
rxaudio(rx_enabled); //Update now if we have RX audio on
|
||||
check_rogerbeep.set_value(false); // reset the possible activation of roger beep, because it is not compatible with SSB , by now.
|
||||
check_rogerbeep.hidden(1); // hide that roger beep selection.
|
||||
|
||||
rxbw.emplace_back(" LSB-3k ", 0); // locked a fixed option , to display it .
|
||||
field_rxbw.set_options(rxbw); // store that aux GUI option to the field_rxbw.
|
||||
|
||||
set_dirty(); // Refresh display
|
||||
break;
|
||||
case 4:
|
||||
case 5: //{ "DSB-SC", 5 }
|
||||
enable_dsb = true;
|
||||
rxaudio(rx_enabled); //Update now if we have RX audio on
|
||||
check_rogerbeep.hidden(0); // make visible again the "rogerbeep" selection.
|
||||
|
||||
rxbw.emplace_back("SSB1:USB+3k", 0); // added dynamically two options (index 0,1) to that DSB-C case to the field_rxbw value.
|
||||
rxbw.emplace_back("SSB2:LSB-3k", 1);
|
||||
|
||||
field_rxbw.set_options(rxbw); // store that aux GUI option to the field_rxbw.
|
||||
|
||||
break;
|
||||
}
|
||||
//configure_baseband();
|
||||
@@ -481,19 +539,20 @@ MicTXView::MicTXView(
|
||||
field_volume.on_change = [this](int32_t v) { this->on_headphone_volume_changed(v); };
|
||||
|
||||
field_rxbw.on_change = [this](size_t, int32_t v) {
|
||||
switch(v) {
|
||||
case 0:
|
||||
receiver_model.set_nbfm_configuration(0);
|
||||
break;
|
||||
case 1:
|
||||
receiver_model.set_nbfm_configuration(1);
|
||||
break;
|
||||
case 2:
|
||||
receiver_model.set_nbfm_configuration(2);
|
||||
break;
|
||||
if (!(enable_am || enable_usb || enable_lsb || enable_dsb || enable_wfm )) {
|
||||
// In Previous fw versions, that nbfm_configuration(n) was done in any mode (FM/AM/SSB/DSB)...strictly speaking only need it in (NFM/FM)
|
||||
receiver_model.set_nbfm_configuration(v ); // we are in NFM/FM case, we need to select proper NFM/FM RX channel filter , NFM BW 8K5(0), NFM BW 11K(1) , FM BW 16K (2)
|
||||
}
|
||||
else { // we are not in NFM/FM mode .(we could be in any of the rest : AM /USB/LSB/DSB-SC)
|
||||
if (enable_am) { // we are in AM TX mode , we will allow both independent RX audio BW : AM 9K (9K00AE3 / AM 6K (6K00AE3). (In AM option v can be 0 (9k) , 1 (6k)
|
||||
receiver_model.set_am_configuration(v ); // we are in AM TX mode , we need to select proper AM full path config AM-9K filter. 0+0 =>AM-9K(0), 0+1=1 =>AM-6K(1),
|
||||
}
|
||||
|
||||
if (enable_dsb) { // we are in DSB-SC in TX mode , we will allow both independent RX SSB demodulation (USB / LSB side band). in that submenu, v is 0 (SSB1 USB) or 1 (SSB2 LSB)
|
||||
receiver_model.set_am_configuration(v +2 ); // we are in DSB-SC TX mode , we need to select proper SSB filter. 0+2 =>usb(2), 1+2=3 =>lsb(3),
|
||||
}
|
||||
}
|
||||
};
|
||||
field_rxbw.set_selected_index(2);
|
||||
|
||||
field_squelch.on_change = [this](int32_t v) {
|
||||
receiver_model.set_squelch_level(100 - v);
|
||||
|
||||
@@ -106,13 +106,14 @@ private:
|
||||
bool enable_dsb { false };
|
||||
bool enable_usb { false };
|
||||
bool enable_lsb { false };
|
||||
bool enable_wfm { false }; // added to distinguish in the FM mode , RX BW : NFM (8K5, 11K), FM (16K), WFM(200K)
|
||||
|
||||
|
||||
Labels labels_WM8731 {
|
||||
{ { 3 * 8, 1 * 8 }, "MIC-GAIN:", Color::light_grey() },
|
||||
{ { 17 * 8, 1 * 8 }, "Boost", Color::light_grey() },
|
||||
{ { 3 * 8, 3 * 8 }, "F:", Color::light_grey() },
|
||||
{ { 15 * 8, 3 * 8 }, "BW: FM kHz", Color::light_grey() },
|
||||
{ { 15 * 8, 3 * 8 }, "FM TXBW: kHz", Color::light_grey() }, // to be more symetric and consistent to the below FM RXBW
|
||||
{ { 3 * 8, 5 * 8 }, "GAIN:", Color::light_grey() },
|
||||
{ {11 * 8, 5 * 8 }, "Amp:", Color::light_grey() },
|
||||
{ { 18 * 8, (5 * 8) }, "Mode:", Color::light_grey() },
|
||||
@@ -122,7 +123,7 @@ private:
|
||||
{ {20 * 8, 10 * 8 }, "DEC:", Color::light_grey() },
|
||||
{ { 4 * 8, ( 13 * 8 ) - 2 }, "TONE KEY:", Color::light_grey() },
|
||||
{ { 7 * 8, 23 * 8 }, "VOL:", Color::light_grey() },
|
||||
{ {15 * 8, 23 * 8 }, "FM RXBW:", Color::light_grey() },
|
||||
{ {14 * 8, 23 * 8 }, "RXBW:", Color::light_grey() }, //we remove the label "FM" because we will display all MOD types RX_BW.
|
||||
{ {17 * 8, 25 * 8 }, "SQ:", Color::light_grey() },
|
||||
{ { 5 * 8, 25 * 8 }, "F:", Color::light_grey() },
|
||||
{ { 5 * 8, 27 * 8 }, "LNA:", Color::light_grey()},
|
||||
@@ -133,7 +134,7 @@ private:
|
||||
{ { 3 * 8, 1 * 8 }, "MIC-GAIN:", Color::light_grey() },
|
||||
{ { 17 * 8, 1 * 8 }, "ALC", Color::light_grey() },
|
||||
{ { 3 * 8, 3 * 8 }, "F:", Color::light_grey() },
|
||||
{ { 15 * 8, 3 * 8 }, "BW: FM kHz", Color::light_grey() },
|
||||
{ { 15 * 8, 3 * 8 }, "FM TXBW: kHz", Color::light_grey() },
|
||||
{ { 3 * 8, 5 * 8 }, "GAIN:", Color::light_grey() },
|
||||
{ {11 * 8, 5 * 8 }, "Amp:", Color::light_grey() },
|
||||
{ { 18 * 8, (5 * 8) }, "Mode:", Color::light_grey() },
|
||||
@@ -142,8 +143,8 @@ private:
|
||||
{ {12 * 8, 10 * 8 }, "ATT:", Color::light_grey() },
|
||||
{ {20 * 8, 10 * 8 }, "DEC:", Color::light_grey() },
|
||||
{ { 4 * 8, ( 13 * 8 ) - 2 }, "TONE KEY:", Color::light_grey() },
|
||||
{ { 7 * 8, 23 * 8 }, "VOL:", Color::light_grey() },
|
||||
{ {15 * 8, 23 * 8 }, "FM RXBW:", Color::light_grey() },
|
||||
{ { (6 * 8)+4, 23 * 8 }, "VOL:", Color::light_grey() },
|
||||
{ {14 * 8, 23 * 8 }, "RXBW:", Color::light_grey() }, //we remove the label "FM" because we will display all MOD types RX_BW.
|
||||
{ {17 * 8, 25 * 8 }, "SQ:", Color::light_grey() },
|
||||
{ { 5 * 8, 25 * 8 }, "F:", Color::light_grey() },
|
||||
{ { 5 * 8, 27 * 8 }, "LNA:", Color::light_grey()},
|
||||
@@ -204,7 +205,7 @@ OptionsField options_wm8731_boost_mode {
|
||||
{ 5 * 8, 3 * 8 },
|
||||
};
|
||||
NumberField field_bw {
|
||||
{ 18 * 8, 3 * 8 },
|
||||
{ 23 * 8, 3 * 8 },
|
||||
3,
|
||||
{ 0, 150 },
|
||||
1,
|
||||
@@ -228,13 +229,14 @@ OptionsField options_wm8731_boost_mode {
|
||||
|
||||
OptionsField options_mode {
|
||||
{ 24 * 8, 5 * 8 },
|
||||
3,
|
||||
4,
|
||||
{
|
||||
{ "FM", 0 },
|
||||
{ "AM", 1 },
|
||||
{ "USB", 2 },
|
||||
{ "LSB", 3 },
|
||||
{ "DSB", 4 }
|
||||
{ "NFM/FM", 0 },
|
||||
{ " WFM ", 1 },
|
||||
{ " AM ", 2 }, // in fact that TX mode = AM -DSB with carrier .
|
||||
{ " USB ", 3 },
|
||||
{ " LSB ", 4 },
|
||||
{ "DSB-SC", 5 } // We are TX Double Side AM Band with suppressed carrier, and allowing in RX both indep SSB lateral band (USB/LSB).
|
||||
}
|
||||
};
|
||||
/*
|
||||
@@ -307,13 +309,13 @@ OptionsField options_wm8731_boost_mode {
|
||||
};
|
||||
|
||||
OptionsField field_rxbw {
|
||||
{ 23* 8, 23 * 8},
|
||||
{ 19* 8, 23 * 8},
|
||||
3,
|
||||
{
|
||||
{"8k5", 0},
|
||||
{"11k", 1},
|
||||
{"16k", 2}
|
||||
}
|
||||
{" NFM1:8k5 ", 0},
|
||||
{" NFM2:11k ", 1},
|
||||
{" FM :16k ", 2},
|
||||
}
|
||||
};
|
||||
|
||||
NumberField field_squelch {
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
#include "file.hpp"
|
||||
|
||||
// Id's for messages between ReconThread and ReconView
|
||||
#define MSG_RECON_PAUSE 9999 // for handle_retune to know that recon thread triggered a pause. f is not important with that message
|
||||
#define MSG_RECON_SET_MODULATION 10000 // for handle_retune to know that recon thread triggered a modulation change. f is the index of the modulation
|
||||
#define MSG_RECON_SET_BANDWIDTH 20000 // for handle_retune to know that recon thread triggered a bandwidth change. f is the new bandwidth value index for current modulation
|
||||
#define MSG_RECON_SET_STEP 30000 // for handle_retune to know that recon thread triggered a bandwidth change. f is the new bandwidth value index for current modulation
|
||||
#define MSG_RECON_PAUSE 9999 // for handle_retune to know that recon thread triggered a pause. f is not important with that message
|
||||
#define MSG_RECON_SET_MODULATION 10000 // for handle_retune to know that recon thread triggered a modulation change. f is the index of the modulation
|
||||
#define MSG_RECON_SET_BANDWIDTH 20000 // for handle_retune to know that recon thread triggered a bandwidth change. f is the new bandwidth value index for current modulation
|
||||
#define MSG_RECON_SET_STEP 30000 // for handle_retune to know that recon thread triggered a bandwidth change. f is the new bandwidth value index for current modulation
|
||||
#define MSG_RECON_SET_RECEIVER_BANDWIDTH 40000 // for handle_retune to know that recon thread triggered a receiver bandwidth change. f is the new bandwidth in hz
|
||||
#define MSG_RECON_SET_RECEIVER_SAMPLERATE 50000 // for handle_retune to know that recon thread triggered a receiver samplerate change. f is the new samplerate in hz/s
|
||||
#define MSG_RECON_SET_RECEIVER_SAMPLERATE 50000 // for handle_retune to know that recon thread triggered a receiver samplerate change. f is the new samplerate in hz/s
|
||||
|
||||
|
||||
using namespace portapack;
|
||||
@@ -1000,23 +1000,32 @@ namespace ui {
|
||||
delete_file( "FREQMAN/"+output_file+".TXT" );
|
||||
}
|
||||
|
||||
if( recon_thread )
|
||||
{
|
||||
recon_thread->set_freq_index( current_index );
|
||||
timer = 0 ;
|
||||
if( recon_thread )
|
||||
{
|
||||
timer = 0 ;
|
||||
|
||||
recon_thread->set_freq_index( current_index );
|
||||
|
||||
RetuneMessage message { };
|
||||
receiver_model.set_tuning_frequency( frequency_list[ current_index ] . frequency_a ); // Retune
|
||||
message.freq = frequency_list[ current_index ] . frequency_a ;
|
||||
message.range = current_index ;
|
||||
EventDispatcher::send_message(message);
|
||||
|
||||
chThdSleepMilliseconds( recon_lock_duration ); // give some time to Thread::Run to pause
|
||||
|
||||
if( previous_userpause )
|
||||
{
|
||||
user_pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
user_resume();
|
||||
}
|
||||
|
||||
if( previous_userpause )
|
||||
{
|
||||
user_pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
user_resume();
|
||||
}
|
||||
recon_thread->set_recon( previous_is_recon );
|
||||
recon_thread->set_freq_delete(false);
|
||||
chThdSleepMilliseconds( recon_lock_duration ); // give some time to Thread::Run to pause
|
||||
}
|
||||
recon_thread->set_freq_delete(false);
|
||||
recon_thread->set_recon( previous_is_recon );
|
||||
}
|
||||
};
|
||||
|
||||
button_remove.on_change = [this]() {
|
||||
@@ -1690,7 +1699,7 @@ namespace ui {
|
||||
break;
|
||||
case WFM_MODULATION:
|
||||
freqman_set_bandwidth_option( new_mod , field_bw );
|
||||
//bw 16k (0) only/default
|
||||
//bw 200k (0) only/default
|
||||
field_bw.set_selected_index(0);
|
||||
baseband::run_image(portapack::spi_flash::image_tag_wfm_audio);
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
|
||||
|
||||
@@ -207,7 +207,7 @@ namespace ui {
|
||||
Labels labels
|
||||
{
|
||||
{ { 0 * 8 , 0 * 16 }, "LNA: VGA: AMP: VOL: ", Color::light_grey() },
|
||||
{ { 0 * 8 , 1 * 16 }, "BW : SQ: W,L: , ", Color::light_grey() },
|
||||
{ { 0 * 8 , 1 * 16 }, "BW: SQ: W,L: , ", Color::light_grey() },
|
||||
{ { 3 * 8 , 10 * 16 }, "START END MANUAL", Color::light_grey() },
|
||||
{ { 0 * 8 , (26 * 8) + 4 }, "MODE:", Color::light_grey() },
|
||||
{ { 11 * 8 , (26 * 8) + 4 }, "STEP:", Color::light_grey() },
|
||||
@@ -235,12 +235,12 @@ namespace ui {
|
||||
|
||||
OptionsField field_bw {
|
||||
{ 3 * 8, 1 * 16 },
|
||||
4,
|
||||
6,
|
||||
{ }
|
||||
};
|
||||
|
||||
NumberField field_squelch {
|
||||
{ 10 * 8, 1 * 16 },
|
||||
{ 12 * 8, 1 * 16 },
|
||||
3,
|
||||
{ -90, 20 },
|
||||
1,
|
||||
@@ -248,7 +248,7 @@ namespace ui {
|
||||
};
|
||||
|
||||
NumberField field_wait {
|
||||
{ 18 * 8, 1 * 16 },
|
||||
{ 20 * 8, 1 * 16 },
|
||||
5,
|
||||
{ -9000, 9000 },
|
||||
100,
|
||||
@@ -256,7 +256,7 @@ namespace ui {
|
||||
};
|
||||
|
||||
NumberField field_lock_wait {
|
||||
{ 24 * 8, 1 * 16 },
|
||||
{ 26 * 8, 1 * 16 },
|
||||
4,
|
||||
{ 100 , 9000 },
|
||||
100,
|
||||
|
||||
@@ -160,9 +160,9 @@ ScannerView::~ScannerView() {
|
||||
}
|
||||
|
||||
void ScannerView::show_max() { //show total number of freqs to scan
|
||||
if (frequency_list.size() == MAX_DB_ENTRY) {
|
||||
if (frequency_list.size() == FREQMAN_MAX_PER_FILE ) {
|
||||
text_max.set_style(&style_red);
|
||||
text_max.set( "/ " + to_string_dec_uint(MAX_DB_ENTRY) + " (DB MAX!)");
|
||||
text_max.set( "/ " + to_string_dec_uint(FREQMAN_MAX_PER_FILE ) + " (DB MAX!)");
|
||||
}
|
||||
else {
|
||||
text_max.set_style(&style_grey);
|
||||
@@ -304,7 +304,7 @@ ScannerView::ScannerView(
|
||||
);
|
||||
|
||||
rf::Frequency frequency = frequency_range.min;
|
||||
while (frequency_list.size() < MAX_DB_ENTRY && frequency <= frequency_range.max) { //add manual range
|
||||
while (frequency_list.size() < FREQMAN_MAX_PER_FILE && frequency <= frequency_range.max) { //add manual range
|
||||
frequency_list.push_back(frequency);
|
||||
description_list.push_back(""); //If empty, will keep showing the last description
|
||||
frequency+=def_step;
|
||||
@@ -398,7 +398,7 @@ void ScannerView::frequency_file_load(std::string file_name, bool stop_all_befor
|
||||
if ( load_freqman_file(file_name, database) ) {
|
||||
loaded_file_name = file_name; // keep loaded filename in memory
|
||||
for(auto& entry : database) { // READ LINE PER LINE
|
||||
if (frequency_list.size() < MAX_DB_ENTRY) { //We got space!
|
||||
if (frequency_list.size() < FREQMAN_MAX_PER_FILE ) { //We got space!
|
||||
if (entry.type == RANGE) { //RANGE
|
||||
switch (entry.step) {
|
||||
case AM_US: def_step = 10000; break ;
|
||||
@@ -421,7 +421,7 @@ void ScannerView::frequency_file_load(std::string file_name, bool stop_all_befor
|
||||
+ ">" + to_string_short_freq(entry.frequency_b)
|
||||
+ " S" + to_string_short_freq(def_step).erase(0,1) //euquiq: lame kludge to reduce spacing in step freq
|
||||
);
|
||||
while (frequency_list.size() < MAX_DB_ENTRY && entry.frequency_a <= entry.frequency_b) { //add the rest of the range
|
||||
while (frequency_list.size() < FREQMAN_MAX_PER_FILE && entry.frequency_a <= entry.frequency_b) { //add the rest of the range
|
||||
entry.frequency_a+=def_step;
|
||||
frequency_list.push_back(entry.frequency_a);
|
||||
description_list.push_back(""); //Token (keep showing the last description)
|
||||
@@ -529,10 +529,12 @@ size_t ScannerView::change_mode(uint8_t new_mod) { //Before this, do a scan_thre
|
||||
receiver_model.set_sampling_rate(3072000); receiver_model.set_baseband_bandwidth(1750000);
|
||||
break;
|
||||
case AM:
|
||||
bw.emplace_back("DSB", 0);
|
||||
bw.emplace_back("USB", 0);
|
||||
bw.emplace_back("LSB", 0);
|
||||
bw.emplace_back("CW ", 0);
|
||||
bw.emplace_back("DSB 9k" , 0 );
|
||||
bw.emplace_back("DSB 6k" , 1 );
|
||||
bw.emplace_back("USB+3k" , 2 );
|
||||
bw.emplace_back("LSB-3k" , 3 );
|
||||
bw.emplace_back("CW " , 4 );
|
||||
|
||||
field_bw.set_options(bw);
|
||||
|
||||
baseband::run_image(portapack::spi_flash::image_tag_am_audio);
|
||||
@@ -543,7 +545,7 @@ size_t ScannerView::change_mode(uint8_t new_mod) { //Before this, do a scan_thre
|
||||
receiver_model.set_sampling_rate(3072000); receiver_model.set_baseband_bandwidth(1750000);
|
||||
break;
|
||||
case WFM:
|
||||
bw.emplace_back("16k", 0);
|
||||
bw.emplace_back("200k", 0);
|
||||
field_bw.set_options(bw);
|
||||
|
||||
baseband::run_image(portapack::spi_flash::image_tag_wfm_audio);
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "file.hpp"
|
||||
|
||||
|
||||
#define MAX_DB_ENTRY 500
|
||||
#define MAX_FREQ_LOCK 10 //50ms cycles scanner locks into freq when signal detected, to verify signal is not spureous
|
||||
|
||||
namespace ui {
|
||||
@@ -144,7 +143,7 @@ private:
|
||||
|
||||
Labels labels {
|
||||
{ { 0 * 8, 0 * 16 }, "LNA: VGA: AMP: VOL:", Color::light_grey() },
|
||||
{ { 0 * 8, 1* 16 }, "BW: SQUELCH: db WAIT:", Color::light_grey() },
|
||||
{ { 0 * 8, 1* 16 }, "BW: SQLCH: db WAIT:", Color::light_grey() },
|
||||
{ { 3 * 8, 10 * 16 }, "START END MANUAL", Color::light_grey() },
|
||||
{ { 0 * 8, (26 * 8) + 4 }, "MODE:", Color::light_grey() },
|
||||
{ { 11 * 8, (26 * 8) + 4 }, "STEP:", Color::light_grey() },
|
||||
@@ -177,7 +176,7 @@ private:
|
||||
};
|
||||
|
||||
NumberField field_squelch {
|
||||
{ 15 * 8, 1 * 16 },
|
||||
{ 18 * 8, 1 * 16 },
|
||||
3,
|
||||
{ -90, 20 },
|
||||
1,
|
||||
@@ -185,7 +184,7 @@ private:
|
||||
};
|
||||
|
||||
NumberField field_wait {
|
||||
{ 26 * 8, 1 * 16 },
|
||||
{ 27 * 8, 1 * 16 },
|
||||
2,
|
||||
{ 0, 99 },
|
||||
1,
|
||||
|
||||
@@ -45,11 +45,11 @@ static void send_message(const Message* const message) {
|
||||
|
||||
void AMConfig::apply() const {
|
||||
const AMConfigureMessage message {
|
||||
taps_6k0_decim_0,
|
||||
taps_6k0_decim_1,
|
||||
taps_6k0_decim_2,
|
||||
channel,
|
||||
modulation,
|
||||
taps_6k0_decim_0, // common FIR filter taps pre-decim_0 to all 5 x AM mod types.(AM-9K, AM-6K, USB, LSB, CW)
|
||||
taps_6k0_decim_1, // common FIR filter taps pre-decim_1 to all 5 x AM mod. types.
|
||||
decim_2, // var decim_2 FIR taps filter , variable values, depending selected AM mod(AM 9k / 6k all rest AM modes)
|
||||
channel, // var channel FIR taps filter , variable values, depending selected AM mode, each one different (DSB-9K, DSB-6K, USB-3K, LSB-3K,CW)
|
||||
modulation, // var parameter .
|
||||
audio_12k_hpf_300hz_config
|
||||
};
|
||||
send_message(&message);
|
||||
@@ -146,7 +146,7 @@ void set_btle(const uint32_t baudrate, const uint32_t word_length, const uint32_
|
||||
};
|
||||
send_message(&message);
|
||||
}
|
||||
|
||||
|
||||
void set_nrf(const uint32_t baudrate, const uint32_t word_length, const uint32_t trigger_value, const bool trigger_word) {
|
||||
const NRFRxConfigureMessage message {
|
||||
baudrate,
|
||||
@@ -156,7 +156,7 @@ void set_nrf(const uint32_t baudrate, const uint32_t word_length, const uint32_t
|
||||
};
|
||||
send_message(&message);
|
||||
}
|
||||
|
||||
|
||||
void set_afsk_data(const uint32_t afsk_samples_per_bit, const uint32_t afsk_phase_inc_mark, const uint32_t afsk_phase_inc_space,
|
||||
const uint8_t afsk_repeat, const uint32_t afsk_bw, const uint8_t symbol_count) {
|
||||
const AFSKTxConfigureMessage message {
|
||||
@@ -183,7 +183,7 @@ void kill_afsk() {
|
||||
}
|
||||
|
||||
void set_audiotx_config(const uint32_t divider, const float deviation_hz, const float audio_gain,
|
||||
uint8_t audio_shift_bits_s16, const uint32_t tone_key_delta, const bool am_enabled,
|
||||
uint8_t audio_shift_bits_s16, const uint32_t tone_key_delta, const bool am_enabled,
|
||||
const bool dsb_enabled, const bool usb_enabled, const bool lsb_enabled) {
|
||||
const AudioTXConfigMessage message {
|
||||
divider,
|
||||
@@ -212,16 +212,28 @@ void set_pitch_rssi(int32_t avg, bool enabled) {
|
||||
enabled,
|
||||
avg
|
||||
};
|
||||
send_message(&message);
|
||||
send_message(&message);
|
||||
}
|
||||
|
||||
void set_ook_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint8_t repeat,
|
||||
const uint32_t pause_symbols) {
|
||||
const uint32_t pause_symbols, const uint8_t de_bruijn_length) {
|
||||
const OOKConfigureMessage message {
|
||||
stream_length,
|
||||
samples_per_bit,
|
||||
repeat,
|
||||
pause_symbols
|
||||
pause_symbols,
|
||||
de_bruijn_length
|
||||
};
|
||||
send_message(&message);
|
||||
}
|
||||
|
||||
void kill_ook() {
|
||||
const OOKConfigureMessage message {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
send_message(&message);
|
||||
}
|
||||
@@ -251,7 +263,7 @@ void set_adsb() {
|
||||
|
||||
void set_jammer(const bool run, const jammer::JammerType type, const uint32_t speed) {
|
||||
const JammerConfigureMessage message {
|
||||
run,
|
||||
run,
|
||||
type,
|
||||
speed
|
||||
};
|
||||
@@ -312,7 +324,7 @@ void shutdown() {
|
||||
send_message(&message);
|
||||
|
||||
shared_memory.application_queue.reset();
|
||||
|
||||
|
||||
baseband_image_running = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
namespace baseband {
|
||||
|
||||
struct AMConfig {
|
||||
const fir_taps_real<32> decim_2; // added to handle two types decim_2 9k, 6k
|
||||
const fir_taps_complex<64> channel;
|
||||
const AMConfigureMessage::Modulation modulation;
|
||||
|
||||
@@ -61,7 +62,7 @@ void set_tones_config(const uint32_t bw, const uint32_t pre_silence, const uint1
|
||||
void kill_tone();
|
||||
void set_sstv_data(const uint8_t vis_code, const uint32_t pixel_duration);
|
||||
void set_audiotx_config(const uint32_t divider, const float deviation_hz, const float audio_gain,
|
||||
uint8_t audio_shift_bits_s16, const uint32_t tone_key_delta, const bool am_enabled,
|
||||
uint8_t audio_shift_bits_s16, const uint32_t tone_key_delta, const bool am_enabled,
|
||||
const bool dsb_enabled, const bool usb_enabled, const bool lsb_enabled);
|
||||
void set_fifo_data(const int8_t * data);
|
||||
void set_pitch_rssi(int32_t avg, bool enabled);
|
||||
@@ -76,7 +77,8 @@ void set_btle(const uint32_t baudrate, const uint32_t word_length, const uint32_
|
||||
void set_nrf(const uint32_t baudrate, const uint32_t word_length, const uint32_t trigger_value, const bool trigger_word);
|
||||
|
||||
void set_ook_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint8_t repeat,
|
||||
const uint32_t pause_symbols);
|
||||
const uint32_t pause_symbols, const uint8_t de_bruijn_length = 0);
|
||||
void kill_ook();
|
||||
void set_fsk_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint32_t shift,
|
||||
const uint32_t progress_notice);
|
||||
void set_pocsag();
|
||||
|
||||
@@ -34,10 +34,11 @@ options_t freqman_entry_modulations = {
|
||||
|
||||
options_t freqman_entry_bandwidths[ 4 ] = {
|
||||
{ //AM
|
||||
{ "DSB", 0 },
|
||||
{ "USB", 1 },
|
||||
{ "LSB", 2 },
|
||||
{ "CW" , 3 }
|
||||
{ "DSB 9k" , 0 },
|
||||
{ "DSB 6k" , 1 },
|
||||
{ "USB+3k" , 2 },
|
||||
{ "LSB-3k" , 3 },
|
||||
{ "CW" , 4 }
|
||||
},
|
||||
{ //NFM
|
||||
{ "8k5" , 0 },
|
||||
@@ -45,7 +46,7 @@ options_t freqman_entry_bandwidths[ 4 ] = {
|
||||
{ "16k" , 2 }
|
||||
},
|
||||
{ //WFM
|
||||
{ "16k" , 0 },
|
||||
{ "200k" , 0 },
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,10 +59,11 @@ options_t freqman_entry_steps = {
|
||||
{ "12.5KHz(NFM)" , 12500 },
|
||||
{ "15KHz (HFM)" , 15000 },
|
||||
{ "25KHz (N1)" , 25000 },
|
||||
{ "30KHz (OIRT)" , 30000 },
|
||||
{ "50KHz (FM1)" , 50000 },
|
||||
{ "100KHz (FM2)" , 100000 },
|
||||
{ "250KHz (N2)" , 250000 },
|
||||
{ "500KHz " , 500000 },
|
||||
{ "500KHz (WFM)" , 500000 },
|
||||
{ "1MHz " , 1000000 }
|
||||
};
|
||||
|
||||
@@ -74,6 +76,7 @@ options_t freqman_entry_steps_short = {
|
||||
{ "12.5KHz" , 12500 },
|
||||
{ "15KHz" , 15000 },
|
||||
{ "25KHz" , 25000 },
|
||||
{ "30KHz" , 30000 },
|
||||
{ "50KHz" , 50000 },
|
||||
{ "100KHz" , 100000 },
|
||||
{ "250KHz" , 250000 },
|
||||
@@ -99,91 +102,6 @@ std::vector<std::string> get_freqman_files() {
|
||||
|
||||
bool load_freqman_file(std::string& file_stem, freqman_db &db) {
|
||||
return load_freqman_file_ex( file_stem , db , true , true , true );
|
||||
/* File freqman_file;
|
||||
size_t length, n = 0, file_position = 0;
|
||||
char * pos;
|
||||
char * line_start;
|
||||
char * line_end;
|
||||
std::string description;
|
||||
rf::Frequency frequency_a, frequency_b;
|
||||
char file_data[257];
|
||||
freqman_entry_type type;
|
||||
|
||||
db.clear();
|
||||
|
||||
auto result = freqman_file.open("FREQMAN/" + file_stem + ".TXT");
|
||||
if (result.is_valid())
|
||||
return false;
|
||||
|
||||
while (1) {
|
||||
// Read a 256 bytes block from file
|
||||
freqman_file.seek(file_position);
|
||||
|
||||
memset(file_data, 0, 257);
|
||||
auto read_size = freqman_file.read(file_data, 256);
|
||||
if (read_size.is_error())
|
||||
return false; // Read error
|
||||
|
||||
file_position += 256;
|
||||
|
||||
// Reset line_start to beginning of buffer
|
||||
line_start = file_data;
|
||||
|
||||
if (!strstr(file_data, "f=") && !strstr(file_data, "a="))
|
||||
break;
|
||||
|
||||
// Look for complete lines in buffer
|
||||
while ((line_end = strstr(line_start, "\x0A"))) {
|
||||
// Read frequency
|
||||
pos = strstr(line_start, "f=");
|
||||
frequency_b = 0;
|
||||
type = SINGLE;
|
||||
if (pos) {
|
||||
pos += 2;
|
||||
frequency_a = strtoll(pos, nullptr, 10);
|
||||
} else {
|
||||
// ...or range
|
||||
pos = strstr(line_start, "a=");
|
||||
if (pos) {
|
||||
pos += 2;
|
||||
frequency_a = strtoll(pos, nullptr, 10);
|
||||
type = RANGE;
|
||||
pos = strstr(line_start, "b=");
|
||||
if (pos) {
|
||||
pos += 2;
|
||||
frequency_b = strtoll(pos, nullptr, 10);
|
||||
} else
|
||||
frequency_b = 0;
|
||||
} else
|
||||
frequency_a = 0;
|
||||
}
|
||||
|
||||
// Read description until , or LF
|
||||
pos = strstr(line_start, "d=");
|
||||
if (pos) {
|
||||
pos += 2;
|
||||
length = std::min(strcspn(pos, ",\x0A"), (size_t)FREQMAN_DESC_MAX_LEN);
|
||||
description = string(pos, length);
|
||||
} else
|
||||
description = "-";
|
||||
|
||||
db.push_back({ frequency_a, frequency_b, description, type , -1 , -1 , -1 , -1 });
|
||||
n++;
|
||||
|
||||
if (n >= FREQMAN_MAX_PER_FILE) return true;
|
||||
|
||||
line_start = line_end + 1;
|
||||
if (line_start - file_data >= 256) break;
|
||||
}
|
||||
|
||||
if (read_size.value() != 256)
|
||||
break; // End of file
|
||||
|
||||
// Restart at beginning of last incomplete line
|
||||
file_position -= (file_data + 256 - line_start);
|
||||
}
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
bool load_freqman_file_ex(std::string& file_stem, freqman_db& db, bool load_freqs , bool load_ranges , bool load_hamradios ) {
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
#include "ui_widget.hpp"
|
||||
|
||||
#define FREQMAN_DESC_MAX_LEN 30
|
||||
#define FREQMAN_MAX_PER_FILE 99
|
||||
#define FREQMAN_MAX_PER_FILE_STR "99"
|
||||
#define FREQMAN_MAX_PER_FILE 500 /* MAX PER FILES */
|
||||
#define FREQMAN_MAX_PER_FILE_STR "500" /*STRING OF FREQMAN_MAX_PER_FILE */
|
||||
|
||||
using namespace ui;
|
||||
using namespace std;
|
||||
|
||||
@@ -38,11 +38,12 @@ using namespace portapack;
|
||||
|
||||
namespace {
|
||||
|
||||
static constexpr std::array<baseband::AMConfig, 4> am_configs { {
|
||||
{ taps_6k0_dsb_channel, AMConfigureMessage::Modulation::DSB },
|
||||
{ taps_2k8_usb_channel, AMConfigureMessage::Modulation::SSB },
|
||||
{ taps_2k8_lsb_channel, AMConfigureMessage::Modulation::SSB },
|
||||
{ taps_0k7_usb_channel, AMConfigureMessage::Modulation::SSB },
|
||||
static constexpr std::array<baseband::AMConfig, 5> am_configs { { // we config here all the non COMMON parameters to each AM modulation type in RX.
|
||||
{ taps_9k0_decim_2, taps_9k0_dsb_channel, AMConfigureMessage::Modulation::DSB }, // AM DSB-C BW 9khz (+-4k5) commercial EU bandwidth .
|
||||
{ taps_6k0_decim_2, taps_6k0_dsb_channel, AMConfigureMessage::Modulation::DSB }, // AM DSB-C BW 6khz (+-3k0) narrow AM , ham equipments.
|
||||
{ taps_6k0_decim_2, taps_2k8_usb_channel, AMConfigureMessage::Modulation::SSB }, // SSB USB BW 2K8 (+ 2K8)
|
||||
{ taps_6k0_decim_2, taps_2k8_lsb_channel, AMConfigureMessage::Modulation::SSB }, // SSB LSB BW 2K8 (- 2K8)
|
||||
{ taps_6k0_decim_2, taps_0k7_usb_channel, AMConfigureMessage::Modulation::SSB }, // SSB USB BW 0K7 (+ 0K7) used to get audio tone from CW Morse, assuming tx shifted +700hz aprox
|
||||
} };
|
||||
|
||||
static constexpr std::array<baseband::NBFMConfig, 3> nbfm_configs { {
|
||||
|
||||
@@ -281,262 +281,262 @@ const std::array<ui::Color, 256> spectrum_rgb2_lut { {
|
||||
} };
|
||||
|
||||
const std::array<ui::Color, 256> spectrum_rgb3_lut { {
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 3 },
|
||||
{ 0, 0, 6 },
|
||||
{ 0, 0, 9 },
|
||||
{ 0, 0, 12 },
|
||||
{ 0, 0, 15 },
|
||||
{ 0, 0, 18 },
|
||||
{ 0, 0, 21 },
|
||||
{ 0, 0, 24 },
|
||||
{ 0, 0, 27 },
|
||||
{ 0, 0, 30 },
|
||||
{ 0, 0, 33 },
|
||||
{ 0, 0, 36 },
|
||||
{ 0, 0, 39 },
|
||||
{ 0, 0, 42 },
|
||||
{ 0, 0, 45 },
|
||||
{ 0, 0, 48 },
|
||||
{ 0, 0, 51 },
|
||||
{ 0, 0, 54 },
|
||||
{ 0, 0, 57 },
|
||||
{ 0, 0, 60 },
|
||||
{ 0, 0, 63 },
|
||||
{ 0, 0, 66 },
|
||||
{ 0, 0, 69 },
|
||||
{ 0, 0, 72 },
|
||||
{ 0, 0, 75 },
|
||||
{ 0, 0, 78 },
|
||||
{ 0, 0, 81 },
|
||||
{ 0, 0, 84 },
|
||||
{ 0, 0, 87 },
|
||||
{ 0, 0, 90 },
|
||||
{ 0, 0, 93 },
|
||||
{ 0, 0, 96 },
|
||||
{ 0, 0, 99 },
|
||||
{ 0, 0, 102 },
|
||||
{ 0, 0, 105 },
|
||||
{ 0, 0, 108 },
|
||||
{ 0, 0, 111 },
|
||||
{ 0, 0, 114 },
|
||||
{ 0, 0, 117 },
|
||||
{ 0, 0, 120 },
|
||||
{ 0, 0, 123 },
|
||||
{ 0, 0, 126 },
|
||||
{ 0, 0, 129 },
|
||||
{ 0, 0, 132 },
|
||||
{ 0, 0, 135 },
|
||||
{ 0, 0, 138 },
|
||||
{ 0, 0, 141 },
|
||||
{ 0, 0, 144 },
|
||||
{ 0, 0, 147 },
|
||||
{ 0, 0, 150 },
|
||||
{ 0, 0, 153 },
|
||||
{ 0, 0, 156 },
|
||||
{ 0, 0, 159 },
|
||||
{ 0, 0, 162 },
|
||||
{ 0, 0, 165 },
|
||||
{ 0, 0, 168 },
|
||||
{ 0, 0, 171 },
|
||||
{ 0, 0, 174 },
|
||||
{ 0, 0, 177 },
|
||||
{ 0, 0, 180 },
|
||||
{ 0, 0, 183 },
|
||||
{ 0, 0, 186 },
|
||||
{ 0, 0, 189 },
|
||||
{ 0, 0, 192 },
|
||||
{ 0, 0, 195 },
|
||||
{ 0, 0, 198 },
|
||||
{ 0, 0, 201 },
|
||||
{ 0, 0, 204 },
|
||||
{ 0, 0, 207 },
|
||||
{ 0, 0, 210 },
|
||||
{ 0, 0, 213 },
|
||||
{ 0, 0, 216 },
|
||||
{ 0, 0, 219 },
|
||||
{ 0, 0, 222 },
|
||||
{ 0, 0, 225 },
|
||||
{ 0, 0, 228 },
|
||||
{ 0, 0, 231 },
|
||||
{ 0, 0, 234 },
|
||||
{ 0, 0, 237 },
|
||||
{ 0, 0, 240 },
|
||||
{ 0, 0, 243 },
|
||||
{ 0, 0, 246 },
|
||||
{ 0, 0, 249 },
|
||||
{ 0, 0, 252 },
|
||||
{ 0, 0, 255 },
|
||||
{ 0, 3, 252 },
|
||||
{ 0, 6, 249 },
|
||||
{ 0, 9, 246 },
|
||||
{ 0, 12, 243 },
|
||||
{ 0, 15, 240 },
|
||||
{ 0, 18, 237 },
|
||||
{ 0, 21, 234 },
|
||||
{ 0, 24, 231 },
|
||||
{ 0, 27, 228 },
|
||||
{ 0, 30, 225 },
|
||||
{ 0, 33, 222 },
|
||||
{ 0, 36, 219 },
|
||||
{ 0, 39, 216 },
|
||||
{ 0, 42, 213 },
|
||||
{ 0, 45, 210 },
|
||||
{ 0, 48, 207 },
|
||||
{ 0, 51, 204 },
|
||||
{ 0, 54, 201 },
|
||||
{ 0, 57, 198 },
|
||||
{ 0, 60, 195 },
|
||||
{ 0, 63, 192 },
|
||||
{ 0, 66, 189 },
|
||||
{ 0, 69, 186 },
|
||||
{ 0, 72, 183 },
|
||||
{ 0, 75, 180 },
|
||||
{ 0, 78, 177 },
|
||||
{ 0, 81, 174 },
|
||||
{ 0, 84, 171 },
|
||||
{ 0, 87, 168 },
|
||||
{ 0, 90, 165 },
|
||||
{ 0, 93, 162 },
|
||||
{ 0, 96, 159 },
|
||||
{ 0, 99, 156 },
|
||||
{ 0, 102, 153 },
|
||||
{ 0, 105, 150 },
|
||||
{ 0, 108, 147 },
|
||||
{ 0, 111, 144 },
|
||||
{ 0, 114, 141 },
|
||||
{ 0, 117, 138 },
|
||||
{ 0, 120, 135 },
|
||||
{ 0, 123, 132 },
|
||||
{ 0, 126, 129 },
|
||||
{ 0, 129, 126 },
|
||||
{ 0, 132, 123 },
|
||||
{ 0, 135, 120 },
|
||||
{ 0, 138, 117 },
|
||||
{ 0, 141, 114 },
|
||||
{ 0, 144, 111 },
|
||||
{ 0, 147, 108 },
|
||||
{ 0, 150, 105 },
|
||||
{ 0, 153, 102 },
|
||||
{ 0, 156, 99 },
|
||||
{ 0, 159, 96 },
|
||||
{ 0, 162, 93 },
|
||||
{ 0, 165, 90 },
|
||||
{ 0, 168, 87 },
|
||||
{ 0, 171, 84 },
|
||||
{ 0, 174, 81 },
|
||||
{ 0, 177, 78 },
|
||||
{ 0, 180, 75 },
|
||||
{ 0, 183, 72 },
|
||||
{ 0, 186, 69 },
|
||||
{ 0, 189, 66 },
|
||||
{ 0, 192, 63 },
|
||||
{ 0, 195, 60 },
|
||||
{ 0, 198, 57 },
|
||||
{ 0, 201, 54 },
|
||||
{ 0, 204, 51 },
|
||||
{ 0, 207, 48 },
|
||||
{ 0, 210, 45 },
|
||||
{ 0, 213, 42 },
|
||||
{ 0, 216, 39 },
|
||||
{ 0, 219, 36 },
|
||||
{ 0, 222, 33 },
|
||||
{ 0, 225, 30 },
|
||||
{ 0, 228, 27 },
|
||||
{ 0, 231, 24 },
|
||||
{ 0, 234, 21 },
|
||||
{ 0, 237, 18 },
|
||||
{ 0, 240, 15 },
|
||||
{ 0, 243, 12 },
|
||||
{ 0, 246, 9 },
|
||||
{ 0, 249, 6 },
|
||||
{ 0, 252, 3 },
|
||||
{ 0, 255, 0 },
|
||||
{ 3, 252, 0 },
|
||||
{ 6, 249, 0 },
|
||||
{ 9, 246, 0 },
|
||||
{ 12, 243, 0 },
|
||||
{ 15, 240, 0 },
|
||||
{ 18, 237, 0 },
|
||||
{ 21, 234, 0 },
|
||||
{ 24, 231, 0 },
|
||||
{ 27, 228, 0 },
|
||||
{ 30, 225, 0 },
|
||||
{ 33, 222, 0 },
|
||||
{ 36, 219, 0 },
|
||||
{ 39, 216, 0 },
|
||||
{ 42, 213, 0 },
|
||||
{ 45, 210, 0 },
|
||||
{ 48, 207, 0 },
|
||||
{ 51, 204, 0 },
|
||||
{ 54, 201, 0 },
|
||||
{ 57, 198, 0 },
|
||||
{ 60, 195, 0 },
|
||||
{ 63, 192, 0 },
|
||||
{ 66, 189, 0 },
|
||||
{ 69, 186, 0 },
|
||||
{ 72, 183, 0 },
|
||||
{ 75, 180, 0 },
|
||||
{ 78, 177, 0 },
|
||||
{ 81, 174, 0 },
|
||||
{ 84, 171, 0 },
|
||||
{ 87, 168, 0 },
|
||||
{ 90, 165, 0 },
|
||||
{ 93, 162, 0 },
|
||||
{ 96, 159, 0 },
|
||||
{ 99, 156, 0 },
|
||||
{ 102, 153, 0 },
|
||||
{ 105, 150, 0 },
|
||||
{ 108, 147, 0 },
|
||||
{ 111, 144, 0 },
|
||||
{ 114, 141, 0 },
|
||||
{ 117, 138, 0 },
|
||||
{ 120, 135, 0 },
|
||||
{ 123, 132, 0 },
|
||||
{ 126, 129, 0 },
|
||||
{ 129, 126, 0 },
|
||||
{ 132, 123, 0 },
|
||||
{ 135, 120, 0 },
|
||||
{ 138, 117, 0 },
|
||||
{ 141, 114, 0 },
|
||||
{ 144, 111, 0 },
|
||||
{ 147, 108, 0 },
|
||||
{ 150, 105, 0 },
|
||||
{ 153, 102, 0 },
|
||||
{ 156, 99, 0 },
|
||||
{ 159, 96, 0 },
|
||||
{ 162, 93, 0 },
|
||||
{ 165, 90, 0 },
|
||||
{ 168, 87, 0 },
|
||||
{ 171, 84, 0 },
|
||||
{ 174, 81, 0 },
|
||||
{ 177, 78, 0 },
|
||||
{ 180, 75, 0 },
|
||||
{ 183, 72, 0 },
|
||||
{ 186, 69, 0 },
|
||||
{ 189, 66, 0 },
|
||||
{ 192, 63, 0 },
|
||||
{ 195, 60, 0 },
|
||||
{ 198, 57, 0 },
|
||||
{ 201, 54, 0 },
|
||||
{ 204, 51, 0 },
|
||||
{ 207, 48, 0 },
|
||||
{ 210, 45, 0 },
|
||||
{ 213, 42, 0 },
|
||||
{ 216, 39, 0 },
|
||||
{ 219, 36, 0 },
|
||||
{ 222, 33, 0 },
|
||||
{ 225, 30, 0 },
|
||||
{ 228, 27, 0 },
|
||||
{ 231, 24, 0 },
|
||||
{ 234, 21, 0 },
|
||||
{ 237, 18, 0 },
|
||||
{ 240, 15, 0 },
|
||||
{ 243, 12, 0 },
|
||||
{ 246, 9, 0 },
|
||||
{ 249, 6, 0 },
|
||||
{ 252, 3, 0 },
|
||||
{ 255, 0, 0 },
|
||||
{ 0x00, 0x00, 0x02 },
|
||||
{ 0x00, 0x00, 0x04 },
|
||||
{ 0x00, 0x00, 0x05 },
|
||||
{ 0x00, 0x00, 0x07 },
|
||||
{ 0x00, 0x00, 0x0a },
|
||||
{ 0x00, 0x00, 0x0c },
|
||||
{ 0x00, 0x00, 0x0e },
|
||||
{ 0x00, 0x00, 0x10 },
|
||||
{ 0x00, 0x00, 0x13 },
|
||||
{ 0x00, 0x00, 0x15 },
|
||||
{ 0x00, 0x00, 0x17 },
|
||||
{ 0x00, 0x00, 0x19 },
|
||||
{ 0x00, 0x00, 0x1b },
|
||||
{ 0x00, 0x00, 0x1d },
|
||||
{ 0x00, 0x00, 0x1f },
|
||||
{ 0x00, 0x00, 0x21 },
|
||||
{ 0x00, 0x00, 0x24 },
|
||||
{ 0x00, 0x00, 0x25 },
|
||||
{ 0x00, 0x00, 0x28 },
|
||||
{ 0x00, 0x00, 0x29 },
|
||||
{ 0x00, 0x00, 0x2c },
|
||||
{ 0x00, 0x00, 0x2e },
|
||||
{ 0x00, 0x00, 0x30 },
|
||||
{ 0x00, 0x00, 0x33 },
|
||||
{ 0x00, 0x00, 0x35 },
|
||||
{ 0x00, 0x00, 0x37 },
|
||||
{ 0x00, 0x00, 0x39 },
|
||||
{ 0x00, 0x00, 0x3b },
|
||||
{ 0x00, 0x00, 0x3d },
|
||||
{ 0x00, 0x00, 0x3f },
|
||||
{ 0x00, 0x00, 0x41 },
|
||||
{ 0x00, 0x00, 0x43 },
|
||||
{ 0x00, 0x00, 0x46 },
|
||||
{ 0x00, 0x00, 0x48 },
|
||||
{ 0x00, 0x00, 0x4a },
|
||||
{ 0x00, 0x00, 0x4c },
|
||||
{ 0x00, 0x00, 0x4e },
|
||||
{ 0x00, 0x00, 0x50 },
|
||||
{ 0x00, 0x00, 0x53 },
|
||||
{ 0x00, 0x00, 0x55 },
|
||||
{ 0x00, 0x00, 0x56 },
|
||||
{ 0x00, 0x00, 0x59 },
|
||||
{ 0x00, 0x00, 0x5b },
|
||||
{ 0x00, 0x00, 0x5d },
|
||||
{ 0x00, 0x00, 0x5f },
|
||||
{ 0x00, 0x00, 0x62 },
|
||||
{ 0x00, 0x00, 0x63 },
|
||||
{ 0x00, 0x00, 0x66 },
|
||||
{ 0x00, 0x00, 0x68 },
|
||||
{ 0x00, 0x00, 0x6a },
|
||||
{ 0x00, 0x00, 0x6c },
|
||||
{ 0x00, 0x00, 0x6e },
|
||||
{ 0x00, 0x00, 0x70 },
|
||||
{ 0x00, 0x00, 0x73 },
|
||||
{ 0x00, 0x00, 0x75 },
|
||||
{ 0x00, 0x00, 0x77 },
|
||||
{ 0x00, 0x00, 0x79 },
|
||||
{ 0x00, 0x00, 0x7b },
|
||||
{ 0x00, 0x00, 0x7d },
|
||||
{ 0x00, 0x00, 0x7f },
|
||||
{ 0x00, 0x00, 0x82 },
|
||||
{ 0x00, 0x00, 0x84 },
|
||||
{ 0x00, 0x00, 0x86 },
|
||||
{ 0x00, 0x00, 0x88 },
|
||||
{ 0x00, 0x00, 0x8a },
|
||||
{ 0x00, 0x00, 0x8c },
|
||||
{ 0x00, 0x00, 0x8e },
|
||||
{ 0x00, 0x00, 0x91 },
|
||||
{ 0x00, 0x00, 0x93 },
|
||||
{ 0x00, 0x00, 0x95 },
|
||||
{ 0x00, 0x00, 0x97 },
|
||||
{ 0x00, 0x00, 0x99 },
|
||||
{ 0x00, 0x00, 0x9b },
|
||||
{ 0x00, 0x00, 0x9d },
|
||||
{ 0x00, 0x00, 0x9f },
|
||||
{ 0x00, 0x00, 0xa2 },
|
||||
{ 0x00, 0x00, 0xa4 },
|
||||
{ 0x00, 0x00, 0xa6 },
|
||||
{ 0x00, 0x00, 0xa8 },
|
||||
{ 0x00, 0x00, 0xaa },
|
||||
{ 0x00, 0x00, 0xac },
|
||||
{ 0x00, 0x00, 0xae },
|
||||
{ 0x00, 0x00, 0xb1 },
|
||||
{ 0x00, 0x00, 0xb3 },
|
||||
{ 0x00, 0x00, 0xb5 },
|
||||
{ 0x00, 0x00, 0xb7 },
|
||||
{ 0x00, 0x00, 0xb9 },
|
||||
{ 0x00, 0x00, 0xbb },
|
||||
{ 0x00, 0x00, 0xbd },
|
||||
{ 0x00, 0x00, 0xbf },
|
||||
{ 0x00, 0x00, 0xc2 },
|
||||
{ 0x00, 0x00, 0xc4 },
|
||||
{ 0x00, 0x00, 0xc6 },
|
||||
{ 0x00, 0x00, 0xc8 },
|
||||
{ 0x00, 0x00, 0xca },
|
||||
{ 0x00, 0x00, 0xcc },
|
||||
{ 0x00, 0x00, 0xce },
|
||||
{ 0x00, 0x00, 0xd1 },
|
||||
{ 0x00, 0x00, 0xd3 },
|
||||
{ 0x00, 0x00, 0xd5 },
|
||||
{ 0x00, 0x00, 0xd7 },
|
||||
{ 0x00, 0x00, 0xd9 },
|
||||
{ 0x00, 0x00, 0xdb },
|
||||
{ 0x00, 0x00, 0xdd },
|
||||
{ 0x00, 0x00, 0xdf },
|
||||
{ 0x00, 0x00, 0xe2 },
|
||||
{ 0x00, 0x00, 0xe4 },
|
||||
{ 0x00, 0x00, 0xe6 },
|
||||
{ 0x00, 0x00, 0xe8 },
|
||||
{ 0x00, 0x00, 0xea },
|
||||
{ 0x00, 0x00, 0xec },
|
||||
{ 0x00, 0x00, 0xee },
|
||||
{ 0x00, 0x00, 0xf1 },
|
||||
{ 0x00, 0x00, 0xf3 },
|
||||
{ 0x00, 0x00, 0xf5 },
|
||||
{ 0x00, 0x00, 0xf7 },
|
||||
{ 0x00, 0x00, 0xf9 },
|
||||
{ 0x00, 0x00, 0xfb },
|
||||
{ 0x00, 0x00, 0xfd },
|
||||
{ 0x01, 0x00, 0xfe },
|
||||
{ 0x05, 0x00, 0xfa },
|
||||
{ 0x09, 0x00, 0xf6 },
|
||||
{ 0x0e, 0x00, 0xf2 },
|
||||
{ 0x12, 0x00, 0xed },
|
||||
{ 0x16, 0x00, 0xe9 },
|
||||
{ 0x1b, 0x00, 0xe4 },
|
||||
{ 0x1f, 0x00, 0xe0 },
|
||||
{ 0x24, 0x00, 0xdc },
|
||||
{ 0x27, 0x00, 0xd8 },
|
||||
{ 0x2c, 0x00, 0xd3 },
|
||||
{ 0x30, 0x00, 0xcf },
|
||||
{ 0x35, 0x00, 0xcb },
|
||||
{ 0x39, 0x00, 0xc6 },
|
||||
{ 0x3d, 0x00, 0xc2 },
|
||||
{ 0x42, 0x00, 0xbd },
|
||||
{ 0x46, 0x00, 0xb9 },
|
||||
{ 0x4b, 0x00, 0xb5 },
|
||||
{ 0x4f, 0x00, 0xb0 },
|
||||
{ 0x53, 0x00, 0xac },
|
||||
{ 0x58, 0x00, 0xa7 },
|
||||
{ 0x5c, 0x00, 0xa3 },
|
||||
{ 0x61, 0x00, 0x9f },
|
||||
{ 0x65, 0x00, 0x9a },
|
||||
{ 0x69, 0x00, 0x96 },
|
||||
{ 0x6e, 0x00, 0x91 },
|
||||
{ 0x72, 0x00, 0x8d },
|
||||
{ 0x77, 0x00, 0x89 },
|
||||
{ 0x7b, 0x00, 0x84 },
|
||||
{ 0x7f, 0x00, 0x80 },
|
||||
{ 0x84, 0x00, 0x7b },
|
||||
{ 0x88, 0x00, 0x77 },
|
||||
{ 0x8d, 0x00, 0x73 },
|
||||
{ 0x91, 0x00, 0x6e },
|
||||
{ 0x95, 0x00, 0x6a },
|
||||
{ 0x9a, 0x00, 0x65 },
|
||||
{ 0x9e, 0x00, 0x61 },
|
||||
{ 0xa3, 0x00, 0x5d },
|
||||
{ 0xa7, 0x00, 0x58 },
|
||||
{ 0xab, 0x00, 0x54 },
|
||||
{ 0xb0, 0x00, 0x4f },
|
||||
{ 0xb4, 0x00, 0x4b },
|
||||
{ 0xb9, 0x00, 0x47 },
|
||||
{ 0xbd, 0x00, 0x42 },
|
||||
{ 0xc1, 0x00, 0x3e },
|
||||
{ 0xc6, 0x00, 0x39 },
|
||||
{ 0xca, 0x00, 0x35 },
|
||||
{ 0xcf, 0x00, 0x31 },
|
||||
{ 0xd3, 0x00, 0x2c },
|
||||
{ 0xd7, 0x00, 0x28 },
|
||||
{ 0xdc, 0x00, 0x23 },
|
||||
{ 0xe0, 0x00, 0x1f },
|
||||
{ 0xe5, 0x00, 0x1b },
|
||||
{ 0xe9, 0x00, 0x16 },
|
||||
{ 0xed, 0x00, 0x12 },
|
||||
{ 0xf2, 0x00, 0x0d },
|
||||
{ 0xf6, 0x00, 0x09 },
|
||||
{ 0xfb, 0x00, 0x05 },
|
||||
{ 0xfe, 0x01, 0x01 },
|
||||
{ 0xff, 0x06, 0x00 },
|
||||
{ 0xff, 0x0d, 0x00 },
|
||||
{ 0xff, 0x13, 0x00 },
|
||||
{ 0xff, 0x1a, 0x00 },
|
||||
{ 0xff, 0x20, 0x00 },
|
||||
{ 0xff, 0x26, 0x00 },
|
||||
{ 0xff, 0x2d, 0x00 },
|
||||
{ 0xff, 0x33, 0x00 },
|
||||
{ 0xff, 0x3a, 0x00 },
|
||||
{ 0xff, 0x40, 0x00 },
|
||||
{ 0xff, 0x46, 0x00 },
|
||||
{ 0xff, 0x4d, 0x00 },
|
||||
{ 0xff, 0x53, 0x00 },
|
||||
{ 0xff, 0x59, 0x00 },
|
||||
{ 0xff, 0x60, 0x00 },
|
||||
{ 0xff, 0x66, 0x00 },
|
||||
{ 0xff, 0x6c, 0x00 },
|
||||
{ 0xff, 0x73, 0x00 },
|
||||
{ 0xff, 0x79, 0x00 },
|
||||
{ 0xff, 0x80, 0x00 },
|
||||
{ 0xff, 0x86, 0x00 },
|
||||
{ 0xff, 0x8c, 0x00 },
|
||||
{ 0xff, 0x93, 0x00 },
|
||||
{ 0xff, 0x99, 0x00 },
|
||||
{ 0xff, 0x9f, 0x00 },
|
||||
{ 0xff, 0xa6, 0x00 },
|
||||
{ 0xff, 0xac, 0x00 },
|
||||
{ 0xff, 0xb3, 0x00 },
|
||||
{ 0xff, 0xb9, 0x00 },
|
||||
{ 0xff, 0xbf, 0x00 },
|
||||
{ 0xff, 0xc6, 0x00 },
|
||||
{ 0xff, 0xcc, 0x00 },
|
||||
{ 0xff, 0xd2, 0x00 },
|
||||
{ 0xff, 0xd9, 0x00 },
|
||||
{ 0xff, 0xdf, 0x00 },
|
||||
{ 0xff, 0xe6, 0x00 },
|
||||
{ 0xff, 0xec, 0x00 },
|
||||
{ 0xff, 0xf2, 0x00 },
|
||||
{ 0xff, 0xf9, 0x00 },
|
||||
{ 0xff, 0xfe, 0x01 },
|
||||
{ 0xff, 0xff, 0x06 },
|
||||
{ 0xff, 0xff, 0x0d },
|
||||
{ 0xff, 0xff, 0x14 },
|
||||
{ 0xff, 0xff, 0x1b },
|
||||
{ 0xff, 0xff, 0x21 },
|
||||
{ 0xff, 0xff, 0x28 },
|
||||
{ 0xff, 0xff, 0x2f },
|
||||
{ 0xff, 0xff, 0x35 },
|
||||
{ 0xff, 0xff, 0x3c },
|
||||
{ 0xff, 0xff, 0x42 },
|
||||
{ 0xff, 0xff, 0x49 },
|
||||
{ 0xff, 0xff, 0x4f },
|
||||
{ 0xff, 0xff, 0x56 },
|
||||
{ 0xff, 0xff, 0x5d },
|
||||
{ 0xff, 0xff, 0x63 },
|
||||
{ 0xff, 0xff, 0x6a },
|
||||
{ 0xff, 0xff, 0x71 },
|
||||
{ 0xff, 0xff, 0x77 },
|
||||
{ 0xff, 0xff, 0x7e },
|
||||
{ 0xff, 0xff, 0x84 },
|
||||
{ 0xff, 0xff, 0x8b },
|
||||
{ 0xff, 0xff, 0x92 },
|
||||
{ 0xff, 0xff, 0x98 },
|
||||
{ 0xff, 0xff, 0x9f },
|
||||
{ 0xff, 0xff, 0xa6 },
|
||||
{ 0xff, 0xff, 0xac },
|
||||
{ 0xff, 0xff, 0xb3 },
|
||||
{ 0xff, 0xff, 0xb9 },
|
||||
{ 0xff, 0xff, 0xc0 },
|
||||
{ 0xff, 0xff, 0xc7 },
|
||||
{ 0xff, 0xff, 0xcd },
|
||||
{ 0xff, 0xff, 0xd4 },
|
||||
{ 0xff, 0xff, 0xdb },
|
||||
{ 0xff, 0xff, 0xe1 },
|
||||
{ 0xff, 0xff, 0xe8 },
|
||||
{ 0xff, 0xff, 0xee },
|
||||
{ 0xff, 0xff, 0xf5 },
|
||||
{ 0xff, 0xff, 0xfb }
|
||||
} };
|
||||
|
||||
const std::array<ui::Color, 256> spectrum_rgb4_lut { {
|
||||
|
||||
+113
-22
@@ -27,15 +27,88 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
void OOKProcessor::execute(const buffer_c8_t& buffer) {
|
||||
inline void OOKProcessor::write_sample(const buffer_c8_t& buffer, uint8_t bit_value, size_t i) {
|
||||
int8_t re, im;
|
||||
|
||||
|
||||
if (bit_value) {
|
||||
phase = (phase + 200); // What ?
|
||||
sphase = phase + (64 << 18);
|
||||
|
||||
re = (sine_table_i8[(sphase & 0x03FC0000) >> 18]);
|
||||
im = (sine_table_i8[(phase & 0x03FC0000) >> 18]);
|
||||
} else {
|
||||
re = 0;
|
||||
im = 0;
|
||||
}
|
||||
|
||||
buffer.p[i] = {re, im};
|
||||
}
|
||||
|
||||
inline void OOKProcessor::duval_algo(const buffer_c8_t& buffer) {
|
||||
size_t buf_ptr = 0;
|
||||
const unsigned int w = de_bruijn_length;
|
||||
|
||||
// Duval's algorithm for generating de Bruijn sequence
|
||||
while (idx) {
|
||||
if (w % idx == 0) {
|
||||
for (; k < idx; k++) {
|
||||
size_t available_size = buffer.count - buf_ptr;
|
||||
size_t len = (samples_per_bit > available_size) ? available_size : samples_per_bit;
|
||||
|
||||
for (; bit_ptr < len; bit_ptr++) {
|
||||
write_sample(buffer, v[k], buf_ptr);
|
||||
buf_ptr++;
|
||||
}
|
||||
|
||||
if (buf_ptr == buffer.count) {
|
||||
txprogress_message.done = false;
|
||||
txprogress_message.progress = scan_progress++;
|
||||
shared_memory.application_queue.push(txprogress_message);
|
||||
return;
|
||||
}
|
||||
|
||||
bit_ptr = 0;
|
||||
}
|
||||
|
||||
k = 0;
|
||||
}
|
||||
|
||||
for (unsigned int j = 0; j < w - idx; j++)
|
||||
v[idx + j] = v[j];
|
||||
|
||||
for (idx = w; idx > 0 && v[idx - 1]; idx--) ;
|
||||
|
||||
if (idx)
|
||||
v[idx - 1] = 1;
|
||||
}
|
||||
|
||||
// clear the buffer in case we have any bytes left
|
||||
if (buf_ptr < buffer.count) {
|
||||
for (size_t i = buf_ptr; i < buffer.count; i++) {
|
||||
buffer.p[i] = {0, 0};
|
||||
}
|
||||
}
|
||||
|
||||
if (!scan_done) {
|
||||
txprogress_message.done = true;
|
||||
shared_memory.application_queue.push(txprogress_message);
|
||||
}
|
||||
|
||||
scan_done = 1;
|
||||
}
|
||||
|
||||
void OOKProcessor::execute(const buffer_c8_t& buffer) {
|
||||
// This is called at 2.28M/2048 = 1113Hz
|
||||
|
||||
|
||||
if (!configured) return;
|
||||
|
||||
|
||||
if (de_bruijn_length) {
|
||||
duval_algo(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < buffer.count; i++) {
|
||||
|
||||
|
||||
// Synthesis at 2.28M/10 = 228kHz
|
||||
if (!s) {
|
||||
s = 10 - 1;
|
||||
@@ -49,11 +122,11 @@ void OOKProcessor::execute(const buffer_c8_t& buffer) {
|
||||
} else if (pause_counter == 1) {
|
||||
if (repeat_counter < repeat) {
|
||||
// Repeat
|
||||
bit_pos = 0;
|
||||
cur_bit = shared_memory.bb_data.data[0] & 0x80;
|
||||
txprogress_message.progress = repeat_counter + 1;
|
||||
txprogress_message.done = false;
|
||||
shared_memory.application_queue.push(txprogress_message);
|
||||
bit_pos = 1;
|
||||
repeat_counter++;
|
||||
} else {
|
||||
// Stop
|
||||
@@ -71,7 +144,7 @@ void OOKProcessor::execute(const buffer_c8_t& buffer) {
|
||||
bit_pos++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sample_count = 0;
|
||||
} else {
|
||||
sample_count++;
|
||||
@@ -79,31 +152,49 @@ void OOKProcessor::execute(const buffer_c8_t& buffer) {
|
||||
} else {
|
||||
s--;
|
||||
}
|
||||
|
||||
if (cur_bit) {
|
||||
phase = (phase + 200); // What ?
|
||||
sphase = phase + (64 << 18);
|
||||
|
||||
re = (sine_table_i8[(sphase & 0x03FC0000) >> 18]);
|
||||
im = (sine_table_i8[(phase & 0x03FC0000) >> 18]);
|
||||
} else {
|
||||
re = 0;
|
||||
im = 0;
|
||||
}
|
||||
|
||||
buffer.p[i] = {re, im};
|
||||
write_sample(buffer, cur_bit, i);
|
||||
}
|
||||
}
|
||||
|
||||
void OOKProcessor::on_message(const Message* const p) {
|
||||
const auto message = *reinterpret_cast<const OOKConfigureMessage*>(p);
|
||||
|
||||
|
||||
if (message.id == Message::ID::OOKConfigure) {
|
||||
samples_per_bit = message.samples_per_bit / 10;
|
||||
configured = false;
|
||||
|
||||
repeat = message.repeat - 1;
|
||||
length = message.stream_length;
|
||||
pause = message.pause_symbols + 1;
|
||||
|
||||
de_bruijn_length = message.de_bruijn_length;
|
||||
samples_per_bit = message.samples_per_bit;
|
||||
|
||||
if (!length && !samples_per_bit) {
|
||||
// shutdown
|
||||
return;
|
||||
}
|
||||
|
||||
if (de_bruijn_length) {
|
||||
if (de_bruijn_length > sizeof(v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (samples_per_bit > 2048) {
|
||||
// can't handle more than dma::transfer_samples
|
||||
return;
|
||||
}
|
||||
|
||||
k = 0;
|
||||
bit_ptr = 0;
|
||||
idx = 1;
|
||||
scan_done = false;
|
||||
scan_progress = 0;
|
||||
|
||||
memset(v, 0, sizeof(v));
|
||||
} else {
|
||||
samples_per_bit /= 10;
|
||||
}
|
||||
|
||||
pause_counter = 0;
|
||||
s = 0;
|
||||
sample_count = samples_per_bit;
|
||||
|
||||
@@ -29,19 +29,20 @@
|
||||
class OOKProcessor : public BasebandProcessor {
|
||||
public:
|
||||
void execute(const buffer_c8_t& buffer) override;
|
||||
|
||||
|
||||
void on_message(const Message* const p) override;
|
||||
|
||||
private:
|
||||
bool configured = false;
|
||||
|
||||
|
||||
BasebandThread baseband_thread { 2280000, this, NORMALPRIO + 20, baseband::Direction::Transmit };
|
||||
|
||||
|
||||
uint32_t samples_per_bit { 0 };
|
||||
uint8_t repeat { 0 };
|
||||
uint32_t length { 0 };
|
||||
uint32_t pause { 0 };
|
||||
|
||||
uint8_t de_bruijn_length { 0 };
|
||||
|
||||
uint32_t pause_counter { 0 };
|
||||
uint8_t repeat_counter { 0 };
|
||||
uint8_t s { 0 };
|
||||
@@ -50,8 +51,19 @@ private:
|
||||
uint32_t sample_count { 0 };
|
||||
uint32_t tone_phase { 0 }, phase { 0 }, sphase { 0 };
|
||||
int32_t tone_sample { 0 }, sig { 0 }, frq { 0 };
|
||||
|
||||
|
||||
TXProgressMessage txprogress_message { };
|
||||
|
||||
static constexpr auto MAX_DE_BRUIJN_ORDER = 24;
|
||||
uint8_t v[MAX_DE_BRUIJN_ORDER];
|
||||
unsigned int idx { 0 };
|
||||
unsigned int k { 0 };
|
||||
size_t bit_ptr{ 0 };
|
||||
size_t scan_progress{ 0 };
|
||||
uint8_t scan_done { true };
|
||||
|
||||
void write_sample(const buffer_c8_t& buffer, uint8_t bit_value, size_t i);
|
||||
void duval_algo(const buffer_c8_t& buffer);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -245,12 +245,29 @@ constexpr fir_taps_real<32> taps_6k0_decim_2 {
|
||||
11815, 10413, 7946, 4978, 2134, -83, -1411, -1857,
|
||||
-1640, -1080, -474, -21, 208, 247, 178, 95,
|
||||
} },
|
||||
};
|
||||
|
||||
// IFIR prototype filter fs=48000 ; pass=4500 (cutt off -3dBs) , stop=8000 (<-60dBs), decim=4, fout=12000
|
||||
// For Europe AM commercial broadcasting stations in LF/MF/HF, Emissions Designator 9K00A3E Bandwidth: 9.00 kHz (derivated from taps_6k0_decim_2 )
|
||||
// Pre-decimate LPF FIR filter design Created with SciPy Python with the "window method", num_taps = 32, cut_off = 5150. sample_rate = 48000 # Hz,
|
||||
// Created with h = signal.firwin(num_taps, cut_off, nyq=sample_rate/2, window=('chebwin',50)) , achieving good STOP band plot < -60 dB's with some ripple.
|
||||
// post-scaled h taps to avoid decimals , targeting <= similar int values as previous taps_6k0_dsb_channel peak < 32.767 (2 exp 15) and similar H(f)gain
|
||||
constexpr fir_taps_real<32> taps_9k0_decim_2 {
|
||||
.low_frequency_normalized = -4500.0f / 48000.0f, // Negative -cutt off freq -3dB (real achieved data ,in the plot and measurements)
|
||||
.high_frequency_normalized = 4500.0f / 48000.0f, // Positive +cutt off freq -3dB (idem)
|
||||
.transition_normalized = 3500.0f / 48000.0f, // 3500 Hz = (8000 Hz - 4500 Hz) (both from plot H(f) curve plot)
|
||||
.taps = { {
|
||||
-53, -30, 47, 198, 355, 372, 89, -535,
|
||||
-1307, -1771, -1353, 370, 3384, 7109, 10535, 12591,
|
||||
12591, 10535, 7109, 3384, 370, -1353, -1771, -1307,
|
||||
-535, 89, 372, 355, 198, 47, -30, -53
|
||||
} },
|
||||
};
|
||||
|
||||
// Channel filter: fs=12000, pass=3000, stop=3300, decim=1, fout=12000
|
||||
/* NOTE: Slightly less than 1.0 gain (normalized to 65536) due to max(taps) being
|
||||
* slightly larger than 32767 (33312).
|
||||
*/
|
||||
*/
|
||||
constexpr fir_taps_complex<64> taps_6k0_dsb_channel {
|
||||
.low_frequency_normalized = -3000.0f / 12000.0f,
|
||||
.high_frequency_normalized = 3000.0f / 12000.0f,
|
||||
@@ -275,6 +292,36 @@ constexpr fir_taps_complex<64> taps_6k0_dsb_channel {
|
||||
} },
|
||||
};
|
||||
|
||||
// Channel filter: fs=12000, pass=4500 (cutt off -3dBs), stop=4940 (<-60dBs), decim=1, fout=12000 (*1) real frec pass / stop , based on plotted H(f) curve)
|
||||
// For Europe AM commercial broadcasting stations in LF/MF/HF, Emissions Designator 9K00A3E Bandwidth: 9.00 kHz (derivative from taps_6k0_dsb_channel)
|
||||
// FIR filter design created with SciPy Python using "window method"; selected design parameters: num_taps = 64, cut_off = 4575. sample_rate = 12000 # Hz,
|
||||
// Created with : h = signal.firwin(num_taps, cut_off, nyq=sample_rate/2, window=('chebwin',50)) , achieving real plot curve (*1) with peak stop band ripple -60dBs.
|
||||
// post-scaled h taps to avoid decimals , targeting <= similar int values as previous taps_6k0_dsb_channel peak < 32.767 (2 exp 15), (29625) and similar H(f)gain
|
||||
constexpr fir_taps_complex<64> taps_9k0_dsb_channel {
|
||||
.low_frequency_normalized = -4500.0f / 12000.0f, // Negative -cutt off freq -3dB (in the H(f) curve plot)
|
||||
.high_frequency_normalized = 4500.0f / 12000.0f, // Positive +cutt off freq -3dB (in the H(f) curve plot)
|
||||
.transition_normalized = 440.0f / 12000.0f, // 440Hz = (4940 Hz -4500 Hz) cut-3dB's (both data comes from H(f) curve plot and confirmed by measurements )
|
||||
.taps = { {
|
||||
{ 2, 0 }, { -18, 0 }, { 34, 0 }, { -33, 0 },
|
||||
{ 6, 0 }, { 44, 0 }, { -91, 0 }, { 96, 0 },
|
||||
{ -35, 0 }, { -80, 0 }, { 193, 0 }, { -223, 0 },
|
||||
{ 116, 0 }, { 112, 0 }, { -353, 0 }, { 452, 0 },
|
||||
{ -293, 0 }, { -111, 0 }, { 584, 0 }, { -844, 0 },
|
||||
{ 653, 0 }, { 22, 0 }, { -921, 0 }, { 1554, 0 },
|
||||
{ -1422, 0 }, { 301, 0 }, { 1533, 0 }, { -3282, 0 },
|
||||
{ 3804, 0 }, { -1819, 0 }, { -4605, 0 }, { 29625, 0 },
|
||||
{ 29625, 0 }, { -4605, 0 }, { -1819, 0 }, { 3804, 0 },
|
||||
{ -3282, 0 }, { 1533, 0 }, { 301, 0 }, { -1422, 0 },
|
||||
{ 1554, 0 }, { -921, 0 }, { 22, 0 }, { 653, 0 },
|
||||
{ -844, 0 }, { 584, 0 }, { -111, 0 }, { -293, 0 },
|
||||
{ 452, 0 }, { -353, 0 }, { 112, 0 }, { 116, 0 },
|
||||
{ -223, 0 }, { 193, 0 }, { -80, 0 }, { -35, 0 },
|
||||
{ 96, 0 }, { -91, 0 }, { 44, 0 }, { 6, 0 },
|
||||
{ -33, 0 }, { 34, 0 }, { -18, 0 }, { 2, 0 },
|
||||
} },
|
||||
};
|
||||
|
||||
|
||||
// USB AM 2K80J3E emission type ///////////////////////////////////////////
|
||||
|
||||
// IFIR prototype filter: fs=12000, pass=3000, stop=3300, decim=1, fout=12000
|
||||
|
||||
+23
-20
@@ -306,7 +306,7 @@ using ChannelSpectrumFIFO = FIFO<ChannelSpectrum>;
|
||||
class ChannelSpectrumConfigMessage : public Message {
|
||||
public:
|
||||
static constexpr size_t fifo_k = 2;
|
||||
|
||||
|
||||
constexpr ChannelSpectrumConfigMessage(
|
||||
ChannelSpectrumFIFO* fifo
|
||||
) : Message { ID::ChannelSpectrumConfig },
|
||||
@@ -352,7 +352,7 @@ public:
|
||||
packet { packet }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
pocsag::POCSAGPacket packet;
|
||||
};
|
||||
|
||||
@@ -378,7 +378,7 @@ public:
|
||||
amp(amp)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
adsb::ADSBFrame frame;
|
||||
uint32_t amp;
|
||||
};
|
||||
@@ -393,7 +393,7 @@ public:
|
||||
value { value }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool is_data;
|
||||
uint32_t value;
|
||||
};
|
||||
@@ -406,7 +406,7 @@ public:
|
||||
value { value }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
@@ -584,7 +584,7 @@ public:
|
||||
used_ += copy_size;
|
||||
return copy_size;
|
||||
}
|
||||
|
||||
|
||||
size_t read(void* p, const size_t count) {
|
||||
const auto copy_size = std::min(used_, count);
|
||||
memcpy(p, &data_[capacity_ - used_], copy_size);
|
||||
@@ -595,7 +595,7 @@ public:
|
||||
bool is_full() const {
|
||||
return used_ >= capacity_;
|
||||
}
|
||||
|
||||
|
||||
bool is_empty() const {
|
||||
return used_ == 0;
|
||||
}
|
||||
@@ -607,7 +607,7 @@ public:
|
||||
size_t size() const {
|
||||
return used_;
|
||||
}
|
||||
|
||||
|
||||
size_t capacity() const {
|
||||
return capacity_;
|
||||
}
|
||||
@@ -700,7 +700,7 @@ public:
|
||||
) : Message { ID::TXProgress }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
uint32_t progress = 0;
|
||||
bool done = false;
|
||||
};
|
||||
@@ -719,7 +719,7 @@ public:
|
||||
trigger_word(trigger_word)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const uint32_t baudrate;
|
||||
const uint32_t word_length;
|
||||
const uint32_t trigger_value;
|
||||
@@ -734,7 +734,7 @@ public:
|
||||
baudrate(baudrate)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const uint32_t baudrate;
|
||||
};
|
||||
|
||||
@@ -788,7 +788,7 @@ public:
|
||||
rssi(rssi)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const bool enabled;
|
||||
const int32_t rssi;
|
||||
};
|
||||
@@ -825,7 +825,7 @@ public:
|
||||
length(length)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const uint16_t length = 0;
|
||||
};
|
||||
|
||||
@@ -835,7 +835,7 @@ public:
|
||||
) : Message { ID::Retune }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int64_t freq = 0;
|
||||
uint32_t range = 0;
|
||||
};
|
||||
@@ -848,7 +848,7 @@ public:
|
||||
sample_rate(sample_rate)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const uint32_t sample_rate = 0;
|
||||
};
|
||||
|
||||
@@ -858,7 +858,7 @@ public:
|
||||
) : Message { ID::AudioLevelReport }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
uint32_t value = 0;
|
||||
};
|
||||
|
||||
@@ -964,12 +964,14 @@ public:
|
||||
const uint32_t stream_length,
|
||||
const uint32_t samples_per_bit,
|
||||
const uint8_t repeat,
|
||||
const uint32_t pause_symbols
|
||||
const uint32_t pause_symbols,
|
||||
const uint8_t de_bruijn_length
|
||||
) : Message { ID::OOKConfigure },
|
||||
stream_length(stream_length),
|
||||
samples_per_bit(samples_per_bit),
|
||||
repeat(repeat),
|
||||
pause_symbols(pause_symbols)
|
||||
pause_symbols(pause_symbols),
|
||||
de_bruijn_length(de_bruijn_length)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -977,6 +979,7 @@ public:
|
||||
const uint32_t samples_per_bit;
|
||||
const uint8_t repeat;
|
||||
const uint32_t pause_symbols;
|
||||
const uint8_t de_bruijn_length;
|
||||
};
|
||||
|
||||
class SSTVConfigureMessage : public Message {
|
||||
@@ -1017,7 +1020,7 @@ public:
|
||||
|
||||
class POCSAGConfigureMessage : public Message {
|
||||
public:
|
||||
constexpr POCSAGConfigureMessage()
|
||||
constexpr POCSAGConfigureMessage()
|
||||
: Message { ID::POCSAGConfigure }
|
||||
{
|
||||
}
|
||||
@@ -1031,7 +1034,7 @@ public:
|
||||
packet { packet }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
aprs::APRSPacket packet;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,11 +35,9 @@ w = numpy.arange(length, dtype=numpy.float64) * (2 * numpy.pi / length)
|
||||
v = numpy.sin(w)
|
||||
print(v)
|
||||
*/
|
||||
constexpr size_t sine_table_f32_period_log2 = 8;
|
||||
constexpr size_t sine_table_f32_period = 1 << sine_table_f32_period_log2;
|
||||
constexpr uint32_t sine_table_f32_index_mask = sine_table_f32_period - 1;
|
||||
constexpr uint16_t sine_table_f32_period = 256;
|
||||
|
||||
static constexpr std::array<float, sine_table_f32_period + 1> sine_table_f32 { {
|
||||
static constexpr std::array<float, sine_table_f32_period + 2> sine_table_f32{
|
||||
0.00000000e+00, 2.45412285e-02, 4.90676743e-02,
|
||||
7.35645636e-02, 9.80171403e-02, 1.22410675e-01,
|
||||
1.46730474e-01, 1.70961889e-01, 1.95090322e-01,
|
||||
@@ -125,24 +123,22 @@ static constexpr std::array<float, sine_table_f32_period + 1> sine_table_f32 { {
|
||||
-2.42980180e-01, -2.19101240e-01, -1.95090322e-01,
|
||||
-1.70961889e-01, -1.46730474e-01, -1.22410675e-01,
|
||||
-9.80171403e-02, -7.35645636e-02, -4.90676743e-02,
|
||||
-2.45412285e-02, 0.00000000e+00,
|
||||
} };
|
||||
-2.45412285e-02, 0.00000000e+00, 0.00000000e+00
|
||||
};
|
||||
|
||||
inline float sin_f32(const float w) {
|
||||
constexpr float normalize = 1.0 / (2 * pi);
|
||||
|
||||
const float x = w * normalize;
|
||||
const int32_t x_int = std::floor(x);
|
||||
const float x_frac = x - x_int;
|
||||
const float x = w / (2 * pi); // normalization
|
||||
const float x_frac = x - std::floor(x); // [0, 1]
|
||||
|
||||
const float n = x_frac * sine_table_f32_period;
|
||||
const int32_t n_int = static_cast<uint32_t>(n) & sine_table_f32_index_mask;
|
||||
const uint16_t n_int = static_cast<uint16_t>(n);
|
||||
const float n_frac = n - n_int;
|
||||
|
||||
const float p0 = sine_table_f32[n_int + 0];
|
||||
const float p0 = sine_table_f32[n_int];
|
||||
const float p1 = sine_table_f32[n_int + 1];
|
||||
const float diff = p1 - p0;
|
||||
const float result = p0 + n_frac * diff;
|
||||
const float result = p0 + n_frac * diff; // linear interpolation
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
#
|
||||
# Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||
@@ -80,7 +80,7 @@ def print_block(block):
|
||||
for n in range(0, len(block), 8):
|
||||
chunk = block[n:n+8]
|
||||
line = ['0x%04x,' % v for v in chunk]
|
||||
print('\t%s' % ' '.join(line))
|
||||
print(('\t%s' % ' '.join(line)))
|
||||
|
||||
def crc32(blocks):
|
||||
import zlib
|
||||
@@ -92,7 +92,7 @@ def crc32(blocks):
|
||||
crc_bytes.append((word >> 8) & 0xff)
|
||||
return zlib.crc32(bytearray(crc_bytes)) & 0xffffffff
|
||||
|
||||
print("""#include "portapack_cpld_data.hpp"
|
||||
print(("""#include "portapack_cpld_data.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
@@ -100,23 +100,23 @@ print("""#include "portapack_cpld_data.hpp"
|
||||
namespace portapack {
|
||||
namespace cpld {
|
||||
namespace %s {
|
||||
""" % revision_name)
|
||||
""" % revision_name))
|
||||
|
||||
print('const std::array<uint16_t, %d> block_0 { {' % len(block_0))
|
||||
print(('const std::array<uint16_t, %d> block_0 { {' % len(block_0)))
|
||||
print_block(block_0)
|
||||
|
||||
print("""} };
|
||||
""")
|
||||
|
||||
print('const std::array<uint16_t, %d> block_1 { {' % len(block_1))
|
||||
print(('const std::array<uint16_t, %d> block_1 { {' % len(block_1)))
|
||||
print_block(block_1)
|
||||
|
||||
print("""} };
|
||||
print(("""} };
|
||||
|
||||
} /* namespace %s */
|
||||
} /* namespace cpld */
|
||||
} /* namespace portapack */
|
||||
""" % revision_name)
|
||||
""" % revision_name))
|
||||
|
||||
if calculate_crc:
|
||||
# Apply post-programming modification to make post-programming CRC correct:
|
||||
@@ -124,4 +124,4 @@ if calculate_crc:
|
||||
programmed_block_0[0] &= 0xfbff
|
||||
|
||||
crc = crc32((programmed_block_0, block_1))
|
||||
print('%08x' % crc)
|
||||
print(('%08x' % crc))
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import math
|
||||
|
||||
m = 64 - 1
|
||||
@@ -6,7 +8,7 @@ ft = 300.0 / 24000.0
|
||||
taps = []
|
||||
window = []
|
||||
|
||||
print("Normalized ft = " + str(ft))
|
||||
print(("Normalized ft = " + str(ft)))
|
||||
|
||||
for n in range(0, 64):
|
||||
taps.append(math.sin(2 * math.pi * ft * (n - (m / 2.0))) / (math.pi * (n - (m / 2.0))))
|
||||
|
||||
@@ -29,10 +29,10 @@ outfile = open('../../sdcard/ADSB/world_map.bin', 'wb')
|
||||
Image.MAX_IMAGE_PIXELS = None
|
||||
im = Image.open("../../sdcard/ADSB/world_map.jpg")
|
||||
pix = im.load()
|
||||
|
||||
outfile.write(struct.pack('H', im.size[0]))
|
||||
outfile.write(struct.pack('H', im.size[1]))
|
||||
|
||||
# Write as unsigned short (2 bytes) as little endian
|
||||
outfile.write(struct.pack('<H', im.size[0]))
|
||||
outfile.write(struct.pack('<H', im.size[1]))
|
||||
print("image \t size[0]=" + str(im.size[0]) + "\tsize[1]=" + str(im.size[1]) + " pixels");
|
||||
print("Generating: \t" + outfile.name + "\n from\t\t" + im.filename + "\n please wait...");
|
||||
|
||||
for y in range (0, im.size[1]):
|
||||
@@ -47,8 +47,9 @@ for y in range (0, im.size[1]):
|
||||
# pixel_lcd = (pix[x, y][0] >> 5) << 5
|
||||
# pixel_lcd |= (pix[x, y][1] >> 5) << 2
|
||||
# pixel_lcd |= (pix[x, y][2] >> 6)
|
||||
line += struct.pack('H', pixel_lcd)
|
||||
line += struct.pack('<H', pixel_lcd)
|
||||
outfile.write(line)
|
||||
print(str(y) + '/' + str(im.size[1]) + '\r', end="")
|
||||
|
||||
outfile.close();
|
||||
print("Ready.");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2016 Furrtek
|
||||
#
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2016 Furrtek
|
||||
#
|
||||
@@ -42,7 +42,7 @@ def convert_png(file):
|
||||
rgb_im = im.convert('RGBA')
|
||||
|
||||
if rgb_im.size[0] % 8 or rgb_im.size[1] % 8:
|
||||
print(file + ": Size isn\'t a multiple of 8")
|
||||
print((file + ": Size isn\'t a multiple of 8"))
|
||||
sys.exit(-1)
|
||||
|
||||
name = path.basename(file).split(".")[0].lower();
|
||||
@@ -112,4 +112,4 @@ f.write("\n")
|
||||
f.write("} /* namespace ui */\n\n")
|
||||
f.write("#endif/*__BITMAP_HPP__*/\n")
|
||||
|
||||
print("Converted " + str(count) + " files")
|
||||
print(("Converted " + str(count) + " files"))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2016 Furrtek
|
||||
#
|
||||
@@ -40,4 +40,4 @@ for c in range (0, 0x200): # DCS code is 9 bits
|
||||
p10 = cb[3] ^ cb[5] ^ cb[6] ^ cb[8] ^ 1;
|
||||
p11 = cb[0] ^ cb[1] ^ cb[2] ^ cb[3] ^ cb[6] ^ 1;
|
||||
|
||||
print ' 0b{0:011b}'.format((p11<<10) | (p10<<9) | (p9<<8) |(p8<<7) | (p7<<6) | (p6<<5) | (p5<<4) | (p4<<3) | (p3<<2) | (p2<<1) | (p1)) + ', // ' + str(c);
|
||||
print(' 0b{0:011b}'.format((p11<<10) | (p10<<9) | (p9<<8) |(p8<<7) | (p7<<6) | (p6<<5) | (p5<<4) | (p4<<3) | (p3<<2) | (p2<<1) | (p1)) + ', // ' + str(c));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
#
|
||||
# Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
#
|
||||
# Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
|
||||
+1
-1
Submodule hackrf updated: dfadf6a31c...eff4a20022
@@ -0,0 +1 @@
|
||||
a=76000000,b=90000000,m=WFM,bw=16k,s=50KHz,d=WFM Japan
|
||||
@@ -0,0 +1 @@
|
||||
a=65800000,b=74000000,m=WFM,bw=16k,s=30KHz,d=WFM OIRT
|
||||
@@ -0,0 +1 @@
|
||||
a=87500000,b=108000000,m=WFM,bw=16k,s=50KHz,d=WFM Standard
|
||||
@@ -0,0 +1,22 @@
|
||||
a=150000,b=285000,m=AM,bw=DSB,s=5KHz,d=Longwave broadcast band|BCB (EU)
|
||||
a=525000,b=1605000,m=AM,bw=DSB,s=5KHz,d=AM broadcast band|BCB (EU & J)
|
||||
a=530000,b=1710000,m=AM,bw=DSB,s=5KHz,d=AM broadcast band|BCB (US)
|
||||
a=1800000,b=29700000,m=WFM,bw=16k,d=Amateur_radio|Amateur
|
||||
a=26900000,b=27400000,m=WFM,bw=16k,d=Citizens_band_radio|Citizens band
|
||||
a=28000000,b=30000000,m=WFM,bw=16k,d=Amateur_radio|Amateur
|
||||
a=29000000,b=54000000,m=WFM,bw=16k,d=Land mobile
|
||||
a=50000000,b=54000000,m=WFM,bw=16k,d=Amateur_radio|Amateur
|
||||
a=65000000,b=85000000,m=WFM,bw=16k,d=Land mobile (EU)
|
||||
a=108000000,b=136000000,m=WFM,bw=16k,d=Aircraft
|
||||
a=120000000,b=160000000,m=WFM,bw=16k,s=50KHz,d=Land mobile (EU)
|
||||
a=132000000,b=174000000,m=WFM,bw=16k,s=50KHz,d=Land mobile
|
||||
a=142000000,b=170000000,m=WFM,bw=16k,s=50KHz,d=Land mobile (J)
|
||||
a=144000000,b=148000000,m=WFM,bw=16k,s=50KHz,d=Amateur_radio|Amateur
|
||||
a=216000000,b=222000000,m=WFM,bw=16k,s=50KHz,d=Land mobile
|
||||
a=222000000,b=225000000,m=WFM,bw=16k,s=50KHz,d=Amateur_radio|Amateur
|
||||
a=335000000,b=384000000,m=WFM,bw=16k,s=50KHz,d=Land mobile (J)
|
||||
a=406000000,b=512000000,m=WFM,bw=16k,s=50KHz,d=Land mobile
|
||||
a=450000000,b=470000000,m=WFM,bw=16k,s=50KHz,d=Land mobile (J)
|
||||
a=430000000,b=450000000,m=WFM,bw=16k,s=50KHz,d=Amateur_radio|Amateur
|
||||
a=806000000,b=947000000,m=WFM,bw=16k,s=50KHz,d=Land mobile
|
||||
a=1200000000,b=1600000000,m=WFM,bw=16k,s=50KHz,d=Amateur|Land mobile|GPS
|
||||
Reference in New Issue
Block a user