173 lines
9.6 KiB
Markdown
173 lines
9.6 KiB
Markdown
# re-bba-rb — bring-up TODO / findings (first physical unit)
|
||
|
||
Findings from bringing up the first assembled V1 board (repaired: 7 shorted
|
||
vias drilled out, some collateral trace damage). Started 2026-08-23. This is a
|
||
running list — items are **not** being worked yet, just recorded.
|
||
|
||
## Established good so far (context)
|
||
|
||
- Bitstream flashes + verifies (`iceprog`, channel A); FPGA configures (heartbeat).
|
||
- FT2232H healthy (channel-A MPSSE + channel-B internal loopback both pass).
|
||
- **W5100 clock confirmed GOOD** (Y2 25 MHz crystal oscillating): the on-board
|
||
diagnostic (`scratchpad/w5100_check.py`) shows solid green — MR software-reset
|
||
self-clears, which only happens on the internal clock.
|
||
- W5100 register write/read-back works on 7 of 8 data lines.
|
||
|
||
## Known damage on THIS unit (self-inflicted, from the via repair — not design bugs)
|
||
|
||
- **UART_RXD trace broken** (FPGA pin 19 → FT2232H pin 39). Workaround built:
|
||
`UART_J4=1` synth build relocates the UART to the J4 header (DBG0=pin9=TX,
|
||
DBG1=pin10=RX, GND=J4 pin1) for an external USB-UART/Pi dongle.
|
||
- **ETH_D3 trace broken** (W5100 data bit 3): net `ETH_D3` = FPGA **U9 pin 28**
|
||
↔ W5100 **U11 pin 40**. Confirmed by the diagnostic's red blink-code (4 blinks
|
||
= D3). One bodge needed; bridge the drilled break (scrape to trace copper / a
|
||
via — no need to touch the 0.5 mm chip pads). Optional: remap the FPGA D3 bit
|
||
to a spare J4 pad (DBG2=pin11=J4 pin4) to make one end a coarse header pad.
|
||
|
||
---
|
||
|
||
## V2 schematic changes already applied (2026-08-25)
|
||
|
||
- **U7 EEPROM → 93LC56B** (LCSC C6164, MPN 93LC56BT-I/SN, same SOIC-8). Fixes the
|
||
soft-brick (256 B is the FT2232H's full EEPROM size). [TODO/REVIEW updated]
|
||
- **All 7 LEDs → Everlight 24-21 reverse-mount 1206** (bottom-viewed, top-populated
|
||
single-side assembly): red D7/D11 = **C2892757** (24-21SURC), green
|
||
D6/D8/D9/D12 = **C2980185** (24-21/G6C), amber D13 = **C424133** (24-21UYC).
|
||
All Vf ≈ 2.0 V (3.3 V-rail + SB_RGBA_DRV safe), moderate mcd. New footprint
|
||
`hardware/LED_1206_ReverseMount_Everlight_24-21.kicad_mod` (pad1=cathode,
|
||
**ø1.7 mm Edge.Cuts light-window — datasheet-confirmed** 2026-08-28, spec
|
||
1.7 mm ±0.1). Refdes text is 1.0 mm (JLC silk floor).
|
||
- **LED series resistors R37/R41/R42: 49.9 Ω → 330 Ω** (reused existing part
|
||
C25104; R38 already 330). ~3.9 mA vs the blinding ~26 mA — closes item 1's
|
||
resistor half. Green PWM (`_GRN_DUTY`) in gateware still applies to D6/D12; the
|
||
new green is only 18–45 mcd so it can likely be relaxed.
|
||
- **Gateware (`synth.py`):** RGB drive bug fixed (raw-pad `o_RGB*`) + green PWM
|
||
dimming — see items 1 & 5.
|
||
|
||
Still open below: GC_ON handover redesign (#2), the datasheet-aperture verify,
|
||
EXI/W5100 functional validation (needs a working board), plus the ground-plane
|
||
fill for fab.
|
||
|
||
## TODO
|
||
|
||
### 1. LED brightness — LED_G and the two transistor-driven LEDs are blindingly bright
|
||
|
||
**Observation:** `LED_G` (D6, green) and the two transistor-driven LEDs are far
|
||
too bright; `LED_R` (D7, red) is fine.
|
||
|
||
**Root cause (from netlist):** the series resistors are wrong.
|
||
- `LED_R` (D7, red): **R38 = 330 Ω** → correct brightness (the reference).
|
||
- `LED_G` (D6, green): **R37 = 49.9 Ω** → ~25 mA, blinding.
|
||
- Transistor-driven: **D8** (green, via Q1 S8050) and **D9** (green, via Q2
|
||
S8550, collector → **R42 = 49.9 Ω** → D9) → same over-drive. (Confirm D8's
|
||
own series resistor value too.)
|
||
|
||
**Fix direction:** raise the 49.9 Ω LED series resistors (**R37**, **R42**, and
|
||
D8's) to ~**330 Ω–1 kΩ** to match D7. (The 49.9 Ω value looks copy-pasted from
|
||
the impedance-matching resistors — wrong part for an LED.) The RGB LED
|
||
(D11/D12/D13 via `SB_RGBA_DRV`, `RGB*_CURRENT=0b000001`) is separate and not
|
||
part of this complaint. BOM/PCB change for V2; a rework could tack larger
|
||
resistors on this unit if the brightness is a bench nuisance.
|
||
|
||
### 2. GC_ON is not the clean on/off the gateware assumed (sits at 2.3 V; both handover LEDs on)
|
||
|
||
**Observation:** `GC_ON` measures **2.3 V** (not a clean rail). With **both USB
|
||
and GC connected**, both transistor-driven LEDs (D8, D9) are lit — the intent
|
||
was a power-handover indicator with only ever one active (USB vs GC).
|
||
|
||
**Analysis (from netlist):** `GC_ON` = TPS2116 status (net: U2.8 = mux ST,
|
||
U12.3, FPGA **U9 pin 21**, pulled up by R5 10 k to 3V3; drives Q1 base via R39
|
||
10 k and Q2 base via R40 10 k). The two indicator transistors are complementary
|
||
(Q1 = S8050 NPN, Q2 = S8550 PNP) expecting GC_ON to swing rail-to-rail:
|
||
- At **GC_ON ≈ 2.3 V**, the NPN (Q1, on when base ≳0.7 V) **and** the PNP (Q2, on
|
||
when base ≲2.6 V) **both conduct** → both D8 and D9 light. There is no clean
|
||
one-or-the-other point at this intermediate voltage.
|
||
|
||
**Two things to resolve:**
|
||
- **Hardware:** the complementary-transistor indicator doesn't give a clean
|
||
handover display at the actual GC_ON level. Re-think for V2 (e.g., a comparator
|
||
/ proper level, or drive the two indicators from a real one-hot power-source
|
||
signal). First confirm what GC_ON's ST pin actually does across the USB-only /
|
||
GC-only / both states (TPS2116 ST semantics — see REVIEW.md).
|
||
- **Gateware:** GC_ON is wired to FPGA pin 21 but **not yet used**. The planned
|
||
"gate all outputs on GC_ON" (see TODO.md) assumed GC_ON is a clean logic level.
|
||
2.3 V is above the iCE40 3.3 V-LVCMOS V_IH (~2.0 V) so pin 21 would read HIGH,
|
||
but it's marginal and the semantics aren't the assumed on/off. Verify the real
|
||
signal before relying on it for output gating.
|
||
|
||
### 3. Functional W5100 test — send a packet capturable in Wireshark (works around broken D3?)
|
||
|
||
**Goal:** a test bitstream that makes the W5100 transmit a frame on the wire,
|
||
captured with Wireshark on the laptop (magjack J2 → laptop).
|
||
|
||
**Feasible:** reuse `W5100ParallelMaster` (MACRAW socket 0, or the UDP socket
|
||
path) with a small periodic trigger + a canned frame. Init runs on NCRA/startup.
|
||
|
||
**Caveat — the broken ETH_D3:** every byte written to the W5100 has data bit 3
|
||
corrupted, so a frame sent *now* would have wrong MAC/ethertype/payload bytes —
|
||
Wireshark might see a malformed frame (or the W5100 may reject a bad length).
|
||
- A garbled frame appearing at all would still prove **TX path + PHY + magnetics**
|
||
work on the wire.
|
||
- For a **clean, valid** packet capture, do the **ETH_D3 bodge first** (item in
|
||
"Known damage"). Recommended order: bodge D3 → re-run `w5100_check` (red should
|
||
go dark) → then this packet test.
|
||
|
||
### 4. Bit-bang EXI from a Raspberry Pi to test the FPGA's EXI capture
|
||
|
||
**Goal:** validate the EXI Mode-3 capture front-end without a GameCube, by having
|
||
a Pi emulate the GC EXI master.
|
||
|
||
**Approach:** Pi SPI **master, Mode 3 (CPOL=1, CPHA=1)**, 3.3 V (both sides
|
||
3.3 V — no shifting). Drive the EXI **device-ID query** and check the response:
|
||
write `0x0000` (2 bytes) then read 4 bytes → must be **`0x04 0x02 0x02 0x00`**.
|
||
In SPI terms: assert CS, clock out `00 00 xx xx xx xx`, the last 4 MISO bytes are
|
||
the device ID. A match proves ExiCapture → register file → MISO end-to-end.
|
||
|
||
**Connections (FPGA EXI pins):** CLK=44, MOSI=4, MISO=3, CS=45 (INT=46) — reach
|
||
them at the SP1 edge connector J3 or the damper resistors (R21/R25). Map to Pi:
|
||
Pi SCLK→CLK, Pi MOSI→MOSI(FPGA in), Pi MISO←MISO(FPGA out), Pi CE→CS, GND↔GND.
|
||
|
||
**Notes:** run the Pi SPI **slow** (e.g., 1 MHz) — the capture domain oversamples
|
||
the EXI clock, so a slow clock is *easier* than the real 27 MHz and fully
|
||
exercises the Mode-3 logic + register file. Good first EXI smoke test before
|
||
trusting it against a real console.
|
||
|
||
### 5. RGB LEDs (D11 red / D12 green / D13 yellow) — drive bug + brightness
|
||
|
||
Two findings, from lighting them for the first time at bring-up:
|
||
|
||
**(a) DRIVE BUG — they don't light in the current gateware (functional, not cosmetic).**
|
||
`SB_RGBA_DRV`'s `o_RGB0/1/2` outputs are left as dangling internal signals in
|
||
`synth.py` (and were in the first test builds). nextpnr never bonds them to the
|
||
dedicated RGB pads (pins 39/40/41 — confirmed absent from the PCF), so the driver
|
||
outputs float and **the LEDs never light**. This means the **rx / tx / ready RGB
|
||
indicators are non-functional in the default build.**
|
||
- **Fix (confirmed on the bench):** request the RGB pins *raw* (no SB_IO buffer)
|
||
and connect the driver outputs directly to the pads:
|
||
```python
|
||
rgb = platform.request("rgbpad", 0, dir="-") # Resource: r=39 g=40 b=41
|
||
Instance("SB_RGBA_DRV", ...,
|
||
o_RGB0=rgb.r.io, o_RGB1=rgb.g.io, o_RGB2=rgb.b.io)
|
||
```
|
||
Connecting through a normal `dir="o"` request fails packing:
|
||
`ERROR: SB_RGB_DRV/SB_RGBA_DRV port connected to more than just package pin!`
|
||
- **APPLIED 2026-08-23** in `synth.py`: added a raw `rgb` Resource (39/40/41) and
|
||
wired `o_RGB0/1/2 = rgb.{r,g,b}.io`; the RGB indicators now light.
|
||
|
||
**(b) BRIGHTNESS — only GREEN (D12) is too bright; red (D11) and yellow (D13)
|
||
are fine.** Measured with the corrected drive at the driver's *minimum* current
|
||
(`CURRENT_MODE` half, `RGBx_CURRENT=0b000001`). The green die is much more
|
||
efficient per mA, so at the same minimum current it's blinding while red/yellow
|
||
look right. Since the current code is already at minimum, the fix is **PWM
|
||
dimming on green only** — feed a low-duty PWM into `RGB1PWM` (green) instead of a
|
||
static `1`, and leave red/yellow (`RGB0PWM`/`RGB2PWM`) driven solid.
|
||
- **APPLIED 2026-08-23** in `synth.py`: a `_GRN_DUTY` (default 2/16 ≈ 1/8) PWM now
|
||
gates **both** green emitters — `RGB1PWM` (D12) and `LED_G`/D6 (the discrete
|
||
heartbeat, over-bright from R37 — item 1). Red/yellow/LED_R stay solid. Tune
|
||
`_GRN_DUTY` (0..15) at the bench. Gateware mitigation; the proper V2 hardware
|
||
fix for D6 is still R37 → ~330 Ω (item 1).
|
||
|
||
### 6. (reserved — Dennis to add)
|
||
|
||
_Placeholder for the item Dennis was trying to recall._
|