(version 1) # SP1 edge-connector (J3): the gold fingers must reach the board edge to make # contact in the GameCube slot, so copper-to-edge clearance is intentionally # relaxed for this footprint only. This is by design, not a defect. # Test BOTH items because the violated pair is (Edge.Cuts segment of J3) vs (pad # of J3) - the edge segment is item A, the pad is item B. (rule "SP1 gold fingers - allow copper to board edge" (condition "A.memberOfFootprint('J3') || B.memberOfFootprint('J3')") (constraint edge_clearance (min -0.5mm))) # Reverse-mount LED light-windows (D6/D7/D8/D9/D11/D12/D13, Everlight 24-21). # Each footprint has an Edge.Cuts light-window cutout under the LED body; the # datasheet land places the solder pads ~0.15mm from that cutout - below the # JLCPCB 0.3mm copper-to-edge default, but the intended, manufacturer-recommended # geometry (the copper sits under the part, not exposed). Relax edge_clearance to # 0.1mm for these footprints so the deliberate geometry doesn't spam DRC, while # still catching a genuinely-too-tight future edit (<0.1mm). Test BOTH items: the # violated pair is (pad) vs (the footprint's own Edge.Cuts window segment). (rule "Reverse-mount LED light-window - allow pad-to-cutout clearance" (condition "A.memberOfFootprint('D6') || A.memberOfFootprint('D7') || A.memberOfFootprint('D8') || A.memberOfFootprint('D9') || A.memberOfFootprint('D11') || A.memberOfFootprint('D12') || A.memberOfFootprint('D13') || B.memberOfFootprint('D6') || B.memberOfFootprint('D7') || B.memberOfFootprint('D8') || B.memberOfFootprint('D9') || B.memberOfFootprint('D11') || B.memberOfFootprint('D12') || B.memberOfFootprint('D13')") (constraint edge_clearance (min 0.1mm))) # Power-integrity: flag any power-rail track narrower than its netclass width. # A netclass "track width" is only the DEFAULT for new routing - KiCad does NOT # enforce it - so without these rules an under-width power trace passes DRC # silently. These make DRC surface every thin power segment so they don't have to # be found by eye. Severity is "warning" (not error) so an unavoidable neck into a # fine-pitch pin is flagged for review but never blocks fab export. (rule "Power rail minimum width (0.3mm)" (severity warning) (condition "A.NetClass == 'Power'") (constraint track_width (min 0.3mm))) (rule "Low-current power rail minimum width (0.25mm)" (severity warning) (condition "A.NetClass == 'PowerLV'") (constraint track_width (min 0.25mm))) # --------------------------------------------------------------------------- # JLCPCB manufacturing capability floor (standard multi-layer tier), pulled # from jlcpcb.com/capabilities/pcb-capabilities. These are "the board cannot # physically be made this way" limits, not house-style margins - severity is # "error" because violating one means a rejected/reworked fab order, not just # a style nit. They sit BELOW the netclass defaults above (0.2-0.3mm), so on # a board routed to house style they should never fire; they exist as a # backstop for hand-tweaked geometry (e.g. necking into a fine-pitch pin) # that dips below what JLCPCB can actually etch/drill. # # NOT covered here (no DRC constraint type exists for these - check manually # before ordering): # - Board thickness: JLCPCB stocks 0.6/0.8/1.0/1.2/1.6/2.0mm. This board's # stackup sums to 1.1412mm, which is NOT one of those - confirm with # JLCPCB's stackup tool (their impedance-controlled 4-layer config can # produce non-stock totals like this deliberately) before ordering. # - Solder mask minimum bridge/dam width (0.10mm standard, 0.13mm black/ # white): no matching KiCad custom-rule constraint type as of this # version. # - NPTH minimum hole size (0.50mm): skipped - no confirmed condition # syntax to select NPTH-only pads without risking a rule that silently # never matches; the general hole_size floor below still catches any # NPTH hole below the PTH/via floor, just not the tighter 0.50mm NPTH- # specific one. (rule "JLCPCB min copper trace width (0.09mm)" (severity error) (constraint track_width (min 0.09mm))) (rule "JLCPCB min copper clearance (0.09mm)" (severity error) (constraint clearance (min 0.09mm))) (rule "JLCPCB min via/PTH drill (0.15mm)" (severity error) (constraint hole_size (min 0.15mm))) (rule "JLCPCB min via pad diameter (0.25mm)" (severity error) (constraint via_diameter (min 0.25mm))) (rule "JLCPCB min hole-to-hole spacing (0.2mm)" (severity error) (constraint hole_to_hole (min 0.2mm))) (rule "JLCPCB min hole-to-copper clearance (0.2mm)" (severity error) (constraint hole_clearance (min 0.2mm))) (rule "JLCPCB min silkscreen line/text thickness (0.15mm, front)" (severity warning) (layer "F.SilkS") (constraint text_thickness (min 0.15mm))) (rule "JLCPCB min silkscreen line/text thickness (0.15mm, back)" (severity warning) (layer "B.SilkS") (constraint text_thickness (min 0.15mm))) (rule "JLCPCB min silkscreen text height (1.0mm, front)" (severity warning) (layer "F.SilkS") (constraint text_height (min 1.0mm))) (rule "JLCPCB min silkscreen text height (1.0mm, back)" (severity warning) (layer "B.SilkS") (constraint text_height (min 1.0mm))) (rule "JLCPCB min silkscreen-to-pad clearance (0.15mm, front)" (severity warning) (layer "F.SilkS") (constraint silk_clearance (min 0.15mm))) (rule "JLCPCB min silkscreen-to-pad clearance (0.15mm, back)" (severity warning) (layer "B.SilkS") (constraint silk_clearance (min 0.15mm))) # --------------------------------------------------------------------------- # Differential pair geometry vs calculated target impedance. The USB_DP/ETH_DP # netclasses (0.25/0.15mm, 0.2/0.14mm) only set the DEFAULT for new routing - # same caveat as the power-rail rules above, KiCad does not enforce a # netclass's width/gap on already-routed copper. These rules close that gap: # they check the geometry actually laid down, not just what a fresh route # would use, so re-routing to the wrong default (the original bug that had # USB sitting at ~113ohm on the Default netclass's 0.2/0.25mm) gets caught by # DRC instead of requiring another hand calculation to notice. # # Target values and their impedance were derived by hand (IPC-2141-style # edge-coupled microstrip formula) from this board's actual stackup - F.Cu/ # B.Cu are symmetric microstrip over In1.Cu/In2.Cu respectively (both 0.2104mm # FR4 dielectrics, same εr), so one target pair covers a net whether it's # routed on F.Cu or briefly detours to B.Cu for a crossover. Severity is # "error": these two nets only exist to hit a controlled-impedance target, so # missing it isn't a style nit like the power-rail/silkscreen rules above - # it's the one thing the routing was actually for. # USB_DP: 0.25mm width / 0.15mm gap -> ~91ohm (target 90ohm +/-15%) # ETH_DP: 0.20mm width / 0.14mm gap -> ~100ohm (target 100ohm +/-15%) # track_width +/-0.02mm tolerance bands are routing precision, not re-derived # targets. diff_pair_gap has a min (catches traces routed too close, below fab # clearance) and opt, but intentionally NO max: a gap-max false-flags normal pad # fanout, where P/N necessarily diverge over a sub-mm stub right at the pads # before converging into the coupled run - KiCad can't tell that apart from a # genuinely uncoupled long run (a length-matching/loss question, not one this # board-wide per-segment rule can judge). Do NOT re-add a diff_pair_gap max. (rule "USB differential pair width/gap (target ~90ohm)" (severity error) (condition "A.NetClass == 'USB_DP'") (constraint track_width (min 0.23mm) (opt 0.25mm) (max 0.27mm)) (constraint diff_pair_gap (min 0.13mm) (opt 0.15mm))) (rule "Ethernet differential pair width/gap (target ~100ohm)" (severity error) (condition "A.NetClass == 'ETH_DP'") (constraint track_width (min 0.18mm) (opt 0.20mm) (max 0.22mm)) (constraint diff_pair_gap (min 0.12mm) (opt 0.14mm)))