diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index 5f21caab8..9afbbd462 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -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 diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 34774bf81..4f23d1899 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -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 ? diff --git a/firmware/application/modems.cpp b/firmware/application/modems.cpp index e8166b60b..29a047e42 100644 --- a/firmware/application/modems.cpp +++ b/firmware/application/modems.cpp @@ -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; diff --git a/firmware/application/modems.hpp b/firmware/application/modems.hpp index 129f4e398..7bb317476 100644 --- a/firmware/application/modems.hpp +++ b/firmware/application/modems.hpp @@ -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); diff --git a/firmware/application/protocols/lcr.cpp b/firmware/application/protocols/lcr.cpp index d7c4453bb..4fc886437 100644 --- a/firmware/application/protocols/lcr.cpp +++ b/firmware/application/protocols/lcr.cpp @@ -29,7 +29,7 @@ std::string generate_message(std::string rgsb, std::vector 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 ?) diff --git a/firmware/application/serializer.cpp b/firmware/application/serializer.cpp new file mode 100644 index 000000000..aac2b4cbf --- /dev/null +++ b/firmware/application/serializer.cpp @@ -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 */ diff --git a/firmware/application/serializer.hpp b/firmware/application/serializer.hpp new file mode 100644 index 000000000..dedfcad51 --- /dev/null +++ b/firmware/application/serializer.hpp @@ -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 +#include + +#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__*/ diff --git a/firmware/application/string_format.cpp b/firmware/application/string_format.cpp index 53a9d76f0..4dd6af51f 100644 --- a/firmware/application/string_format.cpp +++ b/firmware/application/string_format.cpp @@ -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); diff --git a/firmware/application/string_format.hpp b/firmware/application/string_format.hpp index 3fa962773..82db3f421 100644 --- a/firmware/application/string_format.hpp +++ b/firmware/application/string_format.hpp @@ -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); diff --git a/firmware/application/ui_debug.cpp b/firmware/application/ui_debug.cpp index a1a81d2a3..e2e8edc6c 100644 --- a/firmware/application/ui_debug.cpp +++ b/firmware/application/ui_debug.cpp @@ -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 */ diff --git a/firmware/application/ui_debug.hpp b/firmware/application/ui_debug.hpp index ae1fa31d6..2f6aa0340 100644 --- a/firmware/application/ui_debug.hpp +++ b/firmware/application/ui_debug.hpp @@ -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: diff --git a/firmware/application/ui_lcr.cpp b/firmware/application/ui_lcr.cpp index 07447885c..e3a56b7c4 100644 --- a/firmware/application/ui_lcr.cpp +++ b/firmware/application/ui_lcr.cpp @@ -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 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(48), + static_cast(40), static_cast(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(16), + static_cast(8), static_cast(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(104 - 2), + static_cast(98), static_cast(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(); - }; - - button_lcrdebug.on_select = [this, &nav](Button&) { - nav.push(lcr::generate_message(rgsb, parse_litterals(), options_ec.selected_index())); + nav.push(); }; 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 diff --git a/firmware/application/ui_lcr.hpp b/firmware/application/ui_lcr.hpp index 9862a8bf7..88eaf5e1d 100644 --- a/firmware/application/ui_lcr.hpp +++ b/firmware/application/ui_lcr.hpp @@ -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 buttons { }; std::array checkboxes { }; std::array 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" }; diff --git a/firmware/application/ui_afsksetup.cpp b/firmware/application/ui_modemsetup.cpp similarity index 92% rename from firmware/application/ui_afsksetup.cpp rename to firmware/application/ui_modemsetup.cpp index 7e7c1c540..76b2c2b1e 100644 --- a/firmware/application/ui_afsksetup.cpp +++ b/firmware/application/ui_modemsetup.cpp @@ -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 ) { diff --git a/firmware/application/ui_afsksetup.hpp b/firmware/application/ui_modemsetup.hpp similarity index 93% rename from firmware/application/ui_afsksetup.hpp rename to firmware/application/ui_modemsetup.hpp index 858f4f9ff..045cd92b7 100644 --- a/firmware/application/ui_afsksetup.hpp +++ b/firmware/application/ui_modemsetup.hpp @@ -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); diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index d2d7026bf..37360ac52 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -23,7 +23,6 @@ #include "portapack_persistent_memory.hpp" #include "portapack.hpp" - #include "hal.h" #include "utility.hpp" diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index ec1a9540a..d1ece441d 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -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 { diff --git a/firmware/portapack-h1-havoc.bin b/firmware/portapack-h1-havoc.bin index 7586fdcad..e934cc183 100644 Binary files a/firmware/portapack-h1-havoc.bin and b/firmware/portapack-h1-havoc.bin differ