mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-05-16 13:42:16 -04:00
More AFSK options, scan lists,
This commit is contained in:
parent
72f3c08e9b
commit
e2218a0f32
20 changed files with 445 additions and 275 deletions
|
@ -135,6 +135,7 @@ set(CPPSRC
|
||||||
touch_adc.cpp
|
touch_adc.cpp
|
||||||
encoder.cpp
|
encoder.cpp
|
||||||
audio.cpp
|
audio.cpp
|
||||||
|
afsk.cpp
|
||||||
${COMMON}/lcd_ili9341.cpp
|
${COMMON}/lcd_ili9341.cpp
|
||||||
${COMMON}/ui.cpp
|
${COMMON}/ui.cpp
|
||||||
${COMMON}/ui_text.cpp
|
${COMMON}/ui_text.cpp
|
||||||
|
|
|
@ -2454,6 +2454,30 @@ __/common/wm8731.cpp.s:
|
||||||
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/__/common/wm8731.cpp.s
|
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/__/common/wm8731.cpp.s
|
||||||
.PHONY : __/common/wm8731.cpp.s
|
.PHONY : __/common/wm8731.cpp.s
|
||||||
|
|
||||||
|
afsk.obj: afsk.cpp.obj
|
||||||
|
.PHONY : afsk.obj
|
||||||
|
|
||||||
|
# target to build an object file
|
||||||
|
afsk.cpp.obj:
|
||||||
|
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/afsk.cpp.obj
|
||||||
|
.PHONY : afsk.cpp.obj
|
||||||
|
|
||||||
|
afsk.i: afsk.cpp.i
|
||||||
|
.PHONY : afsk.i
|
||||||
|
|
||||||
|
# target to preprocess a source file
|
||||||
|
afsk.cpp.i:
|
||||||
|
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/afsk.cpp.i
|
||||||
|
.PHONY : afsk.cpp.i
|
||||||
|
|
||||||
|
afsk.s: afsk.cpp.s
|
||||||
|
.PHONY : afsk.s
|
||||||
|
|
||||||
|
# target to generate assembly for a file
|
||||||
|
afsk.cpp.s:
|
||||||
|
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/afsk.cpp.s
|
||||||
|
.PHONY : afsk.cpp.s
|
||||||
|
|
||||||
ais_app.obj: ais_app.cpp.obj
|
ais_app.obj: ais_app.cpp.obj
|
||||||
.PHONY : ais_app.obj
|
.PHONY : ais_app.obj
|
||||||
|
|
||||||
|
@ -4411,6 +4435,9 @@ help:
|
||||||
@echo "... __/common/wm8731.obj"
|
@echo "... __/common/wm8731.obj"
|
||||||
@echo "... __/common/wm8731.i"
|
@echo "... __/common/wm8731.i"
|
||||||
@echo "... __/common/wm8731.s"
|
@echo "... __/common/wm8731.s"
|
||||||
|
@echo "... afsk.obj"
|
||||||
|
@echo "... afsk.i"
|
||||||
|
@echo "... afsk.s"
|
||||||
@echo "... ais_app.obj"
|
@echo "... ais_app.obj"
|
||||||
@echo "... ais_app.i"
|
@echo "... ais_app.i"
|
||||||
@echo "... ais_app.s"
|
@echo "... ais_app.s"
|
||||||
|
|
111
firmware/application/afsk.cpp
Normal file
111
firmware/application/afsk.cpp
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
* Copyright (C) 2016 Furrtek
|
||||||
|
*
|
||||||
|
* This file is part of PortaPack.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "afsk.hpp"
|
||||||
|
|
||||||
|
#include "portapack_persistent_memory.hpp"
|
||||||
|
|
||||||
|
namespace afsk {
|
||||||
|
|
||||||
|
void generate_data(const char * in_message, char * out_data) {
|
||||||
|
const afsk_formats_t * format_def;
|
||||||
|
uint8_t pm, pp, bit, cp, cur_byte, new_byte;
|
||||||
|
uint16_t dp;
|
||||||
|
|
||||||
|
format_def = &afsk_formats[portapack::persistent_memory::afsk_format()];
|
||||||
|
|
||||||
|
if (format_def->parity == ODD)
|
||||||
|
pm = 1; // Odd parity
|
||||||
|
else
|
||||||
|
pm = 0; // Even parity
|
||||||
|
|
||||||
|
if (format_def->data_bits == 7) {
|
||||||
|
if (!format_def->use_LUT) {
|
||||||
|
for (dp = 0; dp < strlen(in_message); dp++) {
|
||||||
|
pp = pm;
|
||||||
|
new_byte = 0;
|
||||||
|
cur_byte = in_message[dp];
|
||||||
|
for (cp = 0; cp < 7; cp++) {
|
||||||
|
bit = (cur_byte >> cp) & 1;
|
||||||
|
pp += bit;
|
||||||
|
new_byte |= (bit << (7 - cp));
|
||||||
|
}
|
||||||
|
if (format_def->parity != NONE) new_byte |= (pp & 1);
|
||||||
|
out_data[dp] = new_byte;
|
||||||
|
}
|
||||||
|
out_data[dp++] = 0;
|
||||||
|
out_data[dp] = 0;
|
||||||
|
} else {
|
||||||
|
for (dp = 0; dp < strlen(in_message); dp++) {
|
||||||
|
pp = pm;
|
||||||
|
|
||||||
|
// Do not apply LUT on checksum (last byte) ?
|
||||||
|
if (dp != strlen(in_message) - 1)
|
||||||
|
cur_byte = alt_lookup[(uint8_t)in_message[dp] & 0x7F];
|
||||||
|
else
|
||||||
|
cur_byte = in_message[dp];
|
||||||
|
|
||||||
|
for (cp = 0; cp < 8; cp++)
|
||||||
|
if ((cur_byte >> cp) & 1) pp++;
|
||||||
|
|
||||||
|
out_data[dp * 2] = cur_byte;
|
||||||
|
out_data[(dp * 2) + 1] = 0xFE;
|
||||||
|
if (format_def->parity != NONE) out_data[(dp * 2) + 1] |= (pp & 1);
|
||||||
|
}
|
||||||
|
out_data[dp * 2] = 0;
|
||||||
|
out_data[(dp * 2) + 1] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
for (dp = 0; dp < strlen(in_message); dp++) {
|
||||||
|
pp = pm;
|
||||||
|
|
||||||
|
// Do not apply LUT on checksum (last byte) ?
|
||||||
|
if (dp != strlen(in_message) - 1)
|
||||||
|
cur_byte = alt_lookup[(uint8_t)in_message[dp] & 0x7F];
|
||||||
|
else
|
||||||
|
cur_byte = in_message[dp];
|
||||||
|
|
||||||
|
for (cp = 0; cp < 8; cp++)
|
||||||
|
if ((cur_byte >> cp) & 1) pp++;
|
||||||
|
|
||||||
|
out_data[dp * 2] = cur_byte;
|
||||||
|
out_data[(dp * 2) + 1] = 0xFE | (pp & 1);
|
||||||
|
}
|
||||||
|
out_data[dp * 2] = 0;
|
||||||
|
out_data[(dp * 2) + 1] = 0;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// MSB first
|
||||||
|
for (dp = 0; dp < strlen(lcr_message); dp++) {
|
||||||
|
pp = pm;
|
||||||
|
cur_byte = lcr_message[dp];
|
||||||
|
for (cp = 0; cp < 7; cp++)
|
||||||
|
if ((cur_byte >> cp) & 1) pp++;
|
||||||
|
lcr_message_data[dp] = (cur_byte << 1) | (pp & 1);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace afsk */
|
73
firmware/application/afsk.hpp
Normal file
73
firmware/application/afsk.hpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
* Copyright (C) 2016 Furrtek
|
||||||
|
*
|
||||||
|
* This file is part of PortaPack.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ui.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifndef __AFSK_H__
|
||||||
|
#define __AFSK_H__
|
||||||
|
|
||||||
|
namespace afsk {
|
||||||
|
|
||||||
|
#define AFSK_MODES_COUNT 4
|
||||||
|
|
||||||
|
enum parity_enum {
|
||||||
|
NONE = 0,
|
||||||
|
EVEN,
|
||||||
|
ODD
|
||||||
|
};
|
||||||
|
|
||||||
|
struct afsk_formats_t {
|
||||||
|
std::string fullname;
|
||||||
|
std::string shortname;
|
||||||
|
uint8_t data_bits;
|
||||||
|
parity_enum parity;
|
||||||
|
uint8_t stop_bits;
|
||||||
|
bool MSB_first;
|
||||||
|
bool use_LUT;
|
||||||
|
};
|
||||||
|
|
||||||
|
const afsk_formats_t afsk_formats[4] = {
|
||||||
|
{ "7-Even-1 R", "7E1", 7, EVEN, 1, false, false },
|
||||||
|
{ "7E1 LUT ", "7Ea", 7, EVEN, 1, true, true },
|
||||||
|
{ "7-Odd-1 ", "7o1", 7, ODD, 1, true, false },
|
||||||
|
{ "8-Even-0 ", "8E0", 8, EVEN, 1, true, false }
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Complete table
|
||||||
|
const char alt_lookup[128] = {
|
||||||
|
0, 0, 0, 0x5F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0F, // 0
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10
|
||||||
|
0xF8, 0, 0x99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 !"#$%&'()*+,-./
|
||||||
|
0xF5, 0, 0x94, 0x55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1C, 0, 0, // 30 0123456789:;<=>?
|
||||||
|
0, 0x3C, 0x9C, 0x5D, 0, 0, 0, 0, 0, 0x44, 0x85, 0, 0xD5, 0x14, 0, 0, // 40 @ABCDEFGHIJKLMNO
|
||||||
|
0xF0, 0, 0, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 50 PQRSTUVWXYZ[\]^_
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60 `abcdefghijklmno
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x7F // 70 pqrstuvwxyz{|}~
|
||||||
|
};
|
||||||
|
|
||||||
|
void generate_data(const char * in_message, char * out_data);
|
||||||
|
|
||||||
|
} /* namespace afsk */
|
||||||
|
|
||||||
|
#endif/*__AFSK_H__*/
|
|
@ -24,11 +24,9 @@
|
||||||
// Gimp image > indexed colors (16), then "xxd -i *.bmp"
|
// Gimp image > indexed colors (16), then "xxd -i *.bmp"
|
||||||
|
|
||||||
//BUG: No audio in about when shown second time
|
//BUG: No audio in about when shown second time
|
||||||
//BUG: Description doesn't show up first time going to system>module info (UI drawn on top)
|
|
||||||
|
|
||||||
//TODO: Check AFSK transmit end, skips last bits ?
|
//TODO: Check AFSK transmit end, skips last bits ?
|
||||||
//TODO: Weird LCR AFSK scrambling ?
|
//TODO: Use msgpack for settings, lists... on sd card
|
||||||
//TODO: Use msgpack !
|
|
||||||
//TODO: Frequency manager
|
//TODO: Frequency manager
|
||||||
//TODO: Morse coder
|
//TODO: Morse coder
|
||||||
|
|
||||||
|
@ -55,6 +53,7 @@
|
||||||
//TODO: Persistent playdead !
|
//TODO: Persistent playdead !
|
||||||
//TODO: Show MD5 mismatches for modules not found, etc...
|
//TODO: Show MD5 mismatches for modules not found, etc...
|
||||||
//TODO: Module name/filename in modules.hpp to indicate requirement in case it's not found ui_loadmodule
|
//TODO: Module name/filename in modules.hpp to indicate requirement in case it's not found ui_loadmodule
|
||||||
|
//BUG: Description doesn't show up first time going to system>module info (UI drawn on top)
|
||||||
|
|
||||||
//TODO: Draw on touchscreen and transmit as spectrum paint
|
//TODO: Draw on touchscreen and transmit as spectrum paint
|
||||||
//TODO: Two players tic-tac-toe
|
//TODO: Two players tic-tac-toe
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
* Copyright (C) 2016 Furrtek
|
||||||
*
|
*
|
||||||
* This file is part of PortaPack.
|
* This file is part of PortaPack.
|
||||||
*
|
*
|
||||||
|
@ -19,19 +20,14 @@
|
||||||
* Boston, MA 02110-1301, USA.
|
* Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ui_rds.hpp"
|
|
||||||
#include "ui_afsksetup.hpp"
|
#include "ui_afsksetup.hpp"
|
||||||
#include "ui_receiver.hpp"
|
#include "ui_receiver.hpp"
|
||||||
|
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
|
|
||||||
#include "ff.h"
|
|
||||||
#include "hackrf_gpio.hpp"
|
|
||||||
#include "portapack.hpp"
|
#include "portapack.hpp"
|
||||||
#include "radio.hpp"
|
|
||||||
#include "string_format.hpp"
|
#include "string_format.hpp"
|
||||||
|
|
||||||
#include "hackrf_hal.hpp"
|
|
||||||
#include "portapack_shared_memory.hpp"
|
#include "portapack_shared_memory.hpp"
|
||||||
#include "portapack_persistent_memory.hpp"
|
#include "portapack_persistent_memory.hpp"
|
||||||
|
|
||||||
|
@ -39,6 +35,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
|
using namespace afsk;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
@ -46,11 +43,7 @@ void AFSKSetupView::focus() {
|
||||||
button_setfreq.focus();
|
button_setfreq.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AFSKSetupView::paint(Painter& painter) {
|
void AFSKSetupView::update_freq(rf::Frequency f) {
|
||||||
(void)painter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AFSKSetupView::updfreq(rf::Frequency f) {
|
|
||||||
char finalstr[9] = {0};
|
char finalstr[9] = {0};
|
||||||
|
|
||||||
portapack::persistent_memory::set_tuned_frequency(f);
|
portapack::persistent_memory::set_tuned_frequency(f);
|
||||||
|
@ -69,12 +62,19 @@ AFSKSetupView::AFSKSetupView(
|
||||||
NavigationView& nav
|
NavigationView& nav
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
using name_t = std::string;
|
||||||
|
using value_t = int32_t;
|
||||||
|
using option_t = std::pair<name_t, value_t>;
|
||||||
|
using options_t = std::vector<option_t>;
|
||||||
|
options_t format_options;
|
||||||
uint8_t rpt;
|
uint8_t rpt;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
add_children({ {
|
add_children({ {
|
||||||
&text_title,
|
&text_setfreq,
|
||||||
&button_setfreq,
|
&button_setfreq,
|
||||||
&button_setbps,
|
&text_bps,
|
||||||
|
&options_bps,
|
||||||
&text_mark,
|
&text_mark,
|
||||||
&field_mark,
|
&field_mark,
|
||||||
&text_space,
|
&text_space,
|
||||||
|
@ -83,62 +83,45 @@ AFSKSetupView::AFSKSetupView(
|
||||||
&field_bw,
|
&field_bw,
|
||||||
&text_repeat,
|
&text_repeat,
|
||||||
&field_repeat,
|
&field_repeat,
|
||||||
//&checkbox_lsb,
|
&text_format,
|
||||||
//&checkbox_parity,
|
&options_format,
|
||||||
//&checkbox_datasize,
|
&button_save
|
||||||
&checkbox_altformat,
|
|
||||||
&button_done
|
|
||||||
} });
|
} });
|
||||||
|
|
||||||
//if (portapack::persistent_memory::afsk_config() & 1) checkbox_lsb.set_value(true);
|
for (i = 0; i < AFSK_MODES_COUNT; i++)
|
||||||
//if (portapack::persistent_memory::afsk_config() & 2) checkbox_parity.set_value(true);
|
format_options.emplace_back(std::make_pair(afsk_formats[i].fullname, i));
|
||||||
//if (portapack::persistent_memory::afsk_config() & 4) checkbox_datasize.set_value(true);
|
|
||||||
if (portapack::persistent_memory::afsk_config() & 8) checkbox_altformat.set_value(true);
|
|
||||||
|
|
||||||
updfreq(portapack::persistent_memory::tuned_frequency());
|
options_format.set_options(format_options);
|
||||||
|
options_format.set_selected_index(portapack::persistent_memory::afsk_format());
|
||||||
|
|
||||||
field_mark.set_value(portapack::persistent_memory::afsk_mark_freq()*100);
|
update_freq(portapack::persistent_memory::tuned_frequency());
|
||||||
field_space.set_value(portapack::persistent_memory::afsk_space_freq()*100);
|
|
||||||
|
field_mark.set_value(portapack::persistent_memory::afsk_mark_freq() * 25);
|
||||||
|
field_space.set_value(portapack::persistent_memory::afsk_space_freq() * 25);
|
||||||
field_bw.set_value(portapack::persistent_memory::afsk_bw());
|
field_bw.set_value(portapack::persistent_memory::afsk_bw());
|
||||||
rpt = (portapack::persistent_memory::afsk_config() >> 8) & 0xFF;
|
rpt = portapack::persistent_memory::afsk_repeats();
|
||||||
if (rpt > 99) rpt = 5;
|
if ((rpt > 99) || (!rpt)) rpt = 5;
|
||||||
field_repeat.set_value(rpt);
|
field_repeat.set_value(rpt);
|
||||||
|
|
||||||
button_setfreq.on_select = [this,&nav](Button&){
|
button_setfreq.on_select = [this,&nav](Button&) {
|
||||||
auto new_view = nav.push<FrequencyKeypadView>(portapack::persistent_memory::tuned_frequency());
|
auto new_view = nav.push<FrequencyKeypadView>(portapack::persistent_memory::tuned_frequency());
|
||||||
new_view->on_changed = [this](rf::Frequency f) {
|
new_view->on_changed = [this](rf::Frequency f) {
|
||||||
updfreq(f);
|
update_freq(f);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
if (portapack::persistent_memory::afsk_bitrate() == 1200) {
|
options_bps.set_by_value(portapack::persistent_memory::afsk_bitrate());
|
||||||
button_setbps.set_text("1200 bps");
|
|
||||||
} else {
|
|
||||||
button_setbps.set_text("2400 bps");
|
|
||||||
}
|
|
||||||
|
|
||||||
button_setbps.on_select = [this](Button&){
|
|
||||||
if (portapack::persistent_memory::afsk_bitrate() == 1200) {
|
|
||||||
portapack::persistent_memory::set_afsk_bitrate(2400);
|
|
||||||
button_setbps.set_text("2400 bps");
|
|
||||||
} else {
|
|
||||||
portapack::persistent_memory::set_afsk_bitrate(1200);
|
|
||||||
button_setbps.set_text("1200 bps");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
button_done.on_select = [this,&nav](Button&){
|
button_save.on_select = [this,&nav](Button&) {
|
||||||
uint32_t afsk_config = 0;
|
uint32_t afsk_config = 0;
|
||||||
|
|
||||||
portapack::persistent_memory::set_afsk_mark(field_mark.value()/100);
|
portapack::persistent_memory::set_afsk_bitrate(options_bps.selected_index_value());
|
||||||
portapack::persistent_memory::set_afsk_space(field_space.value()/100);
|
portapack::persistent_memory::set_afsk_mark(field_mark.value() / 25);
|
||||||
|
portapack::persistent_memory::set_afsk_space(field_space.value() / 25);
|
||||||
portapack::persistent_memory::set_afsk_bw(field_bw.value());
|
portapack::persistent_memory::set_afsk_bw(field_bw.value());
|
||||||
|
|
||||||
//if (checkbox_lsb.value() == true) afsk_config |= 1;
|
afsk_config |= (options_format.selected_index() << 16);
|
||||||
//if (checkbox_parity.value() == true) afsk_config |= 2;
|
afsk_config |= (field_repeat.value() << 24);
|
||||||
//if (checkbox_datasize.value() == true) afsk_config |= 4;
|
|
||||||
if (checkbox_altformat.value() == true) afsk_config |= 8;
|
|
||||||
afsk_config |= (field_repeat.value() << 8);
|
|
||||||
portapack::persistent_memory::set_afsk_config(afsk_config);
|
portapack::persistent_memory::set_afsk_config(afsk_config);
|
||||||
|
|
||||||
nav.pop();
|
nav.pop();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
* Copyright (C) 2016 Furrtek
|
||||||
*
|
*
|
||||||
* This file is part of PortaPack.
|
* This file is part of PortaPack.
|
||||||
*
|
*
|
||||||
|
@ -19,17 +20,13 @@
|
||||||
* Boston, MA 02110-1301, USA.
|
* Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "afsk.hpp"
|
||||||
|
|
||||||
#include "ui.hpp"
|
#include "ui.hpp"
|
||||||
#include "ui_widget.hpp"
|
#include "ui_widget.hpp"
|
||||||
#include "ui_painter.hpp"
|
#include "ui_painter.hpp"
|
||||||
#include "ui_menu.hpp"
|
|
||||||
#include "ui_navigation.hpp"
|
#include "ui_navigation.hpp"
|
||||||
#include "ui_font_fixed_8x16.hpp"
|
#include "ui_font_fixed_8x16.hpp"
|
||||||
#include "clock_manager.hpp"
|
|
||||||
#include "message.hpp"
|
|
||||||
#include "rf_path.hpp"
|
|
||||||
#include "max2837.hpp"
|
|
||||||
#include "volume.hpp"
|
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
@ -37,23 +34,36 @@ class AFSKSetupView : public View {
|
||||||
public:
|
public:
|
||||||
AFSKSetupView(NavigationView& nav);
|
AFSKSetupView(NavigationView& nav);
|
||||||
|
|
||||||
void updfreq(rf::Frequency f);
|
|
||||||
void focus() override;
|
void focus() override;
|
||||||
void paint(Painter& painter) override;
|
|
||||||
|
std::string title() const override { return "AFSK setup"; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Text text_title {
|
void update_freq(rf::Frequency f);
|
||||||
{ 40, 32, 160, 16 },
|
|
||||||
"AFSK modulator setup"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
Text text_setfreq {
|
||||||
|
{ 8, 32, 104, 16 },
|
||||||
|
"Frequency:"
|
||||||
|
};
|
||||||
Button button_setfreq {
|
Button button_setfreq {
|
||||||
{ 8, 64, 104, 32 },
|
{ 8, 48, 104, 32 },
|
||||||
"---.----M"
|
"---.----M"
|
||||||
};
|
};
|
||||||
Button button_setbps {
|
|
||||||
{ 128, 64, 96, 32 },
|
Text text_bps {
|
||||||
"----bps"
|
{ 128, 40, 104, 16 },
|
||||||
|
"Speed:"
|
||||||
|
};
|
||||||
|
OptionsField options_bps {
|
||||||
|
{ 128, 60 },
|
||||||
|
7,
|
||||||
|
{
|
||||||
|
{ "600bps ", 600 },
|
||||||
|
{ "1200bps", 1200 },
|
||||||
|
{ "2400bps", 2400 },
|
||||||
|
{ "4800bps", 4800 },
|
||||||
|
{ "9600bps", 9600 }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Text text_mark {
|
Text text_mark {
|
||||||
|
@ -86,8 +96,8 @@ private:
|
||||||
};
|
};
|
||||||
NumberField field_bw {
|
NumberField field_bw {
|
||||||
{ 172, 104 },
|
{ 172, 104 },
|
||||||
3,
|
2,
|
||||||
{ 1, 40 },
|
{ 1, 50 },
|
||||||
1,
|
1,
|
||||||
' '
|
' '
|
||||||
};
|
};
|
||||||
|
@ -104,30 +114,19 @@ private:
|
||||||
' '
|
' '
|
||||||
};
|
};
|
||||||
|
|
||||||
Checkbox checkbox_altformat {
|
Text text_format {
|
||||||
{ 8, 150 },
|
{ 16, 152, 7 * 8, 16 },
|
||||||
11,
|
"Format:"
|
||||||
"Alt. format"
|
};
|
||||||
|
OptionsField options_format {
|
||||||
|
{ 80, 152 },
|
||||||
|
10,
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Checkbox checkbox_lsb {
|
Button button_save {
|
||||||
{ 8, 150 },
|
{ 72, 250, 96, 40 },
|
||||||
9,
|
|
||||||
"LSB first"
|
|
||||||
};
|
|
||||||
Checkbox checkbox_parity {
|
|
||||||
{ 8, 180 },
|
|
||||||
11,
|
|
||||||
"Even parity"
|
|
||||||
};
|
|
||||||
Checkbox checkbox_datasize {
|
|
||||||
{ 8, 210 },
|
|
||||||
6,
|
|
||||||
"8 bits"
|
|
||||||
};
|
|
||||||
|
|
||||||
Button button_done {
|
|
||||||
{ 72, 250, 96, 48 },
|
|
||||||
"Save"
|
"Save"
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "ui_afsksetup.hpp"
|
#include "ui_afsksetup.hpp"
|
||||||
#include "ui_debug.hpp"
|
#include "ui_debug.hpp"
|
||||||
|
|
||||||
|
#include "afsk.hpp"
|
||||||
#include "baseband_api.hpp"
|
#include "baseband_api.hpp"
|
||||||
#include "string_format.hpp"
|
#include "string_format.hpp"
|
||||||
|
|
||||||
|
@ -33,6 +34,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
|
using namespace afsk;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
@ -46,25 +48,21 @@ LCRView::~LCRView() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCRView::generate_message() {
|
void LCRView::generate_message() {
|
||||||
// Modem sync and SOM
|
const char lcr_init[8] = { 127, 127, 127, 127, 127, 127, 127, 15 }; // Modem sync and SOM
|
||||||
const char lcr_init[8] = { 127, 127, 127, 127, 127, 127, 127, 15 };
|
const char ec_lut[4][2] = { { 'A', 0x00 }, // Eclairage (Auto, Jour, Nuit)
|
||||||
// Eclairage (Auto, Jour, Nuit)
|
|
||||||
const char ec_lut[3][2] = { { 'A', 0x00 },
|
|
||||||
{ 'J', 0x00 },
|
{ 'J', 0x00 },
|
||||||
{ 'N', 0x00 } };
|
{ 'N', 0x00 },
|
||||||
|
{ 'S', 0x00 } };
|
||||||
char eom[3] = { 3, 0, 0 }; // EOM and space for checksum
|
char eom[3] = { 3, 0, 0 }; // EOM and space for checksum
|
||||||
uint8_t i, pm, bit;
|
|
||||||
uint16_t dp;
|
uint8_t i;
|
||||||
uint8_t cp, pp, cur_byte, new_byte;
|
|
||||||
|
|
||||||
button_setrgsb.set_text(rgsb);
|
button_setrgsb.set_text(rgsb);
|
||||||
|
|
||||||
// Pad litterals to 7 chars (not required ?)
|
// Pad litterals to 7 chars (not required ?)
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++)
|
||||||
while (strlen(litteral[i]) < 7) {
|
while (strlen(litteral[i]) < 7)
|
||||||
strcat(litteral[i], " ");
|
strcat(litteral[i], " ");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compose LCR message
|
// Compose LCR message
|
||||||
memset(lcr_message, 0, 512);
|
memset(lcr_message, 0, 512);
|
||||||
|
@ -89,74 +87,21 @@ void LCRView::generate_message() {
|
||||||
// Checksum
|
// Checksum
|
||||||
checksum = 0;
|
checksum = 0;
|
||||||
i = 7; // Skip modem sync
|
i = 7; // Skip modem sync
|
||||||
while (lcr_message[i]) {
|
while (lcr_message[i])
|
||||||
checksum ^= lcr_message[i];
|
checksum ^= lcr_message[i++];
|
||||||
i++;
|
|
||||||
}
|
|
||||||
checksum ^= eom[0]; // EOM char
|
checksum ^= eom[0]; // EOM char
|
||||||
checksum &= 0x7F; // Trim
|
checksum &= 0x7F; // Trim
|
||||||
eom[1] = checksum;
|
eom[1] = checksum;
|
||||||
|
|
||||||
strcat(lcr_message, eom);
|
strcat(lcr_message, eom);
|
||||||
|
|
||||||
//if (persistent_memory::afsk_config() & 2)
|
afsk::generate_data(lcr_message, lcr_message_data);
|
||||||
pm = 0; // Even parity
|
|
||||||
//else
|
|
||||||
// pm = 1; // Odd parity
|
|
||||||
|
|
||||||
if (!(persistent_memory::afsk_config() & 8)) {
|
|
||||||
// Normal format
|
|
||||||
for (dp = 0; dp < strlen(lcr_message); dp++) {
|
|
||||||
pp = pm;
|
|
||||||
new_byte = 0;
|
|
||||||
cur_byte = lcr_message[dp];
|
|
||||||
for (cp = 0; cp < 7; cp++) {
|
|
||||||
bit = (cur_byte >> cp) & 1;
|
|
||||||
pp += bit;
|
|
||||||
new_byte |= (bit << (7 - cp));
|
|
||||||
}
|
|
||||||
lcr_message_data[dp] = new_byte | (pp & 1);
|
|
||||||
}
|
|
||||||
lcr_message_data[dp++] = 0;
|
|
||||||
lcr_message_data[dp] = 0;
|
|
||||||
} else {
|
|
||||||
// Alt format
|
|
||||||
for (dp = 0; dp < strlen(lcr_message); dp++) {
|
|
||||||
pp = pm;
|
|
||||||
// Do not apply LUT on checksum (last byte) ?
|
|
||||||
if (dp != strlen(lcr_message) - 1)
|
|
||||||
cur_byte = alt_lookup[(uint8_t)lcr_message[dp] & 0x7F];
|
|
||||||
else
|
|
||||||
cur_byte = lcr_message[dp];
|
|
||||||
for (cp = 0; cp < 8; cp++) {
|
|
||||||
if ((cur_byte >> cp) & 1) pp++;
|
|
||||||
}
|
|
||||||
lcr_message_data[dp * 2] = cur_byte;
|
|
||||||
lcr_message_data[(dp * 2) + 1] = 0xFE | (pp & 1);
|
|
||||||
}
|
|
||||||
lcr_message_data[dp * 2] = 0;
|
|
||||||
lcr_message_data[(dp * 2) + 1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (persistent_memory::afsk_config() & 1) {
|
|
||||||
// LSB first
|
|
||||||
// See above
|
|
||||||
/*} else {
|
|
||||||
// MSB first
|
|
||||||
for (dp=0;dp<strlen(lcr_message);dp++) {
|
|
||||||
pp = pm;
|
|
||||||
cur_byte = lcr_message[dp];
|
|
||||||
for (cp=0;cp<7;cp++) {
|
|
||||||
if ((cur_byte>>cp)&1) pp++;
|
|
||||||
}
|
|
||||||
lcr_message_data[dp] = (cur_byte<<1)|(pp&1);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCRView::paint(Painter& painter) {
|
void LCRView::paint(Painter& painter) {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
char finalstr[24] = {0};
|
std::string final_str;
|
||||||
|
|
||||||
static constexpr Style style_orange {
|
static constexpr Style style_orange {
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
|
@ -180,18 +125,13 @@ void LCRView::paint(Painter& painter) {
|
||||||
|
|
||||||
button_setrgsb.set_text(rgsb);
|
button_setrgsb.set_text(rgsb);
|
||||||
|
|
||||||
// Recap: freq @ bps / ALT
|
// Recap: freq @ bps
|
||||||
auto fstr = to_string_dec_int(portapack::persistent_memory::tuned_frequency() / 1000, 6);
|
final_str = to_string_dec_int(portapack::persistent_memory::tuned_frequency() / 1000, 6);
|
||||||
auto bstr = to_string_dec_int(portapack::persistent_memory::afsk_bitrate(), 4);
|
final_str += '@';
|
||||||
strcpy(finalstr, fstr.c_str());
|
final_str += to_string_dec_int(portapack::persistent_memory::afsk_bitrate(), 4);
|
||||||
strcat(finalstr, "@");
|
final_str += "bps ";
|
||||||
strcat(finalstr, bstr.c_str());
|
final_str += afsk_formats[portapack::persistent_memory::afsk_format()].shortname;
|
||||||
strcat(finalstr, "bps ");
|
text_recap.set(final_str);
|
||||||
if (portapack::persistent_memory::afsk_config() & 8)
|
|
||||||
strcat(finalstr, "ALT");
|
|
||||||
else
|
|
||||||
strcat(finalstr, "NRM");
|
|
||||||
text_recap.set(finalstr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCRView::update_progress() {
|
void LCRView::update_progress() {
|
||||||
|
@ -212,7 +152,7 @@ void LCRView::update_progress() {
|
||||||
strcat(str, " ");
|
strcat(str, " ");
|
||||||
strcat(str, to_string_dec_uint(scan_index + 1).c_str());
|
strcat(str, to_string_dec_uint(scan_index + 1).c_str());
|
||||||
strcat(str, "/");
|
strcat(str, "/");
|
||||||
strcat(str, to_string_dec_uint(LCR_SCAN_COUNT).c_str());
|
strcat(str, to_string_dec_uint(scan_count).c_str());
|
||||||
text_status.set(str);
|
text_status.set(str);
|
||||||
progress.set_value(scan_progress);
|
progress.set_value(scan_progress);
|
||||||
} else {
|
} else {
|
||||||
|
@ -235,7 +175,7 @@ void LCRView::on_txdone(int n) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Done transmitting
|
// Done transmitting
|
||||||
if ((tx_mode == SCAN) && (scan_index < (LCR_SCAN_COUNT - 1))) {
|
if ((tx_mode == SCAN) && (scan_index < (scan_count - 1))) {
|
||||||
transmitter_model.disable();
|
transmitter_model.disable();
|
||||||
if (abort_scan) {
|
if (abort_scan) {
|
||||||
// Kill scan process
|
// Kill scan process
|
||||||
|
@ -250,7 +190,7 @@ void LCRView::on_txdone(int n) {
|
||||||
} else {
|
} else {
|
||||||
// Next address
|
// Next address
|
||||||
scan_index++;
|
scan_index++;
|
||||||
strcpy(rgsb, RGSB_list[scan_index]);
|
strcpy(rgsb, &scan_list[options_scanlist.selected_index()].addresses[scan_index * 5]);
|
||||||
scan_progress++;
|
scan_progress++;
|
||||||
repeat_index = 1;
|
repeat_index = 1;
|
||||||
update_progress();
|
update_progress();
|
||||||
|
@ -267,7 +207,7 @@ void LCRView::on_txdone(int n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCRView::start_tx(const bool scan) {
|
void LCRView::start_tx(const bool scan) {
|
||||||
bool afsk_alt_format;
|
uint8_t afsk_format;
|
||||||
uint8_t afsk_repeats;
|
uint8_t afsk_repeats;
|
||||||
|
|
||||||
afsk_repeats = portapack::persistent_memory::afsk_repeats();
|
afsk_repeats = portapack::persistent_memory::afsk_repeats();
|
||||||
|
@ -275,11 +215,12 @@ void LCRView::start_tx(const bool scan) {
|
||||||
if (scan) {
|
if (scan) {
|
||||||
if (tx_mode != SCAN) {
|
if (tx_mode != SCAN) {
|
||||||
scan_index = 0;
|
scan_index = 0;
|
||||||
|
scan_count = scan_list[options_scanlist.selected_index()].count;
|
||||||
scan_progress = 1;
|
scan_progress = 1;
|
||||||
repeat_index = 1;
|
repeat_index = 1;
|
||||||
tx_mode = SCAN;
|
tx_mode = SCAN;
|
||||||
strcpy(rgsb, RGSB_list[0]);
|
strcpy(rgsb, &scan_list[options_scanlist.selected_index()].addresses[0]);
|
||||||
progress.set_max(LCR_SCAN_COUNT * afsk_repeats);
|
progress.set_max(scan_count * afsk_repeats);
|
||||||
update_progress();
|
update_progress();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -291,10 +232,21 @@ void LCRView::start_tx(const bool scan) {
|
||||||
|
|
||||||
generate_message();
|
generate_message();
|
||||||
|
|
||||||
if (portapack::persistent_memory::afsk_config() & 8)
|
switch (portapack::persistent_memory::afsk_format()) {
|
||||||
afsk_alt_format = true;
|
case 0:
|
||||||
else
|
case 1:
|
||||||
afsk_alt_format = false;
|
case 2:
|
||||||
|
afsk_format = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
afsk_format = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
afsk_format = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
transmitter_model.set_tuning_frequency(portapack::persistent_memory::tuned_frequency());
|
transmitter_model.set_tuning_frequency(portapack::persistent_memory::tuned_frequency());
|
||||||
transmitter_model.set_baseband_configuration({
|
transmitter_model.set_baseband_configuration({
|
||||||
|
@ -311,11 +263,11 @@ void LCRView::start_tx(const bool scan) {
|
||||||
baseband::set_afsk_data(
|
baseband::set_afsk_data(
|
||||||
lcr_message_data,
|
lcr_message_data,
|
||||||
228000 / portapack::persistent_memory::afsk_bitrate(),
|
228000 / portapack::persistent_memory::afsk_bitrate(),
|
||||||
portapack::persistent_memory::afsk_mark_freq() * (0x40000 * 256) / 2280,
|
portapack::persistent_memory::afsk_mark_freq() * (0x40000 * 256) / (228000 / 25),
|
||||||
portapack::persistent_memory::afsk_space_freq() * (0x40000 * 256) / 2280,
|
portapack::persistent_memory::afsk_space_freq() * (0x40000 * 256) / (228000 / 25),
|
||||||
afsk_repeats,
|
afsk_repeats,
|
||||||
portapack::persistent_memory::afsk_bw() * 115, // See proc_fsk_lcr.cpp
|
portapack::persistent_memory::afsk_bw() * 115, // See proc_fsk_lcr.cpp
|
||||||
afsk_alt_format
|
afsk_format
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,11 +279,8 @@ LCRView::LCRView(NavigationView& nav) {
|
||||||
std::string label;
|
std::string label;
|
||||||
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_afsk);
|
baseband::run_image(portapack::spi_flash::image_tag_afsk);
|
||||||
|
|
||||||
memset(litteral, 0, 5 * 8);
|
|
||||||
memset(rgsb, 0, 5);
|
|
||||||
|
|
||||||
strcpy(rgsb, RGSB_list[0]);
|
strcpy(rgsb, &scan_list[options_scanlist.selected_index()].addresses[0]);
|
||||||
|
|
||||||
add_children({ {
|
add_children({ {
|
||||||
&text_recap,
|
&text_recap,
|
||||||
|
@ -342,6 +291,8 @@ LCRView::LCRView(NavigationView& nav) {
|
||||||
&progress,
|
&progress,
|
||||||
&button_lcrdebug,
|
&button_lcrdebug,
|
||||||
&button_transmit,
|
&button_transmit,
|
||||||
|
&text_scanlist,
|
||||||
|
&options_scanlist,
|
||||||
&button_scan,
|
&button_scan,
|
||||||
&button_clear
|
&button_clear
|
||||||
} });
|
} });
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
#define LCR_SCAN_COUNT 36
|
|
||||||
|
|
||||||
class LCRView : public View {
|
class LCRView : public View {
|
||||||
public:
|
public:
|
||||||
LCRView(NavigationView& nav);
|
LCRView(NavigationView& nav);
|
||||||
|
@ -41,16 +39,17 @@ public:
|
||||||
std::string title() const override { return "LCR transmit"; };
|
std::string title() const override { return "LCR transmit"; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum tx_modes {
|
struct scan_list_t {
|
||||||
IDLE = 0,
|
uint8_t count;
|
||||||
SINGLE,
|
const char * addresses;
|
||||||
SCAN
|
|
||||||
};
|
};
|
||||||
// afsk_config()
|
|
||||||
tx_modes tx_mode = IDLE;
|
scan_list_t scan_list[2] = {
|
||||||
bool abort_scan = false;
|
{ 36, &RGSB_list_Lille[0][0] },
|
||||||
double scan_progress;
|
{ 23, &RGSB_list_Reims[0][0] }
|
||||||
const char RGSB_list[LCR_SCAN_COUNT][5] = {
|
};
|
||||||
|
|
||||||
|
const char RGSB_list_Lille[36][5] = {
|
||||||
"AI10", "AI20", "AI30", "AI40",
|
"AI10", "AI20", "AI30", "AI40",
|
||||||
"AI50", "AI60", "AI70", "AJ10",
|
"AI50", "AI60", "AI70", "AJ10",
|
||||||
"AJ20", "AJ30", "AJ40", "AJ50",
|
"AJ20", "AJ30", "AJ40", "AJ50",
|
||||||
|
@ -62,14 +61,35 @@ private:
|
||||||
"EbM0", "EbN0", "EbO0", "EbP0",
|
"EbM0", "EbN0", "EbO0", "EbP0",
|
||||||
"EbS0"
|
"EbS0"
|
||||||
};
|
};
|
||||||
char litteral[5][8];
|
|
||||||
char rgsb[5];
|
const char RGSB_list_Reims[23][5] = {
|
||||||
|
"AI10", "AI20", "AI30", "AI40",
|
||||||
|
"AI50", "AI60", "AI70",
|
||||||
|
"AJ10", "AJ20", "AJ30", "AJ40",
|
||||||
|
"AJ50", "AJ60", "AJ70",
|
||||||
|
"AK10", "AK20", "AK50", "AK60",
|
||||||
|
"AK70",
|
||||||
|
"AP10"
|
||||||
|
};
|
||||||
|
|
||||||
|
enum tx_modes {
|
||||||
|
IDLE = 0,
|
||||||
|
SINGLE,
|
||||||
|
SCAN
|
||||||
|
};
|
||||||
|
|
||||||
|
tx_modes tx_mode = IDLE;
|
||||||
|
bool abort_scan = false;
|
||||||
|
uint8_t scan_count;
|
||||||
|
double scan_progress;
|
||||||
|
unsigned int scan_index;
|
||||||
|
char litteral[5][8] = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 } };
|
||||||
|
char rgsb[5] = { 0 };
|
||||||
char lcr_message[512];
|
char lcr_message[512];
|
||||||
char lcr_message_data[512];
|
char lcr_message_data[512];
|
||||||
char checksum = 0;
|
char checksum = 0;
|
||||||
rf::Frequency f;
|
rf::Frequency f;
|
||||||
uint8_t repeat_index;
|
uint8_t repeat_index;
|
||||||
unsigned int scan_index;
|
|
||||||
|
|
||||||
void generate_message();
|
void generate_message();
|
||||||
void update_progress();
|
void update_progress();
|
||||||
|
@ -79,7 +99,7 @@ private:
|
||||||
|
|
||||||
radio::Configuration lcr_radio_config = {
|
radio::Configuration lcr_radio_config = {
|
||||||
0,
|
0,
|
||||||
2280000, // ?
|
2280000,
|
||||||
2500000, // ?
|
2500000, // ?
|
||||||
rf::Direction::Transmit,
|
rf::Direction::Transmit,
|
||||||
true,
|
true,
|
||||||
|
@ -91,17 +111,6 @@ private:
|
||||||
// 2: 94 ?
|
// 2: 94 ?
|
||||||
// 9: 85 ?
|
// 9: 85 ?
|
||||||
|
|
||||||
const char alt_lookup[128] = {
|
|
||||||
0, 0, 0, 0x5F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0F, // 0
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10
|
|
||||||
0xF8, 0, 0x99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 !"#$%&'()*+,-./
|
|
||||||
0xF5, 0, 0x94, 0x55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1C, 0, 0, // 30 0123456789:;<=>?
|
|
||||||
0, 0x3C, 0x9C, 0x5D, 0, 0, 0, 0, 0, 0x44, 0x85, 0, 0xD5, 0x14, 0, 0, // 40 @ABCDEFGHIJKLMNO
|
|
||||||
0xF0, 0, 0, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 50 PQRSTUVWXYZ[\]^_
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60 `abcdefghijklmno
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x7F // 70 pqrstuvwxyz{|}~
|
|
||||||
};
|
|
||||||
|
|
||||||
const Style style_val {
|
const Style style_val {
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::green(),
|
.background = Color::green(),
|
||||||
|
@ -128,7 +137,8 @@ private:
|
||||||
{
|
{
|
||||||
{ "EC:Auto", 0 },
|
{ "EC:Auto", 0 },
|
||||||
{ "EC:Jour", 1 },
|
{ "EC:Jour", 1 },
|
||||||
{ "EC:Nuit", 2 }
|
{ "EC:Nuit", 2 },
|
||||||
|
{ "EC:S ? ", 3 }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -146,6 +156,11 @@ private:
|
||||||
"DEBUG"
|
"DEBUG"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Button button_clear {
|
||||||
|
{ 174, 64, 50, 9 * 16 },
|
||||||
|
"CLEAR"
|
||||||
|
};
|
||||||
|
|
||||||
Text text_status {
|
Text text_status {
|
||||||
{ 16, 224, 128, 16 },
|
{ 16, 224, 128, 16 },
|
||||||
"Ready"
|
"Ready"
|
||||||
|
@ -158,13 +173,21 @@ private:
|
||||||
{ 16, 270, 64, 32 },
|
{ 16, 270, 64, 32 },
|
||||||
"TX"
|
"TX"
|
||||||
};
|
};
|
||||||
Button button_scan {
|
Text text_scanlist {
|
||||||
{ 88, 270, 64, 32 },
|
{ 88, 268, 80, 16 },
|
||||||
"SCAN"
|
"Scan list:"
|
||||||
};
|
};
|
||||||
Button button_clear {
|
OptionsField options_scanlist {
|
||||||
{ 160, 270, 64, 32 },
|
{ 88, 284 },
|
||||||
"CLEAR"
|
6,
|
||||||
|
{
|
||||||
|
{ "Lille ", 0 },
|
||||||
|
{ "Reims ", 1 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Button button_scan {
|
||||||
|
{ 168, 270, 56, 32 },
|
||||||
|
"SCAN"
|
||||||
};
|
};
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_done {
|
MessageHandlerRegistration message_handler_tx_done {
|
||||||
|
|
|
@ -87,10 +87,7 @@ MenuView::MenuView() {
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuView::~MenuView() {
|
MenuView::~MenuView() {
|
||||||
/* TODO: Double-check this */
|
time::signal_tick_second -= signal_token_tick_second;
|
||||||
for (auto child : children_) {
|
|
||||||
delete child;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuView::on_tick_second() {
|
void MenuView::on_tick_second() {
|
||||||
|
|
|
@ -257,10 +257,10 @@ SetUIView::SetUIView(NavigationView& nav) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetUIView::focus() {
|
void SetUIView::focus() {
|
||||||
button_ok.focus();
|
checkbox_showsplash.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModInfoView::on_show() {
|
/*void ModInfoView::on_show() {
|
||||||
if (modules_nb) update_infos(0);
|
if (modules_nb) update_infos(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,12 +436,12 @@ void ModInfoView::focus() {
|
||||||
option_modules.focus();
|
option_modules.focus();
|
||||||
else
|
else
|
||||||
button_ok.focus();
|
button_ok.focus();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
SetupMenuView::SetupMenuView(NavigationView& nav) {
|
SetupMenuView::SetupMenuView(NavigationView& nav) {
|
||||||
add_items<7>({ {
|
add_items<6>({ {
|
||||||
{ "UI", ui::Color::white(), [&nav](){ nav.push<SetUIView>(); } },
|
{ "UI", ui::Color::white(), [&nav](){ nav.push<SetUIView>(); } },
|
||||||
{ "SD card modules", ui::Color::white(), [&nav](){ nav.push<ModInfoView>(); } },
|
//{ "SD card modules", ui::Color::white(), [&nav](){ nav.push<ModInfoView>(); } },
|
||||||
{ "Date/Time", ui::Color::white(), [&nav](){ nav.push<SetDateTimeView>(); } },
|
{ "Date/Time", ui::Color::white(), [&nav](){ nav.push<SetDateTimeView>(); } },
|
||||||
{ "Frequency correction", ui::Color::white(), [&nav](){ nav.push<SetFrequencyCorrectionView>(); } },
|
{ "Frequency correction", ui::Color::white(), [&nav](){ nav.push<SetFrequencyCorrectionView>(); } },
|
||||||
{ "Antenna Bias Voltage", ui::Color::white(), [&nav](){ nav.push<AntennaBiasSetupView>(); } },
|
{ "Antenna Bias Voltage", ui::Color::white(), [&nav](){ nav.push<AntennaBiasSetupView>(); } },
|
||||||
|
|
|
@ -308,7 +308,7 @@ private:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModInfoView : public View {
|
/*class ModInfoView : public View {
|
||||||
public:
|
public:
|
||||||
ModInfoView(NavigationView& nav);
|
ModInfoView(NavigationView& nav);
|
||||||
void focus() override;
|
void focus() override;
|
||||||
|
@ -376,7 +376,7 @@ private:
|
||||||
{ 4 * 8, 272, 64, 24 },
|
{ 4 * 8, 272, 64, 24 },
|
||||||
"Ok"
|
"Ok"
|
||||||
};
|
};
|
||||||
};
|
};*/
|
||||||
|
|
||||||
class SetupMenuView : public MenuView {
|
class SetupMenuView : public MenuView {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -29,22 +29,24 @@
|
||||||
|
|
||||||
void AFSKProcessor::execute(const buffer_c8_t& buffer) {
|
void AFSKProcessor::execute(const buffer_c8_t& buffer) {
|
||||||
|
|
||||||
// This is called at 2280000/2048 = 1113Hz
|
// This is called at 2.28M/2048 = 1113Hz
|
||||||
|
|
||||||
if (!configured) return;
|
if (!configured) return;
|
||||||
|
|
||||||
for (size_t i = 0; i<buffer.count; i++) {
|
for (size_t i = 0; i<buffer.count; i++) {
|
||||||
|
|
||||||
// Tone generation at 2280000/10 = 228kHz
|
// Tone synthesis at 2.28M/10 = 228kHz
|
||||||
if (s >= (10 - 1)) {
|
if (!s) {
|
||||||
s = 0;
|
s = 10 - 1;
|
||||||
|
|
||||||
if (sample_count >= afsk_samples_per_bit) {
|
if (sample_count >= afsk_samples_per_bit) {
|
||||||
if (configured == true) {
|
if (configured) {
|
||||||
cur_byte = message_data[byte_pos];
|
cur_byte = message_data[byte_pos];
|
||||||
ext_byte = message_data[byte_pos + 1];
|
ext_byte = message_data[byte_pos + 1];
|
||||||
|
|
||||||
if (!(cur_byte | ext_byte)) {
|
if (!(cur_byte | ext_byte)) {
|
||||||
|
// End of data
|
||||||
if (repeat_counter < afsk_repeat) {
|
if (repeat_counter < afsk_repeat) {
|
||||||
|
// Repeat
|
||||||
bit_pos = 0;
|
bit_pos = 0;
|
||||||
byte_pos = 0;
|
byte_pos = 0;
|
||||||
cur_byte = message_data[0];
|
cur_byte = message_data[0];
|
||||||
|
@ -53,36 +55,33 @@ void AFSKProcessor::execute(const buffer_c8_t& buffer) {
|
||||||
shared_memory.application_queue.push(message);
|
shared_memory.application_queue.push(message);
|
||||||
repeat_counter++;
|
repeat_counter++;
|
||||||
} else {
|
} else {
|
||||||
message.n = 0;
|
// Stop
|
||||||
shared_memory.application_queue.push(message);
|
|
||||||
cur_byte = 0;
|
cur_byte = 0;
|
||||||
ext_byte = 0;
|
ext_byte = 0;
|
||||||
|
message.n = 0;
|
||||||
|
shared_memory.application_queue.push(message);
|
||||||
configured = false;
|
configured = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!afsk_alt_format) {
|
if (afsk_format == 0) {
|
||||||
// 0bbbbbbbp1
|
// 0bbbbbbbp1
|
||||||
// Start, 7-bit data, parity, stop
|
// Start, 7-bit data, parity, stop
|
||||||
gbyte = 0;
|
gbyte = (cur_byte << 1) | 1;
|
||||||
gbyte = cur_byte << 1;
|
} else if (afsk_format == 1) {
|
||||||
gbyte |= 1;
|
|
||||||
} else {
|
|
||||||
// 0bbbbbbbbp
|
// 0bbbbbbbbp
|
||||||
// Start, 8-bit data, parity
|
// Start, 8-bit data, parity
|
||||||
gbyte = 0;
|
gbyte = (cur_byte << 1) | (ext_byte & 1);
|
||||||
gbyte = cur_byte << 1;
|
|
||||||
gbyte |= (ext_byte & 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_bit = (gbyte >> (9 - bit_pos)) & 1;
|
cur_bit = (gbyte >> (9 - bit_pos)) & 1;
|
||||||
|
|
||||||
if (bit_pos == 9) {
|
if (bit_pos >= 9) {
|
||||||
bit_pos = 0;
|
bit_pos = 0;
|
||||||
if (!afsk_alt_format)
|
if (afsk_format == 0)
|
||||||
byte_pos++;
|
byte_pos++;
|
||||||
else
|
else if (afsk_format == 1)
|
||||||
byte_pos += 2;
|
byte_pos += 2;
|
||||||
} else {
|
} else {
|
||||||
bit_pos++;
|
bit_pos++;
|
||||||
|
@ -97,10 +96,10 @@ void AFSKProcessor::execute(const buffer_c8_t& buffer) {
|
||||||
else
|
else
|
||||||
tone_phase += afsk_phase_inc_space;
|
tone_phase += afsk_phase_inc_space;
|
||||||
} else {
|
} else {
|
||||||
s++;
|
s--;
|
||||||
}
|
}
|
||||||
|
|
||||||
tone_sample = (sine_table_i8[(tone_phase & 0x03FC0000)>>18]);
|
tone_sample = (sine_table_i8[(tone_phase & 0x03FC0000) >> 18]);
|
||||||
|
|
||||||
// FM
|
// FM
|
||||||
// 1<<18 = 262144
|
// 1<<18 = 262144
|
||||||
|
@ -108,17 +107,18 @@ void AFSKProcessor::execute(const buffer_c8_t& buffer) {
|
||||||
frq = tone_sample * afsk_bw;
|
frq = tone_sample * afsk_bw;
|
||||||
|
|
||||||
phase = (phase + frq);
|
phase = (phase + frq);
|
||||||
sphase = phase + (64<<18);
|
sphase = phase + (64 << 18);
|
||||||
|
|
||||||
re = (sine_table_i8[(sphase & 0x03FC0000)>>18]);
|
re = (sine_table_i8[(sphase & 0x03FC0000) >> 18]);
|
||||||
im = (sine_table_i8[(phase & 0x03FC0000)>>18]);
|
im = (sine_table_i8[(phase & 0x03FC0000) >> 18]);
|
||||||
|
|
||||||
buffer.p[i] = {(int8_t)re,(int8_t)im};
|
buffer.p[i] = {(int8_t)re, (int8_t)im};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AFSKProcessor::on_message(const Message* const p) {
|
void AFSKProcessor::on_message(const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const AFSKConfigureMessage*>(p);
|
const auto message = *reinterpret_cast<const AFSKConfigureMessage*>(p);
|
||||||
|
|
||||||
if (message.id == Message::ID::AFSKConfigure) {
|
if (message.id == Message::ID::AFSKConfigure) {
|
||||||
memcpy(message_data, message.message_data, 512);
|
memcpy(message_data, message.message_data, 512);
|
||||||
afsk_samples_per_bit = message.afsk_samples_per_bit;
|
afsk_samples_per_bit = message.afsk_samples_per_bit;
|
||||||
|
@ -126,8 +126,9 @@ void AFSKProcessor::on_message(const Message* const p) {
|
||||||
afsk_phase_inc_space = message.afsk_phase_inc_space;
|
afsk_phase_inc_space = message.afsk_phase_inc_space;
|
||||||
afsk_repeat = message.afsk_repeat - 1;
|
afsk_repeat = message.afsk_repeat - 1;
|
||||||
afsk_bw = message.afsk_bw;
|
afsk_bw = message.afsk_bw;
|
||||||
afsk_alt_format = message.afsk_alt_format;
|
afsk_format = message.afsk_format;
|
||||||
|
|
||||||
|
s = 0;
|
||||||
sample_count = afsk_samples_per_bit;
|
sample_count = afsk_samples_per_bit;
|
||||||
repeat_counter = 0;
|
repeat_counter = 0;
|
||||||
bit_pos = 0;
|
bit_pos = 0;
|
||||||
|
|
|
@ -42,12 +42,12 @@ private:
|
||||||
uint32_t afsk_phase_inc_space;
|
uint32_t afsk_phase_inc_space;
|
||||||
uint8_t afsk_repeat;
|
uint8_t afsk_repeat;
|
||||||
uint32_t afsk_bw;
|
uint32_t afsk_bw;
|
||||||
bool afsk_alt_format;
|
uint8_t afsk_format;
|
||||||
char message_data[512];
|
char message_data[512];
|
||||||
|
|
||||||
uint8_t repeat_counter = 0;
|
uint8_t repeat_counter = 0;
|
||||||
int8_t re, im;
|
int8_t re, im;
|
||||||
uint8_t s;
|
uint8_t s = 0;
|
||||||
uint8_t bit_pos = 0;
|
uint8_t bit_pos = 0;
|
||||||
uint16_t byte_pos = 0;
|
uint16_t byte_pos = 0;
|
||||||
char cur_byte = 0;
|
char cur_byte = 0;
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 11 KiB |
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
|
@ -530,14 +530,14 @@ public:
|
||||||
const uint32_t afsk_phase_inc_space,
|
const uint32_t afsk_phase_inc_space,
|
||||||
const uint8_t afsk_repeat,
|
const uint8_t afsk_repeat,
|
||||||
const uint32_t afsk_bw,
|
const uint32_t afsk_bw,
|
||||||
const bool afsk_alt_format
|
const uint8_t afsk_format
|
||||||
) : Message { ID::AFSKConfigure },
|
) : Message { ID::AFSKConfigure },
|
||||||
afsk_samples_per_bit(afsk_samples_per_bit),
|
afsk_samples_per_bit(afsk_samples_per_bit),
|
||||||
afsk_phase_inc_mark(afsk_phase_inc_mark),
|
afsk_phase_inc_mark(afsk_phase_inc_mark),
|
||||||
afsk_phase_inc_space(afsk_phase_inc_space),
|
afsk_phase_inc_space(afsk_phase_inc_space),
|
||||||
afsk_repeat(afsk_repeat),
|
afsk_repeat(afsk_repeat),
|
||||||
afsk_bw(afsk_bw),
|
afsk_bw(afsk_bw),
|
||||||
afsk_alt_format(afsk_alt_format)
|
afsk_format(afsk_format)
|
||||||
{
|
{
|
||||||
memcpy(message_data, data, 512);
|
memcpy(message_data, data, 512);
|
||||||
}
|
}
|
||||||
|
@ -547,7 +547,7 @@ public:
|
||||||
uint32_t afsk_phase_inc_space;
|
uint32_t afsk_phase_inc_space;
|
||||||
uint8_t afsk_repeat;
|
uint8_t afsk_repeat;
|
||||||
uint32_t afsk_bw;
|
uint32_t afsk_bw;
|
||||||
bool afsk_alt_format;
|
uint8_t afsk_format;
|
||||||
char message_data[512];
|
char message_data[512];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,16 +36,16 @@ using portapack::memory::map::backup_ram;
|
||||||
namespace portapack {
|
namespace portapack {
|
||||||
namespace persistent_memory {
|
namespace persistent_memory {
|
||||||
|
|
||||||
constexpr rf::Frequency tuned_frequency_reset_value { 858750000 };
|
constexpr rf::Frequency tuned_frequency_reset_value { 88000000 };
|
||||||
|
|
||||||
using ppb_range_t = range_t<ppb_t>;
|
using ppb_range_t = range_t<ppb_t>;
|
||||||
constexpr ppb_range_t ppb_range { -99000, 99000 };
|
constexpr ppb_range_t ppb_range { -99000, 99000 };
|
||||||
constexpr ppb_t ppb_reset_value { 0 };
|
constexpr ppb_t ppb_reset_value { 0 };
|
||||||
|
|
||||||
using afsk_freq_range_t = range_t<int32_t>;
|
using afsk_freq_range_t = range_t<int32_t>;
|
||||||
constexpr afsk_freq_range_t afsk_freq_range { 1, 60 };
|
constexpr afsk_freq_range_t afsk_freq_range { 1, 400 };
|
||||||
constexpr int32_t afsk_mark_reset_value { 12 };
|
constexpr int32_t afsk_mark_reset_value { 48 };
|
||||||
constexpr int32_t afsk_space_reset_value { 22 };
|
constexpr int32_t afsk_space_reset_value { 88 };
|
||||||
|
|
||||||
using afsk_bitrate_range_t = range_t<int32_t>;
|
using afsk_bitrate_range_t = range_t<int32_t>;
|
||||||
constexpr afsk_bitrate_range_t afsk_bitrate_range { 600, 9600 };
|
constexpr afsk_bitrate_range_t afsk_bitrate_range { 600, 9600 };
|
||||||
|
@ -63,7 +63,7 @@ struct data_t {
|
||||||
|
|
||||||
// AFSK modem
|
// AFSK modem
|
||||||
int32_t afsk_mark_freq;
|
int32_t afsk_mark_freq;
|
||||||
int32_t afsk_space_freq; // Todo: optimize size, only 256 bytes of NVRAM !
|
int32_t afsk_space_freq; // Todo: reduce size, only 256 bytes of NVRAM !
|
||||||
int32_t afsk_bitrate;
|
int32_t afsk_bitrate;
|
||||||
int32_t afsk_bw;
|
int32_t afsk_bw;
|
||||||
uint32_t afsk_config;
|
uint32_t afsk_config;
|
||||||
|
@ -139,8 +139,12 @@ uint32_t afsk_config() {
|
||||||
return data->afsk_config;
|
return data->afsk_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t afsk_format() {
|
||||||
|
return ((data->afsk_config >> 16) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t afsk_repeats() {
|
uint8_t afsk_repeats() {
|
||||||
return (data->afsk_config >> 8);
|
return (data->afsk_config >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_afsk_config(const uint32_t new_value) {
|
void set_afsk_config(const uint32_t new_value) {
|
||||||
|
|
|
@ -47,6 +47,7 @@ int32_t afsk_bitrate();
|
||||||
void set_afsk_bitrate(const int32_t new_value);
|
void set_afsk_bitrate(const int32_t new_value);
|
||||||
|
|
||||||
uint32_t afsk_config();
|
uint32_t afsk_config();
|
||||||
|
uint8_t afsk_format();
|
||||||
uint8_t afsk_repeats();
|
uint8_t afsk_repeats();
|
||||||
void set_afsk_config(const uint32_t new_value);
|
void set_afsk_config(const uint32_t new_value);
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue