From 1ff427df3748db62aa432e5b908790c5da3610e7 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 21 Sep 2026 21:15:01 +0200 Subject: [PATCH] srxl2: a frame received in this cycle is not 49 days old srxl2ProcessEsc() takes the time once, before draining the port, and then compares it against the timestamps that draining the port has just written. When the millisecond turns over in between, the unsigned difference wraps: the reading that has only now arrived reads as 49 days old, the telemetry is marked invalid, and it stays invalid until the next frame. On the bench, with an Avian answering every telemetry request but rotating between sensors, so that the ESC readings themselves arrive about twice a second, that cost 19 blackouts in 180 seconds, each lasting from 100 ms to a second. The OSD, Blackbox, current estimation and the RPM filter all lose the ESC data for that long. After taking the time again once the port is drained, the same run had none, with the link up throughout. The same wrap also sits on the link timeout, one line below, which on a bus that agreed to a higher rate would drop back to 115200 and go looking for the ESC again. --- src/main/io/motor_srxl2.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/io/motor_srxl2.c b/src/main/io/motor_srxl2.c index cace00d78c2..6ed156b1e98 100644 --- a/src/main/io/motor_srxl2.c +++ b/src/main/io/motor_srxl2.c @@ -845,6 +845,14 @@ static void srxl2ProcessEsc(srxl2Esc_t *e, timeMs_t now) { srxl2DrainRx(e); + // A frame handled in the line above stamps itself with a time taken after the one this + // cycle began with. Left alone, the unsigned difference against that older stamp wraps, + // the reading it just brought reads as 49 days old, and the telemetry is thrown away + // until the next frame arrives. Measured on an Avian: about one frame in a hundred, and + // with the ESC answering roughly twice a second, up to a second of telemetry lost each + // time. So the time is taken again, now that everything received has been accounted for + now = millis(); + /* A deferred baud change completes as soon as the broadcast has left. */ if (e->baudSwitchPending && isSerialTransmitBufferEmpty(e->port)) { serialSetBaudRate(e->port, SRXL2_BAUD_HIGH);