More AFSK options, scan lists,

This commit is contained in:
furrtek 2016-08-02 12:44:31 +02:00
parent 72f3c08e9b
commit e2218a0f32
20 changed files with 445 additions and 275 deletions

View File

@ -135,6 +135,7 @@ set(CPPSRC
touch_adc.cpp
encoder.cpp
audio.cpp
afsk.cpp
${COMMON}/lcd_ili9341.cpp
${COMMON}/ui.cpp
${COMMON}/ui_text.cpp

View File

@ -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
.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
.PHONY : ais_app.obj
@ -4411,6 +4435,9 @@ help:
@echo "... __/common/wm8731.obj"
@echo "... __/common/wm8731.i"
@echo "... __/common/wm8731.s"
@echo "... afsk.obj"
@echo "... afsk.i"
@echo "... afsk.s"
@echo "... ais_app.obj"
@echo "... ais_app.i"
@echo "... ais_app.s"

View 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 */

View 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__*/

View File

@ -24,11 +24,9 @@
// Gimp image > indexed colors (16), then "xxd -i *.bmp"
//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: Weird LCR AFSK scrambling ?
//TODO: Use msgpack !
//TODO: Use msgpack for settings, lists... on sd card
//TODO: Frequency manager
//TODO: Morse coder
@ -55,6 +53,7 @@
//TODO: Persistent playdead !
//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
//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: Two players tic-tac-toe

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
@ -19,19 +20,14 @@
* Boston, MA 02110-1301, USA.
*/
#include "ui_rds.hpp"
#include "ui_afsksetup.hpp"
#include "ui_receiver.hpp"
#include "ch.h"
#include "ff.h"
#include "hackrf_gpio.hpp"
#include "portapack.hpp"
#include "radio.hpp"
#include "string_format.hpp"
#include "hackrf_hal.hpp"
#include "portapack_shared_memory.hpp"
#include "portapack_persistent_memory.hpp"
@ -39,6 +35,7 @@
#include <stdio.h>
using namespace portapack;
using namespace afsk;
namespace ui {
@ -46,11 +43,7 @@ void AFSKSetupView::focus() {
button_setfreq.focus();
}
void AFSKSetupView::paint(Painter& painter) {
(void)painter;
}
void AFSKSetupView::updfreq(rf::Frequency f) {
void AFSKSetupView::update_freq(rf::Frequency f) {
char finalstr[9] = {0};
portapack::persistent_memory::set_tuned_frequency(f);
@ -69,12 +62,19 @@ AFSKSetupView::AFSKSetupView(
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;
size_t i;
add_children({ {
&text_title,
&text_setfreq,
&button_setfreq,
&button_setbps,
&text_bps,
&options_bps,
&text_mark,
&field_mark,
&text_space,
@ -83,62 +83,45 @@ AFSKSetupView::AFSKSetupView(
&field_bw,
&text_repeat,
&field_repeat,
//&checkbox_lsb,
//&checkbox_parity,
//&checkbox_datasize,
&checkbox_altformat,
&button_done
&text_format,
&options_format,
&button_save
} });
//if (portapack::persistent_memory::afsk_config() & 1) checkbox_lsb.set_value(true);
//if (portapack::persistent_memory::afsk_config() & 2) checkbox_parity.set_value(true);
//if (portapack::persistent_memory::afsk_config() & 4) checkbox_datasize.set_value(true);
if (portapack::persistent_memory::afsk_config() & 8) checkbox_altformat.set_value(true);
for (i = 0; i < AFSK_MODES_COUNT; i++)
format_options.emplace_back(std::make_pair(afsk_formats[i].fullname, i));
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);
field_space.set_value(portapack::persistent_memory::afsk_space_freq()*100);
update_freq(portapack::persistent_memory::tuned_frequency());
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());
rpt = (portapack::persistent_memory::afsk_config() >> 8) & 0xFF;
if (rpt > 99) rpt = 5;
rpt = portapack::persistent_memory::afsk_repeats();
if ((rpt > 99) || (!rpt)) rpt = 5;
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());
new_view->on_changed = [this](rf::Frequency f) {
updfreq(f);
update_freq(f);
};
};
if (portapack::persistent_memory::afsk_bitrate() == 1200) {
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");
}
};
options_bps.set_by_value(portapack::persistent_memory::afsk_bitrate());
button_done.on_select = [this,&nav](Button&){
button_save.on_select = [this,&nav](Button&) {
uint32_t afsk_config = 0;
portapack::persistent_memory::set_afsk_mark(field_mark.value()/100);
portapack::persistent_memory::set_afsk_space(field_space.value()/100);
portapack::persistent_memory::set_afsk_bitrate(options_bps.selected_index_value());
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());
//if (checkbox_lsb.value() == true) afsk_config |= 1;
//if (checkbox_parity.value() == true) afsk_config |= 2;
//if (checkbox_datasize.value() == true) afsk_config |= 4;
if (checkbox_altformat.value() == true) afsk_config |= 8;
afsk_config |= (field_repeat.value() << 8);
afsk_config |= (options_format.selected_index() << 16);
afsk_config |= (field_repeat.value() << 24);
portapack::persistent_memory::set_afsk_config(afsk_config);
nav.pop();

View File

@ -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.
*
@ -19,17 +20,13 @@
* Boston, MA 02110-1301, USA.
*/
#include "afsk.hpp"
#include "ui.hpp"
#include "ui_widget.hpp"
#include "ui_painter.hpp"
#include "ui_menu.hpp"
#include "ui_navigation.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 {
@ -37,23 +34,36 @@ class AFSKSetupView : public View {
public:
AFSKSetupView(NavigationView& nav);
void updfreq(rf::Frequency f);
void focus() override;
void paint(Painter& painter) override;
std::string title() const override { return "AFSK setup"; };
private:
Text text_title {
{ 40, 32, 160, 16 },
"AFSK modulator setup"
};
void update_freq(rf::Frequency f);
Text text_setfreq {
{ 8, 32, 104, 16 },
"Frequency:"
};
Button button_setfreq {
{ 8, 64, 104, 32 },
{ 8, 48, 104, 32 },
"---.----M"
};
Button button_setbps {
{ 128, 64, 96, 32 },
"----bps"
Text text_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 {
@ -86,8 +96,8 @@ private:
};
NumberField field_bw {
{ 172, 104 },
3,
{ 1, 40 },
2,
{ 1, 50 },
1,
' '
};
@ -104,30 +114,19 @@ private:
' '
};
Checkbox checkbox_altformat {
{ 8, 150 },
11,
"Alt. format"
Text text_format {
{ 16, 152, 7 * 8, 16 },
"Format:"
};
OptionsField options_format {
{ 80, 152 },
10,
{
}
};
Checkbox checkbox_lsb {
{ 8, 150 },
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 },
Button button_save {
{ 72, 250, 96, 40 },
"Save"
};
};

View File

@ -24,6 +24,7 @@
#include "ui_afsksetup.hpp"
#include "ui_debug.hpp"
#include "afsk.hpp"
#include "baseband_api.hpp"
#include "string_format.hpp"
@ -33,6 +34,7 @@
#include <stdio.h>
using namespace portapack;
using namespace afsk;
namespace ui {
@ -46,25 +48,21 @@ LCRView::~LCRView() {
}
void LCRView::generate_message() {
// Modem sync and SOM
const char lcr_init[8] = { 127, 127, 127, 127, 127, 127, 127, 15 };
// Eclairage (Auto, Jour, Nuit)
const char ec_lut[3][2] = { { 'A', 0x00 },
const char lcr_init[8] = { 127, 127, 127, 127, 127, 127, 127, 15 }; // Modem sync and SOM
const char ec_lut[4][2] = { { 'A', 0x00 }, // Eclairage (Auto, Jour, Nuit)
{ 'J', 0x00 },
{ 'N', 0x00 } };
{ 'N', 0x00 },
{ 'S', 0x00 } };
char eom[3] = { 3, 0, 0 }; // EOM and space for checksum
uint8_t i, pm, bit;
uint16_t dp;
uint8_t cp, pp, cur_byte, new_byte;
uint8_t i;
button_setrgsb.set_text(rgsb);
// Pad litterals to 7 chars (not required ?)
for (i = 0; i < 5; i++) {
while (strlen(litteral[i]) < 7) {
for (i = 0; i < 5; i++)
while (strlen(litteral[i]) < 7)
strcat(litteral[i], " ");
}
}
// Compose LCR message
memset(lcr_message, 0, 512);
@ -89,74 +87,21 @@ void LCRView::generate_message() {
// Checksum
checksum = 0;
i = 7; // Skip modem sync
while (lcr_message[i]) {
checksum ^= lcr_message[i];
i++;
}
while (lcr_message[i])
checksum ^= lcr_message[i++];
checksum ^= eom[0]; // EOM char
checksum &= 0x7F; // Trim
eom[1] = checksum;
strcat(lcr_message, eom);
//if (persistent_memory::afsk_config() & 2)
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);
}
}*/
afsk::generate_data(lcr_message, lcr_message_data);
}
void LCRView::paint(Painter& painter) {
uint8_t i;
char finalstr[24] = {0};
std::string final_str;
static constexpr Style style_orange {
.font = font::fixed_8x16,
@ -180,18 +125,13 @@ void LCRView::paint(Painter& painter) {
button_setrgsb.set_text(rgsb);
// Recap: freq @ bps / ALT
auto fstr = to_string_dec_int(portapack::persistent_memory::tuned_frequency() / 1000, 6);
auto bstr = to_string_dec_int(portapack::persistent_memory::afsk_bitrate(), 4);
strcpy(finalstr, fstr.c_str());
strcat(finalstr, "@");
strcat(finalstr, bstr.c_str());
strcat(finalstr, "bps ");
if (portapack::persistent_memory::afsk_config() & 8)
strcat(finalstr, "ALT");
else
strcat(finalstr, "NRM");
text_recap.set(finalstr);
// Recap: freq @ bps
final_str = to_string_dec_int(portapack::persistent_memory::tuned_frequency() / 1000, 6);
final_str += '@';
final_str += to_string_dec_int(portapack::persistent_memory::afsk_bitrate(), 4);
final_str += "bps ";
final_str += afsk_formats[portapack::persistent_memory::afsk_format()].shortname;
text_recap.set(final_str);
}
void LCRView::update_progress() {
@ -212,7 +152,7 @@ void LCRView::update_progress() {
strcat(str, " ");
strcat(str, to_string_dec_uint(scan_index + 1).c_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);
progress.set_value(scan_progress);
} else {
@ -235,7 +175,7 @@ void LCRView::on_txdone(int n) {
}
} else {
// Done transmitting
if ((tx_mode == SCAN) && (scan_index < (LCR_SCAN_COUNT - 1))) {
if ((tx_mode == SCAN) && (scan_index < (scan_count - 1))) {
transmitter_model.disable();
if (abort_scan) {
// Kill scan process
@ -250,7 +190,7 @@ void LCRView::on_txdone(int n) {
} else {
// Next address
scan_index++;
strcpy(rgsb, RGSB_list[scan_index]);
strcpy(rgsb, &scan_list[options_scanlist.selected_index()].addresses[scan_index * 5]);
scan_progress++;
repeat_index = 1;
update_progress();
@ -267,7 +207,7 @@ void LCRView::on_txdone(int n) {
}
void LCRView::start_tx(const bool scan) {
bool afsk_alt_format;
uint8_t afsk_format;
uint8_t afsk_repeats;
afsk_repeats = portapack::persistent_memory::afsk_repeats();
@ -275,11 +215,12 @@ void LCRView::start_tx(const bool scan) {
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, RGSB_list[0]);
progress.set_max(LCR_SCAN_COUNT * afsk_repeats);
strcpy(rgsb, &scan_list[options_scanlist.selected_index()].addresses[0]);
progress.set_max(scan_count * afsk_repeats);
update_progress();
}
} else {
@ -291,10 +232,21 @@ void LCRView::start_tx(const bool scan) {
generate_message();
if (portapack::persistent_memory::afsk_config() & 8)
afsk_alt_format = true;
else
afsk_alt_format = false;
switch (portapack::persistent_memory::afsk_format()) {
case 0:
case 1:
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_baseband_configuration({
@ -311,11 +263,11 @@ void LCRView::start_tx(const bool scan) {
baseband::set_afsk_data(
lcr_message_data,
228000 / portapack::persistent_memory::afsk_bitrate(),
portapack::persistent_memory::afsk_mark_freq() * (0x40000 * 256) / 2280,
portapack::persistent_memory::afsk_space_freq() * (0x40000 * 256) / 2280,
portapack::persistent_memory::afsk_mark_freq() * (0x40000 * 256) / (228000 / 25),
portapack::persistent_memory::afsk_space_freq() * (0x40000 * 256) / (228000 / 25),
afsk_repeats,
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;
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({ {
&text_recap,
@ -342,6 +291,8 @@ LCRView::LCRView(NavigationView& nav) {
&progress,
&button_lcrdebug,
&button_transmit,
&text_scanlist,
&options_scanlist,
&button_scan,
&button_clear
} });

View File

@ -28,8 +28,6 @@
namespace ui {
#define LCR_SCAN_COUNT 36
class LCRView : public View {
public:
LCRView(NavigationView& nav);
@ -41,16 +39,17 @@ public:
std::string title() const override { return "LCR transmit"; };
private:
enum tx_modes {
IDLE = 0,
SINGLE,
SCAN
struct scan_list_t {
uint8_t count;
const char * addresses;
};
// afsk_config()
tx_modes tx_mode = IDLE;
bool abort_scan = false;
double scan_progress;
const char RGSB_list[LCR_SCAN_COUNT][5] = {
scan_list_t scan_list[2] = {
{ 36, &RGSB_list_Lille[0][0] },
{ 23, &RGSB_list_Reims[0][0] }
};
const char RGSB_list_Lille[36][5] = {
"AI10", "AI20", "AI30", "AI40",
"AI50", "AI60", "AI70", "AJ10",
"AJ20", "AJ30", "AJ40", "AJ50",
@ -62,14 +61,35 @@ private:
"EbM0", "EbN0", "EbO0", "EbP0",
"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_data[512];
char checksum = 0;
rf::Frequency f;
uint8_t repeat_index;
unsigned int scan_index;
void generate_message();
void update_progress();
@ -79,7 +99,7 @@ private:
radio::Configuration lcr_radio_config = {
0,
2280000, // ?
2280000,
2500000, // ?
rf::Direction::Transmit,
true,
@ -91,17 +111,6 @@ private:
// 2: 94 ?
// 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 {
.font = font::fixed_8x16,
.background = Color::green(),
@ -128,7 +137,8 @@ private:
{
{ "EC:Auto", 0 },
{ "EC:Jour", 1 },
{ "EC:Nuit", 2 }
{ "EC:Nuit", 2 },
{ "EC:S ? ", 3 }
}
};
@ -146,6 +156,11 @@ private:
"DEBUG"
};
Button button_clear {
{ 174, 64, 50, 9 * 16 },
"CLEAR"
};
Text text_status {
{ 16, 224, 128, 16 },
"Ready"
@ -158,13 +173,21 @@ private:
{ 16, 270, 64, 32 },
"TX"
};
Button button_scan {
{ 88, 270, 64, 32 },
"SCAN"
Text text_scanlist {
{ 88, 268, 80, 16 },
"Scan list:"
};
Button button_clear {
{ 160, 270, 64, 32 },
"CLEAR"
OptionsField options_scanlist {
{ 88, 284 },
6,
{
{ "Lille ", 0 },
{ "Reims ", 1 }
}
};
Button button_scan {
{ 168, 270, 56, 32 },
"SCAN"
};
MessageHandlerRegistration message_handler_tx_done {

View File

@ -87,10 +87,7 @@ MenuView::MenuView() {
}
MenuView::~MenuView() {
/* TODO: Double-check this */
for (auto child : children_) {
delete child;
}
time::signal_tick_second -= signal_token_tick_second;
}
void MenuView::on_tick_second() {

View File

@ -257,10 +257,10 @@ SetUIView::SetUIView(NavigationView& nav) {
}
void SetUIView::focus() {
button_ok.focus();
checkbox_showsplash.focus();
}
void ModInfoView::on_show() {
/*void ModInfoView::on_show() {
if (modules_nb) update_infos(0);
}
@ -436,12 +436,12 @@ void ModInfoView::focus() {
option_modules.focus();
else
button_ok.focus();
}
}*/
SetupMenuView::SetupMenuView(NavigationView& nav) {
add_items<7>({ {
add_items<6>({ {
{ "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>(); } },
{ "Frequency correction", ui::Color::white(), [&nav](){ nav.push<SetFrequencyCorrectionView>(); } },
{ "Antenna Bias Voltage", ui::Color::white(), [&nav](){ nav.push<AntennaBiasSetupView>(); } },

View File

@ -308,7 +308,7 @@ private:
};
};
class ModInfoView : public View {
/*class ModInfoView : public View {
public:
ModInfoView(NavigationView& nav);
void focus() override;
@ -376,7 +376,7 @@ private:
{ 4 * 8, 272, 64, 24 },
"Ok"
};
};
};*/
class SetupMenuView : public MenuView {
public:

View File

@ -29,22 +29,24 @@
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;
for (size_t i = 0; i<buffer.count; i++) {
// Tone generation at 2280000/10 = 228kHz
if (s >= (10 - 1)) {
s = 0;
// Tone synthesis at 2.28M/10 = 228kHz
if (!s) {
s = 10 - 1;
if (sample_count >= afsk_samples_per_bit) {
if (configured == true) {
if (configured) {
cur_byte = message_data[byte_pos];
ext_byte = message_data[byte_pos + 1];
if (!(cur_byte | ext_byte)) {
// End of data
if (repeat_counter < afsk_repeat) {
// Repeat
bit_pos = 0;
byte_pos = 0;
cur_byte = message_data[0];
@ -53,36 +55,33 @@ void AFSKProcessor::execute(const buffer_c8_t& buffer) {
shared_memory.application_queue.push(message);
repeat_counter++;
} else {
message.n = 0;
shared_memory.application_queue.push(message);
// Stop
cur_byte = 0;
ext_byte = 0;
message.n = 0;
shared_memory.application_queue.push(message);
configured = false;
}
}
}
if (!afsk_alt_format) {
if (afsk_format == 0) {
// 0bbbbbbbp1
// Start, 7-bit data, parity, stop
gbyte = 0;
gbyte = cur_byte << 1;
gbyte |= 1;
} else {
gbyte = (cur_byte << 1) | 1;
} else if (afsk_format == 1) {
// 0bbbbbbbbp
// Start, 8-bit data, parity
gbyte = 0;
gbyte = cur_byte << 1;
gbyte |= (ext_byte & 1);
gbyte = (cur_byte << 1) | (ext_byte & 1);
}
cur_bit = (gbyte >> (9 - bit_pos)) & 1;
if (bit_pos == 9) {
if (bit_pos >= 9) {
bit_pos = 0;
if (!afsk_alt_format)
if (afsk_format == 0)
byte_pos++;
else
else if (afsk_format == 1)
byte_pos += 2;
} else {
bit_pos++;
@ -97,10 +96,10 @@ void AFSKProcessor::execute(const buffer_c8_t& buffer) {
else
tone_phase += afsk_phase_inc_space;
} else {
s++;
s--;
}
tone_sample = (sine_table_i8[(tone_phase & 0x03FC0000)>>18]);
tone_sample = (sine_table_i8[(tone_phase & 0x03FC0000) >> 18]);
// FM
// 1<<18 = 262144
@ -108,17 +107,18 @@ void AFSKProcessor::execute(const buffer_c8_t& buffer) {
frq = tone_sample * afsk_bw;
phase = (phase + frq);
sphase = phase + (64<<18);
sphase = phase + (64 << 18);
re = (sine_table_i8[(sphase & 0x03FC0000)>>18]);
im = (sine_table_i8[(phase & 0x03FC0000)>>18]);
re = (sine_table_i8[(sphase & 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) {
const auto message = *reinterpret_cast<const AFSKConfigureMessage*>(p);
if (message.id == Message::ID::AFSKConfigure) {
memcpy(message_data, message.message_data, 512);
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_repeat = message.afsk_repeat - 1;
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;
repeat_counter = 0;
bit_pos = 0;

View File

@ -42,12 +42,12 @@ private:
uint32_t afsk_phase_inc_space;
uint8_t afsk_repeat;
uint32_t afsk_bw;
bool afsk_alt_format;
uint8_t afsk_format;
char message_data[512];
uint8_t repeat_counter = 0;
int8_t re, im;
uint8_t s;
uint8_t s = 0;
uint8_t bit_pos = 0;
uint16_t byte_pos = 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

View File

@ -530,14 +530,14 @@ public:
const uint32_t afsk_phase_inc_space,
const uint8_t afsk_repeat,
const uint32_t afsk_bw,
const bool afsk_alt_format
const uint8_t afsk_format
) : Message { ID::AFSKConfigure },
afsk_samples_per_bit(afsk_samples_per_bit),
afsk_phase_inc_mark(afsk_phase_inc_mark),
afsk_phase_inc_space(afsk_phase_inc_space),
afsk_repeat(afsk_repeat),
afsk_bw(afsk_bw),
afsk_alt_format(afsk_alt_format)
afsk_format(afsk_format)
{
memcpy(message_data, data, 512);
}
@ -547,7 +547,7 @@ public:
uint32_t afsk_phase_inc_space;
uint8_t afsk_repeat;
uint32_t afsk_bw;
bool afsk_alt_format;
uint8_t afsk_format;
char message_data[512];
};

View File

@ -36,16 +36,16 @@ using portapack::memory::map::backup_ram;
namespace portapack {
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>;
constexpr ppb_range_t ppb_range { -99000, 99000 };
constexpr ppb_t ppb_reset_value { 0 };
using afsk_freq_range_t = range_t<int32_t>;
constexpr afsk_freq_range_t afsk_freq_range { 1, 60 };
constexpr int32_t afsk_mark_reset_value { 12 };
constexpr int32_t afsk_space_reset_value { 22 };
constexpr afsk_freq_range_t afsk_freq_range { 1, 400 };
constexpr int32_t afsk_mark_reset_value { 48 };
constexpr int32_t afsk_space_reset_value { 88 };
using afsk_bitrate_range_t = range_t<int32_t>;
constexpr afsk_bitrate_range_t afsk_bitrate_range { 600, 9600 };
@ -63,7 +63,7 @@ struct data_t {
// AFSK modem
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_bw;
uint32_t afsk_config;
@ -139,8 +139,12 @@ uint32_t afsk_config() {
return data->afsk_config;
}
uint8_t afsk_format() {
return ((data->afsk_config >> 16) & 0xFF);
}
uint8_t afsk_repeats() {
return (data->afsk_config >> 8);
return (data->afsk_config >> 24);
}
void set_afsk_config(const uint32_t new_value) {

View File

@ -47,6 +47,7 @@ int32_t afsk_bitrate();
void set_afsk_bitrate(const int32_t new_value);
uint32_t afsk_config();
uint8_t afsk_format();
uint8_t afsk_repeats();
void set_afsk_config(const uint32_t new_value);

Binary file not shown.