From 80e74f12bed68251df32a8897f9bcec78bdea2f6 Mon Sep 17 00:00:00 2001 From: Itay Sharoni <110981018+Itay-Sharoni@users.noreply.github.com> Date: Wed, 26 Aug 2026 22:11:03 +0300 Subject: [PATCH] fix command polling when the device sends timeout 0 --- src/SCRIPTS/ELRS/crsf_session.lua | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/SCRIPTS/ELRS/crsf_session.lua b/src/SCRIPTS/ELRS/crsf_session.lua index a422e0d..b753272 100644 --- a/src/SCRIPTS/ELRS/crsf_session.lua +++ b/src/SCRIPTS/ELRS/crsf_session.lua @@ -29,6 +29,7 @@ local PING_PERIOD = 100 -- discovery ping cadence while no device answered local WRITE_SPACING = 5 -- minimum gap between parameter writes (50 ms) local WRITE_SETTLE = 20 -- post-write quiet time before the next read local CANCEL_GRACE = 200 -- wait for CMD_IDLE after a requested cancel (2 s) +local QUERY_PERIOD = 100 -- command poll cadence when the device sends no timeout (1 s) local CRSFSession = {} CRSFSession.__index = CRSFSession @@ -119,6 +120,17 @@ function CRSFSession:_responseTimeout() return self.isElrsTx and 50 or 500 end +-- Poll cadence for the active command: the device's timeout, or QUERY_PERIOD +-- when it sends none. Some devices send 0, which must not mean "poll now" -- +-- that floods the link with CMD_QUERY before the answer to the click is back. +function CRSFSession:_queryPeriod() + local timeout = self.command.timeout + if timeout and timeout > 0 then + return timeout + end + return QUERY_PERIOD +end + -- ============================================================================ -- Lifecycle -- ============================================================================ @@ -253,7 +265,7 @@ function CRSFSession:_onEntry(data) self._refreshAt = now self._refreshLeft = self._refreshAttempts elseif self.command then - self._nextQueryAt = now + (self.command.timeout or 100) + self._nextQueryAt = now + self:_queryPeriod() end return end @@ -332,7 +344,7 @@ function CRSFSession:_onEntry(data) self._nextReadAt = 0 else if self.command then - self._nextQueryAt = now + (self.command.timeout or 100) + self._nextQueryAt = now + self:_queryPeriod() end if self._preloadArmed and self:isFolderLoaded(nil) then self._preloadArmed = nil @@ -575,7 +587,7 @@ function CRSFSession:execCommand(field) field.status = crsf.CONST.CMD_CLICK crsf.push(params.encodeCommandStep(self.deviceId, self.handsetId, field.id, crsf.CONST.CMD_CLICK)) self.command = field - self._nextQueryAt = getTime() + (field.timeout or 100) + self._nextQueryAt = getTime() + self:_queryPeriod() end end @@ -583,7 +595,7 @@ end function CRSFSession:confirmCommand() if self.command then crsf.push(params.encodeCommandStep(self.deviceId, self.handsetId, self.command.id, crsf.CONST.CMD_CONFIRMED)) - self._nextQueryAt = getTime() + (self.command.timeout or 100) + self._nextQueryAt = getTime() + self:_queryPeriod() self.command.status = crsf.CONST.CMD_CONFIRMED end end @@ -647,7 +659,7 @@ function CRSFSession:tick() if self.command then if now > self._nextQueryAt and self.command.status ~= crsf.CONST.CMD_ASKCONFIRM then crsf.push(params.encodeCommandStep(self.deviceId, self.handsetId, self.command.id, crsf.CONST.CMD_QUERY)) - self._nextQueryAt = now + (self.command.timeout or 100) + self._nextQueryAt = now + self:_queryPeriod() end return end