Support for Rotary Encoder Dial sensitivity levels, issue #965 (#1057)

* Support for 3 levels of rotary encoder sensitivity #965

Backend support; UI will still need to call set function to configure.

* Support for 3 levels of rotary encoder sensitivity #965

Backend support only.  UI will still need to be changed to call the set_sensitivity() function to configure.

* Removed trailing space

* Deleted blank lines to see if format checker will be happier

* Simpler support for multiple levels of encoder sensitivity, for issue #965

Removed the convoluted code :-) and instead just using a 2-dimensional array to choose which transition map to use.  For now I only have 2 (vs 3) levels enabled as well, to save code space and because high-sensitivity is very touchy.

* Simpler version of configurable encoder sensitivity, issue #965

* Formatting

* Formatting test for Clang

* Formatting test

* Formatting (removed helpful comment)

* Formatting test (remove commented-out code)

* Formatting & swapping medium/low so default mode=0

* Swapped medium/low so default mode=0

* Adding UI & PMEM support to make encoder dial sensitivity configurable, issue #965

* Adding UI & PMEM support to make encoder dial sensitivity configurable, issue #965

* Adding UI & PMEM support to make encoder dial sensitivity configurable, issue #965

* Adding UI & PMEM support to make encoder dial sensitivity configurable, issue #965

* Adding UI & PMEM support to make encoder dial sensitivity configurable, issue #965

* Adding UI & PMEM support to make encoder dial sensitivity configurable, issue #965

* Removed unneeded range check (trusting in pmem checksum)
This commit is contained in:
Mark Thompson 2023-05-24 21:32:12 -05:00 committed by GitHub
parent edc6dc819c
commit 6b44a77ef6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 157 additions and 22 deletions

View File

@ -529,9 +529,9 @@ void SetPersistentMemoryView::focus() {
button_return.focus(); button_return.focus();
} }
// // ---------------------------------------------------------
// Audio settings // Audio Settings
// // ---------------------------------------------------------
SetAudioView::SetAudioView(NavigationView& nav) { SetAudioView::SetAudioView(NavigationView& nav) {
add_children({&labels, add_children({&labels,
&field_tone_mix, &field_tone_mix,
@ -554,6 +554,9 @@ void SetAudioView::focus() {
button_save.focus(); button_save.focus();
} }
// ---------------------------------------------------------
// QR Code Settings
// ------------------------------------------------------
SetQRCodeView::SetQRCodeView(NavigationView& nav) { SetQRCodeView::SetQRCodeView(NavigationView& nav) {
add_children({&checkbox_bigger_qr, add_children({&checkbox_bigger_qr,
&button_save, &button_save,
@ -575,6 +578,31 @@ void SetQRCodeView::focus() {
button_save.focus(); button_save.focus();
} }
// ---------------------------------------------------------
// Rotary Encoder Dial Settings
// ---------------------------------------------------------
SetEncoderDialView::SetEncoderDialView(NavigationView& nav) {
add_children({&labels,
&field_encoder_dial_sensitivity,
&button_save,
&button_cancel});
field_encoder_dial_sensitivity.set_by_value(persistent_memory::config_encoder_dial_sensitivity());
button_save.on_select = [&nav, this](Button&) {
persistent_memory::set_encoder_dial_sensitivity(field_encoder_dial_sensitivity.selected_index_value());
nav.pop();
};
button_cancel.on_select = [&nav, this](Button&) {
nav.pop();
};
}
void SetEncoderDialView::focus() {
button_save.focus();
}
// --------------------------------------------------------- // ---------------------------------------------------------
// Settings main menu // Settings main menu
// --------------------------------------------------------- // ---------------------------------------------------------
@ -593,6 +621,7 @@ SettingsMenuView::SettingsMenuView(NavigationView& nav) {
{"FreqCorrection", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav]() { nav.push<SetFrequencyCorrectionView>(); }}, {"FreqCorrection", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav]() { nav.push<SetFrequencyCorrectionView>(); }},
{"QR Code", ui::Color::dark_cyan(), &bitmap_icon_qr_code, [&nav]() { nav.push<SetQRCodeView>(); }}, {"QR Code", ui::Color::dark_cyan(), &bitmap_icon_qr_code, [&nav]() { nav.push<SetQRCodeView>(); }},
{"P.Memory Mgmt", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push<SetPersistentMemoryView>(); }}, {"P.Memory Mgmt", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push<SetPersistentMemoryView>(); }},
{"Encoder Dial", ui::Color::dark_cyan(), &bitmap_icon_setup, [&nav]() { nav.push<SetEncoderDialView>(); }},
}); });
set_max_rows(2); // allow wider buttons set_max_rows(2); // allow wider buttons
} }

View File

@ -432,6 +432,38 @@ class SetQRCodeView : public View {
}; };
}; };
using portapack::persistent_memory::encoder_dial_sensitivity;
class SetEncoderDialView : public View {
public:
SetEncoderDialView(NavigationView& nav);
void focus() override;
std::string title() const override { return "Encoder Dial"; };
private:
Labels labels{
{{2 * 8, 3 * 16}, "Dial sensitivity:", Color::light_grey()},
};
OptionsField field_encoder_dial_sensitivity{
{20 * 8, 3 * 16},
6,
{{"LOW", encoder_dial_sensitivity::DIAL_SENSITIVITY_LOW},
{"NORMAL", encoder_dial_sensitivity::DIAL_SENSITIVITY_MEDIUM},
{"HIGH", encoder_dial_sensitivity::DIAL_SENSITIVITY_HIGH}}};
Button button_save{
{2 * 8, 16 * 16, 12 * 8, 32},
"Save"};
Button button_cancel{
{16 * 8, 16 * 16, 12 * 8, 32},
"Cancel",
};
};
class SetPersistentMemoryView : public View { class SetPersistentMemoryView : public View {
public: public:
SetPersistentMemoryView(NavigationView& nav); SetPersistentMemoryView(NavigationView& nav);

View File

@ -23,23 +23,75 @@
#include "utility.hpp" #include "utility.hpp"
static const int8_t transition_map[] = { #include "portapack.hpp"
#include "portapack_persistent_memory.hpp"
// Now supporting multiple levels of rotary encoder dial sensitivity
//
// Portapack H2 normally has a 30-step encoder, meaning one step (pulse) every
// 12 degrees of rotation.
//
// For each encoder "pulse" there are 4 state transitions, and we can choose
// between looking at all of them (high sensitivity), half of them (medium/default),
// or one quarter of them (low sensitivity).
static const int8_t transition_map[][16] = {
// Normal (Medium) Sensitivity -- default
{
0, // 0000: noop 0, // 0000: noop
0, // 0001: start 0, // 0001: ccw start
0, // 0010: start 0, // 0010: cw start
0, // 0011: rate 0, // 0011: rate
1, // 0100: end 1, // 0100: cw end
0, // 0101: noop 0, // 0101: noop
0, // 0110: rate 0, // 0110: rate
-1, // 0111: end -1, // 0111: ccw end
-1, // 1000: end -1, // 1000: ccw end
0, // 1001: rate 0, // 1001: rate
0, // 1010: noop 0, // 1010: noop
1, // 1011: end 1, // 1011: cw end
0, // 1100: rate 0, // 1100: rate
0, // 1101: start 0, // 1101: cw start
0, // 1110: start 0, // 1110: ccw start
0, // 1111: noop 0, // 1111: noop
},
// Low Sensitivity
{
0, // 0000: noop
0, // 0001: ccw start
0, // 0010: cw start
0, // 0011: rate
1, // 0100: cw end
0, // 0101: noop
0, // 0110: rate
0, // 0111: ccw end
-1, // 1000: ccw end
0, // 1001: rate
0, // 1010: noop
0, // 1011: cw end
0, // 1100: rate
0, // 1101: cw start
0, // 1110: ccw start
0, // 1111: noop
},
// High Sensitivity
{
0, // 0000: noop
-1, // 0001: ccw start
1, // 0010: cw start
0, // 0011: rate
1, // 0100: cw end
0, // 0101: noop
0, // 0110: rate
-1, // 0111: ccw end
-1, // 1000: ccw end
0, // 1001: rate
0, // 1010: noop
1, // 1011: cw end
0, // 1100: rate
1, // 1101: cw start
-1, // 1110: ccw start
0, // 1111: noop
},
}; };
int_fast8_t Encoder::update( int_fast8_t Encoder::update(
@ -50,5 +102,6 @@ int_fast8_t Encoder::update(
state <<= 1; state <<= 1;
state |= phase_1; state |= phase_1;
return transition_map[state & 0xf]; // dial sensitivity setting is stored in pmem
return transition_map[portapack::persistent_memory::config_encoder_dial_sensitivity()][state & 0xf];
} }

View File

@ -302,6 +302,9 @@ struct data_t {
uint32_t frequency_tx_correction; uint32_t frequency_tx_correction;
bool updown_frequency_tx_correction; bool updown_frequency_tx_correction;
// Rotary encoder dial sensitivity (encoder.cpp/hpp)
uint8_t encoder_dial_sensitivity;
constexpr data_t() constexpr data_t()
: structure_version(data_structure_version_enum::VERSION_CURRENT), : structure_version(data_structure_version_enum::VERSION_CURRENT),
tuned_frequency(tuned_frequency_reset_value), tuned_frequency(tuned_frequency_reset_value),
@ -337,7 +340,8 @@ struct data_t {
frequency_rx_correction(0), frequency_rx_correction(0),
updown_frequency_rx_correction(0), updown_frequency_rx_correction(0),
frequency_tx_correction(0), frequency_tx_correction(0),
updown_frequency_tx_correction(0) { updown_frequency_tx_correction(0),
encoder_dial_sensitivity(0) {
} }
}; };
@ -808,6 +812,14 @@ void set_config_freq_rx_correction(uint32_t v) {
data->frequency_rx_correction = v; data->frequency_rx_correction = v;
} }
// rotary encoder dial settings
uint8_t config_encoder_dial_sensitivity() {
return data->encoder_dial_sensitivity;
}
void set_encoder_dial_sensitivity(uint8_t v) {
data->encoder_dial_sensitivity = v;
}
// sd persisting settings // sd persisting settings
int save_persistent_settings_to_file(std::string filename) { int save_persistent_settings_to_file(std::string filename) {
delete_file(filename); delete_file(filename);

View File

@ -99,6 +99,13 @@ struct backlight_config_t {
bool _timeout_enabled; bool _timeout_enabled;
}; };
enum encoder_dial_sensitivity {
DIAL_SENSITIVITY_MEDIUM = 0,
DIAL_SENSITIVITY_LOW = 1,
DIAL_SENSITIVITY_HIGH = 2,
NUM_DIAL_SENSITIVITY
};
namespace cache { namespace cache {
/* Set values in cache to sensible defaults. */ /* Set values in cache to sensible defaults. */
@ -199,6 +206,8 @@ void set_config_login(bool v);
void set_config_speaker(bool v); void set_config_speaker(bool v);
void set_config_backlight_timer(const backlight_config_t& new_value); void set_config_backlight_timer(const backlight_config_t& new_value);
void set_disable_touchscreen(bool v); void set_disable_touchscreen(bool v);
uint8_t config_encoder_dial_sensitivity();
void set_encoder_dial_sensitivity(uint8_t v);
// uint8_t ui_config_textentry(); // uint8_t ui_config_textentry();
// void set_config_textentry(uint8_t new_value); // void set_config_textentry(uint8_t new_value);