Simplified LCR code a bit

Split modem into modem and serializer
Frequency string formatter
This commit is contained in:
furrtek 2017-04-24 18:15:57 +01:00
parent 90feadd9f5
commit 8c680ff893
18 changed files with 198 additions and 125 deletions

View File

@ -140,6 +140,7 @@ set(CPPSRC
protocols/dcs.cpp
protocols/lcr.cpp
protocols/rds.cpp
serializer.cpp
modems.cpp
audio.cpp
${COMMON}/bch_code.cpp
@ -154,7 +155,7 @@ set(CPPSRC
${COMMON}/ui_focus.cpp
ui_about.cpp
ui_adsbtx.cpp
ui_afsksetup.cpp
ui_modemsetup.cpp
ui_alphanum.cpp
ui_audio.cpp
ui_mictx.cpp

View File

@ -24,7 +24,6 @@
// Gimp image > indexed colors (16), then "xxd -i *.bmp"
//BUG: Replay freezes when SD card not present
//TODO: CTCSS detector
//BUG: RDS doesn't stop baseband when stopping tx ?
//BUG: Check AFSK transmit end, skips last bits ?

View File

@ -21,6 +21,7 @@
*/
#include "modems.hpp"
#include "serializer.hpp"
#include "portapack_persistent_memory.hpp"
@ -28,19 +29,6 @@ using namespace portapack;
namespace modems {
uint8_t symbol_count() {
serial_format_t serial_format;
uint8_t count;
serial_format = persistent_memory::serial_format();
count = 1 + serial_format.data_bits; // Start
if (serial_format.parity) count++;
count += serial_format.stop_bits;
return count;
};
void generate_data(const std::string& in_message, uint16_t * out_data) {
serial_format_t serial_format;
uint8_t parity_init, parity, data_bits, bits, bit, cur_byte;
@ -58,6 +46,7 @@ void generate_data(const std::string& in_message, uint16_t * out_data) {
for (bytes = 0; bytes < in_message.length(); bytes++) {
parity = parity_init;
cur_byte = in_message[bytes];
bit = 0;
if (serial_format.bit_order == MSB_FIRST) {
ordered_word = cur_byte;

View File

@ -31,26 +31,6 @@ namespace modems {
#define MODEM_DEF_COUNT 7
enum parity_enum : uint8_t {
NONE = 0,
EVEN = 1,
ODD = 2
};
enum order_enum : uint8_t {
MSB_FIRST = 0,
LSB_FIRST = 1
};
struct serial_format_t {
uint8_t data_bits;
parity_enum parity;
uint8_t stop_bits;
order_enum bit_order;
};
uint8_t symbol_count();
enum modulation_enum {
AFSK = 0,
FSK,
@ -74,11 +54,6 @@ const modem_def_t modem_defs[MODEM_DEF_COUNT] = {
{ "V23 M2", AFSK, 1300, 2100, 1200 },
{ "RTTY US", SSB, 2295, 2125, 45 },
{ "RTTY EU", SSB, 2125, 1955, 45 }
/*{ "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 }*/
};
void generate_data(const std::string& in_message, uint16_t * out_data);

View File

@ -29,7 +29,7 @@ std::string generate_message(std::string rgsb, std::vector<std::string> litteral
const std::string ec_lut[4] = { "A", "J", "N", "S" }; // Eclairage (Auto, Jour, Nuit)
char eom[3] = { 3, 0, 0 }; // EOM and space for checksum
uint8_t i;
std::string lcr_message { 127, 127, 127, 127, 127, 127, 127, 15 }; // Modem sync and SOM
std::string lcr_message { 127, 127, 127, 127, 127, 127, 127, 5 }; // 5/15 ? Modem sync and SOM
char checksum = 0;
// Pad litterals to 7 chars (not required ?)

View File

@ -0,0 +1,55 @@
/*
* 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 "serializer.hpp"
#include "portapack_persistent_memory.hpp"
using namespace portapack;
namespace serializer {
/* Raw: 00110110100111
* NRZ-L: 00110110100111
* NRZ-M: 00100100111010
* NRZ-S: 10001110010000
* RZ: 00 00 10 10 00 10 10 00 10 00 00 10 10 10
* Bi-L: 01 01 10 10 01 10 10 01 10 01 01 10 10 10
* Bi-M: 00 11 01 01 00 10 10 11 01 00 11 01 01 01
* Bi-S: 01 01 00 11 01 00 11 01 00 10 10 11 00 11
* Diff M.: ...
*/
uint8_t symbol_count() {
serial_format_t serial_format;
uint8_t count;
serial_format = persistent_memory::serial_format();
count = 1 + serial_format.data_bits; // Start
if (serial_format.parity) count++;
count += serial_format.stop_bits;
return count;
};
} /* namespace serializer */

View File

@ -0,0 +1,59 @@
/*
* 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 __SERIALIZER_H__
#define __SERIALIZER_H__
namespace serializer {
uint8_t symbol_count();
enum parity_enum : uint8_t {
NONE = 0,
EVEN = 1,
ODD = 2
};
enum order_enum : uint8_t {
MSB_FIRST = 0,
LSB_FIRST = 1
};
struct serial_format_t {
uint8_t data_bits;
parity_enum parity;
uint8_t stop_bits;
order_enum bit_order;
};
/*{ "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 }*/
} /* namespace serializer */
#endif/*__SERIALIZER_H__*/

View File

@ -112,6 +112,13 @@ std::string to_string_dec_int(
return q;
}
std::string to_string_short_freq(const uint64_t f, const int32_t l) {
auto final_str = to_string_dec_int(f / 1000000, 4) + ".";
final_str += to_string_dec_int((f / 100) % 10000, l, '0');
return final_str;
}
static void to_string_hex_internal(char* p, const uint64_t n, const int32_t l) {
const uint32_t d = n & 0xf;
p[l] = (d > 9) ? (d + 55) : (d + 48);

View File

@ -35,6 +35,8 @@ std::string to_string_dec_uint(const uint32_t n, const int32_t l = 0, const char
std::string to_string_dec_int(const int32_t n, const int32_t l = 0, const char fill = 0);
std::string to_string_hex(const uint64_t n, const int32_t l = 0);
std::string to_string_short_freq(const uint64_t f, const int32_t l = 4);
std::string to_string_datetime(const rtc::RTC& value);
std::string to_string_time(const rtc::RTC& value);
std::string to_string_timestamp(const rtc::RTC& value);

View File

@ -281,7 +281,7 @@ DebugMenuView::DebugMenuView(NavigationView& nav) {
on_left = [&nav](){ nav.pop(); };
}
DebugLCRView::DebugLCRView(NavigationView& nav, std::string lcr_string) {
/*DebugLCRView::DebugLCRView(NavigationView& nav, std::string lcr_string) {
std::string debug_text;
@ -310,6 +310,6 @@ DebugLCRView::DebugLCRView(NavigationView& nav, std::string lcr_string) {
void DebugLCRView::focus() {
button_exit.focus();
}
}*/
} /* namespace ui */

View File

@ -208,7 +208,7 @@ private:
};
};
class DebugLCRView : public View {
/*class DebugLCRView : public View {
public:
DebugLCRView(NavigationView& nav, std::string lcrstring);
@ -225,7 +225,7 @@ private:
{ 72, 264, 96, 32 },
"Exit"
};
};
};*/
class DebugPeripheralsMenuView : public MenuView {
public:

View File

@ -21,8 +21,7 @@
*/
#include "ui_lcr.hpp"
#include "ui_afsksetup.hpp"
#include "ui_debug.hpp"
#include "ui_modemsetup.hpp"
#include "modems.hpp"
#include "lcr.hpp"
@ -35,7 +34,6 @@
#include <stdio.h>
using namespace portapack;
using namespace modems;
namespace ui {
@ -74,8 +72,8 @@ void LCRView::paint(Painter& painter) {
button_setrgsb.set_text(rgsb);
// Recap: freq @ bps
final_str = to_string_dec_int(persistent_memory::tuned_frequency() / 1000, 6);
// Recap: frequency @ baudrate
final_str = to_string_short_freq(persistent_memory::tuned_frequency(), 3);
final_str += '@';
final_str += to_string_dec_int(persistent_memory::modem_baudrate(), 4);
final_str += "bps ";
@ -99,13 +97,13 @@ void LCRView::update_progress() {
text_status.set(" "); // Clear
progress_str = to_string_dec_uint(repeat_index) + "/" + to_string_dec_uint(persistent_memory::modem_repeat());
progress_str += " " + to_string_dec_uint(scan_index + 1) + "/" + to_string_dec_uint(scan_count);
if (tx_mode == SINGLE) {
progress_str = to_string_dec_uint(repeat_index) + "/" + to_string_dec_uint(persistent_memory::modem_repeat());
text_status.set(progress_str);
progress.set_value(repeat_index);
} else if (tx_mode == SCAN) {
progress_str = to_string_dec_uint(repeat_index) + "/" + to_string_dec_uint(persistent_memory::modem_repeat());
progress_str += " " + to_string_dec_uint(scan_index + 1) + "/" + to_string_dec_uint(scan_count);
text_status.set(progress_str);
progress.set_value(scan_progress);
} else {
@ -115,34 +113,30 @@ void LCRView::update_progress() {
}
void LCRView::on_txdone(int n) {
if (n > 0) {
if (n) {
// Repeating...
repeat_index = n + 1;
if (tx_mode == SCAN) {
if (tx_mode == SCAN)
scan_progress++;
update_progress();
} else {
update_progress();
}
} else {
// Done transmitting
if ((tx_mode == SCAN) && (scan_index < (scan_count - 1))) {
transmitter_model.disable();
// Next address
scan_index++;
rgsb = scan_list[options_scanlist.selected_index()].addresses[scan_index];
scan_progress++;
repeat_index = 1;
update_progress();
start_tx(true);
} else {
transmitter_model.disable();
tx_mode = IDLE;
update_progress();
button_scan.set_style(&style_val);
button_scan.set_text("SCAN");
}
}
}
update_progress();
}
void LCRView::start_tx(const bool scan) {
@ -157,13 +151,15 @@ void LCRView::start_tx(const bool scan) {
scan_progress = 1;
repeat_index = 1;
tx_mode = SCAN;
rgsb = scan_list[options_scanlist.selected_index()].addresses[0];
progress.set_max(scan_count * repeats);
update_progress();
}
rgsb = scan_list[options_scanlist.selected_index()].addresses[scan_index];
} else {
tx_mode = SINGLE;
repeat_index = 1;
scan_count = 1;
scan_index = 0;
progress.set_max(repeats);
update_progress();
}
@ -177,7 +173,7 @@ void LCRView::start_tx(const bool scan) {
transmitter_model.set_baseband_bandwidth(1750000);
transmitter_model.enable();
memcpy(shared_memory.bb_data.data, lcr_message_data, 300);
memcpy(shared_memory.bb_data.data, lcr_message_data, sizeof(lcr_message_data));
baseband::set_afsk_data(
1536000 / persistent_memory::modem_baudrate(),
@ -185,7 +181,7 @@ void LCRView::start_tx(const bool scan) {
persistent_memory::afsk_space_freq(),
repeats,
persistent_memory::modem_bw(),
modems::symbol_count()
serializer::symbol_count()
);
}
@ -201,15 +197,14 @@ LCRView::LCRView(NavigationView& nav) {
rgsb = scan_list[0].addresses[0];
add_children({
&labels,
&text_recap,
&options_ec,
&button_setrgsb,
&button_txsetup,
&text_status,
&progress,
&button_lcrdebug,
&button_transmit,
&text_scanlist,
&options_scanlist,
&button_scan,
&button_clear
@ -222,13 +217,12 @@ LCRView::LCRView(NavigationView& nav) {
};
size_t n = 0;
for(auto& button : buttons) {
for (auto& button : buttons) {
button.on_select = button_setam_fn;
button.id = n;
label = "AM " + to_string_dec_uint(n + 1, 1);;
button.set_text(label);
button.set_text("AM " + to_string_dec_uint(n + 1, 1));
button.set_parent_rect({
static_cast<Coord>(48),
static_cast<Coord>(40),
static_cast<Coord>(n * 32 + 64),
48, 24
});
@ -237,9 +231,9 @@ LCRView::LCRView(NavigationView& nav) {
}
n = 0;
for(auto& checkbox : checkboxes) {
for (auto& checkbox : checkboxes) {
checkbox.set_parent_rect({
static_cast<Coord>(16),
static_cast<Coord>(8),
static_cast<Coord>(n * 32 + 64),
48, 24
});
@ -249,11 +243,11 @@ LCRView::LCRView(NavigationView& nav) {
}
n = 0;
for(auto& rectangle : rectangles) {
for (auto& rectangle : rectangles) {
rectangle.set_parent_rect({
static_cast<Coord>(104 - 2),
static_cast<Coord>(98),
static_cast<Coord>(n * 32 + 68 - 2),
56 + 4, 16 + 4
64, 20
});
rectangle.set_color(ui::Color::grey());
rectangle.set_outline(true);
@ -273,15 +267,12 @@ LCRView::LCRView(NavigationView& nav) {
};
button_txsetup.on_select = [&nav](Button&) {
nav.push<AFSKSetupView>();
};
button_lcrdebug.on_select = [this, &nav](Button&) {
nav.push<DebugLCRView>(lcr::generate_message(rgsb, parse_litterals(), options_ec.selected_index()));
nav.push<ModemSetupView>();
};
button_transmit.on_select = [this](Button&) {
if (tx_mode == IDLE) start_tx(false);
if (tx_mode == IDLE)
start_tx(false);
};
button_scan.on_select = [this](Button&) {
@ -303,7 +294,7 @@ LCRView::LCRView(NavigationView& nav) {
};
button_clear.on_select = [this, &nav](Button&) {
uint8_t n;
size_t n;
if (tx_mode == IDLE) {
options_ec.set_selected_index(0); // Auto

View File

@ -37,7 +37,7 @@ public:
void paint(Painter& painter) override;
std::string title() const override { return "LCR transmit"; };
private:
struct scan_list_t {
uint8_t count;
@ -80,7 +80,7 @@ private:
tx_modes tx_mode = IDLE;
uint8_t scan_count { 0 }, scan_index { 0 };
double scan_progress { 0 };
uint32_t scan_progress { 0 };
std::string litteral[5] { " " };
std::string rgsb { " " };
char lcr_message[512];
@ -105,61 +105,58 @@ private:
.foreground = Color::red(),
};
Labels labels {
{ { 2 * 8, 4 }, "EC:", Color::light_grey() },
{ { 88, 268 }, "Scan list:", Color::light_grey() }
};
std::array<Button, 5> buttons { };
std::array<Checkbox, 5> checkboxes { };
std::array<Rectangle, 5> rectangles { };
Text text_recap {
{ 8, 6, 18 * 8, 16 },
{ 12 * 8, 4, 18 * 8, 16 },
"-"
};
OptionsField options_ec {
{ 21 * 8, 6 },
7,
{ 40, 4 },
4,
{
{ "EC:Auto", 0 },
{ "EC:Jour", 1 },
{ "EC:Nuit", 2 },
{ "EC:S ? ", 3 }
{ "Auto", 0 },
{ "Jour", 1 },
{ "Nuit", 2 },
{ "S ? ", 3 }
}
};
Button button_setrgsb {
{ 16, 24, 96, 32 },
"Set RGSB"
{ 8, 24, 80, 32 },
"RGSB"
};
Button button_txsetup {
{ 128, 24, 96, 32 },
"TX setup"
};
Button button_lcrdebug {
{ 168, 216, 56, 24 },
"DEBUG"
{ 13 * 8, 24, 128, 32 },
"Modem setup"
};
Button button_clear {
{ 174, 64, 50, 9 * 16 },
{ 174, 64, 58, 19 * 8 },
"CLEAR"
};
Text text_status {
{ 16, 224, 128, 16 },
{ 16, 222, 128, 16 },
"Ready"
};
ProgressBar progress {
{ 16, 224 + 20, 208, 16 }
{ 16, 242, 208, 16 }
};
Button button_transmit {
{ 16, 270, 64, 32 },
{ 8, 270, 64, 32 },
"TX"
};
Text text_scanlist {
{ 88, 268, 80, 16 },
"Scan list:"
};
OptionsField options_scanlist {
{ 88, 284 },
6,
@ -168,8 +165,9 @@ private:
{ "Reims ", 1 }
}
};
Button button_scan {
{ 168, 270, 56, 32 },
{ 166, 270, 64, 32 },
"SCAN"
};

View File

@ -20,7 +20,7 @@
* Boston, MA 02110-1301, USA.
*/
#include "ui_afsksetup.hpp"
#include "ui_modemsetup.hpp"
#include "ui_receiver.hpp"
#include "portapack.hpp"
@ -37,22 +37,17 @@ using namespace modems;
namespace ui {
void AFSKSetupView::focus() {
void ModemSetupView::focus() {
button_setfreq.focus();
}
void AFSKSetupView::update_freq(rf::Frequency f) {
std::string final_str;
void ModemSetupView::update_freq(rf::Frequency f) {
persistent_memory::set_tuned_frequency(f);
final_str = to_string_dec_int(f / 1000000, 4) + ".";
final_str += to_string_dec_int((f / 100) % 10000, 4, '0');
button_setfreq.set_text(final_str);
button_setfreq.set_text(to_string_short_freq(f, 4));
}
AFSKSetupView::AFSKSetupView(
ModemSetupView::ModemSetupView(
NavigationView& nav
)
{

View File

@ -21,6 +21,7 @@
*/
#include "modems.hpp"
#include "serializer.hpp"
#include "ui.hpp"
#include "ui_widget.hpp"
@ -28,13 +29,13 @@
namespace ui {
class AFSKSetupView : public View {
class ModemSetupView : public View {
public:
AFSKSetupView(NavigationView& nav);
ModemSetupView(NavigationView& nav);
void focus() override;
std::string title() const override { return "AFSK setup"; };
std::string title() const override { return "Modem setup"; };
private:
void update_freq(rf::Frequency f);

View File

@ -23,7 +23,6 @@
#include "portapack_persistent_memory.hpp"
#include "portapack.hpp"
#include "hal.h"
#include "utility.hpp"

View File

@ -28,8 +28,10 @@
#include "rf_path.hpp"
#include "touch.hpp"
#include "modems.hpp"
#include "serializer.hpp"
using namespace modems;
using namespace serializer;
namespace portapack {
namespace persistent_memory {

Binary file not shown.