#!/usr/bin/env python3 """--scan's walk and report logic, no simulator: the probe order, the rate arithmetic, and the advice's direction. The rate physics itself is not sim-testable — a pty carries bytes at any termios rate — so what the wire would arbitrate is pinned here as logic instead. Usage: test_scan.py """ import os import sys def fail(message): print(f"FAIL: {message}") sys.exit(1) def main(): sys.path.insert(0, os.path.dirname(os.path.abspath(sys.argv[1]))) import pureboot as pb walk = pb.scan_ratios() if walk != [0, -2, 2, -4, 4, -6, 6, -8, 8, -10, 10]: fail(f"probe walk is not built-rate-first, nearest-out: {walk}") if pb.scan_rate(9600, 4) != 9984 or pb.scan_rate(9600, -4) != 9216: fail("probe rate arithmetic") if pb.scan_rate(115200, 0) != 115200: fail("the built rate must probe unchanged") # A loader answering fast means a fast oscillator: the trim goes down. report = "\n".join(pb.scan_report(9600, 4, 6)) for needle in ("9984", "+4 %", "--baud 9984", "4 steps lower", "pureboot 6"): if needle not in report: fail(f"+4 % report lacks {needle!r}:\n{report}") report = "\n".join(pb.scan_report(9600, -6, 6)) if "6 steps higher" not in report: fail(f"-6 % report advises the wrong direction:\n{report}") report = "\n".join(pb.scan_report(9600, 0, 6)) if "none" not in report or "steps" in report: fail(f"an on-rate answer must advise no trim:\n{report}") report = "\n".join(pb.scan_report(9600, 4, 6, clock=9600000)) if "9984000" not in report: fail(f"the absolute clock must scale with the found ratio:\n{report}") # The walk's rates mostly have no termios B-constant, so the POSIX port # must set them through termios2 — probed on a pty, which accepts the # ioctl without caring about the speed. Without this every off-nominal # probe would abort the walk on the platform --scan matters most on. if os.name == "posix": import pty master, slave = pty.openpty() try: port = pb.Port(os.ttyname(slave), pb.scan_rate(9600, 4)) port.set_baud(pb.scan_rate(9600, -4)) port.close() except pb.Error as error: fail(f"PosixPort refused an off-nominal probe rate: {error}") finally: os.close(master) os.close(slave) print("OK") if __name__ == "__main__": main()