From 4eb3f044a01c02b17835841f95dfbb414ebf47ea Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 25 Jul 2016 15:29:52 -0700 Subject: [PATCH 01/33] TPMS: Close row between controls and table header. --- firmware/application/tpms_app.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/tpms_app.hpp b/firmware/application/tpms_app.hpp index 84aacd61f..fc9e0c350 100644 --- a/firmware/application/tpms_app.hpp +++ b/firmware/application/tpms_app.hpp @@ -119,7 +119,7 @@ private: } }; - static constexpr ui::Dim header_height = 2 * 16; + static constexpr ui::Dim header_height = 1 * 16; RSSI rssi { { 21 * 8, 0, 6 * 8, 4 }, From 512539fd8c38720b3d9069276b14491f17d5ed69 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 25 Jul 2016 15:45:27 -0700 Subject: [PATCH 02/33] AIS: Add RSSI reporting to processor. --- firmware/baseband/proc_ais.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/baseband/proc_ais.hpp b/firmware/baseband/proc_ais.hpp index 7fa0d40c2..eff71b4a5 100644 --- a/firmware/baseband/proc_ais.hpp +++ b/firmware/baseband/proc_ais.hpp @@ -24,6 +24,7 @@ #include "baseband_processor.hpp" #include "baseband_thread.hpp" +#include "rssi_thread.hpp" #include "channel_decimator.hpp" #include "matched_filter.hpp" @@ -51,6 +52,7 @@ private: static constexpr size_t baseband_fs = 2457600; BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20 }; + RSSIThread rssi_thread { NORMALPRIO + 10 }; std::array dst; const buffer_c16_t dst_buffer { From aaa0e389b9a2db2cc20dd73c25423b24a619198b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 25 Jul 2016 15:46:37 -0700 Subject: [PATCH 03/33] AIS: Add gain controls, RSSI and channel indications. --- firmware/application/ais_app.cpp | 5 +++++ firmware/application/ais_app.hpp | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/firmware/application/ais_app.cpp b/firmware/application/ais_app.cpp index 543e55530..d406c5406 100644 --- a/firmware/application/ais_app.cpp +++ b/firmware/application/ais_app.cpp @@ -291,6 +291,11 @@ AISAppView::AISAppView(NavigationView&) { add_children({ { &label_channel, &options_channel, + &field_rf_amp, + &field_lna, + &field_vga, + &rssi, + &channel, &recent_entries_view, &recent_entry_detail_view, } }); diff --git a/firmware/application/ais_app.hpp b/firmware/application/ais_app.hpp index 19286e6de..b38a21467 100644 --- a/firmware/application/ais_app.hpp +++ b/firmware/application/ais_app.hpp @@ -24,6 +24,9 @@ #include "ui_widget.hpp" #include "ui_navigation.hpp" +#include "ui_receiver.hpp" +#include "ui_rssi.hpp" +#include "ui_channel.hpp" #include "event_m0.hpp" @@ -177,6 +180,26 @@ private: } }; + RFAmpField field_rf_amp { + { 13 * 8, 0 * 16 } + }; + + LNAGainField field_lna { + { 15 * 8, 0 * 16 } + }; + + VGAGainField field_vga { + { 18 * 8, 0 * 16 } + }; + + RSSI rssi { + { 21 * 8, 0, 6 * 8, 4 }, + }; + + Channel channel { + { 21 * 8, 5, 6 * 8, 4 }, + }; + MessageHandlerRegistration message_handler_packet { Message::ID::AISPacket, [this](Message* const p) { From 00f542e96b1905d19b2ea1d6c35459173c198f06 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 25 Jul 2016 16:06:09 -0700 Subject: [PATCH 04/33] ERT: Add gain controls. --- firmware/application/ert_app.cpp | 5 ++++- firmware/application/ert_app.hpp | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/firmware/application/ert_app.cpp b/firmware/application/ert_app.cpp index 269b1096c..0fbdd61d8 100644 --- a/firmware/application/ert_app.cpp +++ b/firmware/application/ert_app.cpp @@ -124,6 +124,9 @@ ERTAppView::ERTAppView(NavigationView&) { baseband::run_image(portapack::spi_flash::image_tag_ert); add_children({ { + &field_rf_amp, + &field_lna, + &field_vga, &recent_entries_view, } }); @@ -154,7 +157,7 @@ void ERTAppView::focus() { void ERTAppView::set_parent_rect(const Rect new_parent_rect) { View::set_parent_rect(new_parent_rect); - recent_entries_view.set_parent_rect({ 0, 0, new_parent_rect.width(), new_parent_rect.height() }); + recent_entries_view.set_parent_rect({ 0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height }); } void ERTAppView::on_packet(const ert::Packet& packet) { diff --git a/firmware/application/ert_app.hpp b/firmware/application/ert_app.hpp index b74d599ed..854a21e18 100644 --- a/firmware/application/ert_app.hpp +++ b/firmware/application/ert_app.hpp @@ -23,6 +23,9 @@ #define __ERT_APP_H__ #include "ui_navigation.hpp" +#include "ui_receiver.hpp" +#include "ui_rssi.hpp" +#include "ui_channel.hpp" #include "event_m0.hpp" @@ -128,6 +131,20 @@ private: ERTRecentEntriesView recent_entries_view { recent }; + static constexpr auto header_height = 1 * 16; + + RFAmpField field_rf_amp { + { 13 * 8, 0 * 16 } + }; + + LNAGainField field_lna { + { 15 * 8, 0 * 16 } + }; + + VGAGainField field_vga { + { 18 * 8, 0 * 16 } + }; + MessageHandlerRegistration message_handler_packet { Message::ID::ERTPacket, [this](Message* const p) { From c573f3b57d8c205bbb578a98896529fac1b0c8dc Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 25 Jul 2016 16:06:26 -0700 Subject: [PATCH 05/33] ERT: Fix initial focus. --- firmware/application/ert_app.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/ert_app.cpp b/firmware/application/ert_app.cpp index 0fbdd61d8..d6d3961fb 100644 --- a/firmware/application/ert_app.cpp +++ b/firmware/application/ert_app.cpp @@ -152,7 +152,7 @@ ERTAppView::~ERTAppView() { } void ERTAppView::focus() { - recent_entries_view.focus(); + field_vga.focus(); } void ERTAppView::set_parent_rect(const Rect new_parent_rect) { From 5e362534c33b3b9639e0d663fa16fcc57b291601 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 25 Jul 2016 16:07:22 -0700 Subject: [PATCH 06/33] Transponder apps: Use gains from receiver model. --- firmware/application/ais_app.cpp | 7 ++++++- firmware/application/ert_app.cpp | 7 ++++++- firmware/application/tpms_app.cpp | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/firmware/application/ais_app.cpp b/firmware/application/ais_app.cpp index d406c5406..814262e6d 100644 --- a/firmware/application/ais_app.cpp +++ b/firmware/application/ais_app.cpp @@ -25,6 +25,9 @@ #include "baseband_api.hpp" +#include "portapack.hpp" +using namespace portapack; + #include namespace ais { @@ -309,7 +312,9 @@ AISAppView::AISAppView(NavigationView&) { sampling_rate, baseband_bandwidth, rf::Direction::Receive, - false, 32, 32, + receiver_model.rf_amp(), + static_cast(receiver_model.lna()), + static_cast(receiver_model.vga()), 1, }); diff --git a/firmware/application/ert_app.cpp b/firmware/application/ert_app.cpp index d6d3961fb..23206828e 100644 --- a/firmware/application/ert_app.cpp +++ b/firmware/application/ert_app.cpp @@ -23,6 +23,9 @@ #include "baseband_api.hpp" +#include "portapack.hpp" +using namespace portapack; + #include "manchester.hpp" #include "crc.hpp" @@ -135,7 +138,9 @@ ERTAppView::ERTAppView(NavigationView&) { sampling_rate, baseband_bandwidth, rf::Direction::Receive, - false, 32, 32, + receiver_model.rf_amp(), + static_cast(receiver_model.lna()), + static_cast(receiver_model.vga()), 1, }); diff --git a/firmware/application/tpms_app.cpp b/firmware/application/tpms_app.cpp index 0c96971cb..008a920af 100644 --- a/firmware/application/tpms_app.cpp +++ b/firmware/application/tpms_app.cpp @@ -181,7 +181,7 @@ TPMSAppView::TPMSAppView(NavigationView&) { sampling_rate, baseband_bandwidth, rf::Direction::Receive, - false, + receiver_model.rf_amp(), static_cast(receiver_model.lna()), static_cast(receiver_model.vga()), 1, From 508ce8927171706fceec0ae70fff9d1bd4afd495 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 25 Jul 2016 16:12:13 -0700 Subject: [PATCH 07/33] ERT: Add RSSI reporter to processor. --- firmware/baseband/proc_ert.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/baseband/proc_ert.hpp b/firmware/baseband/proc_ert.hpp index dc0a9ecc2..9642cc9d1 100644 --- a/firmware/baseband/proc_ert.hpp +++ b/firmware/baseband/proc_ert.hpp @@ -24,6 +24,7 @@ #include "baseband_processor.hpp" #include "baseband_thread.hpp" +#include "rssi_thread.hpp" #include "channel_decimator.hpp" @@ -63,6 +64,7 @@ private: const float clock_recovery_rate = symbol_rate * 2; BasebandThread baseband_thread { baseband_sampling_rate, this, NORMALPRIO + 20 }; + RSSIThread rssi_thread { NORMALPRIO + 10 }; clock_recovery::ClockRecovery clock_recovery { clock_recovery_rate, symbol_rate, { 1.0f / 18.0f }, From 3759e142d8dcf60997c23bd5c8b4c178c93a8867 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 25 Jul 2016 16:12:32 -0700 Subject: [PATCH 08/33] ERT: Add RSSI to app UI. --- firmware/application/ert_app.cpp | 1 + firmware/application/ert_app.hpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/firmware/application/ert_app.cpp b/firmware/application/ert_app.cpp index 23206828e..e5597cd8d 100644 --- a/firmware/application/ert_app.cpp +++ b/firmware/application/ert_app.cpp @@ -130,6 +130,7 @@ ERTAppView::ERTAppView(NavigationView&) { &field_rf_amp, &field_lna, &field_vga, + &rssi, &recent_entries_view, } }); diff --git a/firmware/application/ert_app.hpp b/firmware/application/ert_app.hpp index 854a21e18..1d901f453 100644 --- a/firmware/application/ert_app.hpp +++ b/firmware/application/ert_app.hpp @@ -145,6 +145,10 @@ private: { 18 * 8, 0 * 16 } }; + RSSI rssi { + { 21 * 8, 0, 6 * 8, 4 }, + }; + MessageHandlerRegistration message_handler_packet { Message::ID::ERTPacket, [this](Message* const p) { From 729ab9bb8e076cce62b84119a0aa6c221c95e9be Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 25 Jul 2016 16:13:14 -0700 Subject: [PATCH 09/33] TPMS: Increase channel sampling rate, improve hit rate. --- firmware/baseband/proc_tpms.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/baseband/proc_tpms.hpp b/firmware/baseband/proc_tpms.hpp index bc1c0b3f5..f81c48009 100644 --- a/firmware/baseband/proc_tpms.hpp +++ b/firmware/baseband/proc_tpms.hpp @@ -98,7 +98,7 @@ private: }; static constexpr float channel_rate_in = 307200.0f; - static constexpr size_t channel_decimation = 8; + static constexpr size_t channel_decimation = 2; static constexpr float channel_sample_rate = channel_rate_in / channel_decimation; OOKSlicerMagSquaredInt ook_slicer_5sps { channel_sample_rate / 8400 + 1}; uint32_t slicer_history { 0 }; From 20bcbf511e1e924eacfbcbfb0d57b3ea26dc25df Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 26 Jul 2016 10:22:10 -0700 Subject: [PATCH 10/33] Move thread_base.hpp from baseband/ to common/. I want to use it with M0 code as well. --- firmware/{baseband => common}/thread_base.hpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename firmware/{baseband => common}/thread_base.hpp (100%) diff --git a/firmware/baseband/thread_base.hpp b/firmware/common/thread_base.hpp similarity index 100% rename from firmware/baseband/thread_base.hpp rename to firmware/common/thread_base.hpp From d0fd56bc782b8233da9bfc826837769fb17b407b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 26 Jul 2016 15:13:07 -0700 Subject: [PATCH 11/33] Touch: Expose metrics calculation struct/function. --- firmware/application/touch.cpp | 8 +------- firmware/application/touch.hpp | 8 ++++++++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/firmware/application/touch.cpp b/firmware/application/touch.cpp index 09f8db8f1..503af80fe 100644 --- a/firmware/application/touch.cpp +++ b/firmware/application/touch.cpp @@ -23,13 +23,7 @@ namespace touch { -struct Metrics { - const float x; - const float y; - const float r; -}; - -static Metrics calculate_metrics(const Frame& frame) { +Metrics calculate_metrics(const Frame& frame) { /* TODO: Yikes! M0 doesn't have floating point, so this code is * expensive! On the other hand, it seems to be working well (and * fast *enough*?), so maybe leave it alone at least for now. diff --git a/firmware/application/touch.hpp b/firmware/application/touch.hpp index 0402243a6..31c1bd55f 100644 --- a/firmware/application/touch.hpp +++ b/firmware/application/touch.hpp @@ -106,6 +106,14 @@ struct Frame { bool touch { false }; }; +struct Metrics { + const float x; + const float y; + const float r; +}; + +Metrics calculate_metrics(const Frame& frame); + template class Filter { public: From 6c2eb372484537043754e410933991f417603d5a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 26 Jul 2016 21:29:59 -0700 Subject: [PATCH 12/33] Bitmap: Add note about how data is structured. --- firmware/application/bitmap.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/application/bitmap.hpp b/firmware/application/bitmap.hpp index 79906dfbd..66899ff05 100644 --- a/firmware/application/bitmap.hpp +++ b/firmware/application/bitmap.hpp @@ -26,6 +26,8 @@ namespace ui { +/* Pixel data within a byte is "reversed": LSB is left-most pixel. */ + static constexpr uint8_t bitmap_record_data[] = { 0x00, 0x00, 0x00, 0x00, From f1a32019404454ac555defc53b0b6174f9941589 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 11:13:07 -0700 Subject: [PATCH 13/33] Touch: Add bitmaps for calibration UI. --- firmware/application/bitmap.hpp | 92 +++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/firmware/application/bitmap.hpp b/firmware/application/bitmap.hpp index 66899ff05..818fe8fc4 100644 --- a/firmware/application/bitmap.hpp +++ b/firmware/application/bitmap.hpp @@ -153,6 +153,98 @@ static constexpr Bitmap bitmap_sd_card_error { { 16, 16 }, bitmap_sd_card_error_data }; +static constexpr uint8_t bitmap_target_calibrate_data[] = { + 0x02, 0x00, 0x00, 0x40, + 0x07, 0x00, 0x00, 0xe0, + 0x0e, 0x00, 0x00, 0x70, + 0x1c, 0x00, 0x00, 0x38, + + 0x38, 0x00, 0x00, 0x1c, + 0x70, 0x00, 0x00, 0x0e, + 0xe0, 0x00, 0x00, 0x07, + 0xc0, 0x01, 0x80, 0x03, + + 0x80, 0x03, 0xc0, 0x01, + 0x00, 0x07, 0xe0, 0x00, + 0x00, 0x0e, 0x70, 0x00, + 0x00, 0x1c, 0x38, 0x00, + + 0x00, 0x38, 0x1c, 0x00, + 0x00, 0x30, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x0c, 0x00, + 0x00, 0x38, 0x1c, 0x00, + + 0x00, 0x1c, 0x38, 0x00, + 0x00, 0x0e, 0x70, 0x00, + 0x00, 0x07, 0xe0, 0x00, + 0x80, 0x03, 0xc0, 0x01, + + 0xc0, 0x01, 0x80, 0x03, + 0xe0, 0x00, 0x00, 0x07, + 0x70, 0x00, 0x00, 0x0e, + 0x38, 0x00, 0x00, 0x1c, + + 0x1c, 0x00, 0x00, 0x38, + 0x0e, 0x00, 0x00, 0x70, + 0x07, 0x00, 0x00, 0xe0, + 0x02, 0x00, 0x00, 0x40, +}; + +static constexpr Bitmap bitmap_target_calibrate { + { 32, 32 }, bitmap_target_calibrate_data +}; + +static constexpr uint8_t bitmap_target_verify_data[] = { + 0x00, 0xe0, 0x07, 0x00, + 0x00, 0xfc, 0x3f, 0x00, + 0x00, 0x1f, 0xf8, 0x00, + 0xc0, 0x03, 0xc0, 0x03, + + 0xe0, 0x00, 0x00, 0x07, + 0x70, 0x00, 0x00, 0x0e, + 0x38, 0x00, 0x00, 0x1c, + 0x18, 0x00, 0x00, 0x18, + + 0x0c, 0x00, 0x00, 0x30, + 0x0c, 0x00, 0x00, 0x30, + 0x06, 0x00, 0x00, 0x60, + 0x06, 0x00, 0x00, 0x60, + + 0x06, 0x00, 0x00, 0x60, + 0x03, 0x80, 0x01, 0xc0, + 0x03, 0x80, 0x01, 0xc0, + 0x03, 0xe0, 0x07, 0xc0, + + 0x03, 0xe0, 0x07, 0xc0, + 0x03, 0x80, 0x01, 0xc0, + 0x03, 0x80, 0x01, 0xc0, + 0x06, 0x00, 0x00, 0x60, + + 0x06, 0x00, 0x00, 0x60, + 0x06, 0x00, 0x00, 0x60, + 0x0c, 0x00, 0x00, 0x30, + 0x0c, 0x00, 0x00, 0x30, + + 0x18, 0x00, 0x00, 0x18, + 0x38, 0x00, 0x00, 0x1c, + 0x70, 0x00, 0x00, 0x0e, + 0xe0, 0x00, 0x00, 0x07, + + 0xc0, 0x03, 0xc0, 0x03, + 0x00, 0x1f, 0xf8, 0x00, + 0x00, 0xfc, 0x3f, 0x00, + 0x00, 0xe0, 0x07, 0x00, +}; + +static constexpr Bitmap bitmap_target_verify { + { 32, 32 }, bitmap_target_verify_data +}; + } /* namespace ui */ #endif/*__BITMAP_HPP__*/ From 9500da4b1b537cd791bac1d00b5e3ab4438bfc78 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 11:14:11 -0700 Subject: [PATCH 14/33] Touch: Fix small loss of precision calculating X/Y positions. --- firmware/application/touch.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/application/touch.cpp b/firmware/application/touch.cpp index 503af80fe..0aae8a9b6 100644 --- a/firmware/application/touch.cpp +++ b/firmware/application/touch.cpp @@ -32,14 +32,14 @@ Metrics calculate_metrics(const Frame& frame) { const auto x_max = frame.x.xp; const auto x_min = frame.x.xn; const auto x_range = x_max - x_min; - const auto x_position = (frame.x.yp + frame.x.yn) / 2; - const float x_norm = float(x_position - x_min) / x_range; + const float x_position = (frame.x.yp + frame.x.yn) * 0.5f; + const float x_norm = (x_position - x_min) / x_range; const auto y_max = frame.y.yn; const auto y_min = frame.y.yp; const auto y_range = y_max - y_min; - const auto y_position = (frame.y.xp + frame.y.xn) / 2; - const float y_norm = float(y_position - y_min) / y_range; + const float y_position = (frame.y.xp + frame.y.xn) * 0.5f; + const float y_norm = (y_position - y_min) / y_range; const auto z_max = frame.pressure.yp; const auto z_min = frame.pressure.xn; From 8d330784b2e9a49f494d015fb56d22f4bfa75d7f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 11:46:09 -0700 Subject: [PATCH 15/33] CFlags: Add "-g" compiler option for debug symbols. --- firmware/application/CMakeLists.txt | 2 +- firmware/baseband/CMakeLists.txt | 2 +- firmware/bootstrap/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index f4190523f..fee94a090 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -29,7 +29,7 @@ enable_language(C CXX ASM) project(application) # Compiler options here. -set(USE_OPT "-Os --specs=nano.specs") +set(USE_OPT "-Os -g --specs=nano.specs") # C specific options here (added to USE_OPT). set(USE_COPT "-std=gnu99") diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index 54010d736..2a8b1b536 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -29,7 +29,7 @@ enable_language(C CXX ASM) project(baseband_shared) # Compiler options here. -set(USE_OPT "-O3 -falign-functions=16 -fno-math-errno --specs=nano.specs") +set(USE_OPT "-O3 -g -falign-functions=16 -fno-math-errno --specs=nano.specs") # C specific options here (added to USE_OPT). set(USE_COPT "-std=gnu99") diff --git a/firmware/bootstrap/CMakeLists.txt b/firmware/bootstrap/CMakeLists.txt index 4c4d5a41c..7f837998b 100644 --- a/firmware/bootstrap/CMakeLists.txt +++ b/firmware/bootstrap/CMakeLists.txt @@ -29,7 +29,7 @@ enable_language(C CXX ASM) project(bootstrap) # Compiler options here. -set(USE_OPT "-Os -falign-functions=16 -fno-math-errno --specs=nano.specs") +set(USE_OPT "-Os -g -falign-functions=16 -fno-math-errno --specs=nano.specs") # C specific options here (added to USE_OPT). set(USE_COPT "-std=gnu99") From c022a72ef4063bb78dca1c1375b4a79ee2288dc4 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:01:20 -0700 Subject: [PATCH 16/33] Touch: Add Calibration class. Matrix transforms coordinates from digitizer to display. --- firmware/application/touch.cpp | 14 ++++++++++++++ firmware/application/touch.hpp | 35 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/firmware/application/touch.cpp b/firmware/application/touch.cpp index 0aae8a9b6..13efb236b 100644 --- a/firmware/application/touch.cpp +++ b/firmware/application/touch.cpp @@ -60,6 +60,20 @@ Metrics calculate_metrics(const Frame& frame) { }; } +ui::Point Calibration::translate(const DigitizerPoint& p) const { + static constexpr range_t x_range { 0, 240 - 1 }; + static constexpr range_t y_range { 0, 320 - 1 }; + + const int32_t x = (a * p.x + b * p.y + c) / k; + const int32_t y = (d * p.x + e * p.y + f) / k; + const auto x_clipped = x_range.clip(x); + const auto y_clipped = y_range.clip(y); + return { + static_cast(x_clipped), + static_cast(y_clipped) + }; +} + void Manager::feed(const Frame& frame) { // touch_debounce.feed(touch_raw); const auto touch_raw = frame.touch; diff --git a/firmware/application/touch.hpp b/firmware/application/touch.hpp index 31c1bd55f..e4b0f3639 100644 --- a/firmware/application/touch.hpp +++ b/firmware/application/touch.hpp @@ -114,6 +114,41 @@ struct Metrics { Metrics calculate_metrics(const Frame& frame); +struct DigitizerPoint { + int32_t x; + int32_t y; +}; + +struct Calibration { + /* Touch screen calibration matrix, based on article by Carlos E. Vidales: + * http://www.embedded.com/design/system-integration/4023968/How-To-Calibrate-Touch-Screens + */ + + constexpr Calibration( + const std::array& s, + const std::array& d + ) : k { (s[0].x - s[2].x) * (s[1].y - s[2].y) - (s[1].x - s[2].x) * (s[0].y - s[2].y) }, + a { (d[0].x - d[2].x) * (s[1].y - s[2].y) - (d[1].x - d[2].x) * (s[0].y - s[2].y) }, + b { (s[0].x - s[2].x) * (d[1].x - d[2].x) - (d[0].x - d[2].x) * (s[1].x - s[2].x) }, + c { s[0].y * (s[2].x * d[1].x - s[1].x * d[2].x) + s[1].y * (s[0].x * d[2].x - s[2].x * d[0].x) + s[2].y * (s[1].x * d[0].x - s[0].x * d[1].x) }, + d { (d[0].y - d[2].y) * (s[1].y - s[2].y) - (d[1].y - d[2].y) * (s[0].y - s[2].y) }, + e { (s[0].x - s[2].x) * (d[1].y - d[2].y) - (d[0].y - d[2].y) * (s[1].x - s[2].x) }, + f { s[0].y * (s[2].x * d[1].y - s[1].x * d[2].y) + s[1].y * (s[0].x * d[2].y - s[2].x * d[0].y) + s[2].y * (s[1].x * d[0].y - s[0].x * d[1].y) } + { + } + + ui::Point translate(const DigitizerPoint& p) const; + +private: + int32_t k; + int32_t a; + int32_t b; + int32_t c; + int32_t d; + int32_t e; + int32_t f; +}; + template class Filter { public: From 5e5417b45695411ea8d5cf96c15cbc459614fc1e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:03:06 -0700 Subject: [PATCH 17/33] Touch: Default and active calibration API of sorts. --- firmware/application/touch.cpp | 20 ++++++++++++++++++++ firmware/application/touch.hpp | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/firmware/application/touch.cpp b/firmware/application/touch.cpp index 13efb236b..2e01803e9 100644 --- a/firmware/application/touch.cpp +++ b/firmware/application/touch.cpp @@ -74,6 +74,26 @@ ui::Point Calibration::translate(const DigitizerPoint& p) const { }; } +static const Calibration _default_calibration { + /* Values derived from one PortaPack H1 unit. */ + { { { 256, 731 }, { 880, 432 }, { 568, 146 } } }, + { { { 32, 48 }, { 208, 168 }, { 120, 288 } } } +}; + +static Calibration _calibration = _default_calibration; + +void set_calibration(const Calibration& value) { + _calibration = value; +} + +const Calibration& calibration() { + return _calibration; +} + +const Calibration& default_calibration() { + return _default_calibration; +} + void Manager::feed(const Frame& frame) { // touch_debounce.feed(touch_raw); const auto touch_raw = frame.touch; diff --git a/firmware/application/touch.hpp b/firmware/application/touch.hpp index e4b0f3639..cf7ea62be 100644 --- a/firmware/application/touch.hpp +++ b/firmware/application/touch.hpp @@ -149,6 +149,10 @@ private: int32_t f; }; +void set_calibration(const Calibration& calibration); +const Calibration& calibration(); +const Calibration& default_calibration(); + template class Filter { public: From e813db16fd7335ba104031563e7aa0aeb1a5e37c Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:04:04 -0700 Subject: [PATCH 18/33] Touch: Missing #include. --- firmware/application/touch.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/application/touch.cpp b/firmware/application/touch.cpp index 2e01803e9..b9a8b8cba 100644 --- a/firmware/application/touch.cpp +++ b/firmware/application/touch.cpp @@ -21,6 +21,8 @@ #include "touch.hpp" +#include "utility.hpp" + namespace touch { Metrics calculate_metrics(const Frame& frame) { From 7492d50f0b698da0a0b0ff306c35859e665c8f51 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:08:02 -0700 Subject: [PATCH 19/33] Touch: Use calibration matrix. --- firmware/application/touch.cpp | 10 ++++++---- firmware/application/touch.hpp | 18 +----------------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/firmware/application/touch.cpp b/firmware/application/touch.cpp index b9a8b8cba..07c558bfe 100644 --- a/firmware/application/touch.cpp +++ b/firmware/application/touch.cpp @@ -111,10 +111,8 @@ void Manager::feed(const Frame& frame) { // TODO: Add touch pressure hysteresis? touch_pressure = (metrics.r < r_touch_threshold); if( touch_pressure ) { - const float x = width_pixels * (metrics.x - calib_x_low) / calib_x_range; - filter_x.feed(x); - const float y = height_pixels * (calib_y_high - metrics.y) / calib_y_range; - filter_y.feed(y); + filter_x.feed(metrics.x * 1024); + filter_y.feed(metrics.y * 1024); } } else { filter_x.reset(); @@ -146,4 +144,8 @@ void Manager::feed(const Frame& frame) { } } +ui::Point Manager::filtered_point() const { + return calibration().translate({ filter_x.value(), filter_y.value() }); +} + } /* namespace touch */ diff --git a/firmware/application/touch.hpp b/firmware/application/touch.hpp index cf7ea62be..d1e6eaee7 100644 --- a/firmware/application/touch.hpp +++ b/firmware/application/touch.hpp @@ -220,21 +220,10 @@ private: TouchDetected, }; - static constexpr uint32_t width_pixels = 240; - static constexpr uint32_t height_pixels = 320; - static constexpr float r_touch_threshold = 0x1000; static constexpr size_t touch_count_threshold { 4 }; static constexpr uint32_t touch_stable_bound { 4 }; - static constexpr float calib_x_low = 0.07f; - static constexpr float calib_x_high = 0.94f; - static constexpr float calib_x_range = calib_x_high - calib_x_low; - - static constexpr float calib_y_low = 0.04f; - static constexpr float calib_y_high = 0.91f; - static constexpr float calib_y_range = calib_y_high - calib_y_low; - // Ensure filter length is equal or less than touch_count_threshold, // or coordinates from the last touch will be in the initial averages. Filter filter_x; @@ -249,12 +238,7 @@ private: && filter_y.stable(touch_stable_bound); } - ui::Point filtered_point() const { - return { - static_cast(filter_x.value()), - static_cast(filter_y.value()) - }; - } + ui::Point filtered_point() const; void touch_started() { fire_event(ui::TouchEvent::Type::Start); From cd9b76ef786ff267a7490f83762aa2c1c8fa615c Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:08:24 -0700 Subject: [PATCH 20/33] Touch: Average/threshold tweaks. --- firmware/application/touch.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/application/touch.hpp b/firmware/application/touch.hpp index d1e6eaee7..3507c0af3 100644 --- a/firmware/application/touch.hpp +++ b/firmware/application/touch.hpp @@ -221,8 +221,8 @@ private: }; static constexpr float r_touch_threshold = 0x1000; - static constexpr size_t touch_count_threshold { 4 }; - static constexpr uint32_t touch_stable_bound { 4 }; + static constexpr size_t touch_count_threshold { 3 }; + static constexpr uint32_t touch_stable_bound { 16 }; // Ensure filter length is equal or less than touch_count_threshold, // or coordinates from the last touch will be in the initial averages. From 24fa97439d7ca9524f892e5b41996d3a39695649 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:15:21 -0700 Subject: [PATCH 21/33] Touch: Add touch configuration UI. --- firmware/application/CMakeLists.txt | 1 + firmware/application/ui_setup.cpp | 4 +- firmware/application/ui_touch_calibration.cpp | 207 ++++++++++++++++++ firmware/application/ui_touch_calibration.hpp | 161 ++++++++++++++ 4 files changed, 372 insertions(+), 1 deletion(-) create mode 100644 firmware/application/ui_touch_calibration.cpp create mode 100644 firmware/application/ui_touch_calibration.hpp diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index fee94a090..50dc53bbf 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -148,6 +148,7 @@ set(CPPSRC ui_audio.cpp ui_font_fixed_8x16.cpp ui_setup.cpp + ui_touch_calibration.cpp ui_debug.cpp ui_baseband_stats_view.cpp ui_sd_card_status_view.cpp diff --git a/firmware/application/ui_setup.cpp b/firmware/application/ui_setup.cpp index 5a10b20e4..9bc753891 100644 --- a/firmware/application/ui_setup.cpp +++ b/firmware/application/ui_setup.cpp @@ -21,6 +21,8 @@ #include "ui_setup.hpp" +#include "ui_touch_calibration.hpp" + #include "portapack_persistent_memory.hpp" #include "lpc43xx_cpp.hpp" using namespace lpc43xx; @@ -196,7 +198,7 @@ SetupMenuView::SetupMenuView(NavigationView& nav) { { "Date/Time", [&nav](){ nav.push(); } }, { "Frequency Correction", [&nav](){ nav.push(); } }, { "Antenna Bias Voltage", [&nav](){ nav.push(); } }, - { "Touch", [&nav](){ nav.push(); } }, + { "Touch", [&nav](){ nav.push(); } }, } }); on_left = [&nav](){ nav.pop(); }; } diff --git a/firmware/application/ui_touch_calibration.cpp b/firmware/application/ui_touch_calibration.cpp new file mode 100644 index 000000000..d812535d3 --- /dev/null +++ b/firmware/application/ui_touch_calibration.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc. + * + * 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 "ui_touch_calibration.hpp" + +#include "irq_controls.hpp" + +#if defined(TOUCH_DEBUG) +#include "string_format.hpp" +#endif + +namespace ui { + +TouchCalibrationView::TouchCalibrationView( + NavigationView& nav +) : nav { nav }, + calibration { touch::default_calibration() } +{ + add_children({ { + &image_calibrate_0, + &image_calibrate_1, + &image_calibrate_2, + &image_verify_0, + &image_verify_1, + &image_verify_2, + &label_calibrate, + &label_verify, + &label_success, + &label_failure, + &button_cancel, + &button_ok, + } }); + + button_cancel.on_select = [this](Button&){ this->on_cancel(); }; + button_ok.on_select = [this](Button&){ this->on_ok(); }; + + set_phase(Phase::Calibrate0); +} + +void TouchCalibrationView::focus() { + button_cancel.focus(); +} + +void TouchCalibrationView::update_target() { + const auto phase_calibrate = (phase == Phase::Calibrate0) || (phase == Phase::Calibrate1) || (phase == Phase::Calibrate2); + const auto phase_verify = (phase == Phase::Verify0) || (phase == Phase::Verify1) || (phase == Phase::Verify2); + + image_calibrate_0.hidden(phase != Phase::Calibrate0); + image_calibrate_1.hidden(phase != Phase::Calibrate1); + image_calibrate_2.hidden(phase != Phase::Calibrate2); + + image_verify_0.hidden(phase != Phase::Verify0); + image_verify_1.hidden(phase != Phase::Verify1); + image_verify_2.hidden(phase != Phase::Verify2); + + label_calibrate.hidden(!phase_calibrate); + label_verify.hidden(!phase_verify); + label_success.hidden(phase != Phase::Success); + label_failure.hidden(phase != Phase::Failure); + + button_ok.hidden((phase != Phase::Success) && (phase != Phase::Failure)); + + /* TODO: Such a hack to get around a poor repaint implementation! This "technique" + * occurs in other places... + */ + set_dirty(); +} + +void TouchCalibrationView::set_phase(const Phase value) { + if( value != phase ) { + phase = value; + update_target(); + } +} + +uint32_t TouchCalibrationView::distance_squared(const Point& touch_point, const Image& target) { + const auto target_point = target.screen_rect().center(); + const int32_t dx = target_point.x - touch_point.x; + const int32_t dy = target_point.y - touch_point.y; + const uint32_t dx2 = dx * dx; + const uint32_t dy2 = dy * dy; + return dx2 + dy2; +} + +void TouchCalibrationView::touch_complete() { + auto next_phase = static_cast(toUType(phase) + 1); + + switch(phase) { + case Phase::Calibrate0: + case Phase::Verify0: + digitizer_points[0] = average; + break; + + case Phase::Calibrate1: + case Phase::Verify1: + digitizer_points[1] = average; + break; + + case Phase::Calibrate2: + case Phase::Verify2: + digitizer_points[2] = average; + break; + + default: + break; + } + + if( phase == Phase::Calibrate2 ) { + const std::array display_points { { + image_calibrate_0.screen_rect().center(), + image_calibrate_1.screen_rect().center(), + image_calibrate_2.screen_rect().center(), + } }; + + calibration = { digitizer_points, display_points }; + } + + if( phase == Phase::Verify2 ) { + const auto calibrated_0 = calibration.translate(digitizer_points[0]); + const auto d_sq_0 = distance_squared(calibrated_0, image_verify_0); + + const auto calibrated_1 = calibration.translate(digitizer_points[1]); + const auto d_sq_1 = distance_squared(calibrated_1, image_verify_1); + + const auto calibrated_2 = calibration.translate(digitizer_points[2]); + const auto d_sq_2 = distance_squared(calibrated_2, image_verify_2); + + if( (d_sq_0 < verify_d_sq_max) && (d_sq_1 < verify_d_sq_max) && (d_sq_2 < verify_d_sq_max) ) { + next_phase = Phase::Success; + } else { + next_phase = Phase::Failure; + } + } + + set_phase(next_phase); +} + +void TouchCalibrationView::on_ok() { + if( phase == Phase::Success ) { + touch::set_calibration(calibration); + nav.pop(); + } + if( phase == Phase::Failure ) { + set_phase(Phase::Calibrate0); + } +} + +void TouchCalibrationView::on_cancel() { + nav.pop(); +} + +void TouchCalibrationView::on_frame_sync() { + switch(phase) { + case Phase::Calibrate0: + case Phase::Calibrate1: + case Phase::Calibrate2: + case Phase::Verify0: + case Phase::Verify1: + case Phase::Verify2: + break; + + default: + return; + } + + const auto frame = get_touch_frame(); + const auto metrics = touch::calculate_metrics(frame); + const auto x = metrics.x * 1024; + const auto y = metrics.y * 1024; + + if( metrics.r < 1000.0f ) { + if( samples_count > 0 ) { + average.x = ((average.x * 7) + x) / 8; + average.y = ((average.y * 7) + y) / 8; + } else { + average.x = x; + average.y = y; + } + + samples_count += 1; + } else { + if( samples_count >= samples_limit ) { + touch_complete(); + } + samples_count = 0; + } +} + +} /* namespace ui */ diff --git a/firmware/application/ui_touch_calibration.hpp b/firmware/application/ui_touch_calibration.hpp new file mode 100644 index 000000000..8e2d9b082 --- /dev/null +++ b/firmware/application/ui_touch_calibration.hpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc. + * + * 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. + */ + +#ifndef __UI_TOUCH_CALIBRATION_HPP__ +#define __UI_TOUCH_CALIBRATION_HPP__ + +#include "ui_widget.hpp" +#include "ui_navigation.hpp" +#include "touch.hpp" + +namespace ui { + +class TouchCalibrationView : public View { +public: + TouchCalibrationView(NavigationView& nav); + + void focus() override; + +private: + enum class Phase { + Init, + Calibrate0, + Calibrate1, + Calibrate2, + Verify0, + Verify1, + Verify2, + Success, + Failure, + }; + + NavigationView& nav; + Phase phase { Phase::Init }; + + void update_target(); + + void set_phase(const Phase value); + + uint32_t distance_squared(const Point& touch_point, const Image& target); + + void touch_complete(); + void on_ok(); + void on_cancel(); + + const uint32_t samples_limit { 40 }; + const uint32_t verify_d_sq_max = 10 * 10; + + uint32_t samples_count { 0 }; + + touch::DigitizerPoint average; + + std::array digitizer_points; + + touch::Calibration calibration; + + static constexpr ui::Coord y_touch_values = 320 - 16 - 16; + static constexpr ui::Coord y_xlate_values = y_touch_values - 16; + + Image image_calibrate_0 { + { 32 - 16, 32 - 16, 32, 32 }, + &bitmap_target_calibrate, + Color::white(), + Color::black() + }; + + Image image_calibrate_1 { + { 240 - 32 - 16, (320 - 16) / 2 - 16, 32, 32 }, + &bitmap_target_calibrate, + Color::white(), + Color::black() + }; + + Image image_calibrate_2 { + { 240 / 2 - 16, (320 - 16) - 32 - 16, 32, 32 }, + &bitmap_target_calibrate, + Color::white(), + Color::black() + }; + + Image image_verify_0 { + { 32 - 16, 32 - 16, 32, 32 }, + &bitmap_target_verify, + Color::white(), + Color::black() + }; + + Image image_verify_1 { + { 240 - 32 - 16, (320 - 16) / 2 - 16, 32, 32 }, + &bitmap_target_verify, + Color::white(), + Color::black() + }; + + Image image_verify_2 { + { 240 / 2 - 16, (320 - 16) - 32 - 16, 32, 32 }, + &bitmap_target_verify, + Color::white(), + Color::black() + }; + + Text label_calibrate { + { 16, 5 * 16, 26 * 8, 1 * 16 }, + "Touch targets to calibrate" + }; + + Text label_verify { + { 28, 5 * 16, 23 * 8, 1 * 16 }, + "Touch targets to verify" + }; + + Text label_success { + { 32, 5 * 16, 22 * 8, 1 * 16 }, + "Apply new calibration?" + }; + + Text label_failure { + { 16, 5 * 16, 26 * 8, 1 * 16 }, + "Calibration failed. Retry?" + }; + + Button button_cancel { + { 40, 200, 64, 24 }, + "Cancel" + }; + + Button button_ok { + { 136, 200, 64, 24 }, + "OK" + }; + + void on_frame_sync(); + + MessageHandlerRegistration message_handler_frame_sync { + Message::ID::DisplayFrameSync, + [this](const Message* const) { + this->on_frame_sync(); + } + }; +}; + +} /* namespace ui */ + +#endif/*__UI_TOUCH_CALIBRATION_HPP__*/ From 82f6e7c306ed462fdcbfe3d8a44bcce208e4c06c Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:17:57 -0700 Subject: [PATCH 22/33] Change default frequency when NVRAM is initialized. --- firmware/common/portapack_persistent_memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index cd93bd059..2f4c758c8 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -36,7 +36,7 @@ using portapack::memory::map::backup_ram; namespace portapack { namespace persistent_memory { -constexpr rf::Frequency tuned_frequency_reset_value { 858750000 }; +constexpr rf::Frequency tuned_frequency_reset_value { 100000000 }; using ppb_range_t = range_t; constexpr ppb_range_t ppb_range { -99000, 99000 }; From 44a1b7d9d785b18165aba55beae3152abbd3bbbd Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:39:49 -0700 Subject: [PATCH 23/33] ReceiverModel: Method renaming. update_modulation_configuration() -> update_modulation(). --- firmware/application/receiver_model.cpp | 10 +++++----- firmware/application/receiver_model.hpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index bd5def05e..4c9052ff6 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -147,7 +147,7 @@ void ReceiverModel::enable() { update_vga(); update_baseband_bandwidth(); update_baseband_configuration(); - update_modulation_configuration(); + update_modulation(); update_headphone_volume(); } @@ -200,21 +200,21 @@ void ReceiverModel::set_baseband_configuration(const BasebandConfiguration confi void ReceiverModel::set_am_configuration(const size_t n) { if( n < am_configs.size() ) { am_config_index = n; - update_modulation_configuration(); + update_modulation(); } } void ReceiverModel::set_nbfm_configuration(const size_t n) { if( n < nbfm_configs.size() ) { nbfm_config_index = n; - update_modulation_configuration(); + update_modulation(); } } void ReceiverModel::set_wfm_configuration(const size_t n) { if( n < wfm_configs.size() ) { wfm_config_index = n; - update_modulation_configuration(); + update_modulation(); } } @@ -236,7 +236,7 @@ void ReceiverModel::update_headphone_volume() { audio::headphone::set_volume(headphone_volume_); } -void ReceiverModel::update_modulation_configuration() { +void ReceiverModel::update_modulation() { switch(static_cast(modulation())) { default: case Mode::AMAudio: diff --git a/firmware/application/receiver_model.hpp b/firmware/application/receiver_model.hpp index e9ab0efb0..a01871d9e 100644 --- a/firmware/application/receiver_model.hpp +++ b/firmware/application/receiver_model.hpp @@ -134,7 +134,7 @@ private: void update_baseband_configuration(); void update_headphone_volume(); - void update_modulation_configuration(); + void update_modulation(); void update_am_configuration(); void update_nbfm_configuration(); void update_wfm_configuration(); From 5a05a758a106e74813755ca76ef75d66a4724392 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:40:30 -0700 Subject: [PATCH 24/33] ReceiverModel: Use accessor method. --- firmware/application/receiver_model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index 4c9052ff6..73b844a30 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -161,7 +161,7 @@ void ReceiverModel::disable() { } int32_t ReceiverModel::tuning_offset() { - if( (baseband_configuration.mode == 4) ) { + if( (modulation() == 4) ) { return 0; } else { return -(sampling_rate() / 4); From b60e88ef687cf4df308cb9ff88247f18deed9d59 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:41:36 -0700 Subject: [PATCH 25/33] ReceiverModel: More method renaming. update_baseband_configuration() -> update_sampling_rate(). --- firmware/application/receiver_model.cpp | 4 ++-- firmware/application/receiver_model.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index 73b844a30..3d1e023fb 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -146,7 +146,7 @@ void ReceiverModel::enable() { update_lna(); update_vga(); update_baseband_bandwidth(); - update_baseband_configuration(); + update_sampling_rate(); update_modulation(); update_headphone_volume(); } @@ -218,7 +218,7 @@ void ReceiverModel::set_wfm_configuration(const size_t n) { } } -void ReceiverModel::update_baseband_configuration() { +void ReceiverModel::update_sampling_rate() { // TODO: Move more low-level radio control stuff to M4. It'll enable tighter // synchronization for things like wideband (sweeping) spectrum analysis, and // protocols that need quick RX/TX turn-around. diff --git a/firmware/application/receiver_model.hpp b/firmware/application/receiver_model.hpp index a01871d9e..ce0d6f3ac 100644 --- a/firmware/application/receiver_model.hpp +++ b/firmware/application/receiver_model.hpp @@ -131,7 +131,7 @@ private: void update_lna(); void update_baseband_bandwidth(); void update_vga(); - void update_baseband_configuration(); + void update_sampling_rate(); void update_headphone_volume(); void update_modulation(); From 371c6e090646c28c853013161275f1aaf528225a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:42:46 -0700 Subject: [PATCH 26/33] ReceiverModel: Eliminate now-redundant BasebandConfiguration. --- firmware/application/analog_audio_app.cpp | 7 ++--- firmware/application/receiver_model.cpp | 21 +++++++++------ firmware/application/receiver_model.hpp | 33 ++++------------------- 3 files changed, 20 insertions(+), 41 deletions(-) diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index 872a57c27..9a0d7175b 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -286,11 +286,8 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) { baseband::run_image(image_tag); const auto is_wideband_spectrum_mode = (modulation == ReceiverModel::Mode::SpectrumAnalysis); - receiver_model.set_baseband_configuration({ - .mode = toUType(modulation), - .sampling_rate = is_wideband_spectrum_mode ? 20000000U : 3072000U, - .decimation_factor = 1, - }); + receiver_model.set_modulation(toUType(modulation)); + receiver_model.set_sampling_rate(is_wideband_spectrum_mode ? 20000000 : 3072000); receiver_model.set_baseband_bandwidth(is_wideband_spectrum_mode ? 12000000 : 1750000); receiver_model.enable(); diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index 3d1e023fb..f807129ef 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -116,11 +116,21 @@ void ReceiverModel::set_vga(int32_t v_db) { } uint32_t ReceiverModel::sampling_rate() const { - return baseband_configuration.sampling_rate; + return sampling_rate_; +} + +void ReceiverModel::set_sampling_rate(uint32_t v) { + sampling_rate_ = v; + update_sampling_rate(); } uint32_t ReceiverModel::modulation() const { - return baseband_configuration.mode; + return mode_; +} + +void ReceiverModel::set_modulation(const uint32_t v) { + mode_ = v; + update_modulation(); } volume_t ReceiverModel::headphone_volume() const { @@ -134,7 +144,7 @@ void ReceiverModel::set_headphone_volume(volume_t v) { uint32_t ReceiverModel::baseband_oversampling() const { // TODO: Rename decimation_factor. - return baseband_configuration.decimation_factor; + return decimation_factor_; } void ReceiverModel::enable() { @@ -192,11 +202,6 @@ void ReceiverModel::update_vga() { radio::set_vga_gain(vga_gain_db_); } -void ReceiverModel::set_baseband_configuration(const BasebandConfiguration config) { - baseband_configuration = config; - update_baseband_configuration(); -} - void ReceiverModel::set_am_configuration(const size_t n) { if( n < am_configs.size() ) { am_config_index = n; diff --git a/firmware/application/receiver_model.hpp b/firmware/application/receiver_model.hpp index ce0d6f3ac..d4ab71b2a 100644 --- a/firmware/application/receiver_model.hpp +++ b/firmware/application/receiver_model.hpp @@ -30,27 +30,6 @@ #include "max2837.hpp" #include "volume.hpp" -struct BasebandConfiguration { - int32_t mode; - uint32_t sampling_rate; - size_t decimation_factor; - - constexpr BasebandConfiguration( - int32_t mode, - uint32_t sampling_rate, - size_t decimation_factor = 1 - ) : mode { mode }, - sampling_rate { sampling_rate }, - decimation_factor { decimation_factor } - { - } - - constexpr BasebandConfiguration( - ) : BasebandConfiguration { -1, 0, 1 } - { - } -}; - class ReceiverModel { public: enum class Mode : int32_t { @@ -83,8 +62,10 @@ public: void set_vga(int32_t v_db); uint32_t sampling_rate() const; + void set_sampling_rate(uint32_t v); uint32_t modulation() const; + void set_modulation(uint32_t v); volume_t headphone_volume() const; void set_headphone_volume(volume_t v); @@ -94,8 +75,6 @@ public: void enable(); void disable(); - void set_baseband_configuration(const BasebandConfiguration config); - size_t am_configuration() const; void set_am_configuration(const size_t n); @@ -113,11 +92,9 @@ private: int32_t lna_gain_db_ { 32 }; uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum }; int32_t vga_gain_db_ { 32 }; - BasebandConfiguration baseband_configuration { - .mode = 1, /* TODO: Enum! */ - .sampling_rate = 3072000, - .decimation_factor = 1, - }; + uint32_t mode_ { 1 }; + uint32_t sampling_rate_ { 3072000 }; + size_t decimation_factor_ { 1 }; size_t am_config_index = 0; size_t nbfm_config_index = 0; size_t wfm_config_index = 0; From f05d917a7c80a65337a3005d44cbeea9cd542637 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:51:37 -0700 Subject: [PATCH 27/33] ReceiverModel: Use Mode instead of integer. --- firmware/application/analog_audio_app.cpp | 4 ++-- firmware/application/receiver_model.cpp | 8 ++++---- firmware/application/receiver_model.hpp | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index 9a0d7175b..417d1ea12 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -119,7 +119,7 @@ AnalogAudioView::AnalogAudioView( }; const auto modulation = receiver_model.modulation(); - options_modulation.set_by_value(modulation); + options_modulation.set_by_value(toUType(modulation)); options_modulation.on_change = [this](size_t, OptionsField::value_t v) { this->on_modulation_changed(static_cast(v)); }; @@ -286,7 +286,7 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) { baseband::run_image(image_tag); const auto is_wideband_spectrum_mode = (modulation == ReceiverModel::Mode::SpectrumAnalysis); - receiver_model.set_modulation(toUType(modulation)); + receiver_model.set_modulation(modulation); receiver_model.set_sampling_rate(is_wideband_spectrum_mode ? 20000000 : 3072000); receiver_model.set_baseband_bandwidth(is_wideband_spectrum_mode ? 12000000 : 1750000); receiver_model.enable(); diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index f807129ef..35059f5c7 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -124,11 +124,11 @@ void ReceiverModel::set_sampling_rate(uint32_t v) { update_sampling_rate(); } -uint32_t ReceiverModel::modulation() const { +ReceiverModel::Mode ReceiverModel::modulation() const { return mode_; } -void ReceiverModel::set_modulation(const uint32_t v) { +void ReceiverModel::set_modulation(const Mode v) { mode_ = v; update_modulation(); } @@ -171,7 +171,7 @@ void ReceiverModel::disable() { } int32_t ReceiverModel::tuning_offset() { - if( (modulation() == 4) ) { + if( (modulation() == Mode::SpectrumAnalysis) ) { return 0; } else { return -(sampling_rate() / 4); @@ -242,7 +242,7 @@ void ReceiverModel::update_headphone_volume() { } void ReceiverModel::update_modulation() { - switch(static_cast(modulation())) { + switch(modulation()) { default: case Mode::AMAudio: update_am_configuration(); diff --git a/firmware/application/receiver_model.hpp b/firmware/application/receiver_model.hpp index d4ab71b2a..a51a4be0e 100644 --- a/firmware/application/receiver_model.hpp +++ b/firmware/application/receiver_model.hpp @@ -64,8 +64,8 @@ public: uint32_t sampling_rate() const; void set_sampling_rate(uint32_t v); - uint32_t modulation() const; - void set_modulation(uint32_t v); + Mode modulation() const; + void set_modulation(Mode v); volume_t headphone_volume() const; void set_headphone_volume(volume_t v); @@ -92,7 +92,7 @@ private: int32_t lna_gain_db_ { 32 }; uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum }; int32_t vga_gain_db_ { 32 }; - uint32_t mode_ { 1 }; + Mode mode_ { Mode::NarrowbandFMAudio }; uint32_t sampling_rate_ { 3072000 }; size_t decimation_factor_ { 1 }; size_t am_config_index = 0; From f85d83475c2175f2d0abafc694c476833442ae7b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 14:57:50 -0700 Subject: [PATCH 28/33] ReceiverModel: Clean up Mode enum. --- firmware/application/receiver_model.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/firmware/application/receiver_model.hpp b/firmware/application/receiver_model.hpp index a51a4be0e..d103c4c81 100644 --- a/firmware/application/receiver_model.hpp +++ b/firmware/application/receiver_model.hpp @@ -32,12 +32,11 @@ class ReceiverModel { public: - enum class Mode : int32_t { + enum class Mode { AMAudio = 0, NarrowbandFMAudio = 1, WidebandFMAudio = 2, - SpectrumAnalysis = 4, - Capture = 7, + SpectrumAnalysis = 3, }; rf::Frequency tuning_frequency() const; From aa1b8f63fcde2262fa57338f65f556130e67befa Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 15:12:08 -0700 Subject: [PATCH 29/33] Remove errant debug #define. --- firmware/application/ui_touch_calibration.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/firmware/application/ui_touch_calibration.cpp b/firmware/application/ui_touch_calibration.cpp index d812535d3..6e58b6c3a 100644 --- a/firmware/application/ui_touch_calibration.cpp +++ b/firmware/application/ui_touch_calibration.cpp @@ -23,10 +23,6 @@ #include "irq_controls.hpp" -#if defined(TOUCH_DEBUG) -#include "string_format.hpp" -#endif - namespace ui { TouchCalibrationView::TouchCalibrationView( From c424bf08f3cc48048fcc57a966b95e414b9e5cfb Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 15:30:43 -0700 Subject: [PATCH 30/33] Touch: Migrate touch calibration to persistent memory. --- firmware/application/touch.cpp | 27 +++++++------------ firmware/application/touch.hpp | 4 +-- firmware/application/ui_touch_calibration.cpp | 5 +++- .../common/portapack_persistent_memory.cpp | 16 +++++++++++ .../common/portapack_persistent_memory.hpp | 4 +++ 5 files changed, 34 insertions(+), 22 deletions(-) diff --git a/firmware/application/touch.cpp b/firmware/application/touch.cpp index 07c558bfe..ac48c0539 100644 --- a/firmware/application/touch.cpp +++ b/firmware/application/touch.cpp @@ -21,6 +21,9 @@ #include "touch.hpp" +#include "portapack_persistent_memory.hpp" +using namespace portapack; + #include "utility.hpp" namespace touch { @@ -76,26 +79,14 @@ ui::Point Calibration::translate(const DigitizerPoint& p) const { }; } -static const Calibration _default_calibration { +const Calibration default_calibration() { /* Values derived from one PortaPack H1 unit. */ - { { { 256, 731 }, { 880, 432 }, { 568, 146 } } }, - { { { 32, 48 }, { 208, 168 }, { 120, 288 } } } + return { + { { { 256, 731 }, { 880, 432 }, { 568, 146 } } }, + { { { 32, 48 }, { 208, 168 }, { 120, 288 } } } + }; }; -static Calibration _calibration = _default_calibration; - -void set_calibration(const Calibration& value) { - _calibration = value; -} - -const Calibration& calibration() { - return _calibration; -} - -const Calibration& default_calibration() { - return _default_calibration; -} - void Manager::feed(const Frame& frame) { // touch_debounce.feed(touch_raw); const auto touch_raw = frame.touch; @@ -145,7 +136,7 @@ void Manager::feed(const Frame& frame) { } ui::Point Manager::filtered_point() const { - return calibration().translate({ filter_x.value(), filter_y.value() }); + return persistent_memory::touch_calibration().translate({ filter_x.value(), filter_y.value() }); } } /* namespace touch */ diff --git a/firmware/application/touch.hpp b/firmware/application/touch.hpp index 3507c0af3..f862cf188 100644 --- a/firmware/application/touch.hpp +++ b/firmware/application/touch.hpp @@ -149,9 +149,7 @@ private: int32_t f; }; -void set_calibration(const Calibration& calibration); -const Calibration& calibration(); -const Calibration& default_calibration(); +const Calibration default_calibration(); template class Filter { diff --git a/firmware/application/ui_touch_calibration.cpp b/firmware/application/ui_touch_calibration.cpp index 6e58b6c3a..fe11d8901 100644 --- a/firmware/application/ui_touch_calibration.cpp +++ b/firmware/application/ui_touch_calibration.cpp @@ -23,6 +23,9 @@ #include "irq_controls.hpp" +#include "portapack_persistent_memory.hpp" +using namespace portapack; + namespace ui { TouchCalibrationView::TouchCalibrationView( @@ -151,7 +154,7 @@ void TouchCalibrationView::touch_complete() { void TouchCalibrationView::on_ok() { if( phase == Phase::Success ) { - touch::set_calibration(calibration); + persistent_memory::set_touch_calibration(calibration); nav.pop(); } if( phase == Phase::Failure ) { diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index 2f4c758c8..8ee50f420 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -46,6 +46,8 @@ constexpr ppb_t ppb_reset_value { 0 }; struct data_t { int64_t tuned_frequency; int32_t correction_ppb; + uint32_t touch_calibration_magic; + touch::Calibration touch_calibration; }; static_assert(sizeof(data_t) <= backup_ram.size(), "Persistent memory structure too large for VBAT-maintained region"); @@ -72,5 +74,19 @@ void set_correction_ppb(const ppb_t new_value) { portapack::clock_manager.set_reference_ppb(clipped_value); } +static constexpr uint32_t touch_calibration_magic = 0x074af82f; + +void set_touch_calibration(const touch::Calibration& new_value) { + data->touch_calibration = new_value; + data->touch_calibration_magic = touch_calibration_magic; +} + +const touch::Calibration& touch_calibration() { + if( data->touch_calibration_magic != touch_calibration_magic ) { + set_touch_calibration(touch::default_calibration()); + } + return data->touch_calibration; +} + } /* namespace persistent_memory */ } /* namespace portapack */ diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index 3e1a6c146..2ae7f023b 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -25,6 +25,7 @@ #include #include "rf_path.hpp" +#include "touch.hpp" namespace portapack { namespace persistent_memory { @@ -37,6 +38,9 @@ void set_tuned_frequency(const rf::Frequency new_value); ppb_t correction_ppb(); void set_correction_ppb(const ppb_t new_value); +void set_touch_calibration(const touch::Calibration& new_value); +const touch::Calibration& touch_calibration(); + } /* namespace persistent_memory */ } /* namespace portapack */ From 8a8e84d763531d9f5f706c0deab2fde711fb1328 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 21:57:00 -0700 Subject: [PATCH 31/33] Remove debugging code. --- firmware/application/ui_touch_calibration.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/firmware/application/ui_touch_calibration.hpp b/firmware/application/ui_touch_calibration.hpp index 8e2d9b082..40329020e 100644 --- a/firmware/application/ui_touch_calibration.hpp +++ b/firmware/application/ui_touch_calibration.hpp @@ -71,9 +71,6 @@ private: touch::Calibration calibration; - static constexpr ui::Coord y_touch_values = 320 - 16 - 16; - static constexpr ui::Coord y_xlate_values = y_touch_values - 16; - Image image_calibrate_0 { { 32 - 16, 32 - 16, 32, 32 }, &bitmap_target_calibrate, From dd2097a447b4f7a4ccb205fc06dae507e8626aac Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 21:57:51 -0700 Subject: [PATCH 32/33] Touch: Simplify scanning. --- firmware/application/irq_controls.cpp | 27 +++++++++------------------ firmware/application/touch.hpp | 2 +- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/firmware/application/irq_controls.cpp b/firmware/application/irq_controls.cpp index cb6a2df5c..d57e9a9a6 100644 --- a/firmware/application/irq_controls.cpp +++ b/firmware/application/irq_controls.cpp @@ -58,27 +58,18 @@ static volatile uint32_t touch_phase { 0 }; * Noise will only occur when the panel is being touched. Not ideal, but * an acceptable improvement. */ -static std::array touch_pins_configs { +static std::array touch_pins_configs { /* State machine will pause here until touch is detected. */ - portapack::IO::TouchPinsConfig::WaitTouch, - portapack::IO::TouchPinsConfig::SensePressure, portapack::IO::TouchPinsConfig::SenseX, portapack::IO::TouchPinsConfig::SenseY, - portapack::IO::TouchPinsConfig::SenseX, - portapack::IO::TouchPinsConfig::SenseY, - portapack::IO::TouchPinsConfig::SensePressure, - portapack::IO::TouchPinsConfig::SenseX, - portapack::IO::TouchPinsConfig::SenseY, - portapack::IO::TouchPinsConfig::SenseX, - portapack::IO::TouchPinsConfig::SenseY, }; static touch::Frame temp_frame; static touch::Frame touch_frame; static uint32_t touch_debounce = 0; -static uint32_t touch_debounce_mask = (1U << 1) - 1; +static uint32_t touch_debounce_mask = (1U << 4) - 1; static bool touch_detected = false; static bool touch_cycle = false; @@ -87,22 +78,22 @@ static bool touch_update() { const auto current_phase = touch_pins_configs[touch_phase]; switch(current_phase) { - case portapack::IO::TouchPinsConfig::WaitTouch: + case portapack::IO::TouchPinsConfig::SensePressure: { - /* Debounce touches. */ - const bool touch_raw = (samples.yp < touch::touch_threshold) && (samples.yn < touch::touch_threshold); + 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); touch_debounce = (touch_debounce << 1) | (touch_raw ? 1U : 0U); touch_detected = ((touch_debounce & touch_debounce_mask) == touch_debounce_mask); if( !touch_detected && !touch_cycle ) { + temp_frame.pressure = { }; return false; + } else { + temp_frame.pressure += samples; } } break; - case portapack::IO::TouchPinsConfig::SensePressure: - temp_frame.pressure += samples; - break; - case portapack::IO::TouchPinsConfig::SenseX: temp_frame.x += samples; break; diff --git a/firmware/application/touch.hpp b/firmware/application/touch.hpp index f862cf188..6f0895d7f 100644 --- a/firmware/application/touch.hpp +++ b/firmware/application/touch.hpp @@ -38,7 +38,7 @@ using sample_t = uint16_t; constexpr sample_t sample_max = 1023; -constexpr sample_t touch_threshold = sample_max * 0.5f; +constexpr sample_t touch_threshold = sample_max / 5; struct Samples { sample_t xp; From 16a6d7efe057c1b7dea4e7f8bfaf24e2ce54534e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 27 Jul 2016 21:58:35 -0700 Subject: [PATCH 33/33] Touch: Adjust thresholds and parameters for new scan. --- firmware/application/touch.hpp | 4 ++-- firmware/application/ui_touch_calibration.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/application/touch.hpp b/firmware/application/touch.hpp index 6f0895d7f..bc451e36e 100644 --- a/firmware/application/touch.hpp +++ b/firmware/application/touch.hpp @@ -218,9 +218,9 @@ private: TouchDetected, }; - static constexpr float r_touch_threshold = 0x1000; + static constexpr float r_touch_threshold = 640; static constexpr size_t touch_count_threshold { 3 }; - static constexpr uint32_t touch_stable_bound { 16 }; + static constexpr uint32_t touch_stable_bound { 8 }; // Ensure filter length is equal or less than touch_count_threshold, // or coordinates from the last touch will be in the initial averages. diff --git a/firmware/application/ui_touch_calibration.cpp b/firmware/application/ui_touch_calibration.cpp index fe11d8901..6fe200270 100644 --- a/firmware/application/ui_touch_calibration.cpp +++ b/firmware/application/ui_touch_calibration.cpp @@ -185,7 +185,7 @@ void TouchCalibrationView::on_frame_sync() { const auto x = metrics.x * 1024; const auto y = metrics.y * 1024; - if( metrics.r < 1000.0f ) { + if( metrics.r < 640.0f ) { if( samples_count > 0 ) { average.x = ((average.x * 7) + x) / 8; average.y = ((average.y * 7) + y) / 8;