Merge pull request #161 from dqs105/mic_tx_rfgain

Added TX Gain control & code simplification
This commit is contained in:
Erwin Ried 2020-09-14 22:50:35 +02:00 committed by GitHub
commit 3aaa4a0ba1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 288 additions and 43 deletions

View File

@ -37,7 +37,17 @@ using namespace portapack;
namespace ui { namespace ui {
void MicTXView::focus() { void MicTXView::focus() {
field_frequency.focus(); switch(focused_ui) {
case 0:
field_frequency.focus();
break;
case 1:
field_rxfrequency.focus();
break;
default:
field_va.focus();
break;
}
} }
void MicTXView::update_vumeter() { void MicTXView::update_vumeter() {
@ -65,6 +75,9 @@ void MicTXView::set_tx(bool enable) {
rxaudio(false); //Then turn off audio RX rxaudio(false); //Then turn off audio RX
transmitting = true; transmitting = true;
configure_baseband(); configure_baseband();
transmitter_model.set_tuning_frequency(tx_frequency);
transmitter_model.set_tx_gain(tx_gain);
transmitter_model.set_rf_amp(rf_amp);
transmitter_model.enable(); transmitter_model.enable();
portapack::pin_i2s0_rx_sda.mode(3); // This is already done in audio::init but gets changed by the CPLD overlay reprogramming portapack::pin_i2s0_rx_sda.mode(3); // This is already done in audio::init but gets changed by the CPLD overlay reprogramming
} else { } else {
@ -113,16 +126,18 @@ void MicTXView::do_timing() {
} else { } else {
// Check for PTT release // Check for PTT release
const auto switches_state = get_switches_state(); const auto switches_state = get_switches_state();
if (!switches_state[0] && transmitting) // Right button if (!switches_state[4] && transmitting && !button_touch) // Select button
set_tx(false); set_tx(false);
} }
} }
/* Hmmmm. Maybe useless now.
void MicTXView::on_tuning_frequency_changed(rf::Frequency f) { void MicTXView::on_tuning_frequency_changed(rf::Frequency f) {
transmitter_model.set_tuning_frequency(f); transmitter_model.set_tuning_frequency(f);
//if ( rx_enabled ) //if ( rx_enabled )
receiver_model.set_tuning_frequency(f); //Update freq also for RX receiver_model.set_tuning_frequency(f); //Update freq also for RX
} }
*/
void MicTXView::rxaudio(bool is_on) { void MicTXView::rxaudio(bool is_on) {
if (is_on) { if (is_on) {
@ -132,7 +147,11 @@ void MicTXView::rxaudio(bool is_on) {
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
receiver_model.set_sampling_rate(3072000); receiver_model.set_sampling_rate(3072000);
receiver_model.set_baseband_bandwidth(1750000); receiver_model.set_baseband_bandwidth(1750000);
receiver_model.set_tuning_frequency(field_frequency.value()); //probably this too can be commented out. // receiver_model.set_tuning_frequency(field_frequency.value()); //probably this too can be commented out.
receiver_model.set_tuning_frequency(rx_frequency); // Now with seperate controls!
receiver_model.set_lna(rx_lna);
receiver_model.set_vga(rx_vga);
receiver_model.set_rf_amp(rx_amp);
receiver_model.enable(); receiver_model.enable();
audio::output::start(); audio::output::start();
} else { //These incredibly convoluted steps are required for the vumeter to reappear when stopping RX. } else { //These incredibly convoluted steps are required for the vumeter to reappear when stopping RX.
@ -140,11 +159,11 @@ void MicTXView::rxaudio(bool is_on) {
baseband::shutdown(); baseband::shutdown();
baseband::run_image(portapack::spi_flash::image_tag_mic_tx); baseband::run_image(portapack::spi_flash::image_tag_mic_tx);
audio::input::start(); audio::input::start();
transmitter_model.enable(); // transmitter_model.enable();
portapack::pin_i2s0_rx_sda.mode(3); portapack::pin_i2s0_rx_sda.mode(3);
transmitting = false; // transmitting = false;
configure_baseband(); configure_baseband();
transmitter_model.disable(); // transmitter_model.disable();
} }
} }
@ -155,6 +174,10 @@ void MicTXView::on_headphone_volume_changed(int32_t v) {
//} //}
} }
void MicTXView::set_ptt_visibility(bool v) {
tx_button.hidden(!v);
}
MicTXView::MicTXView( MicTXView::MicTXView(
NavigationView& nav NavigationView& nav
) )
@ -167,18 +190,25 @@ MicTXView::MicTXView(
&labels, &labels,
&vumeter, &vumeter,
&options_gain, &options_gain,
&check_va, // &check_va,
&field_va,
&field_va_level, &field_va_level,
&field_va_attack, &field_va_attack,
&field_va_decay, &field_va_decay,
&field_bw, &field_bw,
&field_rfgain,
&field_rfamp,
&field_frequency, &field_frequency,
&options_tone_key, &options_tone_key,
&check_rogerbeep, &check_rogerbeep,
&check_rxactive, &check_rxactive,
&field_volume, &field_volume,
&field_squelch, &field_squelch,
&text_ptt &field_rxfrequency,
&field_rxlna,
&field_rxvga,
&field_rxamp,
&tx_button
}); });
tone_keys_populate(options_tone_key); tone_keys_populate(options_tone_key);
@ -193,16 +223,22 @@ MicTXView::MicTXView(
}; };
options_gain.set_selected_index(1); // x1.0 options_gain.set_selected_index(1); // x1.0
tx_frequency = transmitter_model.tuning_frequency();
field_frequency.set_value(transmitter_model.tuning_frequency()); field_frequency.set_value(transmitter_model.tuning_frequency());
field_frequency.set_step(receiver_model.frequency_step()); field_frequency.set_step(receiver_model.frequency_step());
field_frequency.on_change = [this](rf::Frequency f) { field_frequency.on_change = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f); tx_frequency = f;
if(!rx_enabled)
transmitter_model.set_tuning_frequency(f);
}; };
field_frequency.on_edit = [this, &nav]() { field_frequency.on_edit = [this, &nav]() {
focused_ui = 0;
// TODO: Provide separate modal method/scheme? // TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency()); auto new_view = nav.push<FrequencyKeypadView>(tx_frequency);
new_view->on_changed = [this](rf::Frequency f) { new_view->on_changed = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f); tx_frequency = f;
if(!rx_enabled)
transmitter_model.set_tuning_frequency(f);
this->field_frequency.set_value(f); this->field_frequency.set_value(f);
set_dirty(); set_dirty();
}; };
@ -213,13 +249,57 @@ MicTXView::MicTXView(
}; };
field_bw.set_value(10); field_bw.set_value(10);
tx_gain = transmitter_model.tx_gain();
field_rfgain.on_change = [this](int32_t v) {
tx_gain = v;
};
field_rfgain.set_value(tx_gain);
rf_amp = transmitter_model.rf_amp();
field_rfamp.on_change = [this](int32_t v) {
rf_amp = (bool)v;
};
field_rfamp.set_value(rf_amp ? 14 : 0);
/*
check_va.on_select = [this](Checkbox&, bool v) { check_va.on_select = [this](Checkbox&, bool v) {
va_enabled = v; va_enabled = v;
text_ptt.hidden(v); //hide / show PTT text text_ptt.hidden(v); //hide / show PTT text
check_rxactive.hidden(v); //hide / show the RX AUDIO check_rxactive.hidden(v); //hide / show the RX AUDIO
set_dirty(); //Refresh display set_dirty(); //Refresh display
}; };
*/
field_va.set_selected_index(1);
field_va.on_change = [this](size_t, int32_t v) {
switch(v) {
case 0:
va_enabled = 0;
this->set_ptt_visibility(0);
check_rxactive.hidden(0);
ptt_enabled = 0;
break;
case 1:
va_enabled = 0;
this->set_ptt_visibility(1);
check_rxactive.hidden(0);
ptt_enabled = 1;
break;
case 2:
if (!rx_enabled) {
va_enabled = 1;
this->set_ptt_visibility(0);
check_rxactive.hidden(1);
ptt_enabled = 0;
} else {
field_va.set_selected_index(1);
}
break;
}
set_dirty();
};
check_rogerbeep.on_select = [this](Checkbox&, bool v) { check_rogerbeep.on_select = [this](Checkbox&, bool v) {
rogerbeep_enabled = v; rogerbeep_enabled = v;
}; };
@ -241,9 +321,9 @@ MicTXView::MicTXView(
field_va_decay.set_value(1000); field_va_decay.set_value(1000);
check_rxactive.on_select = [this](Checkbox&, bool v) { check_rxactive.on_select = [this](Checkbox&, bool v) {
//vumeter.set_value(0); //Start with a clean vumeter // vumeter.set_value(0); //Start with a clean vumeter
rx_enabled = v; rx_enabled = v;
check_va.hidden(v); //Hide or show voice activation // check_va.hidden(v); //Hide or show voice activation
rxaudio(v); //Activate-Deactivate audio rx accordingly rxaudio(v); //Activate-Deactivate audio rx accordingly
set_dirty(); //Refresh interface set_dirty(); //Refresh interface
}; };
@ -257,6 +337,71 @@ MicTXView::MicTXView(
field_squelch.set_value(0); field_squelch.set_value(0);
receiver_model.set_squelch_level(0); receiver_model.set_squelch_level(0);
rx_frequency = receiver_model.tuning_frequency();
field_rxfrequency.set_value(rx_frequency);
field_rxfrequency.set_step(receiver_model.frequency_step());
field_rxfrequency.on_change = [this](rf::Frequency f) {
rx_frequency = f;
if(rx_enabled)
receiver_model.set_tuning_frequency(f);
};
field_rxfrequency.on_edit = [this, &nav]() {
focused_ui = 1;
// TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(rx_frequency);
new_view->on_changed = [this](rf::Frequency f) {
rx_frequency = f;
if(rx_enabled)
receiver_model.set_tuning_frequency(f);
this->field_rxfrequency.set_value(f);
set_dirty();
};
};
rx_lna = receiver_model.lna();
field_rxlna.on_change = [this](int32_t v) {
rx_lna = v;
if(rx_enabled)
receiver_model.set_lna(v);
};
field_rxlna.set_value(rx_lna);
rx_vga = receiver_model.vga();
field_rxvga.on_change = [this](int32_t v) {
rx_vga = v;
if(rx_enabled)
receiver_model.set_vga(v);
};
field_rxvga.set_value(rx_vga);
rx_amp = receiver_model.rf_amp();
field_rxamp.on_change = [this](int32_t v) {
rx_amp = v;
if(rx_enabled)
receiver_model.set_rf_amp(rx_amp);
};
field_rxamp.set_value(rx_amp);
tx_button.on_select = [this](Button&) {
if(ptt_enabled && !transmitting) {
set_tx(true);
}
};
tx_button.on_touch_release = [this](Button&) {
if(button_touch) {
button_touch = false;
set_tx(false);
}
};
tx_button.on_touch_press = [this](Button&) {
if(!transmitting) {
button_touch = true;
}
};
transmitter_model.set_sampling_rate(sampling_rate); transmitter_model.set_sampling_rate(sampling_rate);
transmitter_model.set_baseband_bandwidth(1750000); transmitter_model.set_baseband_bandwidth(1750000);
@ -268,6 +413,7 @@ MicTXView::MicTXView(
MicTXView::~MicTXView() { MicTXView::~MicTXView() {
audio::input::stop(); audio::input::stop();
transmitter_model.set_tuning_frequency(tx_frequency); // Save Tx frequency instead of Rx. Or maybe we need some "System Wide" changes to seperate Tx and Rx frequency.
transmitter_model.disable(); transmitter_model.disable();
if (rx_enabled) //Also turn off audio rx if enabled if (rx_enabled) //Also turn off audio rx if enabled
rxaudio(false); rxaudio(false);

View File

@ -47,14 +47,17 @@ public:
void focus() override; void focus() override;
// PTT: Enable through KeyEvent (only works with presses), disable by polling :( // PTT: Enable through KeyEvent (only works with presses), disable by polling :(
// This is the old "RIGHT BUTTON" method.
/*
bool on_key(const KeyEvent key) { bool on_key(const KeyEvent key) {
if ((key == KeyEvent::Right) && (!va_enabled)) { if ((key == KeyEvent::Right) && (!va_enabled) && ptt_enabled) {
set_tx(true); set_tx(true);
return true; return true;
} else } else
return false; return false;
}; };
*/
std::string title() const override { return "Mic TX RX"; }; std::string title() const override { return "Mic TX RX"; };
private: private:
@ -64,15 +67,18 @@ private:
void update_vumeter(); void update_vumeter();
void do_timing(); void do_timing();
void set_tx(bool enable); void set_tx(bool enable);
void on_tuning_frequency_changed(rf::Frequency f); // void on_tuning_frequency_changed(rf::Frequency f);
void on_tx_progress(const bool done); void on_tx_progress(const bool done);
void configure_baseband(); void configure_baseband();
void rxaudio(bool is_on); void rxaudio(bool is_on);
void on_headphone_volume_changed(int32_t v); void on_headphone_volume_changed(int32_t v);
void set_ptt_visibility(bool v);
bool transmitting { false }; bool transmitting { false };
bool va_enabled { false }; bool va_enabled { false };
bool ptt_enabled { true };
bool rogerbeep_enabled { false }; bool rogerbeep_enabled { false };
bool rx_enabled { false }; bool rx_enabled { false };
uint32_t tone_key_index { }; uint32_t tone_key_index { };
@ -83,17 +89,34 @@ private:
uint32_t decay_ms { }; uint32_t decay_ms { };
uint32_t attack_timer { 0 }; uint32_t attack_timer { 0 };
uint32_t decay_timer { 0 }; uint32_t decay_timer { 0 };
int32_t tx_gain { 47 };
bool rf_amp { false };
int32_t rx_lna { 32 };
int32_t rx_vga { 32 };
bool rx_amp { false };
rf::Frequency tx_frequency { 0 };
rf::Frequency rx_frequency { 0 };
int32_t focused_ui { 2 };
bool button_touch { false };
Labels labels { Labels labels {
{ { 3 * 8, 1 * 8 }, "MIC. GAIN:", Color::light_grey() }, { { 3 * 8, 1 * 8 }, "MIC. GAIN:", Color::light_grey() },
{ { 3 * 8, 3 * 8 }, "FREQUENCY:", Color::light_grey() }, { { 3 * 8, 3 * 8 }, "F:", Color::light_grey() },
{ { 3 * 8, 5 * 8 }, "BANDWIDTH: kHz", Color::light_grey() }, { { 15 * 8, 3 * 8 }, "BW: kHz", Color::light_grey() },
{ { 7 * 8, 11 * 8 }, "LEVEL: /255", Color::light_grey() }, { { 3 * 8, 5 * 8 }, "GAIN:", Color::light_grey() },
{ { 6 * 8, 13 * 8 }, "ATTACK: ms", Color::light_grey() }, { {11 * 8, 5 * 8 }, "Amp:", Color::light_grey() },
{ { 7 * 8, 15 * 8 }, "DECAY: ms", Color::light_grey() }, { { 3 * 8, 8 * 8 }, "TX Activation:", Color::light_grey() },
{ { 4 * 8, 18 * 8 }, "TONE KEY:", Color::light_grey() }, { { 4 * 8, 10 * 8 }, "LVL:", Color::light_grey() },
{ { 9 * 8, 30 * 8 }, "VOL:", Color::light_grey() }, { {12 * 8, 10 * 8 }, "ATT:", Color::light_grey() },
{ { 5 * 8, 32 * 8 }, "SQUELCH:", Color::light_grey() } { {20 * 8, 10 * 8 }, "DEC:", Color::light_grey() },
{ { 4 * 8, ( 13 * 8 ) - 2 }, "TONE KEY:", Color::light_grey() },
{ { 9 * 8, 23 * 8 }, "VOL:", Color::light_grey() },
{ {17 * 8, 25 * 8 }, "SQ:", Color::light_grey() },
{ { 5 * 8, 25 * 8 }, "F:", Color::light_grey() },
{ { 5 * 8, 27 * 8 }, "LNA:", Color::light_grey()},
{ {12 * 8, 27 * 8 }, "VGA:", Color::light_grey()},
{ {19 * 8, 27 * 8 }, "AMP:", Color::light_grey()}
}; };
VuMeter vumeter { VuMeter vumeter {
@ -101,6 +124,7 @@ private:
12, 12,
true true
}; };
OptionsField options_gain { OptionsField options_gain {
{ 13 * 8, 1 * 8 }, { 13 * 8, 1 * 8 },
@ -114,39 +138,65 @@ private:
}; };
FrequencyField field_frequency { FrequencyField field_frequency {
{ 13 * 8, 3 * 8 }, { 5 * 8, 3 * 8 },
}; };
NumberField field_bw { NumberField field_bw {
{ 13 * 8, 5 * 8 }, { 18 * 8, 3 * 8 },
3, 3,
{ 0, 150 }, { 0, 150 },
1, 1,
' ' ' '
}; };
NumberField field_rfgain {
{ 8 * 8, 5 * 8 },
2,
{ 0, 47 },
1,
' '
};
NumberField field_rfamp {
{ 15 * 8, 5 * 8 },
2,
{ 0, 14 },
14,
' '
};
/*
Checkbox check_va { Checkbox check_va {
{ 3 * 8, (9 * 8) - 4 }, { 3 * 8, (10 * 8) - 4 },
7, 7,
"Voice activation", "Voice activation",
false false
}; };
*/
OptionsField field_va {
{ 17 * 8, 8 * 8 },
3,
{
{" OFF", 0},
{" PTT", 1},
{"AUTO", 2}
}
};
NumberField field_va_level { NumberField field_va_level {
{ 13 * 8, 11 * 8 }, { 8 * 8, 10 * 8 },
3, 3,
{ 0, 255 }, { 0, 255 },
2, 2,
' ' ' '
}; };
NumberField field_va_attack { NumberField field_va_attack {
{ 13 * 8, 13 * 8 }, { 16 * 8, 10 * 8 },
3, 3,
{ 0, 999 }, { 0, 999 },
20, 20,
' ' ' '
}; };
NumberField field_va_decay { NumberField field_va_decay {
{ 13 * 8, 15 * 8 }, { 24 * 8, 10 * 8 },
4, 4,
{ 0, 9999 }, { 0, 9999 },
100, 100,
@ -154,27 +204,27 @@ private:
}; };
OptionsField options_tone_key { OptionsField options_tone_key {
{ 10 * 8, 20 * 8 }, { 10 * 8, ( 15 * 8 ) - 2 },
23, 23,
{ } { }
}; };
Checkbox check_rogerbeep { Checkbox check_rogerbeep {
{ 3 * 8, 23 * 8 }, { 3 * 8, ( 16 * 8 ) + 4 },
10, 10,
"Roger beep", "Roger beep",
false false
}; };
Checkbox check_rxactive { Checkbox check_rxactive {
{ 3 * 8, (27 * 8) + 4 }, { 3 * 8, ( 21 * 8 ) - 4 },
8, 8,
"RX audio listening", "RX audio listening",
false false
}; };
NumberField field_volume { NumberField field_volume {
{ 13 * 8, 30 * 8 }, { 13 * 8, 23 * 8 },
2, 2,
{ 0, 99 }, { 0, 99 },
1, 1,
@ -182,16 +232,45 @@ private:
}; };
NumberField field_squelch { NumberField field_squelch {
{ 13 * 8, 32 * 8 }, { 20 * 8, 25 * 8 },
2, 2,
{ 0, 99 }, { 0, 99 },
1, 1,
' ', ' ',
}; };
Text text_ptt { FrequencyField field_rxfrequency {
{ 7 * 8, 35 * 8, 16 * 8, 16 }, { 7 * 8, 25 * 8 },
"PTT: RIGHT BUTTON" };
NumberField field_rxlna {
{ 9 * 8, 27 * 8 },
2,
{ 0, 40 },
8,
' ',
};
NumberField field_rxvga {
{ 16 * 8, 27 * 8 },
2,
{ 0, 62 },
2,
' ',
};
NumberField field_rxamp {
{ 23 * 8, 27 * 8 },
1,
{ 0, 1 },
1,
' ',
};
Button tx_button {
{ 10 * 8, 30 * 8, 10 * 8, 5 * 8 },
"TX",
true
}; };

View File

@ -827,9 +827,11 @@ bool Checkbox::on_touch(const TouchEvent event) {
Button::Button( Button::Button(
Rect parent_rect, Rect parent_rect,
std::string text std::string text,
bool instant_exec
) : Widget { parent_rect }, ) : Widget { parent_rect },
text_ { text } text_ { text },
instant_exec_ { instant_exec }
{ {
set_focusable(true); set_focusable(true);
} }
@ -899,15 +901,24 @@ bool Button::on_touch(const TouchEvent event) {
case TouchEvent::Type::Start: case TouchEvent::Type::Start:
set_highlighted(true); set_highlighted(true);
set_dirty(); set_dirty();
if( on_touch_press) {
on_touch_press(*this);
}
if( on_select && instant_exec_ ) {
on_select(*this);
}
return true; return true;
case TouchEvent::Type::End: case TouchEvent::Type::End:
set_highlighted(false); set_highlighted(false);
set_dirty(); set_dirty();
if( on_select ) { if( on_select && !instant_exec_ ) {
on_select(*this); on_select(*this);
} }
if( on_touch_release) {
on_touch_release(*this);
}
return true; return true;
default: default:

View File

@ -378,10 +378,18 @@ private:
class Button : public Widget { class Button : public Widget {
public: public:
std::function<void(Button&)> on_select { }; std::function<void(Button&)> on_select { };
std::function<void(Button&)> on_touch_release { }; // Executed when releasing touch, after on_select.
std::function<void(Button&)> on_touch_press { }; // Executed when touching, before on_select.
std::function<bool(Button&, KeyEvent)> on_dir { }; std::function<bool(Button&, KeyEvent)> on_dir { };
std::function<void(Button&)> on_highlight { }; std::function<void(Button&)> on_highlight { };
Button(Rect parent_rect, std::string text); Button(Rect parent_rect, std::string text, bool instant_exec); // instant_exec: Execute on_select when you touching instead of releasing
Button(
Rect parent_rect,
std::string text
) : Button { parent_rect, text, false }
{
}
Button( Button(
) : Button { { }, { } } ) : Button { { }, { } }
@ -399,6 +407,7 @@ public:
private: private:
std::string text_; std::string text_;
bool instant_exec_ { false };
}; };
class NewButton : public Widget { class NewButton : public Widget {