#!/usr/bin/env python3 """EXI device-ID query for re-bba-rb bring-up — run on a Raspberry Pi wired to the FPGA's EXI pins, to validate the GameCube-facing capture path with NO W5100 involved (so it works even on a unit whose W5100/ethernet side is dead). It bit-bangs the EXI SPI the way the GameCube does: CLK idles HIGH; the FPGA samples MOSI on the falling edge and drives MISO on the rising edge. It sends the device-ID read header (read 4 bytes @ addr 0 = 0x00 0x03), then pauses (the GC pauses the clock between the header and the data so the FPGA can prefetch the response), then clocks read bytes and looks for the reply 04 02 02 00. Wiring (Pi BCM GPIO -> FPGA EXI, all 3.3 V, shared GND): CLK -> EXI CLK (FPGA pin 44) MOSI -> EXI MOSI (FPGA pin 4, an FPGA *input*) MISO <- EXI MISO (FPGA pin 3, an FPGA *output*) CS -> EXI CS (FPGA pin 45) GND <-> GND Reach these at the SP1 edge connector (J3) or on the series damper resistors. Edit the BCM pin numbers below to match your wiring. Run: sudo python3 exi_devid_rpi.py Requires the FPGA to be running the full BBA design (e.g. build/seed3/top.bin) and its 12 MHz clock (X1) alive — both independent of the W5100. """ import time try: import RPi.GPIO as GPIO except ImportError: raise SystemExit("needs RPi.GPIO -> sudo apt install python3-rpi.gpio") # ---- set these to your actual Pi BCM pin numbers ---- CLK, MOSI, MISO, CS = 11, 10, 9, 8 GPIO.setmode(GPIO.BCM) GPIO.setup(CLK, GPIO.OUT, initial=1) # CPOL=1: clock idles HIGH GPIO.setup(MOSI, GPIO.OUT, initial=0) GPIO.setup(CS, GPIO.OUT, initial=1) # inactive HIGH GPIO.setup(MISO, GPIO.IN) def xfer(b): """Clock one byte MSB-first; FPGA samples MOSI on falling, drives MISO on rising.""" r = 0 for i in range(7, -1, -1): GPIO.output(MOSI, (b >> i) & 1) # MOSI stable while CLK is high GPIO.output(CLK, 0) # falling edge -> FPGA samples MOSI GPIO.output(CLK, 1) # rising edge -> FPGA drives MISO r = (r << 1) | GPIO.input(MISO) return r GPIO.output(CS, 0) # assert CS (active low) xfer(0x00) # header byte 0: read, addr[12:6]=0 xfer(0x03) # header byte 1: addr[5:0]=0, len-1=3 (4 B) time.sleep(0.001) # gap so the FPGA can prefetch the reply resp = [xfer(0x00) for _ in range(6)] # clock a few read bytes GPIO.output(CS, 1) # deassert CS GPIO.cleanup() print("read bytes:", " ".join("%02x" % x for x in resp)) want = [0x04, 0x02, 0x02, 0x00] found = any(resp[i:i + 4] == want for i in range(len(resp) - 3)) if found: print("EXI device-ID 04 02 02 00 -> FOUND. EXI capture path works!") else: print("device-ID not found. Try: swap to mode-2 edges (move the MISO sample " "to just before the falling edge), check wiring/GND, confirm the FPGA " "is running the BBA design and its 12 MHz clock is alive.")