#!/usr/bin/env python3 """Full BBA path test: Swiss init, GC->wire TX, wire->GC RX. Sends a broadcast ARP request ("who has 10.0.0.50, tell 10.0.0.99"). The PC should answer, which exercises the RX half in the same shot. """ import time, sys import RPi.GPIO as GPIO CLK, MOSI, MISO, CS = 11, 10, 9, 8 GPIO.setmode(GPIO.BCM); GPIO.setwarnings(False) GPIO.setup(CLK, GPIO.OUT, initial=1); GPIO.setup(MOSI, GPIO.OUT, initial=0) GPIO.setup(CS, GPIO.OUT, initial=1); GPIO.setup(MISO, GPIO.IN) def xfer(b): r = 0 for i in range(7, -1, -1): GPIO.output(MOSI, (b >> i) & 1) GPIO.output(CLK, 0) r = (r << 1) | GPIO.input(MISO) GPIO.output(CLK, 1) return r def read(addr, n): GPIO.output(CS, 0); GPIO.output(CLK, 1); time.sleep(0.0003) xfer((addr >> 6) & 0x7F); xfer(((addr & 0x3F) << 2) | ((n - 1) & 3)) time.sleep(0.002) out = [xfer(0) for _ in range(n)] # EXACTLY n GPIO.output(CS, 1); time.sleep(0.0005) return out def write(addr, data): GPIO.output(CS, 0); GPIO.output(CLK, 1); time.sleep(0.0003) xfer(0x80 | ((addr >> 6) & 0x7F)) xfer(((addr & 0x3F) << 2) | ((len(data) - 1) & 3)) for b in data: xfer(b) GPIO.output(CS, 1); time.sleep(0.0005) def stream(addr, n): """SPRAM/DMA read: addr >= 0x100 streams until CS, so clock freely.""" GPIO.output(CS, 0); GPIO.output(CLK, 1); time.sleep(0.0003) xfer((addr >> 6) & 0x7F); xfer(((addr & 0x3F) << 2) | 3) time.sleep(0.002) out = [xfer(0) for _ in range(n)] GPIO.output(CS, 1); time.sleep(0.0005) return out def hx(v): return " ".join("%02x" % x for x in v) MAC = [0x00, 0x09, 0xBF, 0x00, 0x00, 0x01] SRC_IP, DST_IP = [10, 0, 0, 99], [10, 0, 0, 50] print("=" * 62) print("PHASE 1 Swiss init sequence") print("=" * 62) dev = read(0x0000, 4) print(f" 1. device ID {hx(dev)} {'OK' if dev==[4,2,2,0] else 'FAIL'}") if dev != [4, 2, 2, 0]: print(" (ID is a one-shot before the first NCRA reset - continuing)") write(0x00, [0x01]); print(" 2. NCRA = 0x01 (reset + W5100 init)") for i in range(40): v = read(0x00, 1)[0] if not (v & 1): print(f" 3. NCRA reset self-cleared after {i} polls"); break time.sleep(0.005) else: print(" 3. NCRA reset did NOT clear") write(0x20, MAC[:4]); write(0x24, MAC[4:]) print(f" 4. PAR0-5 = {hx(read(0x20,4))} {hx(read(0x24,2))}") write(0x26, [0xFF]*4); write(0x2A, [0xFF]*4); print(" 5. MAR0-7 = FF (promiscuous multicast)") write(0x2E, [0xD6]); print(" 6. ANALOG = 0xD6") write(0x30, [0x01]); print(" 7. NWAYC") write(0x08, [0x86]); print(f" 8. IMR = 0x86, readback {hx(read(0x08,1))}") write(0x32, [0x02]); print(" 9. GCA") write(0x00, [0x08]); print(f" 10. NCRA SR=1, readback {hx(read(0x00,1))}") nw = read(0x31, 1); print(f" 11. NWAYS = {hx(nw)} {'link up' if nw==[0x17] else 'UNEXPECTED'}") # ---------------- build the ARP frame ---------------- frame = [0xFF]*6 + MAC + [0x08, 0x06] frame += [0x00,0x01, 0x08,0x00, 0x06, 0x04, 0x00,0x01] frame += MAC + SRC_IP + [0x00]*6 + DST_IP frame += [0x00] * (60 - len(frame)) print() print("=" * 62) print(f"PHASE 2 GC -> wire: {len(frame)}-byte broadcast ARP") print("=" * 62) print(f" who has {'.'.join(map(str,DST_IP))}, tell {'.'.join(map(str,SRC_IP))}") print(f" src MAC {':'.join('%02x'%b for b in MAC)}") rwp_before = read(0x16, 2) write(0x34, [len(frame) & 0xFF]); write(0x35, [(len(frame) >> 8) & 0xFF]) print(f" TWD = {hx(read(0x34,2))} (frame length)") t0 = time.time() for b in frame: write(0x48, [b]) # one byte per transaction: eff_addr increments print(f" streamed {len(frame)} bytes to TXDATA in {time.time()-t0:.2f}s") write(0x00, [0x08 | 0x02]) # SR + ST0 -> TX trigger print(" NCRA ST set -> TX triggered") for i in range(30): ir = read(0x09, 1)[0] if ir & 0x04: print(f" IR = {ir:02x} TI (transmit complete) SET after {i} polls"); break time.sleep(0.01) else: print(f" IR = {read(0x09,1)[0]:02x} TI never set") print() print("=" * 62) print("PHASE 3 wire -> GC: waiting for the ARP reply") print("=" * 62) print(f" RWP before = {hx(rwp_before)}") got = None for i in range(60): rwp = read(0x16, 2) ir = read(0x09, 1)[0] if rwp != rwp_before or (ir & 0x02): got = (rwp, ir); break time.sleep(0.05) if got: rwp, ir = got print(f" RWP moved to {hx(rwp)}, IR = {ir:02x} (RI {'set' if ir&2 else 'clear'})") data = stream(0x0100, 80) print(f" SPRAM @0x100: {hx(data[:16])}") print(f" {hx(data[16:32])}") print(f" {hx(data[32:48])}") if 0x08 in data and 0x06 in data: print(" -> looks like an ARP frame came back. RX PATH WORKS.") else: print(f" no RX after 3s (RWP still {hx(read(0x16,2))}, IR {read(0x09,1)[0]:02x})") print(" TX may still have worked - check the capture.") GPIO.cleanup()