diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index 18d1823b5..baa0072e9 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -138,6 +138,7 @@ set(CPPSRC adsb.cpp afsk.cpp rds.cpp + ctcss.cpp ${COMMON}/lcd_ili9341.cpp ${COMMON}/ui.cpp ${COMMON}/ui_text.cpp diff --git a/firmware/application/Makefile b/firmware/application/Makefile index aeac8d74f..1be1dcc29 100644 --- a/firmware/application/Makefile +++ b/firmware/application/Makefile @@ -2766,6 +2766,30 @@ cpld_update.cpp.s: cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/cpld_update.cpp.s .PHONY : cpld_update.cpp.s +ctcss.obj: ctcss.cpp.obj +.PHONY : ctcss.obj + +# target to build an object file +ctcss.cpp.obj: + cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ctcss.cpp.obj +.PHONY : ctcss.cpp.obj + +ctcss.i: ctcss.cpp.i +.PHONY : ctcss.i + +# target to preprocess a source file +ctcss.cpp.i: + cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ctcss.cpp.i +.PHONY : ctcss.cpp.i + +ctcss.s: ctcss.cpp.s +.PHONY : ctcss.s + +# target to generate assembly for a file +ctcss.cpp.s: + cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ctcss.cpp.s +.PHONY : ctcss.cpp.s + debounce.obj: debounce.cpp.obj .PHONY : debounce.obj @@ -4762,6 +4786,9 @@ help: @echo "... cpld_update.obj" @echo "... cpld_update.i" @echo "... cpld_update.s" + @echo "... ctcss.obj" + @echo "... ctcss.i" + @echo "... ctcss.s" @echo "... debounce.obj" @echo "... debounce.i" @echo "... debounce.s" diff --git a/firmware/application/ctcss.cpp b/firmware/application/ctcss.cpp new file mode 100644 index 000000000..760e2fe77 --- /dev/null +++ b/firmware/application/ctcss.cpp @@ -0,0 +1,76 @@ +/* + * 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 "ctcss.hpp" + +ctcss_tone ctcss_tones[CTCSS_TONES_NB] = { + { "XZ", 0, 67000 }, + { "WZ", 1, 69400 }, + { "XA", 39, 71900 }, + { "WA", 3, 74400 }, + { "XB", 4, 77000 }, + { "WB", 5, 79700 }, + { "YZ", 6, 82500 }, + { "YA", 7, 85400 }, + { "YB", 8, 88500 }, + { "ZZ", 9, 91500 }, + { "ZA", 10, 94800 }, + { "ZB", 11, 97400 }, + { "1Z", 12, 100000 }, + { "1A", 13, 103500 }, + { "1B", 14, 107200 }, + { "2Z", 15, 110900 }, + { "2Z", 16, 114800 }, + { "2B", 17, 118800 }, + { "3Z", 18, 123000 }, + { "3A", 19, 127300 }, + { "3B", 20, 131800 }, + { "4Z", 21, 136500 }, + { "4A", 22, 141300 }, + { "4B", 23, 146200 }, + { "5Z", 24, 151400 }, + { "5A", 25, 156700 }, + { "--", 40, 159800 }, + { "5B", 26, 162200 }, + { "--", 41, 165500 }, + { "6Z", 27, 167900 }, + { "--", 42, 171300 }, + { "6A", 28, 173800 }, + { "--", 43, 177300 }, + { "6B", 29, 179900 }, + { "--", 44, 183500 }, + { "7Z", 30, 186200 }, + { "--", 45, 189900 }, + { "7A", 31, 192800 }, + { "--", 46, 196600 }, + { "--", 47, 199500 }, + { "M1", 32, 203500 }, + { "8Z", 48, 206500 }, + { "M2", 33, 210700 }, + { "M3", 34, 218100 }, + { "M4", 35, 225700 }, + { "9Z", 49, 229100 }, + { "--", 36, 233600 }, + { "--", 37, 241800 }, + { "--", 38, 250300 }, + { "0Z", 50, 254100 } +}; diff --git a/firmware/application/ctcss.hpp b/firmware/application/ctcss.hpp new file mode 100644 index 000000000..67c9cb631 --- /dev/null +++ b/firmware/application/ctcss.hpp @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#ifndef __CTCSS_H_ +#define __CTCSS_H_ + +#include "ui.hpp" + +#define CTCSS_TONES_NB 50 + +struct ctcss_tone { + char PL_code[3]; + uint16_t num_code; + uint32_t frequency; // Hz * 1000 +}; + +extern ctcss_tone ctcss_tones[CTCSS_TONES_NB]; + +#endif/*__CTCSS_H_*/ diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 83976b52a..4951518ea 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -23,12 +23,11 @@ // Bitmaps generated with: // Gimp image > indexed colors (16), then "xxd -i *.bmp" -//TODO: CTCSS file/module +//TEST: RDS //TEST: Imperial in whipcalc //TEST: Numbers //TEST: Jammer -//TEST: RDS -//TEST: Morse coder/beacon +//TODO: Morse coder/beacon //BUG (fixed ?): Soundboard crashes on exit if no wav files on sd card //BUG (fixed ?): No audio in about when shown second time @@ -43,7 +42,6 @@ //TODO: Check AFSK transmit end, skips last bits ? //TODO: Use msgpack for settings, lists... on sd card //TODO: Frequency manager -//TODO: Morse coder //TODO: Replay //Multimon-style stuff: diff --git a/firmware/application/rds.cpp b/firmware/application/rds.cpp index 151ff82b2..e2c37a6be 100644 --- a/firmware/application/rds.cpp +++ b/firmware/application/rds.cpp @@ -73,50 +73,13 @@ void make_2A_group(uint32_t group[], const uint16_t PI_code, const bool TP, cons uint16_t gen_PSN(const char * psname, const uint8_t pty) { uint8_t c; uint32_t group[4][4] = { 0 }; - + // 4 groups with 2 PSN characters in each make_0B_group(&group[0][0], 0xF849, true, pty, false, true, false, 0, &psname[0]); make_0B_group(&group[1][0], 0xF849, true, pty, false, true, false, 1, &psname[2]); make_0B_group(&group[2][0], 0xF849, true, pty, false, true, false, 2, &psname[4]); make_0B_group(&group[3][0], 0xF849, true, pty, false, true, false, 3, &psname[6]); - /*uint32_t group[4][4] = { - { - 0b1111100001001001, //PI - 0b0000110011101000, //Address - 0b1111100001001001, //PI - 0b0000000000000000 //Replaced - }, - - { - 0b1111100001001001, //PI - 0b0000110011101001, //Address - 0b1111100001001001, //PI - 0b0000000000000000 //Replaced - }, - - { - 0b1111100001001001, //PI - 0b0000110011101010, //Address - 0b1111100001001001, //PI - 0b0000000000000000 //Replaced - }, - - { - 0b1111100001001001, //PI - 0b0000110011101011, //Address - 0b1111100001001001, //PI - 0b0000000000000000 //Replaced - }, - }; - - //Insert PSN data in groups - group[0][3] = (psname[0] << 8) | psname[1]; - group[1][3] = (psname[2] << 8) | psname[3]; - group[2][3] = (psname[4] << 8) | psname[5]; - group[3][3] = (psname[6] << 8) | psname[7]; - */ - // Generate checkbits for all blocks for (c = 0; c < 4; c++) { group[c][0] = makeblock(group[c][0], RDS_OFFSET_A); @@ -125,9 +88,10 @@ uint16_t gen_PSN(const char * psname, const uint8_t pty) { group[c][3] = makeblock(group[c][3], RDS_OFFSET_D); } - // Todo - //for (c = 0; c < 16; c++) - // shared_memory.radio_data[c] = group[c >> 2][c & 3]; + uint32_t * tx_data_u32 = (uint32_t*)shared_memory.tx_data; + + for (c = 0; c < 4 * 4; c++) + tx_data_u32[c] = group[c >> 2][c & 3]; return 4 * 4 * 26; } diff --git a/firmware/application/ui_about.cpp b/firmware/application/ui_about.cpp index 4c8afe79e..fe16df3f7 100644 --- a/firmware/application/ui_about.cpp +++ b/firmware/application/ui_about.cpp @@ -47,7 +47,7 @@ using namespace portapack; namespace ui { void AboutView::on_show() { - transmitter_model.set_tuning_frequency(92200000); + transmitter_model.set_tuning_frequency(1337000000); // TODO: Change transmitter_model.set_baseband_configuration({ .mode = 0, .sampling_rate = 1536000, diff --git a/firmware/application/ui_afsksetup.cpp b/firmware/application/ui_afsksetup.cpp index 1cae5ade3..db26346e4 100644 --- a/firmware/application/ui_afsksetup.cpp +++ b/firmware/application/ui_afsksetup.cpp @@ -23,8 +23,6 @@ #include "ui_afsksetup.hpp" #include "ui_receiver.hpp" -#include "ch.h" - #include "portapack.hpp" #include "string_format.hpp" diff --git a/firmware/application/ui_afsksetup.hpp b/firmware/application/ui_afsksetup.hpp index b83498197..77fa79604 100644 --- a/firmware/application/ui_afsksetup.hpp +++ b/firmware/application/ui_afsksetup.hpp @@ -24,9 +24,7 @@ #include "ui.hpp" #include "ui_widget.hpp" -#include "ui_painter.hpp" #include "ui_navigation.hpp" -#include "ui_font_fixed_8x16.hpp" namespace ui { diff --git a/firmware/application/ui_closecall.cpp b/firmware/application/ui_closecall.cpp index 1563f354b..44fab6869 100644 --- a/firmware/application/ui_closecall.cpp +++ b/firmware/application/ui_closecall.cpp @@ -46,8 +46,9 @@ void CloseCallView::focus() { } CloseCallView::~CloseCallView() { - receiver_model.disable(); time::signal_tick_second -= signal_token_tick_second; + receiver_model.disable(); + baseband::shutdown(); } void CloseCallView::do_detection() { @@ -88,42 +89,37 @@ void CloseCallView::do_detection() { // Staying around the same frequency (+/- 25.4kHz) if (detect_counter >= (5 / slices_max)) { if ((imax != locked_imax) || (!locked)) { - char finalstr[29] = {0}; + std::string finalstr; - // 236 steps = 3MHz - // Resolution = 12.7kHz - if (locked) + // 236 steps = 3.072MHz + // Resolution = 13.1kHz + if (locked) { resolved_frequency = (resolved_frequency + slice_start + (CC_BIN_WIDTH * (imax - 118))) / 2; // Mean - else + } else { resolved_frequency = slice_start + (CC_BIN_WIDTH * (imax - 118)); // Init - - //text_debug.set(to_string_dec_int(CC_BIN_WIDTH * (imax - 118))); - - // Correct according to DC spike mask width (4 for now) - if (iraw > 118) - resolved_frequency -= (2 * CC_BIN_WIDTH); - else - resolved_frequency += (2 * CC_BIN_WIDTH); + if ((resolved_frequency >= f_min) && (resolved_frequency <= f_max)) { + // Correct according to DC spike mask width (8 for now) + if (iraw > 118) + resolved_frequency -= (4 * CC_BIN_WIDTH); + else + resolved_frequency += (4 * CC_BIN_WIDTH); - text_infos.set("Locked !"); - big_display.set_style(&style_locked); - big_display.set(resolved_frequency); - - // Approximation/error display - freq_low = (resolved_frequency - 6355) / 1000; - freq_high = (resolved_frequency + 6355) / 1000; - strcat(finalstr, "~12.7kHz "); - strcat(finalstr, to_string_dec_uint(freq_low / 1000).c_str()); - strcat(finalstr, "."); - strcat(finalstr, to_string_dec_uint(freq_low % 1000).c_str()); - strcat(finalstr, "/"); - strcat(finalstr, to_string_dec_uint(freq_high / 1000).c_str()); - strcat(finalstr, "."); - strcat(finalstr, to_string_dec_uint(freq_high % 1000).c_str()); - text_precision.set(finalstr); - - locked = true; - locked_imax = imax; + text_infos.set("Locked !"); + big_display.set_style(&style_locked); + big_display.set(resolved_frequency); + + // Approximation/error display + freq_low = (resolved_frequency - 6000) / 1000; + freq_high = (resolved_frequency + 6000) / 1000; + finalstr = "~12kHz: " + to_string_dec_uint(freq_low / 1000) + "." + to_string_dec_uint(freq_low % 1000); + finalstr += "/" + to_string_dec_uint(freq_high / 1000) + "." + to_string_dec_uint(freq_high % 1000); + text_precision.set(finalstr); + + locked = true; + locked_imax = imax; + } + } + //text_debug.set(to_string_dec_int(CC_BIN_WIDTH * (imax - 118))); } release_counter = 0; } else { @@ -134,7 +130,7 @@ void CloseCallView::do_detection() { if (locked) { if (release_counter == 6) { locked = false; - text_infos.set("Lost "); + text_infos.set("Lost"); big_display.set_style(&style_grey); big_display.set(resolved_frequency); } else { @@ -159,18 +155,16 @@ void CloseCallView::on_channel_spectrum(const ChannelSpectrum& spectrum) { baseband::spectrum_streaming_stop(); - // Spectrum line (for debug) + // Draw spectrum line (for debug), 2 black pixels left and right std::array pixel_row; for(i = 0; i < 118; i++) { - const auto pixel_color = spectrum_rgb3_lut[spectrum.db[256 - 120 + i]]; + const auto pixel_color = spectrum_rgb3_lut[spectrum.db[256 - 120 + i]]; // 136~253 in 2~119 pixel_row[i + 2] = pixel_color; } - for(i = 122; i < 240; i++) { - const auto pixel_color = spectrum_rgb3_lut[spectrum.db[i - 120]]; + const auto pixel_color = spectrum_rgb3_lut[spectrum.db[i - 120]]; // 2~119 in 120~237 pixel_row[i - 2] = pixel_color; } - display.draw_pixels( { { 0, 96 + slices_counter * 4 }, { pixel_row.size(), 1 } }, pixel_row @@ -179,12 +173,12 @@ void CloseCallView::on_channel_spectrum(const ChannelSpectrum& spectrum) { // Find max for this slice: // Check if left of slice needs to be trimmed (masked) - if (slices_counter == 0) - i = slice_trim; - else + //if (slices_counter == 0) + // i = slice_trim; + //else i = 0; for ( ; i < 118; i++) { - threshold = spectrum.db[256 - 120 + i]; // 128+8 = 136 ~254 + threshold = spectrum.db[256 - 120 + i]; // 128+8 = 136~254 if (threshold > xmax) { xmax = threshold; imax = i; @@ -197,7 +191,7 @@ void CloseCallView::on_channel_spectrum(const ChannelSpectrum& spectrum) { m = 240; for (i = 122 ; i < m; i++) { threshold = spectrum.db[i - 120]; // 240-120 = 120 -> +8 = 128 - if (threshold > xmax) { // (0~2) 2~120 (120~136) 136~254 (254~256) + if (threshold > xmax) { // (0~2) 2~120 (120~136) 136~254 (254~256) xmax = threshold; imax = i - 4; } @@ -238,7 +232,6 @@ void CloseCallView::on_hide() { } void CloseCallView::on_range_changed() { - rf::Frequency f_min, f_max; rf::Frequency slices_span; rf::Frequency resolved_frequency; int64_t offset; @@ -262,13 +255,13 @@ void CloseCallView::on_range_changed() { slice_start = slice_frequency; receiver_model.set_tuning_frequency(slice_frequency); - resolved_frequency = (CC_SLICE_WIDTH - scan_span) / 2; // Trim frequency span (for both sides) - resolved_frequency /= CC_BIN_WIDTH; // Convert to bin span - slice_trim = resolved_frequency; + //resolved_frequency = (CC_SLICE_WIDTH - scan_span) / 2; // Trim frequency span (for both sides) + //resolved_frequency /= CC_BIN_WIDTH; // Convert to bin span + //slice_trim = resolved_frequency; - portapack::display.fill_rectangle({0, 97, 240, 4}, Color::black()); - portapack::display.fill_rectangle({0, 97, slice_trim, 4}, Color::orange()); - portapack::display.fill_rectangle({240 - slice_trim, 97, slice_trim, 4}, Color::orange()); + //portapack::display.fill_rectangle({0, 97, 240, 4}, Color::black()); + //portapack::display.fill_rectangle({0, 97, slice_trim, 4}, Color::orange()); + //portapack::display.fill_rectangle({240 - slice_trim, 97, slice_trim, 4}, Color::orange()); slices_max = 1; slices_counter = 0; @@ -310,6 +303,8 @@ CloseCallView::CloseCallView( NavigationView& nav ) { + baseband::run_image(portapack::spi_flash::image_tag_closecall); + add_children({ { &text_labels_a, &text_labels_b, @@ -329,39 +324,6 @@ CloseCallView::CloseCallView( &button_exit } }); - // DEBUG ------------------------------------------------------------------------- - /*uint8_t testbuffer[] = { 0xDE, 0x00, 0x02, - 0xCD, 0x00, 0x00, // Key 0000 = False - 0xC2, - 0xCD, 0x00, 0x01, // Key 0001 = True - 0xC3, - 0xCD, 0x00, 0x02, // Key 0002 = False - 0xC2, - 0xCD, 0x00, 0x03, // Key 0003 = fixnum 19 - 19 - };*/ - - uint8_t testbuffer[100]; - uint8_t debug_v = 7; - size_t bptr; - MsgPack msgpack; - - bptr = 0; - - msgpack.msgpack_init(&testbuffer, &bptr); - msgpack.msgpack_add(&testbuffer, &bptr, MsgPack::TestListA, false); - msgpack.msgpack_add(&testbuffer, &bptr, MsgPack::TestListB, true); - msgpack.msgpack_add(&testbuffer, &bptr, MsgPack::TestListC, false); - msgpack.msgpack_add(&testbuffer, &bptr, MsgPack::TestListD, (uint8_t)19); - - msgpack.msgpack_get(&testbuffer, bptr, MsgPack::TestListD, &debug_v); - if (debug_v == 19) - text_debug.set("OK!"); - else - text_debug.set(to_string_dec_uint(testbuffer[0])); - - // DEBUG ------------------------------------------------------------------------- - text_labels_a.set_style(&style_grey); text_labels_b.set_style(&style_grey); text_labels_c.set_style(&style_grey); @@ -370,7 +332,8 @@ CloseCallView::CloseCallView( text_mhz.set_style(&style_grey); big_display.set_style(&style_grey); - receiver_model.set_tuning_frequency(467000000); + // DEBUG + receiver_model.set_tuning_frequency(464400000); field_threshold.set_value(80); field_threshold.on_change = [this](int32_t v) { @@ -380,32 +343,30 @@ CloseCallView::CloseCallView( field_frequency_min.set_value(receiver_model.tuning_frequency()); field_frequency_min.set_step(100000); field_frequency_min.on_change = [this](rf::Frequency f) { - (void) f; + (void)f; this->on_range_changed(); }; field_frequency_min.on_edit = [this, &nav]() { auto new_view = nav.push(receiver_model.tuning_frequency()); new_view->on_changed = [this](rf::Frequency f) { - this->on_range_changed(); + //this->on_range_changed(); this->field_frequency_min.set_value(f); }; }; - field_frequency_max.set_focusable(false); // DEBUG - - field_frequency_max.set_value(receiver_model.tuning_frequency() + 3000000); + field_frequency_max.set_value(receiver_model.tuning_frequency() + 2000000); field_frequency_max.set_step(100000); - /*field_frequency_max.on_change = [this](rf::Frequency f) { - (void) f; + field_frequency_max.on_change = [this](rf::Frequency f) { + (void)f; this->on_range_changed(); }; field_frequency_max.on_edit = [this, &nav]() { auto new_view = nav.push(receiver_model.tuning_frequency()); new_view->on_changed = [this](rf::Frequency f) { - this->on_range_changed(); + //this->on_range_changed(); this->field_frequency_max.set_value(f); }; - };*/ + }; field_lna.set_value(receiver_model.lna()); field_lna.on_change = [this](int32_t v) { @@ -426,7 +387,10 @@ CloseCallView::CloseCallView( signal_token_tick_second = time::signal_tick_second += [this]() { this->on_tick_second(); }; - receiver_model.set_baseband_bandwidth(CC_SLICE_WIDTH); + + receiver_model.set_modulation(ReceiverModel::Mode::SpectrumAnalysis); + receiver_model.set_sampling_rate(3072000); + receiver_model.set_baseband_bandwidth(2500000); receiver_model.enable(); } diff --git a/firmware/application/ui_closecall.hpp b/firmware/application/ui_closecall.hpp index aa16b5c1a..61fa71dbc 100644 --- a/firmware/application/ui_closecall.hpp +++ b/firmware/application/ui_closecall.hpp @@ -27,13 +27,12 @@ #include "ui_receiver.hpp" #include "ui_spectrum.hpp" #include "ui_record_view.hpp" - #include "ui_font_fixed_8x16.hpp" namespace ui { -#define CC_SLICE_WIDTH 3000000 // Radio bandwidth -#define CC_BIN_NB 236 // Total power bins +#define CC_SLICE_WIDTH 3072000 // Radio bandwidth +#define CC_BIN_NB 256 // Total power bins #define CC_BIN_WIDTH CC_SLICE_WIDTH/CC_BIN_NB class CloseCallView : public View { @@ -58,6 +57,8 @@ private: .background = Color::black(), .foreground = Color::green(), }; + + rf::Frequency f_min, f_max; Coord last_pos = 0; ChannelSpectrumFIFO* fifo { nullptr }; uint8_t detect_counter = 0, release_counter = 0; @@ -78,6 +79,7 @@ private: bool ignore = true; bool slicing; bool locked = false; + void on_channel_spectrum(const ChannelSpectrum& spectrum); void on_range_changed(); void do_detection(); @@ -134,11 +136,11 @@ private: }; Text text_rate { { 24 * 8, 3 * 16, 2 * 8, 16 }, - "--2" + "--" }; Text text_infos { - { 1 * 8, 6 * 16, 8 * 8, 16 }, + { 1 * 8, 6 * 16, 28 * 8, 16 }, "..." }; @@ -148,18 +150,18 @@ private: }; Text text_mhz { - { 26 * 8, 12 * 16, 3 * 8, 16 }, + { 26 * 8, 12 * 16 - 4, 3 * 8, 16 }, "MHz" }; Text text_precision { { 1 * 8, 13 * 16, 28 * 8, 16 }, - "" + "..." }; Text text_debug { { 1 * 8, 14 * 16, 28 * 8, 16 }, - "DEBUG: Error" + "DEBUG: -" }; Button button_exit { diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 0ec2e9a5d..3f5f7a563 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -300,7 +300,7 @@ TransmitterAudioMenuView::TransmitterAudioMenuView(NavigationView& nav) { UtilitiesView::UtilitiesView(NavigationView& nav) { add_items<3>({ { - { "Frequency manager", ui::Color::white(), [&nav](){ nav.push(); } }, + { "Frequency manager", ui::Color::grey(), [&nav](){ nav.push(); } }, { "Whip antenna length", ui::Color::green(), [&nav](){ nav.push(); } }, { "Notepad", ui::Color::grey(), [&nav](){ nav.push(); } }, } }); diff --git a/firmware/application/ui_rds.cpp b/firmware/application/ui_rds.cpp index cbda38ad5..c0273a750 100644 --- a/firmware/application/ui_rds.cpp +++ b/firmware/application/ui_rds.cpp @@ -23,13 +23,8 @@ #include "ui_rds.hpp" #include "rds.hpp" -#include "ff.h" -#include "hackrf_gpio.hpp" #include "portapack.hpp" -#include "radio.hpp" #include "baseband_api.hpp" - -#include "hackrf_hal.hpp" #include "portapack_shared_memory.hpp" #include diff --git a/firmware/application/ui_rds.hpp b/firmware/application/ui_rds.hpp index b1f7cf115..78e2afe93 100644 --- a/firmware/application/ui_rds.hpp +++ b/firmware/application/ui_rds.hpp @@ -26,12 +26,7 @@ #include "ui_font_fixed_8x16.hpp" #include "ui_receiver.hpp" #include "ui_textentry.hpp" -#include "clock_manager.hpp" #include "message.hpp" -#include "rf_path.hpp" -#include "max2837.hpp" -#include "volume.hpp" -#include "transmitter_model.hpp" namespace ui { @@ -39,11 +34,12 @@ class RDSView : public View { public: RDSView(NavigationView& nav); ~RDSView(); - std::string title() const override { return "RDS transmit"; }; void focus() override; void paint(Painter& painter) override; + std::string title() const override { return "RDS transmit"; }; + private: char PSN[9]; char RadioText[25]; @@ -168,12 +164,12 @@ private: OptionsField options_coverage { { 1 * 8, 4 * 16 }, - 8, + 13, { { "Local", 0 }, { "International", 1 }, { "National", 2 }, - { "Supra-regional", 3 }, + { "Sup-regional", 3 }, { "R11", 4 }, { "R12", 5 }, { "R13", 6 }, diff --git a/firmware/application/ui_soundboard.cpp b/firmware/application/ui_soundboard.cpp index c58d4ad13..d196899b7 100644 --- a/firmware/application/ui_soundboard.cpp +++ b/firmware/application/ui_soundboard.cpp @@ -25,7 +25,6 @@ #include "ui_soundboard.hpp" #include "lfsr_random.hpp" -#include "ui_alphanum.hpp" #include "portapack.hpp" #include "string_format.hpp" @@ -199,6 +198,11 @@ SoundBoardView::SoundBoardView( NavigationView& nav ) : nav_ (nav) { + using name_t = std::string; + using value_t = int32_t; + using option_t = std::pair; + using options_t = std::vector; + options_t ctcss_options; std::vector file_list; uint8_t c; @@ -243,11 +247,17 @@ SoundBoardView::SoundBoardView( &button_random, &button_exit } }); + + ctcss_options.emplace_back(std::make_pair("None", 0)); + + for (c = 0; c < CTCSS_TONES_NB; c++) + ctcss_options.emplace_back(std::make_pair(ctcss_tones[c].PL_code, c)); + + options_ctcss.set_options(ctcss_options); options_ctcss.on_change = [this](size_t, OptionsField::value_t v) { this->on_ctcss_changed(v); }; - options_ctcss.set_selected_index(0); const auto button_fn = [this](Button& button) { diff --git a/firmware/application/ui_soundboard.hpp b/firmware/application/ui_soundboard.hpp index 67936cc70..dd85822df 100644 --- a/firmware/application/ui_soundboard.hpp +++ b/firmware/application/ui_soundboard.hpp @@ -32,6 +32,7 @@ #include "utility.hpp" #include "message.hpp" #include "wavfile.hpp" +#include "ctcss.hpp" namespace ui { @@ -138,60 +139,7 @@ private: OptionsField options_ctcss { { 18 * 8, 4 }, 6, - { - { "None ", 0 }, - { "XZ 000", 67000 }, - { "WZ 001", 69400 }, - { "XA 039", 71900 }, - { "WA 003", 74400 }, - { "XB 004", 77000 }, - { "WB 005", 79700 }, - { "YZ 006", 82500 }, - { "YA 007", 85400 }, - { "YB 008", 88500 }, - { "ZZ 009", 91500 }, - { "ZA 010", 94800 }, - { "ZB 011", 97400 }, - { "1Z 012", 100000 }, - { "1A 013", 103500 }, - { "1B 014", 107200 }, - { "2Z 015", 110900 }, - { "2Z 016", 114800 }, - { "2B 017", 118800 }, - { "3Z 018", 123000 }, - { "3A 019", 127300 }, - { "3B 020", 131800 }, - { "4Z 021", 136500 }, - { "4A 022", 141300 }, - { "4B 023", 146200 }, - { "MIL ", 150000 }, - { "5Z 024", 151400 }, - { "5A 025", 156700 }, - { "-- 040", 159800 }, - { "5B 026", 162200 }, - { "-- 041", 165500 }, - { "6Z 027", 167900 }, - { "-- 042", 171300 }, - { "6A 028", 173800 }, - { "-- 043", 177300 }, - { "6B 029", 179900 }, - { "-- 044", 183500 }, - { "7Z 030", 186200 }, - { "-- 045", 189900 }, - { "7A 031", 192800 }, - { "-- 046", 196600 }, - { "-- 047", 199500 }, - { "M1 032", 203500 }, - { "8Z 048", 206500 }, - { "M2 033", 210700 }, - { "M3 034", 218100 }, - { "M4 035", 225700 }, - { "9Z 049", 229100 }, - { "-- 036", 233600 }, - { "-- 037", 241800 }, - { "-- 038", 250300 }, - { "0Z 050", 254100 } - } + { } }; Text text_page { diff --git a/firmware/application/wavfile.cpp b/firmware/application/wavfile.cpp index 9cae58acf..558af3704 100644 --- a/firmware/application/wavfile.cpp +++ b/firmware/application/wavfile.cpp @@ -74,8 +74,7 @@ uint32_t WAVFileReader::ms_duration() { } int WAVFileReader::seek_mss(const uint16_t minutes, const uint8_t seconds, const uint32_t samples) { - - auto result = file.seek(data_start + ((((minutes * 60) + seconds) * sample_rate_) + samples) * bytes_per_sample); + const auto result = file.seek(data_start + ((((minutes * 60) + seconds) * sample_rate_) + samples) * bytes_per_sample); if (result.is_error()) return 0; diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index c04e1a5e5..a81ba439e 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -333,6 +333,13 @@ set(MODE_CPPSRC ) DeclareTargets(PSPE wideband_spectrum) +### Close Call + +set(MODE_CPPSRC + proc_closecall.cpp +) +DeclareTargets(PCLC closecall) + ### OOK set(MODE_CPPSRC diff --git a/firmware/baseband/baseband_closecall.img b/firmware/baseband/baseband_closecall.img new file mode 100644 index 000000000..7447ef0d0 Binary files /dev/null and b/firmware/baseband/baseband_closecall.img differ diff --git a/firmware/baseband/proc_closecall.cpp b/firmware/baseband/proc_closecall.cpp index 1ee1dae00..9695d2fab 100644 --- a/firmware/baseband/proc_closecall.cpp +++ b/firmware/baseband/proc_closecall.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek * * This file is part of PortaPack. * diff --git a/firmware/baseband/proc_closecall.hpp b/firmware/baseband/proc_closecall.hpp index f00e6ff72..50345afaf 100644 --- a/firmware/baseband/proc_closecall.hpp +++ b/firmware/baseband/proc_closecall.hpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek * * This file is part of PortaPack. * @@ -23,6 +24,7 @@ #define __PROC_CLOSECALLPROCESSOR_H__ #include "baseband_processor.hpp" +#include "baseband_thread.hpp" #include "spectrum_collector.hpp" #include "message.hpp" @@ -38,6 +40,8 @@ public: void on_message(const Message* const message) override; private: + BasebandThread baseband_thread { 3072000, this, NORMALPRIO + 20, baseband::Direction::Receive }; + SpectrumCollector channel_spectrum; std::array spectrum; diff --git a/firmware/baseband/proc_rds.cpp b/firmware/baseband/proc_rds.cpp index 34d6232df..c05b0b05e 100644 --- a/firmware/baseband/proc_rds.cpp +++ b/firmware/baseband/proc_rds.cpp @@ -35,6 +35,11 @@ void RDSProcessor::execute(const buffer_c8_t& buffer) { if (s >= 9) { s = 0; if (sample_count >= SAMPLES_PER_BIT) { + if (bit_pos >= message_length) { + bit_pos = 0; + cur_output = 0; + } + cur_bit = (rdsdata[(bit_pos / 26) & 15] >> (25 - (bit_pos % 26))) & 1; prev_output = cur_output; cur_output = prev_output ^ cur_bit; @@ -52,10 +57,7 @@ void RDSProcessor::execute(const buffer_c8_t& buffer) { in_sample_index += SAMPLES_PER_BIT; if (in_sample_index >= SAMPLE_BUFFER_SIZE) in_sample_index -= SAMPLE_BUFFER_SIZE; - if (bit_pos < message_length) - bit_pos++; - else - bit_pos = 0; + bit_pos++; sample_count = 0; } diff --git a/firmware/common/spi_image.hpp b/firmware/common/spi_image.hpp index c5a29e055..9e7b23047 100644 --- a/firmware/common/spi_image.hpp +++ b/firmware/common/spi_image.hpp @@ -71,6 +71,7 @@ constexpr image_tag_t image_tag_tpms { 'P', 'T', 'P', 'M' }; constexpr image_tag_t image_tag_pocsag { 'P', 'P', 'O', 'C' }; constexpr image_tag_t image_tag_wfm_audio { 'P', 'W', 'F', 'M' }; constexpr image_tag_t image_tag_wideband_spectrum { 'P', 'S', 'P', 'E' }; +constexpr image_tag_t image_tag_closecall { 'P', 'C', 'L', 'C' }; constexpr image_tag_t image_tag_jammer { 'P', 'J', 'A', 'M' }; constexpr image_tag_t image_tag_audio_tx { 'P', 'A', 'T', 'X' }; diff --git a/firmware/portapack-h1-havoc.bin b/firmware/portapack-h1-havoc.bin index 92f8c9bf6..f1b4b0637 100644 Binary files a/firmware/portapack-h1-havoc.bin and b/firmware/portapack-h1-havoc.bin differ