diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index d53b8c22..d3e48644 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -151,7 +151,7 @@ set(CPPSRC modems.cpp audio.cpp ${COMMON}/bch_code.cpp - ctcss.cpp + tone_key.cpp de_bruijn.cpp encoder.cpp emu_cc1101.cpp diff --git a/firmware/application/ctcss.cpp b/firmware/application/ctcss.cpp deleted file mode 100644 index 58e8dd4a..00000000 --- a/firmware/application/ctcss.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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" -#include "string_format.hpp" - -namespace ctcss { - -const ctcss_tone ctcss_tones[CTCSS_TONES_NB] = { - { "XZ", 0, 67.000 }, - { "WZ", 1, 69.400 }, - { "XA", 2, 71.900 }, - { "WA", 3, 74.400 }, - { "XB", 4, 77.000 }, - { "WB", 5, 79.700 }, - { "YZ", 6, 82.500 }, - { "YA", 7, 85.400 }, - { "YB", 8, 88.500 }, - { "ZZ", 9, 91.500 }, - { "ZA", 10, 94.800 }, - { "ZB", 11, 97.400 }, - { "1Z", 12, 100.000 }, - { "1A", 13, 103.500 }, - { "1B", 14, 107.200 }, - { "2Z", 15, 110.900 }, - { "2Z", 16, 114.800 }, - { "2B", 17, 118.800 }, - { "3Z", 18, 123.000 }, - { "3A", 19, 127.300 }, - { "3B", 20, 131.800 }, - { "4Z", 21, 136.500 }, - { "4A", 22, 141.300 }, - { "4B", 23, 146.200 }, - { "5Z", 24, 151.400 }, - { "5A", 25, 156.700 }, - { "--", 40, 159.800 }, - { "5B", 26, 162.200 }, - { "--", 41, 165.500 }, - { "6Z", 27, 167.900 }, - { "--", 42, 171.300 }, - { "6A", 28, 173.800 }, - { "--", 43, 177.300 }, - { "6B", 29, 179.900 }, - { "--", 44, 183.500 }, - { "7Z", 30, 186.200 }, - { "--", 45, 189.900 }, - { "7A", 31, 192.800 }, - { "--", 46, 196.600 }, - { "--", 47, 199.500 }, - { "M1", 32, 203.500 }, - { "8Z", 48, 206.500 }, - { "M2", 33, 210.700 }, - { "M3", 34, 218.100 }, - { "M4", 35, 225.700 }, - { "9Z", 49, 229.100 }, - { "--", 36, 233.600 }, - { "--", 37, 241.800 }, - { "--", 38, 250.300 }, - { "0Z", 50, 254.100 } -}; - -void ctcss_populate(OptionsField& field) { - using option_t = std::pair; - using options_t = std::vector; - options_t ctcss_options; - std::string f_string; - uint32_t c, f; - - ctcss_options.emplace_back(std::make_pair("None", 0)); - for (c = 0; c < CTCSS_TONES_NB; c++) { - f = (uint32_t)(ctcss_tones[c].frequency * 10); - f_string = ctcss_tones[c].PL_code; - f_string += " " + to_string_dec_uint(f / 10) + "." + to_string_dec_uint(f % 10); - ctcss_options.emplace_back(f_string, c); - } - - field.set_options(ctcss_options); -} - -} diff --git a/firmware/application/tone_key.cpp b/firmware/application/tone_key.cpp new file mode 100644 index 00000000..c34c1853 --- /dev/null +++ b/firmware/application/tone_key.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2017 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 "tone_key.hpp" +#include "string_format.hpp" + +namespace tonekey { + +const tone_key_t tone_keys[] = { + { "0 XZ", 67.000 }, + { "1 WZ", 69.400 }, + { "2 XA", 71.900 }, + { "3 WA", 74.400 }, + { "4 XB", 77.000 }, + { "5 WB", 79.700 }, + { "6 YZ", 82.500 }, + { "7 YA", 85.400 }, + { "8 YB", 88.500 }, + { "9 ZZ", 91.500 }, + { "10 ZA", 94.800 }, + { "11 1ZB", 97.400 }, + { "12 21Z", 100.000 }, + { "13 1A", 103.500 }, + { "14 1B", 107.200 }, + { "15 2Z", 110.900 }, + { "16 2Z", 114.800 }, + { "17 2B", 118.800 }, + { "18 3Z", 123.000 }, + { "19 3A", 127.300 }, + { "20 3B", 131.800 }, + { "21 4Z", 136.500 }, + { "22 4A", 141.300 }, + { "23 4B", 146.200 }, + { "24 5Z", 151.400 }, + { "25 5A", 156.700 }, + { "40 --", 159.800 }, + { "26 5B", 162.200 }, + { "41 --", 165.500 }, + { "27 6Z", 167.900 }, + { "42 --", 171.300 }, + { "28 6A", 173.800 }, + { "43 --", 177.300 }, + { "29 6B", 179.900 }, + { "44 --", 183.500 }, + { "30 7Z", 186.200 }, + { "45 --", 189.900 }, + { "31 7A", 192.800 }, + { "46 --", 196.600 }, + { "47 --", 199.500 }, + { "32 M1", 203.500 }, + { "48 8Z", 206.500 }, + { "33 M2", 210.700 }, + { "34 M3", 218.100 }, + { "35 M4", 225.700 }, + { "49 9Z", 229.100 }, + { "36 --", 233.600 }, + { "37 --", 241.800 }, + { "38 --", 250.300 }, + { "50 0Z", 254.100 }, + { "Axient 28kHz", 28000.0 }, + { "Sennheiser 32.768k", 32768.0 }, + { "Sennheiser 32kHz", 32000.0 }, + { "Shure 19kHz", 19000.0 } +}; + +void tone_keys_populate(OptionsField& field) { + using option_t = std::pair; + using options_t = std::vector; + options_t tone_key_options; + std::string tone_name; + + tone_key_options.emplace_back(std::make_pair("None", 0)); + for (size_t c = 0; c < KEY_TONES_NB; c++) { + if (c < 50) + tone_name = "CTCSS " + tone_keys[c].first; + else + tone_name = tone_keys[c].first; + tone_key_options.emplace_back(tone_name, c); + } + field.set_options(tone_key_options); +} + +} diff --git a/firmware/application/ctcss.hpp b/firmware/application/tone_key.hpp similarity index 74% rename from firmware/application/ctcss.hpp rename to firmware/application/tone_key.hpp index b5a47df9..d16faf62 100644 --- a/firmware/application/ctcss.hpp +++ b/firmware/application/tone_key.hpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. - * Copyright (C) 2016 Furrtek + * Copyright (C) 2017 Furrtek * * This file is part of PortaPack. * @@ -20,28 +20,24 @@ * Boston, MA 02110-1301, USA. */ -#ifndef __CTCSS_H_ -#define __CTCSS_H_ +#ifndef __TONE_KEY_H_ +#define __TONE_KEY_H_ #include "ui.hpp" #include "ui_widget.hpp" using namespace ui; -#define CTCSS_TONES_NB 50 +#define KEY_TONES_NB (sizeof(tone_keys) / sizeof(tone_keys[0])) -namespace ctcss { - -struct ctcss_tone { - char PL_code[3]; - uint16_t num_code; - float frequency; -}; +namespace tonekey { -extern const ctcss_tone ctcss_tones[CTCSS_TONES_NB]; +using tone_key_t = std::pair; -void ctcss_populate(OptionsField& field); +extern const tone_key_t tone_keys[]; + +void tone_keys_populate(OptionsField& field); } -#endif/*__CTCSS_H_*/ +#endif/*__TONE_KEY_H_*/ diff --git a/firmware/application/ui_mictx.cpp b/firmware/application/ui_mictx.cpp index ab6c1dbd..fec6c966 100644 --- a/firmware/application/ui_mictx.cpp +++ b/firmware/application/ui_mictx.cpp @@ -25,6 +25,7 @@ #include "baseband_api.hpp" #include "hackrf_gpio.hpp" #include "audio.hpp" +#include "tonesets.hpp" #include "portapack.hpp" #include "pins.hpp" #include "string_format.hpp" @@ -33,7 +34,7 @@ #include -using namespace ctcss; +using namespace tonekey; using namespace portapack; using namespace hackrf::one; @@ -47,52 +48,38 @@ void MicTXView::update_vumeter() { vumeter.set_value(audio_level); } -void MicTXView::on_tx_progress(const uint32_t progress, const bool done) { - (void)progress; - (void)done; - - // Roger beep transmitted, stop transmitting - set_tx(false); +void MicTXView::on_tx_progress(const bool done) { + // Roger beep played, stop transmitting + if (done) + set_tx(false); +} + +void MicTXView::configure_baseband() { + baseband::set_audiotx_data( + sampling_rate / 20, // Update vu-meter at 20Hz + transmitting ? transmitter_model.channel_bandwidth() : 0, + mic_gain_x10, + transmitting ? tone_key_enabled : false, + TONES_F2D(tone_keys[tone_key_index].second) + ); } void MicTXView::set_tx(bool enable) { - uint32_t ctcss_index; - bool ctcss_enabled; - if (enable) { - ctcss_index = options_ctcss.selected_index(); - - if (ctcss_index) { - ctcss_enabled = true; - ctcss_index--; - } else - ctcss_enabled = false; - - baseband::set_audiotx_data( - 1536000U / 20, // 20Hz level update - transmitter_model.channel_bandwidth(), - mic_gain_x10, - ctcss_enabled, - (uint32_t)((ctcss_tones[ctcss_index].frequency / 1536000.0) * 0xFFFFFFFFULL) - ); + transmitting = true; + configure_baseband(); gpio_tx.write(1); led_tx.on(); - transmitting = true; } else { if (transmitting && rogerbeep_enabled) { baseband::request_beep(); + transmitting = false; } else { - baseband::set_audiotx_data( - 1536000U / 20, // 20Hz level update - 0, // BW 0 = TX off - mic_gain_x10, - false, // Ignore CTCSS - 0 - ); + transmitting = false; + configure_baseband(); gpio_tx.write(0); led_tx.off(); } - transmitting = false; } } @@ -106,7 +93,7 @@ void MicTXView::do_timing() { attack_timer = 0; set_tx(true); } else { - attack_timer += ((256 * 1000) / 60); // 1 frame @ 60fps in ms .8 fixed point + attack_timer += lcd_frame_duration; } } else { attack_timer = 0; @@ -119,16 +106,16 @@ void MicTXView::do_timing() { attack_timer = 0; set_tx(false); } else { - decay_timer += ((256 * 1000) / 60); // 1 frame @ 60fps in ms .8 fixed point + decay_timer += lcd_frame_duration; } } else { decay_timer = 0; } } } else { - // PTT disable :( + // Check for PTT release const auto switches_state = get_switches_state(); - if (!switches_state[1] && transmitting) // Left button + if (!switches_state[0] && transmitting) // Right button set_tx(false); } } @@ -155,17 +142,26 @@ MicTXView::MicTXView( &field_va_decay, &field_bw, &field_frequency, - &options_ctcss, + &options_tone_key, &check_rogerbeep, - &text_ptt, - &button_exit + &text_ptt }); - ctcss_populate(options_ctcss); - options_ctcss.set_selected_index(0); + tone_keys_populate(options_tone_key); + options_tone_key.on_change = [this](size_t i, int32_t) { + tone_key_index = i; + + if (tone_key_index) { + tone_key_enabled = true; + tone_key_index--; + } else + tone_key_enabled = false; + }; + options_tone_key.set_selected_index(0); options_gain.on_change = [this](size_t, int32_t v) { mic_gain_x10 = v; + configure_baseband(); }; options_gain.set_selected_index(1); // x1.0 @@ -214,21 +210,17 @@ MicTXView::MicTXView( field_va_decay.on_change = [this](int32_t v) { decay_ms = v; }; - field_va_decay.set_value(2000); - - button_exit.on_select = [&nav](Button&){ - nav.pop(); - }; + field_va_decay.set_value(1000); // Run baseband as soon as the app starts to get audio levels without transmitting (rf amp off) - transmitter_model.set_sampling_rate(1536000U); + transmitter_model.set_sampling_rate(sampling_rate); transmitter_model.set_rf_amp(true); transmitter_model.set_baseband_bandwidth(1750000); transmitter_model.enable(); set_tx(false); - audio::set_rate(audio::Rate::Hz_24000); + audio::set_rate(audio::Rate::Hz_48000); audio::input::start(); } diff --git a/firmware/application/ui_mictx.hpp b/firmware/application/ui_mictx.hpp index 0e09d800..561b6533 100644 --- a/firmware/application/ui_mictx.hpp +++ b/firmware/application/ui_mictx.hpp @@ -28,10 +28,10 @@ #include "ui_widget.hpp" #include "ui_navigation.hpp" #include "ui_font_fixed_8x16.hpp" -#include "message.hpp" #include "ui_receiver.hpp" #include "transmitter_model.hpp" -#include "ctcss.hpp" +#include "tone_key.hpp" +#include "message.hpp" namespace ui { @@ -49,7 +49,7 @@ public: // PTT: Enable through KeyEvent (only works with presses), disable by polling :( bool on_key(const KeyEvent key) { - if ((key == KeyEvent::Left) && (!va_enabled)) { + if ((key == KeyEvent::Right) && (!va_enabled)) { set_tx(true); return true; } else @@ -59,16 +59,21 @@ public: std::string title() const override { return "Microphone TX"; }; private: + static constexpr uint32_t sampling_rate = 1536000U; + static constexpr uint32_t lcd_frame_duration = (256 * 1000UL) / 60; // 1 frame @ 60fps in ms .8 fixed point + void update_vumeter(); void do_timing(); void set_tx(bool enable); void on_tuning_frequency_changed(rf::Frequency f); - void on_ctcss_changed(uint32_t v); - void on_tx_progress(const uint32_t progress, const bool done); + void on_tx_progress(const bool done); + void configure_baseband(); bool transmitting { false }; bool va_enabled { }; bool rogerbeep_enabled { }; + uint32_t tone_key_index { }; + bool tone_key_enabled { }; uint32_t mic_gain_x10 { }; uint32_t audio_level { 0 }; uint32_t va_level { }; @@ -79,18 +84,17 @@ private: Labels labels { { { 7 * 8, 1 * 8 }, "Mic. gain:", Color::light_grey() }, - { { 7 * 8, 4 * 8 }, "Voice activation:", Color::light_grey() }, - { { 8 * 8, 9 * 8 }, "Level: /255", Color::light_grey() }, - { { 8 * 8, 11 * 8 }, "Attack: ms", Color::light_grey() }, - { { 8 * 8, 13 * 8 }, "Decay: ms", Color::light_grey() }, - { { 7 * 8, 17 * 8 }, "Bandwidth: kHz", Color::light_grey() }, - { { 7 * 8, 19 * 8 }, "Frequency:", Color::light_grey() }, - { { 11 * 8, 21 * 8 }, "CTCSS:", Color::light_grey() } + { { 7 * 8, 4 * 8 }, "Frequency:", Color::light_grey() }, + { { 7 * 8, 6 * 8 }, "Bandwidth: kHz", Color::light_grey() }, + { { 9 * 8, 13 * 8 }, "Level: /255", Color::light_grey() }, + { { 9 * 8, 15 * 8 }, "Attack: ms", Color::light_grey() }, + { { 9 * 8, 17 * 8 }, "Decay: ms", Color::light_grey() }, + { { 7 * 8, 21 * 8 }, "Tone key:", Color::light_grey() } }; VuMeter vumeter { - { 1 * 8, 2 * 8, 5 * 8, 26 * 8 }, - 16, + { 1 * 8, 2 * 8, 5 * 8, 32 * 8 }, + 20, false }; @@ -105,67 +109,62 @@ private: } }; + FrequencyField field_frequency { + { 17 * 8, 4 * 8 }, + }; + NumberField field_bw { + { 17 * 8, 6 * 8 }, + 3, + { 0, 150 }, + 1, + ' ' + }; + Checkbox check_va { - { 8 * 8, 6 * 8 }, + { 7 * 8, 10 * 8 }, 7, - "Enabled", + "Voice activation", false }; NumberField field_va_level { - { 14 * 8, 9 * 8 }, + { 15 * 8, 13 * 8 }, 3, { 0, 255 }, 2, ' ' }; NumberField field_va_attack { - { 15 * 8, 11 * 8 }, + { 16 * 8, 15 * 8 }, 3, { 0, 999 }, 20, ' ' }; NumberField field_va_decay { - { 14 * 8, 13 * 8 }, + { 15 * 8, 17 * 8 }, 4, { 0, 9999 }, 100, ' ' }; - NumberField field_bw { - { 17 * 8, 17 * 8 }, - 3, - { 0, 150 }, - 1, - ' ' - }; - FrequencyField field_frequency { - { 17 * 8, 19 * 8 }, - }; - - OptionsField options_ctcss { - { 17 * 8, 21 * 8 }, - 8, + OptionsField options_tone_key { + { 7 * 8, 23 * 8 }, + 23, { } }; Checkbox check_rogerbeep { - { 8 * 8, 23 * 8 }, + { 7 * 8, 26 * 8 }, 10, "Roger beep", false }; Text text_ptt { - { 7 * 8, 28 * 8, 16 * 8, 16 }, - "PTT: LEFT BUTTON" - }; - - Button button_exit { - { 18 * 8, 32 * 8, 10 * 8, 40 }, - "Exit" + { 7 * 8, 17 * 16, 16 * 8, 16 }, + "PTT: RIGHT BUTTON" }; MessageHandlerRegistration message_handler_lcd_sync { @@ -188,7 +187,7 @@ private: Message::ID::TXProgress, [this](const Message* const p) { const auto message = *reinterpret_cast(p); - this->on_tx_progress(message.progress, message.done); + this->on_tx_progress(message.done); } }; }; diff --git a/firmware/application/ui_soundboard.cpp b/firmware/application/ui_soundboard.cpp index cad24075..d48234a2 100644 --- a/firmware/application/ui_soundboard.cpp +++ b/firmware/application/ui_soundboard.cpp @@ -27,7 +27,7 @@ #include "lfsr_random.hpp" #include "string_format.hpp" -using namespace ctcss; +using namespace tonekey; using namespace portapack; namespace ui { @@ -95,8 +95,8 @@ void SoundBoardView::on_tuning_frequency_changed(rf::Frequency f) { } void SoundBoardView::play_sound(uint16_t id) { - uint32_t ctcss_index; - bool ctcss_enabled; + uint32_t tone_key_index; + bool tone_key_enabled; uint32_t divider; if (sounds[id].size == 0) return; @@ -119,13 +119,13 @@ void SoundBoardView::play_sound(uint16_t id) { transmitter_model.set_baseband_bandwidth(1750000); transmitter_model.enable(); - ctcss_index = options_ctcss.selected_index(); + tone_key_index = options_tone_key.selected_index(); - if (ctcss_index) { - ctcss_enabled = true; - ctcss_index--; + if (tone_key_index) { + tone_key_enabled = true; + tone_key_index--; } else - ctcss_enabled = false; + tone_key_enabled = false; divider = (1536000 / sounds[id].sample_rate) - 1; @@ -133,8 +133,8 @@ void SoundBoardView::play_sound(uint16_t id) { divider, number_bw.value() * 1000, 1, - ctcss_enabled, - (uint32_t)((ctcss_tones[ctcss_index].frequency / 1536000.0) * 0xFFFFFFFFULL) + tone_key_enabled, + (uint32_t)((tone_keys[tone_key_index].second / 1536000.0) * 0xFFFFFFFFULL) ); } @@ -230,7 +230,7 @@ SoundBoardView::SoundBoardView( &field_frequency, &number_bw, &text_kHz, - &options_ctcss, + &options_tone_key, &text_title, &text_page, &text_duration, @@ -240,8 +240,8 @@ SoundBoardView::SoundBoardView( &button_exit }); - ctcss_populate(options_ctcss); - options_ctcss.set_selected_index(0); + tone_keys_populate(options_tone_key); + options_tone_key.set_selected_index(0); const auto button_fn = [this](Button& button) { tx_mode = NORMAL; diff --git a/firmware/application/ui_soundboard.hpp b/firmware/application/ui_soundboard.hpp index 828fbaf8..013645b4 100644 --- a/firmware/application/ui_soundboard.hpp +++ b/firmware/application/ui_soundboard.hpp @@ -29,7 +29,7 @@ #include "baseband_api.hpp" #include "ui_receiver.hpp" #include "io_wave.hpp" -#include "ctcss.hpp" +#include "tone_key.hpp" namespace ui { @@ -132,7 +132,7 @@ private: "k CTCSS:" }; - OptionsField options_ctcss { + OptionsField options_tone_key { { 21 * 8, 4 }, 8, { } diff --git a/firmware/baseband/proc_mictx.cpp b/firmware/baseband/proc_mictx.cpp index 9a1aa0ec..9fb10515 100644 --- a/firmware/baseband/proc_mictx.cpp +++ b/firmware/baseband/proc_mictx.cpp @@ -36,10 +36,10 @@ void MicTXProcessor::execute(const buffer_c8_t& buffer){ audio_input.read_audio_buffer(audio_buffer); - for (size_t i = 0; i> 6] >> 8; // 1536000 / 64 = 24000 + sample = audio_buffer.p[i >> 5] >> 8; // 1536000 / 32 = 48000 sample = (sample * (int32_t)gain_x10) / 10; power += (sample < 0) ? -sample : sample; // Power average for UI vu-meter @@ -56,10 +56,10 @@ void MicTXProcessor::execute(const buffer_c8_t& buffer){ if (beep_timer) { beep_timer--; } else { - beep_timer = 76800; // 50ms @ 1536000Hz + beep_timer = 76800; // 50ms @ 1536000Hz if (beep_index == BEEP_TONES_NB) { configured = false; - fm_delta = 0; // Zero-out the IQ output for the rest of the buffer + fm_delta = 0; // Zero-out the IQ output for the rest of the buffer shared_memory.application_queue.push(txprogress_message); } else { beep_phase_inc = beep_deltas[beep_index]; @@ -102,7 +102,7 @@ void MicTXProcessor::on_message(const Message* const msg) { switch(msg->id) { case Message::ID::AudioTXConfig: - fm_delta = config_message.fm_delta * (0xFFFFFFULL / 1536000); + fm_delta = config_message.fm_delta * (0xFFFFFFULL / baseband_fs); gain_x10 = config_message.gain_x10; divider = config_message.divider; ctcss_enabled = config_message.ctcss_enabled; diff --git a/firmware/baseband/proc_mictx.hpp b/firmware/baseband/proc_mictx.hpp index 003b9fc1..62ec047c 100644 --- a/firmware/baseband/proc_mictx.hpp +++ b/firmware/baseband/proc_mictx.hpp @@ -34,9 +34,11 @@ public: void on_message(const Message* const msg) override; private: + static constexpr size_t baseband_fs = 1536000U; + bool configured { false }; - BasebandThread baseband_thread { 1536000, this, NORMALPRIO + 20, baseband::Direction::Transmit }; + BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Transmit }; int16_t audio_data[64]; buffer_s16_t audio_buffer { diff --git a/firmware/common/ui_widget.cpp b/firmware/common/ui_widget.cpp index 3c9bc96a..2dac2383 100644 --- a/firmware/common/ui_widget.cpp +++ b/firmware/common/ui_widget.cpp @@ -1650,8 +1650,8 @@ void VuMeter::paint(Painter& painter) { } } - // Draw mark - if ((mark != prev_mark) && (mark)) { + // Draw mark (forced refresh) + if (mark) { painter.draw_hline({ marks_x, bottom - (height * prev_mark) / 256 }, 8, Color::black()); painter.draw_hline({ marks_x, bottom - (height * mark) / 256 }, 8, Color::grey()); prev_mark = mark; diff --git a/firmware/portapack-h1-havoc.bin b/firmware/portapack-h1-havoc.bin index 7a04171e..fe122fd2 100644 Binary files a/firmware/portapack-h1-havoc.bin and b/firmware/portapack-h1-havoc.bin differ