birdcage/scripts/ee_dump.py
Ryan Malloy 13a9d804c6 Add G2 bootloader and EEPROM exploration scripts
boot_baud_probe.py: Probe all standard baud rates during G2 power-on
to detect bootloader UART configuration differences.

boot_capture.py: Capture and analyze G2 boot sequence output, with
optional interrupt sequence injection to explore bootloader entry.

ee_dump.py: Dump EEPROM indices from EE> submenu, identifying
initialized vs. uninitialized (0x10101 sentinel) entries.
2026-02-14 18:05:03 -07:00

77 lines
2.1 KiB
Python

#!/usr/bin/env python3
"""Dump all EEPROM indices from Winegard G2 firmware via RS-422."""
import re
import sys
import time
import serial
PORT = "/dev/ttyUSB2"
BAUD = 115200
PROMPT = b">"
MAX_INDEX = 100 # scan up to this index
def send_cmd(ser: serial.Serial, cmd: str) -> str:
"""Send command + CR, read until prompt '>'."""
ser.reset_input_buffer()
ser.write(f"{cmd}\r".encode("ascii"))
buf = bytearray()
while True:
b = ser.read(1)
if len(b) == 0:
break # timeout
buf.append(b[0])
if b[0] == ord(">"):
break
return buf.decode("utf-8", errors="ignore")
def main():
ser = serial.Serial(PORT, BAUD, timeout=3)
time.sleep(0.1)
# Navigate to EE submenu
send_cmd(ser, "q") # ensure root
resp = send_cmd(ser, "eeprom")
if "EE>" not in resp:
print(f"Failed to enter EEPROM menu: {resp!r}", file=sys.stderr)
ser.close()
sys.exit(1)
print(f"{'Index':>5} {'Decimal':>10} {'Hex':>10} Status")
print("-" * 50)
valid_count = 0
for idx in range(MAX_INDEX + 1):
resp = send_cmd(ser, f"ee {idx}")
# Parse response
if "Read value" in resp:
match = re.search(r"Read value = (\d+)", resp)
if match:
val = int(match.group(1))
print(f"{idx:>5} {val:>10} 0x{val:08X} OK")
valid_count += 1
elif "Failed to read" in resp:
match = re.search(r"val:(\d+)", resp)
val_str = match.group(1) if match else "?"
val = int(val_str) if val_str != "?" else 0
print(f"{idx:>5} {val:>10} 0x{val:08X} INVALID")
else:
# Unknown response - might be end of range
clean = resp.strip().replace("\r\n", " | ")
print(f"{idx:>5} {'':>10} {'':>10} ERROR: {clean}")
print("-" * 50)
print(f"Valid entries: {valid_count} / {MAX_INDEX + 1}")
# Return to root
send_cmd(ser, "q")
ser.close()
if __name__ == "__main__":
main()