Skip to content

SYN-363 - PT100 4-wire RTD analog front end board - #375

Open
nyagamunene wants to merge 32 commits into
absmach:mainfrom
nyagamunene:syn-361-class-b-boards
Open

nyagamunene wants to merge 32 commits into
absmach:mainfrom
nyagamunene:syn-361-class-b-boards

Conversation

@nyagamunene

@nyagamunene nyagamunene commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

What type of PR is this?

A design, placement and routing contribution for the SYN-363 Class B qualification board. It is not a qualification result. The board is routed with FreeRouting and passes KiCad's DRC, and the SI/PI/RF review is with the designated reviewer. It has not been fabricated or tested on hardware, and Class-B sign-off (#361) is not claimed here.

The branch is the Class B board branch, so it also carries the prerequisite commits from this work: #362 (ADS124S08 and REF5025 registry parts, 612ccc4), #364 (BLE node parts, d17e651, not this board), and #363's split-ground fence-via fix (81bb62a). The BLE environment node board itself is not in this PR. The branch also includes a merge of main; the merge conflicts were resolved by hand.

This revision reworks the ground to one GND plane on all four layers. The earlier split-ground board left two isolated DGND pours on the merged router; the single plane removes that failure mode and the R_TIE part. The notch is gone: the board is a plain 50.1 x 44.1 mm rectangle (2209 mm²) with a rectangular [[outline]], so a normal synth export-kicad needs no post-export cut. J1 stays at its proven top-edge position because centering it fragmented U2 ground escape. One via-in-pad at C_DV.2 keeps the tighter outline clean; the source declares requires via_in_pad and the profile is jlc-filled-via. It also re-places the reference and analog-supply support into what was a 19 x 19 mm bare rectangle in the top-left; the RTD input chain is unchanged.

What does this do?

A 4-wire PT100 measurement front end with a USB-C readout:

  • J2 is the PT100 input (1x4, 2.54 mm): F+, S+, S-, F-. R_S1/R_S2 1k 0.1%, C_D 100 nF C0G, C_CM1/C_CM2 10 nF C0G and C_F 10 nF C0G form the input filter. The differential corner is about 758 Hz and the common-mode corner about 15.9 kHz.
  • U1 is a TI ADS124S08 24-bit delta-sigma ADC with the internal PGA and IDAC1. AIN0/F+ is the 1 mA force output, AIN1/AIN2 the differential sense input, and R_BIAS 1k sets the RTD common mode near 1.1 V.
  • U3 is a TI REF5025AIDR 2.5 V reference on REFP0/REFN0. The measurement is absolute, not ratiometric; the IDAC accuracy/drift is an open item.
  • U2 is an RP2350A with a W25Q128JV QSPI flash (U4), a 12 MHz ECS-120-20-33-TR crystal (Y1) and a 3-pin SWD header (J3).
  • J1 is a USB-C receptacle (HRO TYPE-C-31-M-12) with 5.1k CC1/CC2, 27R series on D+/D-, and D1/D2 SOD-323 TVS. U5 is a TI LP5907-3.3 LDO making +3V3 from VBUS.
  • L2 is a 600 ohm at 100 MHz ferrite bead isolating +3V3A for U1 and U3.
  • One GND plane on all four copper layers; no AGND/DGND split and no tie resistor.
  • Four M2.5 NPTH mounting holes at (6, 4), (49, 4), (6, 40) and (49, 40) mm.
  • 50.1 x 44.1 mm rectangular board (2209 mm²), 4 layers, a declared 1.586 mm FR4 stackup. The .synth source is qualification/class-b/rtd-afe/rtd_afe.synth; every part has a position in rtd_afe.placement.layout.toml (board millimetres). The schematic has no sidecar.

Files

All in qualification/class-b/rtd-afe/:

  • rtd_afe.synth: the board source
  • rtd_afe.placement.layout.toml: board millimetres, every part has a position, the label overrides
  • check.sh: exports and autoroutes, runs KiCad DRC/ERC on the result, renders the images, asserts the single GND plane in pcbnew, and stamps the source revision
  • README.md: what the board is, the filter and ground reasoning, the routing numbers, the known limits
  • QUALIFICATION.md: the check results, the per-part datasheet table, the single-ground argument, the mechanical geometry table, the open review items, the Synth defects
  • kicad/: the routed .kicad_pcb, schematic, symbol library, project, DRC rules, BOM, PnP, Gerbers and drill files
  • reports/: release.json, the delivered DRC and ERC reports, the KiCad netlist, the FreeRouting record and the connectivity report
  • images/: 3D top, bottom and angled views and the schematic
  • SHA256SUMS: hashes of the committed artifacts

Exporter changes in this PR:

  • crates/synth-kicad/src/pcb.rs: per-instance footprint UUIDs and outline-aware ground fence vias.
  • crates/synth-router/src/island_vias.rs: ground-return via selection and island repair.
  • crates/synth-router/src/lib.rs: an untied island still blocks; a missing return via is the existing W-SYNTH-DRC-016 advisory.
  • crates/synth-kicad/src/bom.rs: BOM now carries dielectric, voltage, tolerance and power from the source.
  • crates/synth-cli/src/release.rs: source_revision is stamped from SYNTH_SOURCE_REVISION, and input is checkout-relative.

Pictures

Rendered with kicad-cli from commit 51104b2.

3D top view:
PCB 3D top

3D angled view:
PCB 3D angled

Schematic:
Schematic

3D bottom view:
PCB 3D bottom

State of the board

Routed with FreeRouting 2.4.1 on Java 25, KiCad 10.0.7, Synth synth-cli 0.1.1. The reports are from the run recorded in reports/release.json; source_revision now names the commit that produced the package and input is checkout-relative.

  • Four layers with one GND zone on each. There is no AGND or DGND net; check.sh asserts that with pcbnew.
  • 373 track segments, 67 vias (50 GND, 27 signal), 664.1 mm of copper, 40 nets, 0 open. The router records 67 vias; the other ten are source ground stitching.
  • The reference cluster (U3, C_RI, L2, C_RO, R_RST, R_CC2) now sits in the top-left. The largest empty rectangle drops from 19 x 19 mm (361 mm²) to 24 x 5 mm (120 mm²), the top margin. VREF grew from 4.83 mm to 21.38 mm and stays on F.Cu; C_RV stays at REFP0.
  • kicad-cli pcb drc --severity-all --refill-zones: 0 errors, 0 warnings, 0 unconnected_items. pcbnew.LoadBoard reopens the board. Synth's connectivity report also has 0 open nets.
  • Silkscreen: 0 DRC warnings. U1 has a hard label override at (24, 34.5) mm; 25 passives/TVS and H1/H2/H3/J1 have their reference label hidden because the compact refdes field has no clear spot. Their refdes remain in the BOM, PnP and schematic.
  • The six RTD/input nets and VREF are on F.Cu only, with no via. RTD_FP 11.02 mm, RTD_SP 4.17 mm, AIN1 9.23 mm, RTD_SN 4.17 mm, AIN2 14.05 mm, RTD_FN 8.32 mm, VREF 21.38 mm.
  • SPI_SCK is 18.97 mm; SPI_MOSI/MISO/CS are 14.46/19.46/17.01 mm and all four SPI nets change layer. QSPI is 3.2 to 11.3 mm and stays on F.Cu. USB is full speed: 21.05 mm on DP and 19.32 mm on DN, a 1.73 mm mismatch. Both sides change layers; the pair is not coupled and not impedance-controlled.
  • Synth signal integrity: 20 non-blocking warnings, 18 layer changes with no ground-return via within 0.64 mm and 2 parallel-run warnings. The flagged nets are REFOUT, SPI_MOSI/CS/SCK/MISO, ADC_DRDY, ADC_START, XIN, XOUT_R, RUN, SWDIO and USB_DP_C/DN_C; the USB pair run is the intended coupled segment. No RTD, AIN or VREF net is flagged; XIN and the USB layer changes are the ones to review first.
  • KiCad schematic ERC: 0 errors, 2 warnings. Device:Ferrite_Bead is the old library name (KiCad 10 has Device:FerriteBead), and the embedded REF5025ID symbol differs from the installed library copy. Both are drawing/library comparisons; the netlist and PCB parity are clean.
  • synth validate: no errors. The warnings and their dispositions are listed in QUALIFICATION.md.
  • release.json keeps production_status: untrusted and release_ready: false because the 12 MHz crystal part has no part-level reviewer (the --allow-unverified-parts override). That is not a DRC failure and not a fabrication approval.
  • J2 and J3 are level at y = 41.5 mm, with their bodies 0.79 mm from the bottom edge. J1 is at (39.5, 6.0) on the top edge, 2.26 mm from it and 12.45 mm right of the board centre. It is not centred: centering it at x = 27.0 fragmented U2 ground escape around pad 47 in every attempt.
  • Mechanical geometry is tabulated in QUALIFICATION.md: the mounting holes leave 2.25 to 2.83 mm of material, and the tab, connector fit and enclosure clearance remain unverified.
  • No test points are fitted. A 12-pad set (rails, reference, USB, SWD) was placed and routed on the earlier notched outline; it failed on a TP6 edge clearance, a QSPI supply clearance and two GND islands. The rectangle adds area but the set has not been re-placed; the failed patch is not in this PR.

Review comments

Fixed:

  • Item 2, reproducibility. The notch is removed. The board is a plain rectangular [[outline]], so a normal synth export-kicad produces the PCB, Gerbers and drill directly with no post-export cut.
  • Item 3, assembly data. bom.csv now has dielectric, voltage, tolerance and power columns copied from the structured .synth attributes. The C0G filter caps and 0.1% resistors are visible to an assembler; regression test structured_attributes_get_their_own_columns.
  • Item 6, provenance and mechanical. release.json stamps source_revision from the checked-out commit and records a checkout-relative input path; check.sh also relativises the netlist path, so reports/rtd_afe.net no longer names the build machine. QUALIFICATION.md has a measured mechanical geometry table for the holes, tab and connectors; the unverified fit items are named there.
  • The exporter gave every placed instance of the same footprint the library's child UUIDs (79 duplicated ids, one shared by 23 footprints). KiCad DRC then attributed a silk collision to an item 11 mm away. ensure_body_uuids now derives ids per placed instance and replaces stock ones; the regression test is included.
  • The compact rework removes the old silkscreen warnings; the delivered board has 0.
  • Missing ground-return vias no longer veto a candidate: they remain W-SYNTH-DRC-016 SI warnings, while an untied copper island still blocks and is reported.
  • The single-ground rework removes the split/tie failure mode: the merged split-ground route left two DGND islands that no 0.6 mm via could tie.
  • CI housekeeping: ci.yml pins ubuntu-24.04. ubuntu-latest moved to 26.04 on 2026-11-03, where the KiCad 10 PPA has no package, so every job failed in the KiCad install step before compiling anything.

Open, recorded as qualification limitations:

  1. Analog accuracy: the measurement is not ratiometric. IDAC accuracy/drift, the REF5025 grade, the filter tolerance and the PT100 wiring are not in an error budget; nothing was calibrated or measured.
  2. Analog/SI review: the single ground plane, the PGA common-mode range at the chosen gain, the IDAC output's 10 nF load, the unused ADC inputs, the 18 return-path warnings and the 1.73 mm USB mismatch are open review items.
  3. USB/ESD: no VBUS fuse, TVS or reverse-polarity protection; CC1/CC2 have no TVS; the shield is tied directly to GND; D1/D2 are a generic TVS with no MPN.
  4. Fabrication: no fab house has seen the Gerbers, drill, BOM or PnP. The 0.4 mm QFN-60, 0.5 mm VQFN-32 and 0.5 mm USB-C need a capability check; the stackup is declared, not a controlled-impedance quote. The JLCPCB DFM/assembly check requested in review item 5 has not been run.
  5. Part review: RP2350, flash, USB-C, crystal, TVS, connectors and most passives are still unreviewed; the crystal is the release override. Review item 4 is open.
  6. Mechanical: tab strength, enclosure, screw-head clearance, connector overhang and header orientation are not checked.
  7. Test points: none fitted; see the note above.
  8. Silkscreen: Synth has no free-text silk, so the board name, revision and header pin functions are not on the copper.

Not verified

  • Analog accuracy, noise, linearity, drift and the actual PT100 reading.
  • The IDAC absolute accuracy/drift, the PGA common-mode range, the ADC's unused-input termination, and the RC filter against the chosen data rate.
  • The 1.1 V core regulator, the 12 MHz crystal's ESR/drive level, the QSPI timing and the USB full-speed signal integrity.
  • ESD, surge, reverse polarity and USB-C compliance.
  • Mechanical fit and any fabrication or assembly check. Nothing was sent to a fab house.
  • The firmware does not exist in this repository: gain, data rate, IDAC value, register map, USB descriptors and calibration are all unwritten/untested.
  • No part was bought or measured on hardware; part-level review status is in the table.

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
…907 3.3 V LDO

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Rebuild the floorplan around the signal chain instead of scaling it: analog chain and input filter on the left, MCU/flash/crystal and USB on the right, connectors on the edges. The board drops from 63.1 x 51.1 mm to 50.1 x 44.1 mm.

- U2/U4 9.6 mm apart, Y1 below U2, USB-C at the top edge, SWD and PT100 at the bottom.
- R_TIE moved to the AGND/DGND bisector at (31.4, 31.5); all 54 ground pads sit on their own side of the split.
- 349 segments, 61 vias, 597.1 mm of copper, 41 nets connected, 0 open.
- KiCad DRC 0 errors / 0 warnings / 0 unconnected, ERC 0 errors / 2 library warnings, tie check R_TIE only.
- U1 label moved; 24 passive/TVS reference labels hidden where the compact layout has no clear spot (refdes remain in BOM, PnP, schematic).
- Record the all-absolute sidecar re-packing defect and refresh QUALIFICATION/SHA256SUMS.
@nyagamunene
nyagamunene force-pushed the syn-361-class-b-boards branch from 206a380 to 5ec0166 Compare October 30, 2026 11:06
Move J2 down 1.5 mm so both headers sit at y = 41.5 mm with their bodies 0.8 mm from the bottom edge. J2 carries no ground pads, so the AGND/DGND split and the route topology are unchanged.

Refresh the route, reports, Gerbers and renders: 339 segments, 64 vias, 586.6 mm, 41 nets, 0 open; DRC 0 errors / 0 warnings / 0 unconnected; R_TIE still the only ground tie.

Record why J1 stays at (39.5, 6.0): centering it was tried and leaves an unconnected AGND/DGND pour sliver at U2's 0.4 mm pad row that the stitching search cannot tie.
Cut a 16.4 x 20 mm notch out of the empty top-left corner, leaving the main top edge x 26.4..52.59 mm so J1 at x 39.5 is centred. The left tab keeps H1 and the top-left ground fence via, and the proven route is unchanged.

J2 and J3 stay level at y = 41.5 mm, 0.8 mm from the bottom edge.

SynthSpec has no non-rectangular outline primitive, so check.sh applies cut_outline.py after export and re-exports the Gerbers/drill from the cut board. DRC 0 errors / 0 warnings / 0 unconnected; R_TIE remains the only ground tie. Board area is 1880 mm², down from the rectangular 2208 mm² and the original 3536 mm².
Do not claim the SI/PI/RF review has not happened. The board and route review is in progress with the designated reviewer; keep the separate part-level caveat for Y1 and the three registry reviews.
Keep the parsed net number as f64 for the format lookup instead of casting it to usize, which clippy denies under -D warnings. The test still passes.
Plot F.Cu, In1.Cu, In2.Cu and B.Cu from the committed board into one labelled panel so the PR shows the 4-layer stackup and the AGND/DGND split on every layer.
@SammyOina

Copy link
Copy Markdown
Collaborator

Class-B qualification review — changes requested

CI is passing and the implementation is mergeable, but this is not ready to be accepted as a Class-B qualification board. Please close the following items:

  1. Complete the SI/PI review. reports/release.json still records 21 non-blocking findings: USB crosstalk plus 20 layer transitions without a nearby ground-return via. The designated reviewer must explicitly sign off on the USB pair, XIN, SPI/SWD transitions, split-ground/tie strategy, reference routing, and return paths.

  2. Make the qualification artifacts reproducible from source. check.sh applies the top-left notch with cut_outline.py after Synth export, so a normal export of rtd_afe.synth produces a different rectangular board. Make the outline a first-class Synth construct, or provide a deterministic official pipeline that generates and validates the final PCB, Gerbers, drills, reports, and hashes together.

  3. Complete the assembly data. kicad/bom.csv omits dielectric, voltage, and tolerance requirements even though this design depends on C0G capacitors and 0.1% resistors. Put those attributes in the generated BOM or add a machine-checkable assembly manifest tied to the source and PCB.

  4. Finish part-level review. RP2350, flash, USB-C, crystal, TVS parts, connectors, and most passives remain unreviewed; the committed release is explicitly production_status: untrusted because the crystal has no reviewer. Complete the reviews and record the sign-off.

  5. Run manufacturability checks. Submit the generated Gerbers, BOM, and PnP to JLCPCB's online DFM/assembly checks without placing an order, and resolve any courtyard, drill, solder-mask, package, or BOM-substitution findings.

  6. Close the mechanical and provenance gaps. Verify the mounting-hole margins, notched tab strength, connector/header fit, and enclosure clearance. Also stamp the exact Synth source revision into reports/release.json and regenerate the committed evidence from that revision.

The automated routing and KiCad DRC gates are useful, but they do not constitute Class-B qualification. Please address these items before approval; the acceptance criteria should not be reduced to make the PR mergeable.

1 similar comment
@SammyOina

Copy link
Copy Markdown
Collaborator

Class-B qualification review — changes requested

CI is passing and the implementation is mergeable, but this is not ready to be accepted as a Class-B qualification board. Please close the following items:

  1. Complete the SI/PI review. reports/release.json still records 21 non-blocking findings: USB crosstalk plus 20 layer transitions without a nearby ground-return via. The designated reviewer must explicitly sign off on the USB pair, XIN, SPI/SWD transitions, split-ground/tie strategy, reference routing, and return paths.

  2. Make the qualification artifacts reproducible from source. check.sh applies the top-left notch with cut_outline.py after Synth export, so a normal export of rtd_afe.synth produces a different rectangular board. Make the outline a first-class Synth construct, or provide a deterministic official pipeline that generates and validates the final PCB, Gerbers, drills, reports, and hashes together.

  3. Complete the assembly data. kicad/bom.csv omits dielectric, voltage, and tolerance requirements even though this design depends on C0G capacitors and 0.1% resistors. Put those attributes in the generated BOM or add a machine-checkable assembly manifest tied to the source and PCB.

  4. Finish part-level review. RP2350, flash, USB-C, crystal, TVS parts, connectors, and most passives remain unreviewed; the committed release is explicitly production_status: untrusted because the crystal has no reviewer. Complete the reviews and record the sign-off.

  5. Run manufacturability checks. Submit the generated Gerbers, BOM, and PnP to JLCPCB's online DFM/assembly checks without placing an order, and resolve any courtyard, drill, solder-mask, package, or BOM-substitution findings.

  6. Close the mechanical and provenance gaps. Verify the mounting-hole margins, notched tab strength, connector/header fit, and enclosure clearance. Also stamp the exact Synth source revision into reports/release.json and regenerate the committed evidence from that revision.

The automated routing and KiCad DRC gates are useful, but they do not constitute Class-B qualification. Please address these items before approval; the acceptance criteria should not be reduced to make the PR mergeable.

The placement sidecar now carries a closed [[outline]] in board millimetres. build_pcb uses it instead of the fitted rectangle, so the top-left notch is generated by a normal synth export-kicad.

Remove cut_outline.py and the post-export cut/re-export from check.sh; the Gerbers and drill now come from the same notched board. Add a sidecar parse/round-trip test for the outline.

Fresh export: 340 segments, 65 vias, 557.8 mm, 41 nets, 0 open; DRC 0 errors / 0 warnings / 0 unconnected; R_TIE remains the only ground tie.
@nyagamunene

Copy link
Copy Markdown
Contributor Author

Item 2 (reproducibility) is addressed in c08f766: the board outline is now a closed [[outline]] path in rtd_afe.placement.layout.toml. build_pcb uses it instead of the fitted rectangle, so a normal synth export-kicad produces the notched board, and the Gerbers/drill are generated from that same board. cut_outline.py and the post-export cut are removed; check.sh is back to export → route → DRC/ERC → render. A fresh run gives 0 DRC errors, 0 warnings, 0 unconnected and R_TIE as the only ground tie. A sidecar parse/round-trip test covers the outline.

nyagamunene and others added 6 commits November 2, 2026 22:05
The 50.1 x 44.1 mm rectangle left 24 x 22 mm of bare board above the
analog chain. Move U3, C_RI, L2, C_RO, R_RST and R_CC2 into it so the
left column is populated from the top edge to J2.

The RTD input chain (J2, the RC filter, U1) is unchanged. VREF now runs
from U3 at (12, 12) to C_RV at the ADC pin; C_RV stays at REFP0.
The exported netlist embeds the absolute path of the schematic, so the
committed evidence named the machine it was built on. Generate the
netlist before the path rewrite and include it in the same pass that
already relativises release.json and the routing record.
Fresh export from e7372ca: 373 segments, 67 router vias, 664.1 mm of
copper, 40 nets, 0 open. KiCad DRC 0 errors / 0 warnings / 0
unconnected; ERC 0 errors / 2 library warnings; one GND plane.

The RTD and AIN net lengths are unchanged. VREF is 21.38 mm on F.Cu
with no via. USB total path 21.05 mm (DP) and 19.32 mm (DN), 1.73 mm
mismatch. Synth SI: 20 warnings, 18 layer changes and 2 parallel runs.

Refresh the renders, reports, netlist, SHA256SUMS and the two
documents.
GitHub moved ubuntu-latest to 26.04 between runs. The KiCad 10 PPA has
no package for 26.04, so install-kicad.sh aborts rather than fall back
to KiCad 9 and every job fails before it compiles anything. Pin the
image the artifact checks were proven against.
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.

2 participants