touchscreen threshold (sensitivity) auto detect (#2306)

* gui

* worked but slow

* not do the auto detect

* worked

* remove debug thing

* format

* remove uneeded thing

* fix hackrf submodule bump

* clean up

* format

* format

* format

* remve batt

* add hint text and eta

* code clean up by @HTotoo

* work around to resolve not clear enough

* correct comments
This commit is contained in:
sommermorgentraum 2024-10-17 00:39:59 +08:00 committed by GitHub
parent 7d28e495c2
commit 8e945024c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 197 additions and 9 deletions

View File

@ -818,6 +818,107 @@ void SetDisplayView::focus() {
button_save.focus();
}
/* SetTouchscreenSensitivityView ************************************/
/* sample max: 1023 sample_t AKA uint16_t
* touch_sensitivity: range: 1 to 128
* threshold = 1023 / sensitive
* threshold range: 1023/1 to 1023/128 = 1023 to 8
*/
SetTouchscreenThresholdView::SetTouchscreenThresholdView(NavigationView& nav) {
add_children({&labels,
&field_threshold,
&button_autodetect,
&button_reset,
&button_save,
&button_cancel,
&text_hint,
&text_wait_timer});
set_dirty();
org_threshold = portapack::touch_threshold;
field_threshold.set_value(pmem::touchscreen_threshold());
text_hint.set_style(Theme::getInstance()->error_dark);
text_hint.hidden(true);
text_wait_timer.set_style(Theme::getInstance()->error_dark);
text_wait_timer.hidden(true);
// clang-format off
button_autodetect.on_select = [this, &nav](Button&) {
nav.display_modal("NOTICE",
"Now on don't touch screen;\n"
"Use arrow keys to operate.\n"
"Follow instructions.\n"
"Press YES to continue",
YESNO, [this, &nav](bool choice) {
if (choice){
time_start_auto_detect = chTimeNow();
text_hint.hidden(false);
text_wait_timer.hidden(false);
text_wait_timer.set("ETA " + to_string_dec_uint(10) + "s");
in_auto_detect = true;
field_threshold.set_value(1);
portapack::touch_threshold = 1;
set_dirty(); } }, TRUE);
};
// clang-format on
button_reset.on_select = [this](Button&) {
field_threshold.set_value(32);
portapack::touch_threshold = 32;
};
button_save.on_select = [&nav, this](Button&) {
pmem::set_touchscreen_threshold(field_threshold.value());
portapack::touch_threshold = field_threshold.value();
send_system_refresh();
nav.pop();
};
button_cancel.on_select = [&nav, this](Button&) {
portapack::touch_threshold = org_threshold;
nav.pop();
};
}
void SetTouchscreenThresholdView::focus() {
button_autodetect.focus();
set_dirty();
}
void SetTouchscreenThresholdView::on_frame_sync() {
if (!in_auto_detect) return;
uint32_t time_now = chTimeNow();
int32_t time_diff = time_now - time_start_auto_detect;
text_wait_timer.set("ETA " + to_string_dec_uint((10 - time_diff / 1000) <= 0 ? 0 : 10 - time_diff / 1000) + "s");
if (time_diff >= 10001 && !auto_detect_succeed_consumed) { // 10s
in_auto_detect = false;
text_wait_timer.hidden(true);
text_hint.set("OK, press save and reboot");
portapack::touch_threshold = org_threshold;
pmem::set_touchscreen_threshold(org_threshold);
set_dirty();
auto_detect_succeed_consumed = true;
button_save.focus();
return;
}
if (get_touch_frame().touch) {
if (in_auto_detect) {
uint16_t sen = field_threshold.value();
sen++;
portapack::touch_threshold = sen;
field_threshold.set_value(sen);
}
}
}
SetTouchscreenThresholdView::~SetTouchscreenThresholdView() {
// it seems that sometimes in the msg handler func it would enter the condi that not possible to entered,
// so added this workaround.
// TODO: find out why
in_auto_detect = false;
auto_detect_succeed_consumed = false;
time_start_auto_detect = 0;
}
/* SetMenuColorView ************************************/
void SetMenuColorView::paint_sample() {
@ -1022,6 +1123,7 @@ void SettingsMenuView::on_populate() {
{"App Settings", ui::Color::dark_cyan(), &bitmap_icon_notepad, [this]() { nav_.push<AppSettingsView>(); }},
{"Audio", ui::Color::dark_cyan(), &bitmap_icon_speaker, [this]() { nav_.push<SetAudioView>(); }},
{"Calibration", ui::Color::dark_cyan(), &bitmap_icon_options_touch, [this]() { nav_.push<TouchCalibrationView>(); }},
{"TouchThreshold", ui::Color::dark_cyan(), &bitmap_icon_options_touch, [this]() { nav_.push<SetTouchscreenThresholdView>(); }},
{"Config Mode", ui::Color::dark_cyan(), &bitmap_icon_clk_ext, [this]() { nav_.push<SetConfigModeView>(); }},
{"Converter", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [this]() { nav_.push<SetConverterSettingsView>(); }},
{"Date/Time", ui::Color::dark_cyan(), &bitmap_icon_options_datetime, [this]() { nav_.push<SetDateTimeView>(); }},

View File

@ -35,6 +35,7 @@
#include "bitmap.hpp"
#include "ff.h"
#include "portapack_persistent_memory.hpp"
#include "irq_controls.hpp"
#include <cstdint>
@ -754,6 +755,77 @@ class SetDisplayView : public View {
};
};
using portapack::persistent_memory::touchscreen_threshold;
class SetTouchscreenThresholdView : public View {
public:
SetTouchscreenThresholdView(NavigationView& nav);
~SetTouchscreenThresholdView();
void focus() override;
std::string title() const override { return "Touch S"; };
private:
bool in_auto_detect = false;
uint16_t org_threshold = 0;
uint8_t auto_detect_succeed_consumed = false; // prevent screen flash but can still change text content
uint32_t time_start_auto_detect = 0;
Labels labels{
{{1 * 8, 1 * 16}, "Set touchscreen sensitivity", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "Or press auto detect button", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 3 * 16}, "FOLLOW INSTRUCTIONS", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 4 * 16}, "REBOOT TO APPLY", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 11 * 16}, "Threshold:", Theme::getInstance()->fg_light->foreground},
};
Text text_hint{
{1 * 8, 7 * 16, screen_width - 2 * 8, 1 * 16},
"DON'T TOUCH SCREEN"};
Text text_wait_timer{
{1 * 8, 8 * 16, screen_width - 2 * 8, 1 * 16},
"ETA 00:00"};
void on_frame_sync();
/* sample max: 1023 sample_t AKA uint16_t
* touch_sensitivity: range: 1 to 128
* threshold range: 1023/1 to 1023/128 = 1023 to 8
*/
NumberField field_threshold{
{1 * 8 + sizeof("Threshold:") * 8 + 8, 11 * 16},
4,
{1, 1023},
1,
' ',
};
Button button_autodetect{
{2 * 8, 13 * 16, 12 * 8, 32},
"Auto Detect"};
Button button_reset{
{16 * 8, 13 * 16, 12 * 8, 32},
"Reset",
};
Button button_save{
{2 * 8, 16 * 16, 12 * 8, 32},
"Save"};
Button button_cancel{
{16 * 8, 16 * 16, 12 * 8, 32},
"Cancel",
};
MessageHandlerRegistration message_handler_frame_sync{
Message::ID::DisplayFrameSync,
[this](const Message* const) {
this->on_frame_sync();
}};
};
class SetMenuColorView : public View {
public:
SetMenuColorView(NavigationView& nav);

View File

@ -85,7 +85,7 @@ static bool touch_update() {
case IO::TouchPinsConfig::SensePressure: {
const auto z1 = samples.xp - samples.xn;
const auto z2 = samples.yp - samples.yn;
const auto touch_raw = (z1 > touch::touch_threshold) || (z2 > touch::touch_threshold);
const auto touch_raw = (z1 > portapack::touch_threshold) || (z2 > portapack::touch_threshold);
touch_debounce = (touch_debounce << 1) | (touch_raw ? 1U : 0U);
touch_detected = ((touch_debounce & touch_debounce_mask) == touch_debounce_mask);
if (!touch_detected && !touch_cycle) {

View File

@ -95,6 +95,7 @@ TemperatureLogger temperature_logger;
bool antenna_bias{false};
uint32_t bl_tick_counter{0};
uint16_t touch_threshold{32};
void set_antenna_bias(const bool v) {
antenna_bias = v;
@ -538,6 +539,11 @@ init_status_t init() {
set_cpu_clock_speed();
if (persistent_memory::config_lcd_inverted_mode()) display.set_inverted(true);
/* sample max: 1023 sample_t AKA uint16_t
* touch_sensitivity: range: 1 to 128
* threshold range: 1023/1 to 1023/128 = 1023 to 8
*/
touch_threshold = portapack::persistent_memory::touchscreen_threshold();
if (lcd_fast_setup)
draw_splash_screen_icon(0, ui::bitmap_icon_memory);

View File

@ -68,6 +68,7 @@ extern TransmitterModel transmitter_model;
extern uint32_t bl_tick_counter;
extern bool antenna_bias;
extern uint16_t touch_threshold;
extern TemperatureLogger temperature_logger;

View File

@ -36,14 +36,6 @@ namespace touch {
using sample_t = uint16_t;
constexpr sample_t sample_max = 1023;
// If you have a dead bottom-left corner try to increase the sensitivity,
// but look for flickering touch indicator in the Buttons test screen
// in which case decrease sensitivity to avoid killing backlight timeout
constexpr sample_t touch_sensitivity = 32;
constexpr sample_t touch_threshold = sample_max / touch_sensitivity;
struct Samples {
sample_t xp;
sample_t xn;

View File

@ -252,6 +252,8 @@ struct data_t {
// Menu Color Scheme
Color menu_color;
uint16_t touchscreen_threshold;
uint16_t UNUSED_16;
constexpr data_t()
@ -310,6 +312,7 @@ struct data_t {
config_mode_storage(CONFIG_MODE_NORMAL_VALUE),
dst_config(),
menu_color(Color::grey()),
touchscreen_threshold(32),
UNUSED_16() {
}
};
@ -1140,6 +1143,13 @@ void set_menu_color(Color v) {
data->menu_color = v;
}
uint16_t touchscreen_threshold() {
return data->touchscreen_threshold;
}
void set_touchscreen_threshold(uint16_t v) {
data->touchscreen_threshold = v;
}
// PMem to sdcard settings
bool should_use_sdcard_for_pmem() {
@ -1244,6 +1254,7 @@ bool debug_dump() {
pmem_dump_file.write_line("dst_config: 0x" + to_string_hex((uint32_t)data->dst_config.v, 8));
pmem_dump_file.write_line("fake_brightness_level: " + to_string_dec_uint(data->fake_brightness_level));
pmem_dump_file.write_line("menu_color: 0x" + to_string_hex(data->menu_color.v, 4));
pmem_dump_file.write_line("touchscreen_threshold: " + to_string_dec_uint(data->touchscreen_threshold));
// ui_config bits
const auto backlight_timer = portapack::persistent_memory::config_backlight_timer();

View File

@ -282,6 +282,10 @@ uint8_t fake_brightness_level();
void set_fake_brightness_level(uint8_t v);
void toggle_fake_brightness_level();
/* Touchscreen threshold */
uint16_t touchscreen_threshold();
void set_touchscreen_threshold(uint16_t v);
Color menu_color();
void set_menu_color(Color v);