Add I2C hot-plug detection and streaming diagnostics (firmware v3.04.0)
Phase D firmware hardening: vendor commands 0xBD (streaming diagnostics) and 0xBE (I2C hot-plug detection) with Python library, bridge, and demo support. All I2C operations use timeout-protected helpers, BCM4500 reads are rate-limited during streaming, and frame counter reads use atomic read-verify-reread pattern. Counters saturate instead of wrapping.
This commit is contained in:
parent
592898dd7a
commit
6e353c351f
4 changed files with 372 additions and 4 deletions
|
|
@ -242,3 +242,13 @@ class USBBridge:
|
|||
def get_last_error_str(self) -> str:
|
||||
with self._lock:
|
||||
return self._dev.get_last_error_str()
|
||||
|
||||
def get_stream_diag(self, reset: bool = False) -> dict:
|
||||
with self._lock:
|
||||
return self._dev.get_stream_diag(reset=reset)
|
||||
|
||||
def get_hotplug_status(self, reset: bool = False,
|
||||
force_scan: bool = False) -> dict:
|
||||
with self._lock:
|
||||
return self._dev.get_hotplug_status(reset=reset,
|
||||
force_scan=force_scan)
|
||||
|
|
|
|||
|
|
@ -576,6 +576,51 @@ class DemoDevice:
|
|||
rng = random.Random(start_reg)
|
||||
return bytes(rng.randint(0, 255) for _ in range(count))
|
||||
|
||||
def get_stream_diag(self, reset: bool = False) -> dict:
|
||||
"""Simulated streaming diagnostics."""
|
||||
self._sd_poll_count = getattr(self, '_sd_poll_count', 0) + random.randint(50, 200)
|
||||
self._sd_overflow_count = getattr(self, '_sd_overflow_count', 0)
|
||||
if random.random() < 0.02: # 2% chance of overflow per call
|
||||
self._sd_overflow_count += 1
|
||||
sig = self.signal_monitor()
|
||||
is_locked = sig["locked"]
|
||||
result = {
|
||||
"poll_count": self._sd_poll_count,
|
||||
"overflow_count": self._sd_overflow_count,
|
||||
"sync_loss": getattr(self, '_sd_sync_loss', 0),
|
||||
"last_status": 0x42,
|
||||
"last_lock": 0x20 if is_locked else 0x00,
|
||||
"armed": True,
|
||||
"had_sync": is_locked,
|
||||
}
|
||||
if reset:
|
||||
self._sd_poll_count = 0
|
||||
self._sd_overflow_count = 0
|
||||
self._sd_sync_loss = 0
|
||||
return result
|
||||
|
||||
def get_hotplug_status(self, reset: bool = False,
|
||||
force_scan: bool = False) -> dict:
|
||||
"""Simulated I2C hot-plug detection."""
|
||||
# Standard SkyWalker-1 I2C devices: BCM4500 (0x08), EEPROM (0x50),
|
||||
# tuner (0x61), LNB controller (0x08 shares)
|
||||
bitmap = bytearray(16)
|
||||
for addr in [0x08, 0x50, 0x51, 0x61]:
|
||||
bitmap[addr >> 3] |= (1 << (addr & 0x07))
|
||||
current = bytes(bitmap)
|
||||
previous = current # no changes in demo
|
||||
addrs = [0x08, 0x50, 0x51, 0x61]
|
||||
result = {
|
||||
"current_bitmap": current,
|
||||
"previous_bitmap": previous,
|
||||
"changes": 0,
|
||||
"added": 0,
|
||||
"removed": 0,
|
||||
"current_devices": addrs,
|
||||
"previous_devices": addrs,
|
||||
}
|
||||
return result
|
||||
|
||||
# --- Internal signal model ---
|
||||
|
||||
def _power_at(self, freq_mhz: float, elapsed: float) -> float:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue