diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index ed48f7db0..1b144c283 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -138,8 +138,9 @@ set(CPPSRC audio.cpp adsb.cpp afsk.cpp - rds.cpp + bht.cpp ctcss.cpp + rds.cpp freqman.cpp ${COMMON}/lcd_ili9341.cpp ${COMMON}/ui.cpp diff --git a/firmware/application/Makefile b/firmware/application/Makefile index 1a7bcd33c..853f5ee11 100644 --- a/firmware/application/Makefile +++ b/firmware/application/Makefile @@ -2948,6 +2948,33 @@ baseband_cpld.cpp.s: cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/baseband_cpld.cpp.s .PHONY : baseband_cpld.cpp.s +bht.obj: bht.cpp.obj + +.PHONY : bht.obj + +# target to build an object file +bht.cpp.obj: + cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/bht.cpp.obj +.PHONY : bht.cpp.obj + +bht.i: bht.cpp.i + +.PHONY : bht.i + +# target to preprocess a source file +bht.cpp.i: + cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/bht.cpp.i +.PHONY : bht.cpp.i + +bht.s: bht.cpp.s + +.PHONY : bht.s + +# target to generate assembly for a file +bht.cpp.s: + cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/bht.cpp.s +.PHONY : bht.cpp.s + capture_app.obj: capture_app.cpp.obj .PHONY : capture_app.obj @@ -5376,6 +5403,9 @@ help: @echo "... baseband_cpld.obj" @echo "... baseband_cpld.i" @echo "... baseband_cpld.s" + @echo "... bht.obj" + @echo "... bht.i" + @echo "... bht.s" @echo "... capture_app.obj" @echo "... capture_app.i" @echo "... capture_app.s" diff --git a/firmware/application/bht.cpp b/firmware/application/bht.cpp new file mode 100644 index 000000000..5014903aa --- /dev/null +++ b/firmware/application/bht.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2015 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 "bht.hpp" + +#include "portapack.hpp" +#include "portapack_persistent_memory.hpp" + +#include +#include + +std::string gen_message_ep(uint8_t city_code, size_t family_code_ep, uint32_t relay_state_A, uint32_t relay_state_B) { + size_t c; + const encoder_def_t * um3750_def; + uint8_t bit[12]; + std::string ep_symbols; + char ook_bitstream[256]; + char ep_message[13] = { 0 }; + + // EP frame + // Repeated 2x 26 times + // Whole frame + space = 128ms, data only = 64ms + + um3750_def = &encoder_defs[8]; + + for (c = 0; c < 8; c++) + bit[c] = (city_code >> c) & 1; + + bit[8] = family_code_ep >> 1; + bit[9] = family_code_ep & 1; + bit[10] = 0; // R1 first + if (relay_state_A) + bit[11] = relay_state_A - 1; + else + bit[11] = 0; + + for (c = 0; c < 12; c++) + ep_message[c] = bit[c] + '0'; + + //text_message.set(ep_message); + + c = 0; + for (auto ch : um3750_def->word_format) { + if (ch == 'S') + ep_symbols += um3750_def->sync; + else + ep_symbols += um3750_def->bit_format[bit[c++]]; + } + + c = 0; + for (auto ch : ep_symbols) { + if (ch != '0') + ook_bitstream[c >> 3] |= (1 << (7 - (c & 7))); + c++; + } + + return ep_message; +} + +std::string gen_message_xy(size_t header_code_a, size_t header_code_b, size_t city_code, size_t family_code, + bool subfamily_wc, size_t subfamily_code, bool id_wc, size_t receiver_code, + size_t relay_state_A, size_t relay_state_B, size_t relay_state_C, size_t relay_state_D) { + size_t c; + uint8_t ccir_message[20]; + + // Xy CCIR frame + + // Header + ccir_message[0] = (header_code_a / 10); + ccir_message[1] = (header_code_a % 10); + ccir_message[2] = (header_code_b / 10); + ccir_message[3] = (header_code_b % 10); + + // Addresses + ccir_message[4] = (city_code / 10); + ccir_message[5] = (city_code % 10); + ccir_message[6] = family_code; + + if (subfamily_wc) + ccir_message[7] = 10; // Wildcard + else + ccir_message[7] = subfamily_code; + + if (id_wc) { + ccir_message[8] = 10; // Wildcard + ccir_message[9] = 10; // Wildcard + } else { + ccir_message[8] = (receiver_code / 10); + ccir_message[9] = (receiver_code % 10); + } + + ccir_message[10] = 11; // B + + // Relay states + ccir_message[11] = relay_state_A; + ccir_message[12] = relay_state_B; + ccir_message[13] = relay_state_C; + ccir_message[14] = relay_state_D; + + ccir_message[15] = 11; // B + + // End + for (c = 16; c < 20; c++) + ccir_message[c] = 0; + + // Replace repeats with E code + for (c = 1; c < 20; c++) + if (ccir_message[c] == ccir_message[c - 1]) ccir_message[c] = 14; + + // Copy for baseband + memcpy(shared_memory.bb_data.tones_data.message, ccir_message, 20); + + // Return as text + return ccir_to_ascii(ccir_message); +} + +std::string ccir_to_ascii(uint8_t * ccir) { + std::string ascii; + + for (size_t c = 0; c < 20; c++) { + if (ccir[c] > 9) + ascii += (char)(ccir[c] - 10 + 'A'); + else + ascii += (char)(ccir[c] + '0'); + } + + return ascii; +} diff --git a/firmware/application/bht.hpp b/firmware/application/bht.hpp new file mode 100644 index 000000000..17849b375 --- /dev/null +++ b/firmware/application/bht.hpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2015 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 "ui_widget.hpp" +#include "ui_navigation.hpp" + +#include "encoders.hpp" +#include "portapack.hpp" + +using namespace encoders; + +#define CCIR_TONE_LENGTH (153600-1) // 1536000*0.1 +#define CCIR_DELTA_COEF (43.691) // (65536*1024)/1536000 +#define CCIR_SILENCE (614400-1) // 400ms + +struct bht_city { + std::string name; + uint8_t freq_index; + bool recent; +}; + +const uint32_t ccir_deltas[16] = { + (uint32_t)(1981 * CCIR_DELTA_COEF), + (uint32_t)(1124 * CCIR_DELTA_COEF), + (uint32_t)(1197 * CCIR_DELTA_COEF), + (uint32_t)(1275 * CCIR_DELTA_COEF), + (uint32_t)(1358 * CCIR_DELTA_COEF), + (uint32_t)(1446 * CCIR_DELTA_COEF), + (uint32_t)(1540 * CCIR_DELTA_COEF), + (uint32_t)(1640 * CCIR_DELTA_COEF), + (uint32_t)(1747 * CCIR_DELTA_COEF), + (uint32_t)(1860 * CCIR_DELTA_COEF), + (uint32_t)(2400 * CCIR_DELTA_COEF), + (uint32_t)(930 * CCIR_DELTA_COEF), + (uint32_t)(2247 * CCIR_DELTA_COEF), + (uint32_t)(991 * CCIR_DELTA_COEF), + (uint32_t)(2110 * CCIR_DELTA_COEF), + (uint32_t)(1055 * CCIR_DELTA_COEF) +}; + +const rf::Frequency bht_freqs[7] = { 31325000, 31387500, 31437500, 31475000, 31687500, 31975000, 88000000 }; + +std::string gen_message_ep(uint8_t city_code, size_t family_code_ep, uint32_t relay_state_A, uint32_t relay_state_B); +std::string gen_message_xy(size_t header_code_a, size_t header_code_b, size_t city_code, size_t family_code, + bool subfamily_wc, size_t subfamily_code, bool id_wc, size_t receiver_code, + size_t relay_state_A, size_t relay_state_B, size_t relay_state_C, size_t relay_state_D); +std::string ccir_to_ascii(uint8_t * ccir); diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 24c7f2930..3045d4020 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -28,7 +28,6 @@ //TEST: Jammer //TEST: Frequency manager + save/load -//BUG: Xylos doesn't play last tone ? //TODO: Morse coder for foxhunts //TODO: Finish EPAR tx //TODO: Test dual tone in proc_tones and remove proc_dtmf_tx diff --git a/firmware/application/ui_bht_tx.cpp b/firmware/application/ui_bht_tx.cpp index 824bf28eb..9859ae198 100644 --- a/firmware/application/ui_bht_tx.cpp +++ b/firmware/application/ui_bht_tx.cpp @@ -22,7 +22,6 @@ #include "ui_bht_tx.hpp" -#include "portapack.hpp" #include "baseband_api.hpp" #include "portapack_persistent_memory.hpp" @@ -43,110 +42,27 @@ BHTView::~BHTView() { } void BHTView::generate_message() { - size_t c; - const encoder_def_t * um3750_def; - uint8_t bit[12]; - uint8_t city_code; - std::string ep_symbols; - char ook_bitstream[256]; - char ep_message[13] = { 0 }; - if (!_mode) { - // Xy CCIR frame - - // Header - ccir_message[0] = (header_code_a.value() / 10) + '0'; - ccir_message[1] = (header_code_a.value() % 10) + '0'; - ccir_message[2] = (header_code_b.value() / 10) + '0'; - ccir_message[3] = (header_code_b.value() % 10) + '0'; - - // Addresses - ccir_message[4] = (city_code_xy.value() / 10) + '0'; - ccir_message[5] = (city_code_xy.value() % 10) + '0'; - ccir_message[6] = family_code_xy.value() + '0'; - - if (!checkbox_wcsubfamily.value()) - ccir_message[7] = subfamily_code.value() + '0'; - else - ccir_message[7] = 'A'; // Wildcard - - if (!checkbox_wcid.value()) { - ccir_message[8] = (receiver_code.value() / 10) + '0'; - ccir_message[9] = (receiver_code.value() % 10) + '0'; - } else { - ccir_message[8] = 'A'; // Wildcard - ccir_message[9] = 'A'; // Wildcard - } - - ccir_message[10] = 'B'; - - // Relay states - for (c = 0; c < 4; c++) - ccir_message[c + 11] = relay_states[c].selected_index() + '0'; - - ccir_message[15] = 'B'; - - // End - for (c = 16; c < 20; c++) - ccir_message[c] = '0'; - - ccir_message[20] = 0; - - // Replace repeats with E code - for (c = 1; c < 20; c++) - if (ccir_message[c] == ccir_message[c - 1]) ccir_message[c] = 'E'; - - // Display as text - text_message.set(ccir_message); - - ascii_to_ccir(ccir_message); + text_message.set( + gen_message_xy(header_code_a.value(), header_code_b.value(), city_code_xy.value(), subfamily_code.value(), + checkbox_wcsubfamily.value(), subfamily_code.value(), checkbox_wcid.value(), receiver_code.value(), + relay_states[0].selected_index(), relay_states[1].selected_index(), + relay_states[2].selected_index(), relay_states[3].selected_index()) + ); } else { - // EP frame - // Repeated 2x 26 times - // Whole frame + space = 128ms, data only = 64ms - - um3750_def = &encoder_defs[8]; - - city_code = city_code_ep.value(); - - for (c = 0; c < 8; c++) - bit[c] = (city_code >> c) & 1; - - bit[8] = family_code_ep.selected_index_value() >> 1; - bit[9] = family_code_ep.selected_index_value() & 1; - bit[10] = 0; // R1 first - if (relay_states[0].selected_index()) - bit[11] = relay_states[0].selected_index() - 1; - else - bit[11] = 0; - - for (c = 0; c < 12; c++) - ep_message[c] = bit[c] + '0'; - - text_message.set(ep_message); - - c = 0; - for (auto ch : um3750_def->word_format) { - if (ch == 'S') - ep_symbols += um3750_def->sync; - else - ep_symbols += um3750_def->bit_format[bit[c++]]; - } - - c = 0; - for (auto ch : ep_symbols) { - if (ch != '0') - ook_bitstream[c >> 3] |= (1 << (7 - (c & 7))); - c++; - } + text_message.set( + gen_message_ep(city_code_ep.value(), family_code_ep.selected_index_value(), + relay_states[0].selected_index(), relay_states[1].selected_index()) + ); } } void BHTView::start_tx() { - if (speaker_enabled && !_mode) audio::headphone::set_volume(volume_t::decibel(90 - 99) + audio::headphone::volume_range().max); - + + generate_message(); + transmitter_model.set_tuning_frequency(bht_freqs[options_freq.selected_index()]); transmitter_model.set_baseband_configuration({ .mode = 0, @@ -159,25 +75,14 @@ void BHTView::start_tx() { transmitter_model.set_baseband_bandwidth(1750000); transmitter_model.enable(); - memcpy(shared_memory.bb_data.tones_data.message, ccir_message, 20); - + // Setup for Xy for (uint8_t c = 0; c < 16; c++) { shared_memory.bb_data.tones_data.tone_defs[c].delta = ccir_deltas[c]; shared_memory.bb_data.tones_data.tone_defs[c].duration = CCIR_TONE_LENGTH; } audio::set_rate(audio::Rate::Hz_24000); - baseband::set_tones_data(10000, CCIR_SILENCE, 20, false, checkbox_speaker.value()); -} - -// ASCII to frequency LUT index -void BHTView::ascii_to_ccir(char * ascii) { - for (size_t c = 0; c < 20; c++) { - if (ascii[c] > '9') - ascii[c] -= 0x37; - else - ascii[c] -= '0'; - } + baseband::set_tones_data(6000, CCIR_SILENCE, 20, false, checkbox_speaker.value()); } void BHTView::on_tx_progress(const int progress, const bool done) { @@ -248,11 +153,13 @@ BHTView::BHTView(NavigationView& nav) { &text_cligno } }); - options_mode.set_selected_index(0); // Xy + options_mode.set_selected_index(0); // Start up in Xy mode header_code_a.set_value(0); header_code_b.set_value(0); city_code_xy.set_value(18); + city_code_ep.set_value(220); family_code_xy.set_value(1); + family_code_ep.set_selected_index(2); subfamily_code.set_value(1); receiver_code.set_value(1); options_freq.set_selected_index(0); @@ -389,19 +296,13 @@ BHTView::BHTView(NavigationView& nav) { generate_message(); button_transmit.on_select = [this, &nav](Button&) { - if (tx_mode == IDLE) { - //auto modal_view = nav.push("TX", "TX ?", true); - //modal_view->on_choice = [this](bool choice) { - // if (choice) { - if (speaker_enabled && _mode) - audio::headphone::set_volume(volume_t::decibel(90 - 99) + audio::headphone::volume_range().max); - tx_mode = SINGLE; - button_transmit.set_style(&style_cancel); - button_transmit.set_text("Wait"); - generate_message(); - start_tx(); - // } - //}; + if ((tx_mode == IDLE) && (!_mode)) { // DEBUG + if (speaker_enabled && _mode) + audio::headphone::set_volume(volume_t::decibel(90 - 99) + audio::headphone::volume_range().max); + tx_mode = SINGLE; + button_transmit.set_style(&style_cancel); + button_transmit.set_text("Wait"); + start_tx(); } }; } diff --git a/firmware/application/ui_bht_tx.hpp b/firmware/application/ui_bht_tx.hpp index 226a94bf7..67a7eb570 100644 --- a/firmware/application/ui_bht_tx.hpp +++ b/firmware/application/ui_bht_tx.hpp @@ -29,20 +29,14 @@ #include "bmp_bulb_off.hpp" #include "bmp_bulb_ignore.hpp" +#include "bht.hpp" #include "message.hpp" #include "volume.hpp" #include "audio.hpp" #include "transmitter_model.hpp" #include "encoders.hpp" -//#include "receiver_model.hpp" #include "portapack.hpp" -using namespace encoders; - -#define CCIR_TONE_LENGTH (153600-1) // 1536000*0.1 -#define CCIR_DELTA_COEF (43.691) // (65536*1024)/1536000 -#define CCIR_SILENCE (614400-1) // 400ms - namespace ui { class BHTView : public View { @@ -55,25 +49,6 @@ public: std::string title() const override { return "BHT transmit"; }; private: - const uint32_t ccir_deltas[16] = { - (uint32_t)(1981 * CCIR_DELTA_COEF), - (uint32_t)(1124 * CCIR_DELTA_COEF), - (uint32_t)(1197 * CCIR_DELTA_COEF), - (uint32_t)(1275 * CCIR_DELTA_COEF), - (uint32_t)(1358 * CCIR_DELTA_COEF), - (uint32_t)(1446 * CCIR_DELTA_COEF), - (uint32_t)(1540 * CCIR_DELTA_COEF), - (uint32_t)(1640 * CCIR_DELTA_COEF), - (uint32_t)(1747 * CCIR_DELTA_COEF), - (uint32_t)(1860 * CCIR_DELTA_COEF), - (uint32_t)(2400 * CCIR_DELTA_COEF), - (uint32_t)(930 * CCIR_DELTA_COEF), - (uint32_t)(2247 * CCIR_DELTA_COEF), - (uint32_t)(991 * CCIR_DELTA_COEF), - (uint32_t)(2110 * CCIR_DELTA_COEF), - (uint32_t)(1055 * CCIR_DELTA_COEF) - }; - enum tx_modes { IDLE = 0, SINGLE, @@ -82,144 +57,9 @@ private: tx_modes tx_mode = IDLE; - struct bht_city { - std::string name; - uint8_t freq_index; - bool recent; - }; - - const bht_city bht_cities[122] = { - { "Aizenay", 0, false }, - { "Albertville", 3, false }, - { "Ales", 3, false }, - { "Artannes/Indre", 5, false }, - { "Avignon", 3, true }, - { "Azay-le-Rideau", 5, false }, - { "Baux Ste. Croix", 0, false }, - { "Beaugency", 4, false }, - { "Beaune", 4, false }, - { "Betton", 2, false }, - { "Bihorel", 0, true }, - { "Blanquefort", 4, true }, - { "Bobigny", 5, false }, - { "Bouffere", 4, true }, - { "Boulogne/Mer", 0, true }, - { "Bourg-en-Bresse", 3, false }, - { "Bourges", 0, false }, - { "Bouscat", 0, false }, - { "Carquefou", 5, false }, - { "St. Cast", 0, false }, - { "Caudebec/Caux", 3, true }, - { "Cercy-la-Tour", 5, false }, - { "Chamalieres", 5, false }, - { "St. Chamond", 5, false }, - { "Chapelle/Fgrtz", 2, false }, - { "Charite/Loire", 3, false }, - { "Charleville-Mzr", 1, false }, - { "Chilly Mazarin", 5, false }, - { "Clermont Frrd.", 5, false }, - { "Cluses", 2, false }, - { "Compiegne", 4, false }, - { "Coulanges/Nevers", 5, false }, - { "Cour Cheverny", 5, false }, - { "Cournon Auvergne", 5, false }, - { "Crolles", 5, true }, - { "Cublize", 4, true }, - { "Donges", 5, false }, - { "Emalleville", 0, false }, - { "Etrepagny", 0, false }, - { "Fecamp", 0, false }, - { "Ferriere", 0, false }, - { "Ferte Imbault", 5, false }, - { "Fontaine", 5, true }, - { "Forbach", 3, false }, - { "Fourchambault", 5, false }, - { "Fresnay/Sarthe", 3, false }, - { "St Fulgent", 5, true }, - { "Gaillac", 3, true }, - { "St. Georges/Grs", 0, false }, - { "St. Gervais/Frt", 5, false }, - { "Givors", 5, false }, - { "Guichen", 2, false }, - { "Guildo", 0, false }, - { "Guipry", 2, false }, - { "St Hilaire/Riez", 0, false }, - { "Hossegor/Capbrtn", 0, true }, - { "Houlbec-Cocherel", 0, false }, - { "Huisseau/Cosson", 5, false }, - { "Huningue", 5, false }, - { "Iffendic", 2, false }, - { "La Croix St. Ouen", 4, false }, - { "Langrune/Mer", 0, false }, - { "Le Neubourg", 2, true }, - { "St Leger/Vignes", 5, false }, - { "Levallois-Perret", 5, false }, - { "Lille", 5, true }, - { "Limoges", 5, false }, - { "Longueil-Anel", 4, false }, - { "Lormont", 5, true }, - { "Mantes-la-Jolie", 5, false }, - { "Martigues", 0, true }, - { "Marzy", 5, false }, - { "Ste. Memmie", 3, false }, - { "Menton", 0, true }, - { "Metz", 3, false }, - { "Mezidon Canon", 1, false }, - { "Millau", 5, false }, - { "Miniac-Morvan", 2, false }, - { "Mt. Pres Chambord", 5, false }, - { "Montesson", 5, false }, - { "Monts", 5, false }, - { "Noisy-le-Grand", 4, true }, - { "St Ouen", 5, false }, - { "Ozoir/Ferriere", 5, false }, - { "Pace", 2, false }, - { "Pelussin", 5, false }, - { "Petite Foret", 1, false }, - { "Plestin/Greves", 0, false }, - { "Pleumeur Bodou", 5, true }, - { "Pont Audemer", 0, false }, - { "Pontcharra", 5, true }, - { "Pontchateau", 5, false }, - { "Pressagny L'Org.", 0, false }, - { "Remiremont", 4, true }, - { "Ribeauville", 5, false }, - { "La Roche sur Yon", 0, false }, - { "Romorantin-Lant.", 5, false }, - { "Rueil Malmaison", 5, false }, - { "Sault-les-Rethel", 3, false }, - { "Selles-St-Denis", 5, false }, - { "Selles/Cher", 5, false }, - { "Sens", 4, false }, - { "Sezanne", 3, false }, - { "Sommesous", 3, false }, - { "Ste. Suzanne", 2, true }, - { "Talence", 3, true }, - { "Thionville", 3, false }, - { "Thonon-les-Bains", 2, false }, - { "Tours en Sologne", 5, true }, - { "Trelaze", 5, true }, - { "Trouville/Mer", 0, false }, - { "Tulle", 2, false }, - { "Ussel", 2, false }, - { "Valberg", 5, true }, - { "Valence", 5, false }, - { "Velizy", 5, false }, - { "Vesoul", 5, false }, - { "Ville S. la Ferte", 0, false }, - { "Villefrance/Saone", 5, false }, - { "Villers Cotterets", 3, false }, - { "Vitre", 2, false }, - { "Vitry-le-Francois", 4, true } - }; - - const rf::Frequency bht_freqs[7] = { 31325000, 31387500, 31437500, 31475000, 31687500, 31975000, 88000000 }; - - char ccir_message[21]; bool speaker_enabled = false; size_t _mode = 0; - void ascii_to_ccir(char * ascii); void start_tx(); void generate_message(); void on_tx_progress(const int progress, const bool done); diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index b15862055..fe036560c 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -278,7 +278,7 @@ ReceiverMenuView::ReceiverMenuView(NavigationView& nav) { add_items<6>({ { // { "AFSK", ui::Color::grey(), [&nav](){ nav.push(); } }, // AFSKRXView { "Audio", ui::Color::green(), [&nav](){ nav.push(); } }, - { "CCIR", ui::Color::grey(), [&nav](){ nav.push(); } }, // XylosRXView + { "CCIR", ui::Color::grey(), [&nav](){ nav.push(); } }, { "Nordic/BTLE", ui::Color::grey(), [&nav](){ nav.push(); } }, { "POCSAG 1200", ui::Color::cyan(), [&nav](){ nav.push(); } }, { "SIGFOX", ui::Color::grey(), [&nav](){ nav.push(); } }, // SIGFRXView @@ -292,7 +292,7 @@ ReceiverMenuView::ReceiverMenuView(NavigationView& nav) { TransmitterCodedMenuView::TransmitterCodedMenuView(NavigationView& nav) { add_items<7>({ { { "ADS-B Mode S", ui::Color::orange(), [&nav](){ nav.push(); } }, - { "BHT EPAR/Xylos", ui::Color::yellow(), [&nav](){ nav.push(); } }, + { "BHT Xy/EP", ui::Color::yellow(), [&nav](){ nav.push(); } }, { "Morse beacon", ui::Color::yellow(), [&nav](){ nav.push(); } }, { "Nuoptix DTMF timecode", ui::Color::green(), [&nav](){ nav.push(); } }, { "OOK remote encoders", ui::Color::green(), [&nav](){ nav.push(); } }, diff --git a/firmware/baseband/baseband_tones.img b/firmware/baseband/baseband_tones.img index d47fa5ad6..9a246ffb9 100644 Binary files a/firmware/baseband/baseband_tones.img and b/firmware/baseband/baseband_tones.img differ diff --git a/firmware/baseband/proc_tones.cpp b/firmware/baseband/proc_tones.cpp index a4d9e3c86..2f6d0db79 100644 --- a/firmware/baseband/proc_tones.cpp +++ b/firmware/baseband/proc_tones.cpp @@ -49,7 +49,7 @@ void TonesProcessor::execute(const buffer_c8_t& buffer) { im = 0; } else { if (!sample_count) { - digit = shared_memory.bb_data.tones_data.message[digit_pos++]; + digit = shared_memory.bb_data.tones_data.message[digit_pos]; if (digit_pos >= message_length) { configured = false; txdone_message.done = true; @@ -59,6 +59,8 @@ void TonesProcessor::execute(const buffer_c8_t& buffer) { shared_memory.application_queue.push(txdone_message); } + digit_pos++; + if ((digit >= 32) || (tone_deltas[digit] == 0)) { silence_count = shared_memory.bb_data.tones_data.silence; } else { diff --git a/firmware/portapack-h1-havoc.bin b/firmware/portapack-h1-havoc.bin index 865fa5d78..bf8ae5a4b 100644 Binary files a/firmware/portapack-h1-havoc.bin and b/firmware/portapack-h1-havoc.bin differ