From 7be2cfed5ec758e342321f2b04a11ffc935ec90c Mon Sep 17 00:00:00 2001 From: Antoine Bertin Date: Tue, 10 Nov 2026 06:09:10 +0100 Subject: [PATCH] Fix activity elapsed time wrapping on the slave (#26545) With SPLIT_ACTIVITY_ENABLE the slave adopts the master's activity timestamps, but applies timer syncs from its main loop, so its synced clock can lag the master's by however long the loop was busy. A key press can then carry a timestamp slightly ahead of the slave's clock, and the unsigned elapsed time wraps to nearly UINT32_MAX, briefly tripping RGB_MATRIX_TIMEOUT, LED_MATRIX_TIMEOUT and other idle checks. Treat a timestamp up to one second in the future as no time elapsed. Fixes #26544 Co-authored-by: Claude Opus 5.5 --- quantum/keyboard.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/quantum/keyboard.c b/quantum/keyboard.c index 9cb555fc8d5..0b3ce2ee342 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c @@ -154,12 +154,19 @@ along with this program. If not, see . # include "sequencer.h" #endif +// Activity synced from the master can be stamped slightly ahead of the slave's clock, since the slave +// applies timer syncs from its main loop; read that as just now instead of wrapping to nearly UINT32_MAX +static uint32_t activity_elapsed(uint32_t timestamp) { + uint32_t elapsed = sync_timer_elapsed32(timestamp); + return elapsed > UINT32_MAX - 1000 ? 0 : elapsed; +} + static uint32_t last_input_modification_time = 0; uint32_t last_input_activity_time(void) { return last_input_modification_time; } uint32_t last_input_activity_elapsed(void) { - return sync_timer_elapsed32(last_input_modification_time); + return activity_elapsed(last_input_modification_time); } static uint32_t last_matrix_modification_time = 0; @@ -167,7 +174,7 @@ uint32_t last_matrix_activity_time(void) { return last_matrix_modification_time; } uint32_t last_matrix_activity_elapsed(void) { - return sync_timer_elapsed32(last_matrix_modification_time); + return activity_elapsed(last_matrix_modification_time); } void last_matrix_activity_trigger(void) { last_matrix_modification_time = last_input_modification_time = sync_timer_read32(); @@ -178,7 +185,7 @@ uint32_t last_encoder_activity_time(void) { return last_encoder_modification_time; } uint32_t last_encoder_activity_elapsed(void) { - return sync_timer_elapsed32(last_encoder_modification_time); + return activity_elapsed(last_encoder_modification_time); } void last_encoder_activity_trigger(void) { last_encoder_modification_time = last_input_modification_time = sync_timer_read32(); @@ -189,7 +196,7 @@ uint32_t last_pointing_device_activity_time(void) { return last_pointing_device_modification_time; } uint32_t last_pointing_device_activity_elapsed(void) { - return sync_timer_elapsed32(last_pointing_device_modification_time); + return activity_elapsed(last_pointing_device_modification_time); } void last_pointing_device_activity_trigger(void) { last_pointing_device_modification_time = last_input_modification_time = sync_timer_read32();