diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 1c8bad99..23058491 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -25,6 +25,7 @@ //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: ui_lcr, make arrays for litterals (checkboxes and buttons) //TODO: Frequency manager //TODO: Weird LCR AFSK scrambling ? //TODO: SD card wiper diff --git a/firmware/application/ui_afsksetup.cpp b/firmware/application/ui_afsksetup.cpp index 8862f048..74fe4956 100644 --- a/firmware/application/ui_afsksetup.cpp +++ b/firmware/application/ui_afsksetup.cpp @@ -81,8 +81,8 @@ AFSKSetupView::AFSKSetupView( &field_space, &text_bw, &field_bw, - //&text_repeat, - //&field_repeat, + &text_repeat, + &field_repeat, //&checkbox_lsb, //&checkbox_parity, //&checkbox_datasize, diff --git a/firmware/application/ui_alphanum.cpp b/firmware/application/ui_alphanum.cpp index ca93e970..0e46111c 100644 --- a/firmware/application/ui_alphanum.cpp +++ b/firmware/application/ui_alphanum.cpp @@ -72,7 +72,6 @@ AlphanumView::AlphanumView( size_t n = 0; for(auto& button : buttons) { - add_child(&button); button.on_select = button_fn; button.set_parent_rect({ static_cast((n % 5) * button_w), @@ -83,6 +82,7 @@ AlphanumView::AlphanumView( button.set_style(&style_num); else button.set_style(&style_alpha); + add_child(&button); n++; } set_uppercase(); diff --git a/firmware/application/ui_lcr.cpp b/firmware/application/ui_lcr.cpp index bff88367..fd758bc1 100644 --- a/firmware/application/ui_lcr.cpp +++ b/firmware/application/ui_lcr.cpp @@ -83,30 +83,14 @@ void LCRView::generate_message() { strcat(lcr_message, rgsb); // Address strcat(lcr_message, "PA "); - if (checkbox_am_a.value() == true) { - strcat(lcr_message, "AM=1 AF=\""); - strcat(lcr_message, litteral[0]); - strcat(lcr_message, "\" CL=0 "); - } - if (checkbox_am_b.value() == true) { - strcat(lcr_message, "AM=2 AF=\""); - strcat(lcr_message, litteral[1]); - strcat(lcr_message, "\" CL=0 "); - } - if (checkbox_am_c.value() == true) { - strcat(lcr_message, "AM=3 AF=\""); - strcat(lcr_message, litteral[2]); - strcat(lcr_message, "\" CL=0 "); - } - if (checkbox_am_d.value() == true) { - strcat(lcr_message, "AM=4 AF=\""); - strcat(lcr_message, litteral[3]); - strcat(lcr_message, "\" CL=0 "); - } - if (checkbox_am_e.value() == true) { - strcat(lcr_message, "AM=5 AF=\""); - strcat(lcr_message, litteral[4]); - strcat(lcr_message, "\" CL=0 "); + for (i = 0; i < 5; i++) { + if (checkboxes[i].value() == true) { + strcat(lcr_message, "AM="); + strcat(lcr_message, to_string_dec_uint(i, 1).c_str()); + strcat(lcr_message, " AF=\""); + strcat(lcr_message, litteral[i]); + strcat(lcr_message, "\" CL=0 "); + } } strcat(lcr_message, "EC="); strcat(lcr_message, ec_lut[options_ec.selected_index()]); @@ -208,65 +192,77 @@ void LCRView::paint(Painter& painter) { strcpy(finalstr, fstr.c_str()); strcat(finalstr, "@"); strcat(finalstr, bstr.c_str()); - strcat(finalstr, "bps"); + strcat(finalstr, "bps "); if (portapack::persistent_memory::afsk_config() & 8) - strcat(finalstr, " ALT"); + strcat(finalstr, "ALT"); else - strcat(finalstr, " NRM"); + strcat(finalstr, "NRM"); text_recap.set(finalstr); } +void LCRView::update_progress() { + char str[16]; + + text_status.set(" "); + + if (tx_mode == SINGLE) { + strcpy(str, to_string_dec_uint(repeat_index).c_str()); + strcat(str, "/"); + strcat(str, to_string_dec_uint(portapack::persistent_memory::afsk_repeats()).c_str()); + text_status.set(str); + progress.set_value(repeat_index); + } else if (tx_mode == SCAN) { + strcpy(str, to_string_dec_uint(repeat_index).c_str()); + strcat(str, "/"); + strcat(str, to_string_dec_uint(portapack::persistent_memory::afsk_repeats()).c_str()); + 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()); + text_status.set(str); + progress.set_value(scan_progress); + } else { + text_status.set("Ready"); + progress.set_value(0); + } +} + void LCRView::on_txdone(int n) { char str[16]; - if (abort_scan) { - text_status.set(" "); - strcpy(str, "Abort @"); - strcat(str, rgsb); - text_status.set(str); - progress.set_value(0); - transmitter_model.disable(); - tx_mode = IDLE; - abort_scan = false; - button_scan.set_style(&style_val); - button_scan.set_text("SCAN"); - return; - } - if (n > 0) { + repeat_index = n + 1; if (tx_mode == SCAN) { - scan_progress += 0.555f; // 100/(37*5) - progress.set_value(scan_progress); + scan_progress++; + update_progress(); } else { - text_status.set(" "); - strcpy(str, to_string_dec_int(6 - n).c_str()); - strcat(str, "/5"); - text_status.set(str); - progress.set_value((6 - n) * 20); + update_progress(); } } else { - if ((tx_mode == SCAN) && (scan_index < LCR_SCAN_COUNT)) { + if ((tx_mode == SCAN) && (scan_index < (LCR_SCAN_COUNT - 1))) { transmitter_model.disable(); - - // Next address - strcpy(rgsb, RGSB_list[scan_index]); - generate_message(); - - text_status.set(" "); - strcpy(str, to_string_dec_int(scan_index).c_str()); - strcat(str, "/"); - strcat(str, to_string_dec_uint(LCR_SCAN_COUNT).c_str()); - text_status.set(str); - scan_progress += 0.694f; - progress.set_value(scan_progress); - - scan_index++; - // start_tx ? + if (abort_scan) { + strcpy(str, "Abort @"); + strcat(str, rgsb); + text_status.set(str); + progress.set_value(0); + tx_mode = IDLE; + abort_scan = false; + button_scan.set_style(&style_val); + button_scan.set_text("SCAN"); + } else { + // Next address + scan_index++; + strcpy(rgsb, RGSB_list[scan_index]); + scan_progress++; + repeat_index = 1; + update_progress(); + start_tx(true); + } } else { - text_status.set("Ready "); - progress.set_value(0); transmitter_model.disable(); tx_mode = IDLE; + update_progress(); button_scan.set_style(&style_val); button_scan.set_text("SCAN"); } @@ -274,33 +270,30 @@ void LCRView::on_txdone(int n) { } void LCRView::start_tx(const bool scan) { - char str[16]; bool afsk_alt_format; + uint8_t afsk_repeats; + + afsk_repeats = portapack::persistent_memory::afsk_repeats(); if (scan) { - tx_mode = SCAN; - scan_index = 0; - strcpy(rgsb, RGSB_list[0]); + if (tx_mode != SCAN) { + scan_index = 0; + scan_progress = 1; + repeat_index = 1; + tx_mode = SCAN; + strcpy(rgsb, RGSB_list[0]); + progress.set_max(LCR_SCAN_COUNT * afsk_repeats); + update_progress(); + } } else { tx_mode = SINGLE; + repeat_index = 1; + progress.set_max(afsk_repeats); + update_progress(); } generate_message(); - if (tx_mode == SCAN) { - text_status.set(" "); - strcpy(str, "1/"); - strcat(str, to_string_dec_uint(LCR_SCAN_COUNT).c_str()); - text_status.set(str); - progress.set_value(1); - scan_index++; - } else { - strcpy(str, "1/5 "); - //strcat(str, to_string_dec_int(shared_memory.afsk_repeat).c_str()); - text_status.set(str); - progress.set_value(20); - } - if (portapack::persistent_memory::afsk_config() & 8) afsk_alt_format = true; else @@ -323,13 +316,19 @@ void LCRView::start_tx(const bool scan) { 228000 / portapack::persistent_memory::afsk_bitrate(), portapack::persistent_memory::afsk_mark_freq() * (0x40000 * 256) / 2280, portapack::persistent_memory::afsk_space_freq() * (0x40000 * 256) / 2280, - 5, + afsk_repeats, portapack::persistent_memory::afsk_bw() * 115, // See proc_fsk_lcr.cpp afsk_alt_format ); } +void LCRView::on_button_setam(NavigationView& nav, Button& button) { + textentry(nav, litteral[button.id], 7); +} + LCRView::LCRView(NavigationView& nav) { + std::string label; + baseband::run_image(portapack::spi_flash::image_tag_afsk); memset(litteral, 0, 5 * 8); @@ -342,16 +341,6 @@ LCRView::LCRView(NavigationView& nav) { &options_ec, &button_setrgsb, &button_txsetup, - &checkbox_am_a, - &button_setam_a, - &checkbox_am_b, - &button_setam_b, - &checkbox_am_c, - &button_setam_c, - &checkbox_am_d, - &button_setam_d, - &checkbox_am_e, - &button_setam_e, &text_status, &progress, &button_lcrdebug, @@ -360,15 +349,40 @@ LCRView::LCRView(NavigationView& nav) { &button_clear } }); + const auto button_setam_fn = [this, &nav](Button& button) { + this->on_button_setam(nav, button); + }; + + size_t n = 0; + for(auto& button : buttons) { + button.on_select = button_setam_fn; + button.id = n; + label = "AM " + to_string_dec_uint(n, 1);; + button.set_text(label); + button.set_parent_rect({ + static_cast(48), + static_cast(n * 32 + 64), + 48, 24 + }); + add_child(&button); + n++; + } + + n = 0; + for(auto& checkbox : checkboxes) { + checkbox.set_parent_rect({ + static_cast(16), + static_cast(n * 32 + 64), + 48, 24 + }); + checkbox.set_value(false); + add_child(&checkbox); + n++; + } + button_setrgsb.set_text(rgsb); - options_ec.set_selected_index(0); // Auto - - checkbox_am_a.set_value(true); - checkbox_am_b.set_value(false); - checkbox_am_c.set_value(false); - checkbox_am_d.set_value(false); - checkbox_am_e.set_value(false); + checkboxes[0].set_value(true); button_transmit.set_style(&style_val); button_scan.set_style(&style_val); @@ -377,22 +391,6 @@ LCRView::LCRView(NavigationView& nav) { textentry(nav, rgsb, 4); }; - button_setam_a.on_select = [this,&nav](Button&) { - textentry(nav, litteral[0], 7); - }; - button_setam_b.on_select = [this,&nav](Button&) { - textentry(nav, litteral[1], 7); - }; - button_setam_c.on_select = [this,&nav](Button&) { - textentry(nav, litteral[2], 7); - }; - button_setam_d.on_select = [this,&nav](Button&) { - textentry(nav, litteral[3], 7); - }; - button_setam_e.on_select = [this,&nav](Button&) { - textentry(nav, litteral[4], 7); - }; - button_txsetup.on_select = [&nav](Button&) { nav.push(); }; @@ -408,7 +406,6 @@ LCRView::LCRView(NavigationView& nav) { button_scan.on_select = [this](Button&) { if (tx_mode == IDLE) { - scan_progress = 0; button_scan.set_style(&style_cancel); button_scan.set_text("ABORT"); start_tx(true); diff --git a/firmware/application/ui_lcr.hpp b/firmware/application/ui_lcr.hpp index bcbed9ae..ae6e9137 100644 --- a/firmware/application/ui_lcr.hpp +++ b/firmware/application/ui_lcr.hpp @@ -54,7 +54,7 @@ private: SINGLE, SCAN }; - + // afsk_config() tx_modes tx_mode = IDLE; bool abort_scan = false; double scan_progress; @@ -77,11 +77,14 @@ private: char lcr_message_data[256]; char checksum = 0; rf::Frequency f; - int scan_index; + uint8_t repeat_index; + unsigned int scan_index; void generate_message(); + void update_progress(); void start_tx(const bool scan); void on_txdone(int n); + void on_button_setam(NavigationView& nav, Button& button); radio::Configuration lcr_radio_config = { 0, @@ -118,6 +121,9 @@ private: .background = Color::red(), .foreground = Color::black(), }; + + std::array buttons; + std::array checkboxes; Text text_recap { { 8, 6, 18 * 8, 16 }, @@ -125,7 +131,7 @@ private: }; OptionsField options_ec { - { 20 * 8, 6 }, + { 21 * 8, 6 }, 7, { { "EC:Auto", 0 }, @@ -148,50 +154,30 @@ private: 0, "" }; - Button button_setam_a { - { 48, 64, 48, 24 }, - "AM 1" - }; Checkbox checkbox_am_b { { 16, 96 }, 0, "" }; - Button button_setam_b { - { 48, 96, 48, 24 }, - "AM 2" - }; Checkbox checkbox_am_c { { 16, 128 }, 0, "" }; - Button button_setam_c { - { 48, 128, 48, 24 }, - "AM 3" - }; Checkbox checkbox_am_d { { 16, 160 }, 0, "" }; - Button button_setam_d { - { 48, 160, 48, 24 }, - "AM 4" - }; Checkbox checkbox_am_e { { 16, 192 }, 0, "" }; - Button button_setam_e { - { 48, 192, 48, 24 }, - "AM 5" - }; Button button_lcrdebug { { 168, 216, 56, 24 }, diff --git a/firmware/baseband/proc_afsk.cpp b/firmware/baseband/proc_afsk.cpp index 17a836d0..3de231a3 100644 --- a/firmware/baseband/proc_afsk.cpp +++ b/firmware/baseband/proc_afsk.cpp @@ -43,22 +43,22 @@ void AFSKProcessor::execute(const buffer_c8_t& buffer) { if (configured == true) { cur_byte = message_data[byte_pos]; ext_byte = message_data[byte_pos + 1]; - } - if (!cur_byte) { - if (afsk_repeat) { - afsk_repeat--; - bit_pos = 0; - byte_pos = 0; - cur_byte = message_data[0]; - ext_byte = message_data[1]; - message.n = afsk_repeat; - shared_memory.application_queue.push(message); - } else { - message.n = 0; - configured = false; - shared_memory.application_queue.push(message); - cur_byte = 0; - ext_byte = 0; + if (!cur_byte) { + if (repeat_counter < afsk_repeat) { + bit_pos = 0; + byte_pos = 0; + cur_byte = message_data[0]; + ext_byte = message_data[1]; + message.n = repeat_counter + 1; + shared_memory.application_queue.push(message); + repeat_counter++; + } else { + message.n = 0; + shared_memory.application_queue.push(message); + cur_byte = 0; + ext_byte = 0; + configured = false; + } } } @@ -124,10 +124,11 @@ void AFSKProcessor::on_message(const Message* const p) { afsk_samples_per_bit = message.afsk_samples_per_bit; afsk_phase_inc_mark = message.afsk_phase_inc_mark; afsk_phase_inc_space = message.afsk_phase_inc_space; - afsk_repeat = message.afsk_repeat; + afsk_repeat = message.afsk_repeat - 1; afsk_bw = message.afsk_bw; afsk_alt_format = message.afsk_alt_format; + repeat_counter = 0; bit_pos = 0; byte_pos = 0; cur_byte = 0; diff --git a/firmware/baseband/proc_afsk.hpp b/firmware/baseband/proc_afsk.hpp index d198d8ba..c748bf47 100644 --- a/firmware/baseband/proc_afsk.hpp +++ b/firmware/baseband/proc_afsk.hpp @@ -45,6 +45,7 @@ private: bool afsk_alt_format; char message_data[256]; + uint8_t repeat_counter = 0; int8_t re, im; uint8_t s; uint8_t bit_pos = 0, byte_pos = 0; diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index 4354ea69..970150a6 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -139,6 +139,10 @@ uint32_t afsk_config() { return data->afsk_config; } +uint8_t afsk_repeats() { + return (data->afsk_config >> 8); +} + void set_afsk_config(const uint32_t new_value) { data->afsk_config = new_value; } diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index 7646ec80..99bd62fc 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -47,6 +47,7 @@ int32_t afsk_bitrate(); void set_afsk_bitrate(const int32_t new_value); uint32_t afsk_config(); +uint8_t afsk_repeats(); void set_afsk_config(const uint32_t new_value); int32_t afsk_bw(); diff --git a/firmware/common/ui_widget.cpp b/firmware/common/ui_widget.cpp index e93e420e..71247cc7 100644 --- a/firmware/common/ui_widget.cpp +++ b/firmware/common/ui_widget.cpp @@ -395,9 +395,15 @@ ProgressBar::ProgressBar( { } +void ProgressBar::set_max(const uint16_t max) { + _value = 0; + _max = max; + set_dirty(); +} + void ProgressBar::set_value(const uint16_t value) { - if (value > 100) - _value = 100; + if (value > _max) + _value = _max; else _value = value; set_dirty(); @@ -409,7 +415,7 @@ void ProgressBar::paint(Painter& painter) { const auto rect = screen_rect(); const auto s = style(); - v_sized = (rect.size.w * _value) / 100; + v_sized = (rect.size.w * _value) / _max; painter.fill_rectangle({rect.pos, {v_sized, rect.size.h}}, style().foreground); painter.fill_rectangle({{rect.pos.x + v_sized, rect.pos.y}, {rect.size.w - v_sized, rect.size.h}}, s.background); diff --git a/firmware/common/ui_widget.hpp b/firmware/common/ui_widget.hpp index cb1331a9..6bb59d6c 100644 --- a/firmware/common/ui_widget.hpp +++ b/firmware/common/ui_widget.hpp @@ -215,12 +215,14 @@ class ProgressBar : public Widget { public: ProgressBar(Rect parent_rect); + void set_max(const uint16_t max); void set_value(const uint16_t value); void paint(Painter& painter) override; private: uint16_t _value = 0; + uint16_t _max = 100; }; class Checkbox : public Widget { @@ -229,6 +231,11 @@ public: Checkbox(Point parent_pos, size_t length, std::string text); + Checkbox( + ) : Checkbox { { }, { }, { } } + { + } + void set_text(const std::string value); std::string text() const; void set_value(const bool value); diff --git a/firmware/portapack-h1-firmware.bin b/firmware/portapack-h1-firmware.bin index e2157b8b..21644d68 100644 Binary files a/firmware/portapack-h1-firmware.bin and b/firmware/portapack-h1-firmware.bin differ