From daed58a8522ea9479fdf18ba5fdaee01102b30b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Tu=C4=8Dek?= Date: Sun, 26 Nov 2023 19:41:15 +0100 Subject: [PATCH 1/7] prevent drifts (Proof of concept) --- right/src/debug.c | 43 +++++++++++++- right/src/debug.h | 17 +++++- right/src/mouse_controller.c | 14 +++++ right/src/segment_display.c | 10 +++- right/src/segment_display.h | 2 +- right/src/slave_drivers/uhk_module_driver.c | 1 + shared/module/slave_protocol_handler.c | 2 + shared/slave_protocol.h | 6 ++ trackpoint/src/module.c | 63 +++++++++++++++++++++ 9 files changed, 151 insertions(+), 7 deletions(-) diff --git a/right/src/debug.c b/right/src/debug.c index 6bd9eb87a..2b97117df 100644 --- a/right/src/debug.c +++ b/right/src/debug.c @@ -3,14 +3,12 @@ #ifdef WATCHES -#include "led_display.h" #include "timer.h" #include "key_states.h" #include #include "usb_interfaces/usb_interface_basic_keyboard.h" -#include "macros/core.h" #include "macros/status_buffer.h" -#include "keymap.h" +#include "segment_display.h" uint8_t CurrentWatch = 0; @@ -140,4 +138,43 @@ void WatchValueMax(int v, uint8_t n) } +void WatchFloatValue(float v, uint8_t n) +{ + if (CurrentTime - lastWatch > watchInterval) { + SegmentDisplay_SetFloat(v, SegmentDisplaySlot_Debug); + lastWatch = CurrentTime; + } +} + +void WatchFloatValueMin(float v, uint8_t n) +{ + static float m = 0; + + if (v < m) { + m = v; + } + + if (CurrentTime - lastWatch > watchInterval) { + SegmentDisplay_SetFloat(m, SegmentDisplaySlot_Debug); + lastWatch = CurrentTime; + m = (float)INT_MAX; + } +} + +void WatchFloatValueMax(float v, uint8_t n) +{ + static float m = 0; + + if (v > m) { + m = v; + } + + if (CurrentTime - lastWatch > watchInterval) { + SegmentDisplay_SetFloat(m, SegmentDisplaySlot_Debug); + lastWatch = CurrentTime; + m = (float)INT_MIN; + } +} + + #endif diff --git a/right/src/debug.h b/right/src/debug.h index c6c9e152d..984014768 100644 --- a/right/src/debug.h +++ b/right/src/debug.h @@ -1,6 +1,4 @@ -#if DEBUG == 1 #define WATCHES -#endif #ifdef WATCHES #ifndef SRC_UTILS_DBG_H_ @@ -41,6 +39,15 @@ // Watches value V in slot N. #define WATCH_VALUE_MAX(V, N) if(CurrentWatch == N) { WatchValueMax(V, N); } + // Watches value V in slot N. + #define WATCH_FLOAT_VALUE(V, N) if(CurrentWatch == N) { WatchFloatValue(V, N); } + + // Watches value V in slot N. + #define WATCH_FLOAT_VALUE_MIN(V, N) if(CurrentWatch == N) { WatchFloatValueMin(V, N); } + + // Watches value V in slot N. + #define WATCH_FLOAT_VALUE_MAX(V, N) if(CurrentWatch == N) { WatchFloatValueMax(V, N); } + // Watches string V in slot N. #define WATCH_STRING(V, N) if(CurrentWatch == N) { WatchString(V, N); } @@ -71,6 +78,9 @@ void WatchValue(int v, uint8_t n); void WatchValueMin(int v, uint8_t n); void WatchValueMax(int v, uint8_t n); + void WatchFloatValue(float v, uint8_t n); + void WatchFloatValueMin(float, uint8_t n); + void WatchFloatValueMax(float, uint8_t n); void WatchString(char const * v, uint8_t n); void ShowValue(int v, uint8_t n); void ShowString(char const * v, uint8_t n); @@ -89,6 +99,9 @@ #define WATCH_VALUE(V, N) #define WATCH_VALUE_MIN(V, N) #define WATCH_VALUE_MAX(V, N) + #define WATCH_FLOAT_VALUE(V, N) + #define WATCH_FLOAT_VALUE_MIN(V, N) + #define WATCH_FLOAT_VALUE_MAX(V, N) #define WATCH_STRING(V, N) #define SHOW_STRING(V, N) #define SHOW_VALUE(V, N) diff --git a/right/src/mouse_controller.c b/right/src/mouse_controller.c index e602ecb0e..bafeaffe1 100644 --- a/right/src/mouse_controller.c +++ b/right/src/mouse_controller.c @@ -2,6 +2,8 @@ #include "key_action.h" #include "led_display.h" #include "layer.h" +#include "macros/status_buffer.h" +#include "slave_protocol.h" #include "usb_interfaces/usb_interface_mouse.h" #include "peripherals/test_led.h" #include "slave_drivers/is31fl3xxx_driver.h" @@ -709,6 +711,12 @@ void MouseController_ProcessMouseActions() for (uint8_t moduleSlotId=0; moduleSlotIdpointerDelta.debugInfo.resetted && moduleState->moduleId == ModuleId_TrackpointRight) { + SHOW_STRING("RST", 0); + moduleState->pointerDelta.debugInfo.resetted = false; + } + if (moduleState->moduleId == ModuleId_Unavailable || moduleState->pointerCount == 0) { continue; } @@ -732,6 +740,12 @@ void MouseController_ProcessMouseActions() moduleState->pointerDelta.y = 0; __enable_irq(); + if (moduleState->moduleId == ModuleId_TrackpointRight && x != 0) { + // WATCH_FLOAT_VALUE(moduleState->pointerDelta.debugInfo.avgDrift, 0); + // WATCH_FLOAT_VALUE_MIN(moduleState->pointerDelta.debugInfo.avgDrift, 1); + // WATCH_FLOAT_VALUE_MAX(moduleState->pointerDelta.debugInfo.avgDrift, 2); + } + processModuleActions(ks, moduleState->moduleId, x, y, 0xFF); } } diff --git a/right/src/segment_display.c b/right/src/segment_display.c index 687792aa9..1756e5071 100644 --- a/right/src/segment_display.c +++ b/right/src/segment_display.c @@ -117,6 +117,7 @@ void SegmentDisplay_SerializeFloat(char* buffer, float num) { if (num <= -10.0f || 10.0f <= num ) { SegmentDisplay_SerializeInt(buffer, num); + return; } int mag = 0; @@ -127,7 +128,7 @@ void SegmentDisplay_SerializeFloat(char* buffer, float num) negative = true; } - while (num < 10.0f) { + while (num < 10.0f && mag < 10) { mag++; num *= 10; } @@ -178,6 +179,13 @@ void SegmentDisplay_SetInt(int32_t a, segment_display_slot_t slot) SegmentDisplay_SetText(3, b, slot); } +void SegmentDisplay_SetFloat(float a, segment_display_slot_t slot) +{ + char b[3]; + SegmentDisplay_SerializeFloat(b, a); + SegmentDisplay_SetText(3, b, slot); +} + bool SegmentDisplay_SlotIsActive(segment_display_slot_t slot) { return slots[slot].active; diff --git a/right/src/segment_display.h b/right/src/segment_display.h index c0959beb8..1ae37e292 100644 --- a/right/src/segment_display.h +++ b/right/src/segment_display.h @@ -5,7 +5,6 @@ #include #include - #include "timer.h" #include "macros/vars.h" // Macros: @@ -36,6 +35,7 @@ void SegmentDisplay_Update(); void SegmentDisplay_SetText(uint8_t len, const char* text, segment_display_slot_t slot); void SegmentDisplay_SetInt(int32_t a, segment_display_slot_t slot); + void SegmentDisplay_SetFloat(float a, segment_display_slot_t slot); void SegmentDisplay_SerializeInt(char* buffer, int32_t a); void SegmentDisplay_SerializeFloat(char* buffer, float f); void SegmentDisplay_SerializeVar(char* buffer, macro_variable_t var); diff --git a/right/src/slave_drivers/uhk_module_driver.c b/right/src/slave_drivers/uhk_module_driver.c index c70da712a..2980bd02f 100644 --- a/right/src/slave_drivers/uhk_module_driver.c +++ b/right/src/slave_drivers/uhk_module_driver.c @@ -362,6 +362,7 @@ slave_result_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId) pointer_delta_t *pointerDelta = (pointer_delta_t*)(rxMessage->data + keyStatesLength); uhkModuleState->pointerDelta.x += pointerDelta->x; uhkModuleState->pointerDelta.y += pointerDelta->y; + uhkModuleState->pointerDelta.debugInfo = pointerDelta->debugInfo; } } res.status = kStatus_Uhk_IdleCycle; diff --git a/shared/module/slave_protocol_handler.c b/shared/module/slave_protocol_handler.c index 77b6a0be0..8eb1adf73 100644 --- a/shared/module/slave_protocol_handler.c +++ b/shared/module/slave_protocol_handler.c @@ -134,6 +134,8 @@ void SlaveTxHandler(void) // (This handler can be interrupted by sensor interrupts.) pointerDelta->x = PointerDelta.x; pointerDelta->y = PointerDelta.y; + pointerDelta->debugInfo = PointerDelta.debugInfo; + PointerDelta.debugInfo.resetted = false; PointerDelta.x = 0; PointerDelta.y = 0; __enable_irq(); diff --git a/shared/slave_protocol.h b/shared/slave_protocol.h index d18192fbe..7fc97bdda 100644 --- a/shared/slave_protocol.h +++ b/shared/slave_protocol.h @@ -64,9 +64,15 @@ uint8_t data[I2C_MESSAGE_MAX_PAYLOAD_LENGTH]; } ATTR_PACKED i2c_message_t; + typedef struct { + float avgDrift; + bool resetted; + } ATTR_PACKED pointer_debug_info_t; + typedef struct { int16_t x; int16_t y; + pointer_debug_info_t debugInfo; } ATTR_PACKED pointer_delta_t; // Variables: diff --git a/trackpoint/src/module.c b/trackpoint/src/module.c index 58f3f6d39..5080d89a7 100644 --- a/trackpoint/src/module.c +++ b/trackpoint/src/module.c @@ -1,5 +1,6 @@ #include "fsl_gpio.h" #include "module.h" +#include pointer_delta_t PointerDelta; @@ -147,6 +148,64 @@ static bool readByte() return false; } +#define AXIS_COUNT 2 +#define WINDOW_LENGTH 16 +#define ABS(x) ((x) < 0 ? -(x) : (x)) +#define DRIFT_RESET_PERIOD 2000 +#define TRACKPOINT_UPDATE_PERIOD 10 +#define DITHERING_THRESHOLD (1.1f/WINDOW_LENGTH) + +static uint16_t window[AXIS_COUNT][WINDOW_LENGTH]; +static uint8_t windowIndex = 0; +static uint16_t windowSum[AXIS_COUNT]; +static float avgSpeed[AXIS_COUNT]; + +void recognizeDrifts(int16_t x, int16_t y) { + uint16_t deltas[AXIS_COUNT] = {ABS(x), ABS(y)}; + + // compute average speed across the window + for (uint8_t axis=0; axis DITHERING_THRESHOLD) { + drifting = false; + } + } + + if (avgSpeed[0] < DITHERING_THRESHOLD && avgSpeed[1] < DITHERING_THRESHOLD) { + drifting = false; + } + + // handle drift detection logic + if (drifting) { + driftLength++; + if (driftLength > DRIFT_RESET_PERIOD / TRACKPOINT_UPDATE_PERIOD) { + driftLength = 0; + shouldReset = true; + PointerDelta.debugInfo.resetted = true; + } + } else { + driftLength = 0; + for (uint8_t axis=0; axis Date: Sun, 26 Nov 2023 21:10:13 +0100 Subject: [PATCH 2/7] Remove debug commands. --- right/src/mouse_controller.c | 21 --------------------- shared/module/slave_protocol_handler.c | 1 - shared/slave_protocol.h | 2 -- trackpoint/src/module.c | 3 --- 4 files changed, 27 deletions(-) diff --git a/right/src/mouse_controller.c b/right/src/mouse_controller.c index bafeaffe1..ce54eb9bc 100644 --- a/right/src/mouse_controller.c +++ b/right/src/mouse_controller.c @@ -1,18 +1,11 @@ #include #include "key_action.h" -#include "led_display.h" #include "layer.h" -#include "macros/status_buffer.h" #include "slave_protocol.h" #include "usb_interfaces/usb_interface_mouse.h" -#include "peripherals/test_led.h" -#include "slave_drivers/is31fl3xxx_driver.h" #include "slave_drivers/uhk_module_driver.h" #include "timer.h" #include "config_parser/parse_keymap.h" -#include "usb_commands/usb_command_get_debug_buffer.h" -#include "arduino_hid/ConsumerAPI.h" -#include "secondary_role_driver.h" #include "slave_drivers/touchpad_driver.h" #include "mouse_controller.h" #include "mouse_keys.h" @@ -20,12 +13,9 @@ #include "layer_switcher.h" #include "usb_report_updater.h" #include "caret_config.h" -#include "keymap.h" -#include "macros/core.h" #include "debug.h" #include "postponer.h" #include "layer.h" -#include "secondary_role_driver.h" typedef struct { float x; @@ -712,11 +702,6 @@ void MouseController_ProcessMouseActions() for (uint8_t moduleSlotId=0; moduleSlotIdpointerDelta.debugInfo.resetted && moduleState->moduleId == ModuleId_TrackpointRight) { - SHOW_STRING("RST", 0); - moduleState->pointerDelta.debugInfo.resetted = false; - } - if (moduleState->moduleId == ModuleId_Unavailable || moduleState->pointerCount == 0) { continue; } @@ -740,12 +725,6 @@ void MouseController_ProcessMouseActions() moduleState->pointerDelta.y = 0; __enable_irq(); - if (moduleState->moduleId == ModuleId_TrackpointRight && x != 0) { - // WATCH_FLOAT_VALUE(moduleState->pointerDelta.debugInfo.avgDrift, 0); - // WATCH_FLOAT_VALUE_MIN(moduleState->pointerDelta.debugInfo.avgDrift, 1); - // WATCH_FLOAT_VALUE_MAX(moduleState->pointerDelta.debugInfo.avgDrift, 2); - } - processModuleActions(ks, moduleState->moduleId, x, y, 0xFF); } } diff --git a/shared/module/slave_protocol_handler.c b/shared/module/slave_protocol_handler.c index 8eb1adf73..42be2766e 100644 --- a/shared/module/slave_protocol_handler.c +++ b/shared/module/slave_protocol_handler.c @@ -135,7 +135,6 @@ void SlaveTxHandler(void) pointerDelta->x = PointerDelta.x; pointerDelta->y = PointerDelta.y; pointerDelta->debugInfo = PointerDelta.debugInfo; - PointerDelta.debugInfo.resetted = false; PointerDelta.x = 0; PointerDelta.y = 0; __enable_irq(); diff --git a/shared/slave_protocol.h b/shared/slave_protocol.h index 7fc97bdda..518d1a5ed 100644 --- a/shared/slave_protocol.h +++ b/shared/slave_protocol.h @@ -65,8 +65,6 @@ } ATTR_PACKED i2c_message_t; typedef struct { - float avgDrift; - bool resetted; } ATTR_PACKED pointer_debug_info_t; typedef struct { diff --git a/trackpoint/src/module.c b/trackpoint/src/module.c index 5080d89a7..db26e6b01 100644 --- a/trackpoint/src/module.c +++ b/trackpoint/src/module.c @@ -193,7 +193,6 @@ void recognizeDrifts(int16_t x, int16_t y) { if (driftLength > DRIFT_RESET_PERIOD / TRACKPOINT_UPDATE_PERIOD) { driftLength = 0; shouldReset = true; - PointerDelta.debugInfo.resetted = true; } } else { driftLength = 0; @@ -201,8 +200,6 @@ void recognizeDrifts(int16_t x, int16_t y) { supposedDrift[axis] = avgSpeed[axis]; } } - - PointerDelta.debugInfo.avgDrift = (float)avgSpeed[0]; } From 50cd81eea993626711defbded26c558050d65d6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Tu=C4=8Dek?= Date: Sun, 26 Nov 2023 22:33:05 +0100 Subject: [PATCH 3/7] Allow longer drift detection timeouts. --- trackpoint/src/module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trackpoint/src/module.c b/trackpoint/src/module.c index db26e6b01..b6fe3012c 100644 --- a/trackpoint/src/module.c +++ b/trackpoint/src/module.c @@ -175,7 +175,7 @@ void recognizeDrifts(int16_t x, int16_t y) { // check whether current speed matches remembered "drift" speed static float supposedDrift[AXIS_COUNT] = {0.0f, 0.0f}; - static uint8_t driftLength = 0; + static uint16_t driftLength = 0; bool drifting = true; for (uint8_t axis=0; axis DITHERING_THRESHOLD) { From bd5836470800e6cce9b85638c5b75bd509654e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Tu=C4=8Dek?= Date: Mon, 27 Nov 2023 20:41:07 +0100 Subject: [PATCH 4/7] Trackpoint drifts: optimize out divisions. --- trackpoint/src/module.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/trackpoint/src/module.c b/trackpoint/src/module.c index b6fe3012c..e4a78409b 100644 --- a/trackpoint/src/module.c +++ b/trackpoint/src/module.c @@ -153,12 +153,10 @@ static bool readByte() #define ABS(x) ((x) < 0 ? -(x) : (x)) #define DRIFT_RESET_PERIOD 2000 #define TRACKPOINT_UPDATE_PERIOD 10 -#define DITHERING_THRESHOLD (1.1f/WINDOW_LENGTH) static uint16_t window[AXIS_COUNT][WINDOW_LENGTH]; static uint8_t windowIndex = 0; static uint16_t windowSum[AXIS_COUNT]; -static float avgSpeed[AXIS_COUNT]; void recognizeDrifts(int16_t x, int16_t y) { uint16_t deltas[AXIS_COUNT] = {ABS(x), ABS(y)}; @@ -168,22 +166,21 @@ void recognizeDrifts(int16_t x, int16_t y) { windowSum[axis] -= window[axis][windowIndex]; window[axis][windowIndex] = deltas[axis]; windowSum[axis] += window[axis][windowIndex]; - avgSpeed[axis] = (float)windowSum[axis] / (float)WINDOW_LENGTH; } windowIndex = (windowIndex + 1) % WINDOW_LENGTH; // check whether current speed matches remembered "drift" speed - static float supposedDrift[AXIS_COUNT] = {0.0f, 0.0f}; + static uint16_t supposedDrift[AXIS_COUNT] = {0, 0}; static uint16_t driftLength = 0; bool drifting = true; for (uint8_t axis=0; axis DITHERING_THRESHOLD) { + if (ABS(windowSum[axis] - supposedDrift[axis]) > 1) { drifting = false; } } - if (avgSpeed[0] < DITHERING_THRESHOLD && avgSpeed[1] < DITHERING_THRESHOLD) { + if (windowSum[0] < 1 && windowSum[1] < 1) { drifting = false; } @@ -197,7 +194,7 @@ void recognizeDrifts(int16_t x, int16_t y) { } else { driftLength = 0; for (uint8_t axis=0; axis Date: Sun, 3 Dec 2023 06:55:19 +0100 Subject: [PATCH 5/7] DOCS: fix forgotten @ --- doc-dev/user-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc-dev/user-guide.md b/doc-dev/user-guide.md index b50ea8a35..5d3873c28 100644 --- a/doc-dev/user-guide.md +++ b/doc-dev/user-guide.md @@ -714,7 +714,7 @@ setVar qActive 1 // toggle fn layer and keep it active for 5 seconds or until some recordKey instance starts recording a macro toggleLayer fn -ifNotRecording ifNotPlaytime 5000 if ($qActive) goTo @0 +ifNotRecording ifNotPlaytime 5000 if ($qActive) goTo $currentAddress untoggleLayer setVar qActive 0 ``` From fd77559b21e7d6b9d89b7ff8910980a6e71155ed Mon Sep 17 00:00:00 2001 From: Karel Tucek Date: Mon, 4 Dec 2023 10:30:29 +0100 Subject: [PATCH 6/7] Increase drift tolerance. --- trackpoint/src/module.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/trackpoint/src/module.c b/trackpoint/src/module.c index e4a78409b..0efde035b 100644 --- a/trackpoint/src/module.c +++ b/trackpoint/src/module.c @@ -153,12 +153,14 @@ static bool readByte() #define ABS(x) ((x) < 0 ? -(x) : (x)) #define DRIFT_RESET_PERIOD 2000 #define TRACKPOINT_UPDATE_PERIOD 10 +#define DRIFT_TOLERANCE 1 static uint16_t window[AXIS_COUNT][WINDOW_LENGTH]; static uint8_t windowIndex = 0; static uint16_t windowSum[AXIS_COUNT]; -void recognizeDrifts(int16_t x, int16_t y) { +void recognizeDrifts(int16_t x, int16_t y) +{ uint16_t deltas[AXIS_COUNT] = {ABS(x), ABS(y)}; // compute average speed across the window @@ -175,7 +177,7 @@ void recognizeDrifts(int16_t x, int16_t y) { static uint16_t driftLength = 0; bool drifting = true; for (uint8_t axis=0; axis 1) { + if (ABS(windowSum[axis] - supposedDrift[axis]) > DRIFT_TOLERANCE + 1) { drifting = false; } } @@ -200,7 +202,8 @@ void recognizeDrifts(int16_t x, int16_t y) { } -void PS2_CLOCK_IRQ_HANDLER(void) { +void PS2_CLOCK_IRQ_HANDLER(void) +{ static uint8_t byte1 = 0; static uint16_t deltaX = 0; static uint16_t deltaY = 0; From c5fbd3943ec5f9b0b3951640a831a9bdcdc1bbdf Mon Sep 17 00:00:00 2001 From: Karel Tucek Date: Mon, 4 Dec 2023 12:35:08 +0100 Subject: [PATCH 7/7] Turn off debug again. --- right/src/debug.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/right/src/debug.h b/right/src/debug.h index 984014768..5b0a23cdd 100644 --- a/right/src/debug.h +++ b/right/src/debug.h @@ -1,4 +1,7 @@ +#if DEBUG == 1 #define WATCHES +#endif + #ifdef WATCHES #ifndef SRC_UTILS_DBG_H_