فهرست منبع

Align discovery-beacon cadence to main (fix multi-ctrl link churn)

The merge left the branch's RF behavior matching main EXCEPT one
air-budget deviation: the ch2 discovery beacon ran every 40ms whenever a
controller was connected but another bonded slot's controller was off
(allUp=false), vs main's 200ms. ch2 discovery shares g_sessCh's air time
while a controller is linked, so the extra ~25 beacons/s stole reply
windows from the connected controller -> reply-rate sag -> >1500ms reply
gaps -> hapticOnReconnect re-fired its re-init burst (the spurious
"onesey twosey" clicks) + link churn.

Restore main's exact cadence: every-loop when nothing is connected,
200ms once any slot is linked. A late joiner still enumerates in ~1s.

With this, every remaining difference from main reduces to identical
single-controller behavior (poll first slot; F2 cooldown; unique
per-puck session address) -- the only true divergences left are the
per-bond addresses and per-cycle multi-slot polling that simultaneous
controllers fundamentally require.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Jariullah Safi 4 ماه پیش
والد
کامیت
184a5796df
1فایلهای تغییر یافته به همراه7 افزوده شده و 18 حذف شده
  1. 7 18
      OpenPuck/rf_link.cpp

+ 7 - 18
OpenPuck/rf_link.cpp

@@ -761,16 +761,6 @@ void rfLinkTask()
 	// that's powering off isn't immediately re-woken/reconnected.
 	if (g_rfHost && millis() - g_connCooldown > 2500) {
 		bool connNow = anySlotLinkUp();
-		// allUp = every BONDED slot currently has a link. Discovery stays aggressive until then so a
-		// controller joining after another is already connected still finds the puck quickly -- throttling
-		// discovery the moment ONE slot links up was starving the late joiner of beacons (it never showed up).
-		bool allUp = true;
-		for (int s = 0; s < NSLOT; s++)
-			if (g_slot[s].used &&
-			    millis() - g_connReplyMs[s] >= 300) {
-				allUp = false;
-				break;
-			}
 		// session keepalive on the clean channel: every loop while connecting (fast), every 25ms once connected
 		// (every-loop beaconing also hammers the session ch and steals reply slots from the poll). The real puck
 		// sends NO E1 on its session channel; gated by g_e1keepalive ('m') so this can be A/B'd on hardware --
@@ -782,14 +772,13 @@ void rfLinkTask()
 			for (int s = 0; s < NSLOT; s++)
 				rfHostFrameOnce(s, false);
 		}
-		// discovery beacon on ch2 (where a searching controller looks). Cadence:
-		//   nobody connected  -> every loop (fastest cold-boot connect)
-		//   some but not all   -> 40 ms (~25 Hz): a late joiner still connects in ~1 s without the
-		//                          every-loop beacon stealing the connected controller's poll budget --
-		//                          important when a slot is bonded but its controller is left off
-		//   all connected      -> 200 ms (keep the rendezvous warm)
-		uint32_t discEvery = allUp ? 200u : (connNow ? 40u : 0u);
-		if (millis() - g_lastDisc >= discEvery) {
+		// discovery beacon on ch2 (where a searching controller looks): every loop when nothing is
+		// connected (fastest cold-boot/late-joiner connect), every 200ms once ANY controller is linked.
+		// Matches main: while a slot is connected, ch2 discovery shares g_sessCh's air budget, so beaconing
+		// faster than 200ms (the old allUp-gated 40ms path) just steals reply windows from the connected
+		// controller -> reply-rate sag -> >1500ms gaps -> spurious hapticOnReconnect re-init. A late joiner
+		// still enumerates within ~1s at 200ms.
+		if (millis() - g_lastDisc >= (connNow ? 200u : 0u)) {
 			g_lastDisc = millis();
 			g_rfCh = 2;
 			for (int s = 0; s < NSLOT; s++)