Skip to content

SYN-260 - The Class A RP2350 SWD debug target - #271

Closed
JeffMboya wants to merge 3 commits into
absmach:mainfrom
JeffMboya:SYN-260-rp2350-debug-target
Closed

JeffMboya wants to merge 3 commits into
absmach:mainfrom
JeffMboya:SYN-260-rp2350-debug-target

Conversation

@JeffMboya

@JeffMboya JeffMboya commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

What type of PR is this?

This is a feature.

What does this do?

Adds qualification/class-a/rp2350-debug-target/: a standalone RP2350 debug target with SWD and USB recovery.

Which issue(s) does this PR fix/relate to?

Resolves #260. Related Issue #39, #273, #274, #276.

Have you included tests for your changes?

No. The board is data; the README records one measured export and routing run.

Did you document any new/modified features?

Yes. A README spec sheet: rails, why four layers, recovery routes, system boundary, and why no GPIO.

Notes

Stacked on #266, #195, #159, #235. #221 costs it a GPIO header and one net.

absmach#39's first test case is an MCU with SWD/JTAG, a crystal, reset and a status
LED. It gets its own pull request rather than sharing one with four other
boards, because it is the one Class-A board that does not pass and that is
worth reviewing on its own.

Four layers, 25 components, 20 nets, 77.90 x 62.95 mm: USB-C in to a 3V3 LDO,
the MCU's own crystal, a tactile reset on RUN, a 1x3 SWD header, QSPI boot
flash and one status LED. No USB data path; that belongs to a faster class.

Four layers is a measurement, not a preference. The QFN-60's 0.4 mm pitch
leaves 0.200 mm between pads while a via on JLCPCB standard needs 0.687 mm
between centres, so the drill that would fit between two pins is 0.013 mm.
Synth's escape analysis and KiCadRoutingTools reach that independently, and
the Raspberry Pi Pico 2 is four layers for the same reason.

Measured on this tree, not carried over: 18 of 20 nets closed, two open --
`net_8` reaching 1 of its 3 pads at `U2.22` and `net_9`, the RUN node,
reaching 2 of its 5 -- 624.6 mm of copper over 293 segments and 42 vias, no
track under the 0.127 mm floor, no via under the 0.3 mm drill or 0.13 mm ring,
and no via inside a pad. `kicad-cli pcb drc` reports zero errors; the routing
verdict is `validation_failed` on the open nets and the package is refused.

The twenty-two `annular_width` errors of the 16 October run are gone, as are
the two vias that landed inside pads, so the geometry disagreements this board
used to carry have been answered by `main`. What is left is connectivity.

The README says plainly what the PR body has no room for: `rp2350` carries
RP2040 pin numbers (absmach#152), so this board is laid out to another device and no
routing figure from it should be read as a Class-A pass until that part is
corrected.

Carved out of the five-board bundle in absmach#196.
Two nets stayed open -- `net_8`, which is XOUT to the crystal, and `net_9`,
the RUN node -- and the package was refused. Neither was a router failure.

`Y1` carried no placement hint at all, so the crystal landed wherever the
placer had room while `C9` and `C10` followed it there, leaving XOUT to cross
the board. `R3`, `SW1` and `C11` were loose for the same reason. XIN/XOUT and
RUN are the two nets here whose length is the circuit rather than the routing,
so Y1, R3 and C11 are now hinted onto U2 the way the decoupling already was.

The second half is the process. 19 of the 47 vias land inside pads, which on a
0.4 mm pitch QFN-60 is the geometry and not a mistake: there is no 0.2 mm gap
to put a 0.56 mm via in, and the README has argued that arithmetic since the
board was written. The board now declares `jlc-filled-via` and `requires
via_in_pad` instead of asking for the standard tier and being refused for
using copper the standard tier cannot plate. That tier carries the same track,
clearance, drill and annular floors -- it adds resin fill and capping, and
relaxes no minimum -- so the copper is judged against the same numbers.

Measured on the default export path, no `--place-route-iterate` needed:

  20 of 20 nets closed, 0 open
  624.6 mm of copper over 209 segments and 47 vias
  0 tracks below 0.127 mm, 0 vias below the 0.3 mm drill or 0.13 mm ring
  kicad-cli pcb drc: 0 errors, 0 unconnected, 2 advisory warnings
  routing verdict: routed, fabrication-ready

The engine's own policy still rejects those 19 vias; Synth's gate accepts them
because the board declares the process that plates them, which is the
difference between a via in a pad by accident and one there on purpose.

absmach#152 is untouched and still the board's real blocker: `rp2350` carries RP2040
pin numbers, so this is laid out to another device. The README says so first,
before any of these figures.
@SammyOina

SammyOina commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

Changes requested — not ready for Class-A qualification

[P1] Resolve the RP2350 pin-map blocker. The source uses the rp2350 registry part, which the README says still carries RP2040 pin numbers (#152). The generated PCB therefore does not represent a valid RP2350 design, so its routing and DRC results cannot be qualification evidence until the registry part and board are corrected.

[P1] Provide issue #260 acceptance evidence. The PR documents one local export/router run, but requires three consecutive byte-identical exports and independent PCB review. Add the three-run artifact/hash evidence and obtain independent sign-off.

[P2] Correct inconsistent metadata. rp2350_debug_target.synth:98 instantiates xtal_8mhz with value 12MHz, while the README reports 77.90 × 60.46 mm and the commit description reports 77.90 × 62.95 mm. Make the source, BOM, and specification agree.

[P1] Close the Class-A protection and procurement gaps. The README records no USB reverse-polarity protection, no SWD ESD clamps, and four parts without distributor identity. These are qualification design and orderability gaps, not merely limitations. Address them.

Generic CI passes, but no qualification-specific workflow is running for this PR, so the claimed export/routing measurements are not independently gated.

…s I/O

Three of its six I/O banks had no supply, one of the connector's four VBUS
contacts was wired, and a board with bad firmware needed a debugger to rescue.
25 components to 50.

It is still not a development board, and that part did not work. A 20-pin
header carrying 8 GPIOs, reset and a ground beside every signal was written,
validated with zero errors, and would not route. absmach#221 is why: every hard
`near` hint on this board is dropped, so the eleven capacitors hinted onto U2
sit 7.9 to 17.2 mm from a 7x7 mm QFN-60, mean 12.1 mm. With its bypass that
far off, the escape from a 0.4 mm pitch package spends its room reaching the
decoupling and has none left for I/O.

  16 GPIOs on the header                      10 open nets
  8 GPIOs, a ground beside each                4
  four mounting holes cut to two               4, byte-identical
  --place-route-iterate, five candidates       10, 6, 6, 7, 6
  no header                                    1

Board area and candidate placement move none of it. The hints are not weighed
and lost to a cost function, they are not applied. The README records that as
`No GPIO header` rather than leaving an absence, with the table above, because
a qualification board that quietly omits a requirement is worth less than one
that measures why it cannot meet it.

The defect first. IOVDD4, IOVDD5 and IOVDD6 were unconnected. They are not
optional pins with a default -- they are the supply for three of the six I/O
banks, and a bank with no supply does not drive. Each now has 3V3 and its own
100 nF. The connector had the same shape of problem: one of its four VBUS
contacts and one of its four grounds were wired, leaving the receptacle to
carry its rating on a quarter of its contacts. All eight are tied now, and
SHLD goes to ground.

Then what makes it a development board:

  - USB D+/D- reach the connector, both halves of each pair so the cable works
    either way up, with D4 and D5 clamping. This was left out as "a faster
    class's problem", but USB full speed is 12 Mbit/s and the point is not
    bandwidth: it is that the board is recoverable.
  - SW2 and R5 1k are BOOTSEL. Holding QSPI_SS low at reset stops the boot ROM
    finding valid flash, so it comes up as mass storage and takes a UF2. With
    the USB path that is the whole recovery story: hold SW2, tap SW1, let go.
    No debugger.
  - F1 500 mA and D2 clamp the input. A debug target gets plugged into
    whatever is on the bench, and a shorted probe lead should trip a fuse
    rather than a host's port. D6 and D7 clamp CC1 and CC2, which are exposed
    contacts on a connector a person handles. Four E-SYNTH-ESD-001 findings
    and E-SYNTH-KG-001 gone.
  - D3 and R6 1k say the 3V3 rail is up. The existing LED is on GP25 and so
    reports firmware; with only that one, a board with no firmware looked
    identical to a board with no power.
  - Two rails declared with `power`, and the core rail named VCORE but not
    declared: it comes out of the MCU's own switcher at about 1.1 V, and the
    part's conditions are device-level 1.8-3.6 V, so declaring a voltage would
    have the range rules judge the core against the I/O limits.
  - C13 to C20 bypass the three new banks, both extra DVDD pins, the regulator
    input and the header. Two E-SYNTH-POWER-001 findings cleared.
  - Four test points -- VBUS, 3V3, the core rail and a ground reference --
    two M2.5 mounting holes on the diagonal and two fiducials. J1 on the left
    edge, J2 along the top.
  - Two holes rather than four: each brings an all-layer `screw head` keepout,
    and this is a bench target that sits on a desk or two standoffs, not a
    board bolted into an enclosure at four corners.

`synth validate` reports zero errors.

Measured on this tree:

  24 of 25 nets closed, net_13 at R3.2 reaching 1 of 5 pads open
  931.3 mm over 425 segments and 59 vias
  kicad-cli pcb drc: 0 errors, 0 unconnected, 1 warnings
  routing verdict: validation_failed, not fabrication-ready

One net does not close, and it is the same cause. `net_13` is RUN -- U2.run,
R3.p2, SW1.p1 and C11.p1, four parts all hinted hard onto U2 and placed 14 to
19 mm from it. R3 is redundant in principle, since the RP2350 pulls RUN up
internally and the Pico leaves the pin bare, and dropping it takes the net
from five pads to three and it routes. It is kept: the registry cannot declare
an internal pull-up, so without R3 the compiler is correct to report
E-SYNTH-KG-001, a switch to ground leaving the input floating when open.
Removing a resistor the compiler asks for, to make the router's job easier, is
not a trade this board makes.

absmach#152 is untouched and still this board's deeper blocker: `rp2350` carries
RP2040 pin numbers, so this is laid out to another device. The README says so
first, before any of these figures.
@JeffMboya

Copy link
Copy Markdown
Contributor Author

@SammyOina Closing: superseded. Case 1 is now the irrigation controller (#270, resolving #260). The RP2350 QFN-60 escape continues in #320 for Class C.

@JeffMboya JeffMboya closed this Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCU + SWD/JTAG + crystal + reset + status LED

2 participants