@protoboardai/ext-tscircuit 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +59 -0
- package/README.md +493 -2
- package/evals/announce-pcb-fallback/case.ts +67 -0
- package/evals/catch-swapped-nets/case.ts +69 -0
- package/evals/generate-imu-board/case.ts +60 -0
- package/evals/locked-board-fix-upstream/case.ts +70 -0
- package/lib/checks.ts +464 -0
- package/lib/config.ts +384 -0
- package/lib/fingerprint.ts +144 -0
- package/lib/footprints.ts +370 -0
- package/lib/kicad/cli.ts +93 -0
- package/lib/kicad/drc.ts +95 -0
- package/lib/kicad/fields.ts +65 -0
- package/lib/kicad/handoff.ts +112 -0
- package/lib/kicad/netlists.ts +311 -0
- package/lib/kicad/probe.cjs +21 -0
- package/lib/kicad/project.ts +594 -0
- package/lib/kicad/refdes.ts +130 -0
- package/lib/kicad/schematic.ts +624 -0
- package/lib/kicad/sexpr.ts +117 -0
- package/lib/land-geometry.ts +177 -0
- package/lib/land-patterns.ts +706 -0
- package/lib/layout.ts +236 -0
- package/lib/models.ts +284 -0
- package/lib/native.ts +199 -0
- package/lib/outputs.ts +383 -0
- package/lib/paste.ts +69 -0
- package/lib/probe.cjs +31 -0
- package/lib/runtime.ts +185 -0
- package/lib/silk.ts +141 -0
- package/lib/source.ts +472 -0
- package/lib/stepfile.ts +210 -0
- package/lib/suppliers.ts +39 -0
- package/ops/circuit.ts +270 -0
- package/ops/kicad.ts +636 -0
- package/ops/package.ts +156 -0
- package/package.json +70 -4
- package/protoboard-extension.json +313 -0
- package/skills/circuit-board/SKILL.md +494 -0
- package/skills/circuit-board/references/pcb-workflow.md +87 -0
- package/skills/kicad-cli/SKILL.md +210 -0
- package/skills/kicad-layout-review/SKILL.md +275 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kicad-cli
|
|
3
|
+
description: Run KiCad 10's kicad-cli on a Protoboard board's KiCad project — DRC and ERC with JSON reports and exit codes, Gerbers and Excellon drill, position file, STEP and GLB, SVG and PDF plots, netlist, BOM, and file-format upgrade — and know where the results belong (a locked board's circuit:export writes out/ itself; manual runs go to a scratch folder). Also the fallback before lock: when circuit:generate or circuit:export fails, inspect the circuit:kicad preview with these commands while the model and tscircuit stay the truth. Use when checking or exporting from <board>/kicad/ or tscircuit/kicad/, or when circuit:export reports a kicad-cli failure.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# kicad-cli
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
locked board: src/boards/<b>/kicad/<b>.kicad_pcb ── circuit:export ──▶ out/ (gerber/, pnp.csv, board.step, board.glb, *.svg, drc.json)
|
|
10
|
+
└── manual kicad-cli ─▶ a scratch folder (never out/)
|
|
11
|
+
before lock: circuit:kicad ──▶ src/boards/<b>/tscircuit/kicad/ (a preview, rewritten each time) ── kicad-cli ─▶ scratch
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`kicad-cli` is KiCad's command-line tool. The stack declares it as a tool
|
|
15
|
+
(`kicad-cli`, KiCad 10): `circuit:lock` and `circuit:kicad` need it, and
|
|
16
|
+
`circuit:export` of a locked board runs it. This skill is the reference for
|
|
17
|
+
running it by hand: to check a board, to look at a layer, or to see why an
|
|
18
|
+
export failed. The review itself is **kicad-layout-review**.
|
|
19
|
+
|
|
20
|
+
## Purpose
|
|
21
|
+
|
|
22
|
+
Give an agent the exact KiCad 10 commands, flags, exit codes and report
|
|
23
|
+
formats for a Protoboard board's KiCad project, and the rule for where their
|
|
24
|
+
output may go. Use it after lock for checks and inspection, and before lock as
|
|
25
|
+
a fallback when the tscircuit path fails.
|
|
26
|
+
|
|
27
|
+
## Inputs
|
|
28
|
+
|
|
29
|
+
| Input | Where |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| A locked board's project | `src/boards/<b>/kicad/<b>.kicad_pcb`, `<b>.kicad_sch`, `<b>.kicad_pro` |
|
|
32
|
+
| A preview project (any board) | `src/boards/<b>/tscircuit/kicad/`, written by `npx protoboard run circuit:kicad --module <b>` |
|
|
33
|
+
| KiCad 10 | `kicad-cli version` prints `10.x`; `npx protoboard doctor` shows the tool |
|
|
34
|
+
|
|
35
|
+
Flags change between KiCad versions (KiCad 10 dropped HPGL board plots, for
|
|
36
|
+
one). When in doubt, `kicad-cli <group> <command> --help` is the authority.
|
|
37
|
+
Spell help out as `--help`: in `pcb render`, `-h` means height.
|
|
38
|
+
|
|
39
|
+
## Steps
|
|
40
|
+
|
|
41
|
+
### 1. Checks
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
P=src/boards/<b>/kicad/<b> # or src/boards/<b>/tscircuit/kicad/<b> for a preview
|
|
45
|
+
S=$(mktemp -d)
|
|
46
|
+
|
|
47
|
+
kicad-cli pcb drc --format json --units mm --severity-all \
|
|
48
|
+
--schematic-parity --refill-zones --exit-code-violations \
|
|
49
|
+
-o "$S/drc.json" "$P.kicad_pcb"
|
|
50
|
+
|
|
51
|
+
kicad-cli sch erc --format json --units mm --severity-all \
|
|
52
|
+
--exit-code-violations -o "$S/erc.json" "$P.kicad_sch"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Exit | Meaning |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| 0 | ran; no violations (or `--exit-code-violations` was not given) |
|
|
58
|
+
| 5 | ran; the report lists violations (only with `--exit-code-violations`) |
|
|
59
|
+
| 3 | the input file could not be loaded |
|
|
60
|
+
| 1 | bad arguments (an unknown flag or value); read stderr |
|
|
61
|
+
| other non-zero | another failure; read stderr |
|
|
62
|
+
|
|
63
|
+
Use `--format json` (the default `report` is text for people). The DRC report
|
|
64
|
+
(`$schema` `https://schemas.kicad.org/drc.v1.json`) has `kicad_version`,
|
|
65
|
+
`source`, `coordinate_units`, and three lists: `violations`,
|
|
66
|
+
`unconnected_items` and `schematic_parity`. The ERC report has the same header
|
|
67
|
+
and `sheets[]`, each with `path` and `violations`. Every entry has `type`,
|
|
68
|
+
`severity` (`error`, `warning`, `exclusion`), `description` and `items[]`
|
|
69
|
+
(each with `description`, `pos` {x, y} and `uuid`). Count by severity, group
|
|
70
|
+
by `type`, and name findings by the designator in the item description.
|
|
71
|
+
|
|
72
|
+
`--refill-zones` refills pours in memory before checking; adding
|
|
73
|
+
`--save-board` writes the refill into the board, which is an edit to the
|
|
74
|
+
layout of record: only when the person asks. `--schematic-parity` needs the
|
|
75
|
+
`.kicad_sch` beside the board under the same name.
|
|
76
|
+
|
|
77
|
+
### 2. Fabrication outputs
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Gerbers: always name the layers; with no --layers every layer is plotted (User, Margin, Courtyard too)
|
|
81
|
+
kicad-cli pcb export gerbers -o "$S/gerber/" \
|
|
82
|
+
-l F.Cu,B.Cu,F.Paste,B.Paste,F.Silkscreen,B.Silkscreen,F.Mask,B.Mask,Edge.Cuts \
|
|
83
|
+
--subtract-soldermask "$P.kicad_pcb" # 4 layers: add In1.Cu,In2.Cu
|
|
84
|
+
|
|
85
|
+
# Drill, Excellon, mm, plated and non-plated in separate files, with a map
|
|
86
|
+
kicad-cli pcb export drill -o "$S/gerber/" --format excellon \
|
|
87
|
+
--drill-origin absolute --excellon-units mm --excellon-zeros-format decimal \
|
|
88
|
+
--excellon-separate-th --generate-map --map-format gerberx2 "$P.kicad_pcb"
|
|
89
|
+
|
|
90
|
+
# Position file (pick-and-place)
|
|
91
|
+
kicad-cli pcb export pos -o "$S/pos.csv" --format csv --units mm \
|
|
92
|
+
--side both --exclude-dnp "$P.kicad_pcb"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Keep Gerbers, drill and position on the same origin: the commands above all
|
|
96
|
+
use the absolute origin. Add `--use-drill-file-origin` to the Gerbers and the
|
|
97
|
+
position file together, and `--drill-origin plot` to the drill, if a fab wants
|
|
98
|
+
the auxiliary origin. The position CSV columns are `Ref,Val,Package,PosX,PosY,Rot,Side`
|
|
99
|
+
(`Side` is `top` or `bottom`). The project's `out/pnp.csv` is not this file:
|
|
100
|
+
`circuit:export` re-keys it by UHD instance through `tscircuit/refdes.json`.
|
|
101
|
+
|
|
102
|
+
Before calling a board ready, look at every Gerber layer. The quickest way is
|
|
103
|
+
an SVG per layer of the board itself:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
kicad-cli pcb export svg -o "$S/layers/" --mode-multi --page-size-mode 2 \
|
|
107
|
+
--exclude-drawing-sheet -l F.Cu,B.Cu,F.Mask,B.Mask,F.Silkscreen,B.Silkscreen,Edge.Cuts "$P.kicad_pcb"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 3. 3D, plots, netlist, BOM
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
kicad-cli pcb export step -o "$S/board.step" --force --subst-models --no-dnp "$P.kicad_pcb"
|
|
114
|
+
kicad-cli pcb export glb -o "$S/board.glb" --force --subst-models --no-dnp \
|
|
115
|
+
--include-tracks --include-pads --include-zones --include-silkscreen --include-soldermask "$P.kicad_pcb"
|
|
116
|
+
|
|
117
|
+
kicad-cli pcb export svg -o "$S/pcb-top.svg" --mode-single --page-size-mode 2 \
|
|
118
|
+
--exclude-drawing-sheet -l F.Cu,F.Mask,F.Silkscreen,Edge.Cuts "$P.kicad_pcb"
|
|
119
|
+
kicad-cli pcb export svg -o "$S/pcb-bottom.svg" --mode-single --mirror --page-size-mode 2 \
|
|
120
|
+
--exclude-drawing-sheet -l B.Cu,B.Mask,B.Silkscreen,Edge.Cuts "$P.kicad_pcb"
|
|
121
|
+
kicad-cli pcb export pdf -o "$S/pcb.pdf" --mode-multipage -l F.Cu,B.Cu,Edge.Cuts "$P.kicad_pcb"
|
|
122
|
+
|
|
123
|
+
kicad-cli sch export svg -o "$S/sch/" --exclude-drawing-sheet "$P.kicad_sch" # a folder: <b>.svg for the root sheet, <b>-<sheet>.svg for each sub-sheet
|
|
124
|
+
kicad-cli sch export pdf -o "$S/schematic.pdf" "$P.kicad_sch"
|
|
125
|
+
|
|
126
|
+
kicad-cli sch export netlist --format kicadxml -o "$S/netlist.xml" "$P.kicad_sch" # or kicadsexpr (the default)
|
|
127
|
+
|
|
128
|
+
kicad-cli sch export bom -o "$S/bom.csv" \
|
|
129
|
+
--fields 'Reference,Value,Footprint,MPN,Manufacturer,LCSC,UHD_Instance,${QUANTITY}' \
|
|
130
|
+
--labels Refs,Value,Footprint,MPN,Manufacturer,LCSC,Instance,Qty \
|
|
131
|
+
--group-by Value,Footprint,MPN --exclude-dnp "$P.kicad_sch"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
STEP and GLB carry the part bodies the footprints link at
|
|
135
|
+
`${KIPRJMOD}/3d/<file>.step`; a body missing there shows as a bare footprint.
|
|
136
|
+
The KiCad BOM is for comparing with the model: the project's `out/bom.csv`
|
|
137
|
+
comes from the model, not from KiCad. `--preset` and `--format-preset` name
|
|
138
|
+
presets saved in the project; none are built in. `--include-excluded-from-bom`
|
|
139
|
+
does nothing in KiCad 10.
|
|
140
|
+
|
|
141
|
+
### 4. Upgrade
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
cp "$P.kicad_pcb" "$S/" && kicad-cli pcb upgrade "$S/<b>.kicad_pcb"
|
|
145
|
+
cp "$P.kicad_sch" "$S/" && kicad-cli sch upgrade "$S/<b>.kicad_sch" # --force resaves even when already current
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Lock already saves both files in KiCad 10's format. Upgrade by hand only to
|
|
149
|
+
read a file from an older KiCad, and on a copy.
|
|
150
|
+
|
|
151
|
+
## Decision points
|
|
152
|
+
|
|
153
|
+
**Before lock, as a fallback.** This is the fallback the **circuit-board** skill names.
|
|
154
|
+
When `circuit:generate` or `circuit:export` fails on an unlocked board, an
|
|
155
|
+
agent may run `npx protoboard run circuit:kicad --module <b>` and use the
|
|
156
|
+
commands above on `tscircuit/kicad/` to see what is wrong (DRC findings by
|
|
157
|
+
designator, a layer image, the netlist). The preview is rewritten every time
|
|
158
|
+
and is never the layout of record. The UHD model and the tscircuit build stay
|
|
159
|
+
the truth: fix the problem there (the module, `circuit.config.ts`,
|
|
160
|
+
`layout.json`, `footprints.json`, `board.tsx`, per **circuit-board**) and
|
|
161
|
+
generate again. Do not hand-edit the preview to get a board out.
|
|
162
|
+
|
|
163
|
+
If the person wants to finish the board in KiCad instead, that is a lock.
|
|
164
|
+
Locking is a human decision: explain what it changes (KiCad becomes the
|
|
165
|
+
layout of record; `circuit:generate` refuses without `--force`) and ask
|
|
166
|
+
before running `circuit:lock` or `circuit:unlock`.
|
|
167
|
+
|
|
168
|
+
## Outputs
|
|
169
|
+
|
|
170
|
+
- A locked board's `circuit:export` runs these commands itself and writes
|
|
171
|
+
`out/`. Do not reproduce that by hand, and never write into `out/` or
|
|
172
|
+
`kicad/` from a manual run.
|
|
173
|
+
- Manual runs write to a scratch folder outside the project, for example
|
|
174
|
+
`S=$(mktemp -d)`, and nothing there is committed.
|
|
175
|
+
- `pcb upgrade` and `sch upgrade` rewrite their input file in place; run them
|
|
176
|
+
on a copy unless the person asked for the project to be upgraded.
|
|
177
|
+
|
|
178
|
+
## Verification
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
kicad-cli version # 10.x
|
|
182
|
+
npx protoboard check --format json # a locked board: CIRCUIT_LOCKED and no CIRCUIT_KICAD_* error
|
|
183
|
+
git status --short src/boards # a manual run left nothing in out/ or kicad/
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Failure handling
|
|
187
|
+
|
|
188
|
+
| Symptom | Do |
|
|
189
|
+
| --- | --- |
|
|
190
|
+
| `kicad-cli: command not found`, or `circuit:export` says it is missing | Install KiCad 10 (`npx protoboard doctor` names the tool); the locked board cannot export without it |
|
|
191
|
+
| `kicad-cli version` prints 9.x or older | Use KiCad 10; the project is saved in KiCad 10's format |
|
|
192
|
+
| Exit 3 | Wrong path, or a file KiCad cannot parse: `protoboard check` reports `CIRCUIT_KICAD_UNREADABLE`; restore from git |
|
|
193
|
+
| DRC exit 5 | Read `drc.json`; fix in KiCad (**kicad-layout-review**). `circuit:export` stops on a DRC error unless `--force` |
|
|
194
|
+
| `schematic_parity` entries | Run Update PCB from Schematic in KiCad; check reports `CIRCUIT_KICAD_PARITY` |
|
|
195
|
+
| A 3D body missing in STEP/GLB | The file under `kicad/3d/` is missing or the footprint's model path changed |
|
|
196
|
+
| `pcb export hpgl` | Not available in KiCad 10; use SVG or PDF |
|
|
197
|
+
|
|
198
|
+
## Hard rules
|
|
199
|
+
|
|
200
|
+
1. Manual output goes to a scratch folder; `out/` belongs to `circuit:export`
|
|
201
|
+
and `kicad/` to the person editing the board.
|
|
202
|
+
2. No `--save-board` and no in-place `upgrade` of the board of record unless
|
|
203
|
+
the person asked.
|
|
204
|
+
3. Before lock, the preview is for looking only; the model and tscircuit are
|
|
205
|
+
the truth.
|
|
206
|
+
4. Ask before `circuit:lock`, `circuit:unlock` or `circuit:lock --input
|
|
207
|
+
refresh=true`.
|
|
208
|
+
5. Nothing is uploaded or ordered.
|
|
209
|
+
|
|
210
|
+
Source: derived from KiStack (American-Embedded/kistack @ 8494dbd, MIT), rewritten.
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kicad-layout-review
|
|
3
|
+
description: Review and finish a locked board's layout in KiCad 10 — placement, decoupling loops, return paths, clearances, silkscreen, courtyards, mounting holes, edge clearance, thermal relief and the fab's DFM rules — run DRC and ERC through kicad-cli and read their JSON reports, bring model changes in with Update PCB from Schematic without losing placement, then run protoboard check and act on every CIRCUIT_KICAD_* finding. Use after circuit:lock, when someone asks for a layout review of <board>/kicad/, or when check reports CIRCUIT_LOCKED or a CIRCUIT_KICAD_* code.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# KiCad layout review
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
UHD board module ── circuit:lock (a human decides) ──▶ <board dir>/kicad/<b>.kicad_pcb (layout of record)
|
|
10
|
+
▲ │ review, hand edits in KiCad
|
|
11
|
+
│ model changes go here first ▼
|
|
12
|
+
└──────────── check finds CIRCUIT_KICAD_* (handoff record vs model vs KiCad; nothing written back)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Once a board is locked, KiCad holds its layout and tscircuit does not. The
|
|
16
|
+
UHD board module still says what is on the board and how it is connected.
|
|
17
|
+
This skill is the review and finishing pass in KiCad, and the loop that keeps
|
|
18
|
+
KiCad and the model in agreement. Command details for every `kicad-cli` call
|
|
19
|
+
are in the **kicad-cli** skill; the lock itself is in **circuit-board** and the
|
|
20
|
+
spec `docs/specs/pcb-kicad-handoff.md`.
|
|
21
|
+
|
|
22
|
+
## Purpose
|
|
23
|
+
|
|
24
|
+
Get a locked board to the point where a fab would build it and it would work:
|
|
25
|
+
parts placed for short loops and clean returns, DRC clean against the fab's
|
|
26
|
+
own rules, silkscreen readable, mechanical features where the enclosure
|
|
27
|
+
expects them, and `protoboard check` free of `CIRCUIT_KICAD_*` errors. Use it
|
|
28
|
+
after `circuit:lock`, when asked to review a board in KiCad, and whenever
|
|
29
|
+
check reports a `CIRCUIT_KICAD_*` code.
|
|
30
|
+
|
|
31
|
+
## Inputs
|
|
32
|
+
|
|
33
|
+
| Input | Where |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| The KiCad project | `src/boards/<b>/kicad/`: `<b>.kicad_pro`, `<b>.kicad_pcb`, `<b>.kicad_sch`, `<b>.pretty/`, `<b>.kicad_sym`, `3d/` |
|
|
36
|
+
| The handoff record | `src/boards/<b>/kicad/handoff.json` (`state: "locked"`, `lockedAt`, the netlist as handed off) |
|
|
37
|
+
| Reference designators | `src/boards/<b>/tscircuit/refdes.json` (instance path to designator; kept across lock, unlock and re-lock) |
|
|
38
|
+
| The model | `src/boards/<b>/<b>.uhd.ts` and its parts' datasheets (decoupling tables, layout guidelines, thermal pad notes) |
|
|
39
|
+
| Enclosure constraints | `circuit.config.ts` (fixed placements, keep-outs, mounting holes) and **enclosure-cad** |
|
|
40
|
+
| The fab's capabilities | the fab's published minimums for track, space, drill, annular ring, mask web, silkscreen width, board-edge clearance |
|
|
41
|
+
| KiCad 10 | `kicad-cli version` prints 10.x; **kicad-cli** skill |
|
|
42
|
+
|
|
43
|
+
Every symbol and footprint carries `Reference`, `Value`, `Footprint`, `MPN`,
|
|
44
|
+
`Manufacturer`, `LCSC` (when the part has an LCSC offer), `UHD_Instance` and
|
|
45
|
+
`UHD_Part`. Use `UHD_Instance` to get from a designator back to the model.
|
|
46
|
+
|
|
47
|
+
## Steps
|
|
48
|
+
|
|
49
|
+
### 0. Before any edit: where the fix belongs
|
|
50
|
+
|
|
51
|
+
KiCad is the last place a board changes, not the first. Protoboard is the
|
|
52
|
+
orchestrator: the model owns the data and the build steps write the KiCad
|
|
53
|
+
project, so do not manage KiCad libraries, symbols or footprints by hand
|
|
54
|
+
unless the job needs something Protoboard cannot do (then say so first, as
|
|
55
|
+
the fallback rule in **circuit-board** asks). Before editing, say in one line
|
|
56
|
+
where each fix belongs, in this order (**circuit-board** step 0):
|
|
57
|
+
|
|
58
|
+
1. the UHD model (parts, connections, values, designators, MPN and LCSC
|
|
59
|
+
fields, test pads);
|
|
60
|
+
2. the tscircuit stage (placement, widths, rules, keep-outs, land patterns,
|
|
61
|
+
`circuit.config.ts`);
|
|
62
|
+
3. the stack (a converter or provider bug: a garbled schematic, mangled pin
|
|
63
|
+
names, wrong silkscreen text; report it with the command and output, do
|
|
64
|
+
not hand-patch the output);
|
|
65
|
+
4. KiCad: only the hand finish the stages above cannot produce (routing
|
|
66
|
+
touch-ups, final placement nudges, silkscreen).
|
|
67
|
+
|
|
68
|
+
**A locked board is not fixed in place.** When a fix belongs at levels 1 to
|
|
69
|
+
3, propose unlocking and re-locking rather than editing KiCad, and say
|
|
70
|
+
plainly what that loses: `circuit:unlock` moves `kicad/` to
|
|
71
|
+
`kicad-archive/<stamp>/`, and the hand routing, placement and silkscreen work
|
|
72
|
+
done since `lockedAt` does not come back by itself. The person decides; ask.
|
|
73
|
+
|
|
74
|
+
**Mistakes and design choices.** List each finding as one or the other: a
|
|
75
|
+
mistake (a DRC violation, a wrong net, a value against the datasheet) is
|
|
76
|
+
fixed where it belongs; a design choice (where a part sits, a layer, a
|
|
77
|
+
trade-off made on purpose) is proposed, and you ask before changing it.
|
|
78
|
+
|
|
79
|
+
**Long work, small areas, the router.** Before a long pass (hand-routing many
|
|
80
|
+
nets, re-placing a section), say what it will do and roughly how long it
|
|
81
|
+
takes, and ask when it is optional. When the routing is poor, look for the
|
|
82
|
+
cause first (parts too close, rules that do not fit, a placement that forces
|
|
83
|
+
crossings) and propose that fix before routing by hand. Do not polish a small
|
|
84
|
+
area before asking whether it needs doing at all. Never make placeholder
|
|
85
|
+
footprints or 3D models from datasheets while the part's UHD artifacts or its
|
|
86
|
+
JLC/LCSC source has one; ask first when none does.
|
|
87
|
+
|
|
88
|
+
### 1. Confirm the state and who is editing
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx protoboard check --format json # CIRCUIT_LOCKED (info) for the board; note every CIRCUIT_KICAD_* already present
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Only one writer at a time. If the person has the board open in KiCad, do not
|
|
95
|
+
write `<b>.kicad_pcb` yourself: propose changes (designator, position,
|
|
96
|
+
rotation, side, the reason) and let them apply, or wait until they save and
|
|
97
|
+
close. Work on the files in `kicad/`; do not create a second board file
|
|
98
|
+
beside them.
|
|
99
|
+
|
|
100
|
+
### 2. Take a baseline
|
|
101
|
+
|
|
102
|
+
Run DRC and ERC into a scratch folder (never `out/`, never `kicad/`), as the
|
|
103
|
+
**kicad-cli** skill describes:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
S=$(mktemp -d)
|
|
107
|
+
kicad-cli pcb drc --format json --severity-all --schematic-parity --refill-zones \
|
|
108
|
+
--exit-code-violations -o "$S/drc.json" src/boards/<b>/kicad/<b>.kicad_pcb
|
|
109
|
+
kicad-cli sch erc --format json --severity-all --exit-code-violations \
|
|
110
|
+
-o "$S/erc.json" src/boards/<b>/kicad/<b>.kicad_sch
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Exit 0 means no violations, 5 means the report has some. Read the JSON rather
|
|
114
|
+
than the console text:
|
|
115
|
+
|
|
116
|
+
- DRC: `violations[]`, `unconnected_items[]`, `schematic_parity[]`. Each entry
|
|
117
|
+
has `type` (for example `clearance`, `courtyards_overlap`,
|
|
118
|
+
`copper_edge_clearance`, `silk_over_copper`), `severity`, `description`,
|
|
119
|
+
and `items[]` with the object's `description`, `pos` (mm) and `uuid`.
|
|
120
|
+
- ERC: `sheets[].violations[]`, same entry shape.
|
|
121
|
+
|
|
122
|
+
Group by `type`, count by `severity`, and name each finding by designator so a
|
|
123
|
+
person can find it. `--refill-zones` refills pours in memory only; leave out
|
|
124
|
+
`--save-board` unless the person asked for the refill to be saved.
|
|
125
|
+
|
|
126
|
+
Also export the copper, mask and silkscreen layers as SVG into the same
|
|
127
|
+
scratch folder and look at them, top and bottom.
|
|
128
|
+
|
|
129
|
+
### 3. Review the layout
|
|
130
|
+
|
|
131
|
+
Work through each point and write down what you found, with the designator,
|
|
132
|
+
the datasheet section that supports the call, whether it is a mistake or a
|
|
133
|
+
design choice, and where its fix belongs (step 0).
|
|
134
|
+
|
|
135
|
+
| Area | What to check |
|
|
136
|
+
| --- | --- |
|
|
137
|
+
| Placement | Parts grouped by function; the MCU's crystal next to its pins; the regulator's input cap, inductor, output cap and feedback divider tight around it as its datasheet's layout example shows; sensitive analog away from switching nodes; parts aligned on a grid, same orientation in a group; nothing on the bottom unless the design calls for it. |
|
|
138
|
+
| Decoupling | Each decoupling capacitor at the pin it serves, smallest value nearest, with the via to ground beside its own pad so the loop (pin, cap, ground via, back) is as small as the board allows. A cap shared across the board is a finding. |
|
|
139
|
+
| Return paths | A continuous ground under every fast or sensitive trace; no split or slot in the plane under a signal that crosses it; stitching vias along pour edges and next to layer-change vias of fast signals; no copper islands left floating. |
|
|
140
|
+
| Clearances | Track, space and via sizes meet the net classes in `<b>.kicad_pro` and the fab's minimums; higher-voltage nets have the spacing their voltage needs. |
|
|
141
|
+
| Silkscreen | Every designator readable, not over pads or vias, not under a part body, one orientation or two at most; pin-1 and polarity marks visible after assembly. |
|
|
142
|
+
| Courtyards | No overlaps (`courtyards_overlap`); room for rework around fine-pitch parts and for the nozzle around tall parts. |
|
|
143
|
+
| Mounting holes | At the positions and diameters in `circuit.config.ts` (the enclosure is built around them); keep copper and parts out of the screw head's and standoff's footprint. |
|
|
144
|
+
| Edge clearance | Copper, pads and vias clear of `Edge.Cuts` by at least the fab's minimum (`copper_edge_clearance`); connectors that a cable mates sit at the edge with their mouth facing out, matching the frames **enclosure-cad** uses. |
|
|
145
|
+
| Thermal | Exposed pads have the via array and paste pattern the datasheet asks for; regulators and power parts have the copper area their dissipation needs; pours to through-hole pins use thermal relief so they can be soldered. |
|
|
146
|
+
| DFM | A second DRC with the fab's rules (step 4). Also acid traps, slivers in pours, annular ring on vias, mask web between fine-pitch pads, and fiducials if the assembler asks for them. |
|
|
147
|
+
|
|
148
|
+
Antenna keep-outs and fixed placements from `circuit.config.ts` still hold
|
|
149
|
+
after the move to KiCad; check them by eye, since KiCad's DRC does not know
|
|
150
|
+
the config.
|
|
151
|
+
|
|
152
|
+
### 4. DRC against the fab's rules
|
|
153
|
+
|
|
154
|
+
The rules exported at lock come from the config and are looser than a fab's.
|
|
155
|
+
Set the fab's minimums in Board Setup (constraints and net classes) or in a
|
|
156
|
+
custom rules file `<b>.kicad_dru`, then run DRC again. Record which rule set
|
|
157
|
+
and which fab the clean run was against.
|
|
158
|
+
|
|
159
|
+
### 5. Hand edits
|
|
160
|
+
|
|
161
|
+
Placement, routing, pours, silkscreen and stitching are KiCad edits and stay
|
|
162
|
+
in KiCad. After each meaningful edit, save, then:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
npx protoboard check --format json
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
and act on what it reports (table below). Parts and connections are not KiCad
|
|
169
|
+
edits: a pin swap, a new test point, a fiducial, a different value or a
|
|
170
|
+
different package starts in the UHD board module, never only in KiCad.
|
|
171
|
+
|
|
172
|
+
A KiCad edit that a re-lock would lose and the stack cannot make yet (a logo,
|
|
173
|
+
a zone the provider does not draw, a silkscreen note) is recorded as a
|
|
174
|
+
post-lock step in the project's `docs/post-lock.md`: what, why, the exact
|
|
175
|
+
edit, and how to check it. It is applied from that list after every lock,
|
|
176
|
+
never left as a silent hand edit.
|
|
177
|
+
|
|
178
|
+
### 6. Bring a model change into KiCad
|
|
179
|
+
|
|
180
|
+
Nothing is written back to UHD and nothing is pushed into KiCad
|
|
181
|
+
automatically. When the model changes (a part added or removed, a land
|
|
182
|
+
pattern, a connection, a value or MPN):
|
|
183
|
+
|
|
184
|
+
1. Make the change in the UHD board module first (**circuit-board** step 1)
|
|
185
|
+
and run `protoboard check`: it reports `CIRCUIT_KICAD_STALE`,
|
|
186
|
+
`CIRCUIT_KICAD_MODEL_CHANGED` or `CIRCUIT_KICAD_FIELDS` with the diff.
|
|
187
|
+
2. Make the same change in the KiCad schematic: the symbol, its fields
|
|
188
|
+
(`Reference` from `tscircuit/refdes.json`, `Value`, `Footprint` as
|
|
189
|
+
`<b>:<entry>`, `MPN`, `Manufacturer`, `LCSC`, `UHD_Instance`, `UHD_Part`)
|
|
190
|
+
and its connections.
|
|
191
|
+
3. In the PCB editor run **Tools > Update PCB from Schematic**. Symbols and
|
|
192
|
+
footprints are linked by the symbol's UUID (the footprint's `path`), so
|
|
193
|
+
leave the option that re-links footprints by reference designator off;
|
|
194
|
+
existing footprints keep their positions and routing, and only new
|
|
195
|
+
footprints arrive unplaced. Leave footprint deletion off unless the change
|
|
196
|
+
removed a part, and replace footprints only when the land pattern changed.
|
|
197
|
+
4. Place and route what is new, run DRC, and run `protoboard check` again.
|
|
198
|
+
The change should now show as `CIRCUIT_KICAD_APPLIED`.
|
|
199
|
+
5. Ask the person before recording it: `npx protoboard run circuit:lock
|
|
200
|
+
--module <b> --input refresh=true` re-records the handoff from the model and
|
|
201
|
+
the KiCad files as they are now.
|
|
202
|
+
|
|
203
|
+
If the change is large (many parts, a new outline, a re-layout of the
|
|
204
|
+
schematic, renamed pins), say so and propose unlocking, fixing it upstream
|
|
205
|
+
and re-locking instead. Say which KiCad work would be lost (step 0) and which
|
|
206
|
+
post-lock steps would be applied again. Unlocking is the person's decision.
|
|
207
|
+
|
|
208
|
+
## Decision points
|
|
209
|
+
|
|
210
|
+
| Decision | Rule |
|
|
211
|
+
| --- | --- |
|
|
212
|
+
| A model change since lock | Small (a part, a value, a connection): bring it into KiCad (step 6). Large (many parts, a new outline): propose unlock, fix upstream, re-lock, and say what KiCad work it loses; the person decides |
|
|
213
|
+
| A schematic that reads badly, pin names that are wrong, silkscreen text that is wrong | A converter or provider bug (level 3): report it; do not re-lay out or rename in KiCad, since a re-lock reproduces it |
|
|
214
|
+
| A KiCad edit that must survive a re-lock | A post-lock step in `docs/post-lock.md` (step 5) |
|
|
215
|
+
| A finding the fab's rules allow | Record the fab and the rule; leave it |
|
|
216
|
+
| A fixed placement or keep-out in the way | Ask; it changes only with `circuit.config.ts` |
|
|
217
|
+
| `CIRCUIT_KICAD_APPLIED` | Ask before `circuit:lock --input refresh=true` |
|
|
218
|
+
|
|
219
|
+
## Outputs
|
|
220
|
+
|
|
221
|
+
| Output | Where |
|
|
222
|
+
| --- | --- |
|
|
223
|
+
| The finished layout | `src/boards/<b>/kicad/` (committed) |
|
|
224
|
+
| Fabrication outputs | `src/boards/<b>/out/` from `circuit:export` (never by hand) |
|
|
225
|
+
| Reports | a scratch folder; the review's findings in your answer |
|
|
226
|
+
|
|
227
|
+
## Verification
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
npx protoboard check --format json # CIRCUIT_LOCKED only: no CIRCUIT_KICAD_* error or warning
|
|
231
|
+
kicad-cli pcb drc --format json --severity-all --schematic-parity --exit-code-violations -o "$S/drc.json" src/boards/<b>/kicad/<b>.kicad_pcb # exit 0 with the fab's rules
|
|
232
|
+
npx protoboard run circuit:export --module <b> # drc.json in out/ is clean; export does not fail on DRC
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Report what you reviewed, what you changed, which findings remain and why,
|
|
236
|
+
and which fab's rules the clean DRC used.
|
|
237
|
+
|
|
238
|
+
## Failure handling
|
|
239
|
+
|
|
240
|
+
What check reports on a locked board, and what to do:
|
|
241
|
+
|
|
242
|
+
| Code | Means | Do |
|
|
243
|
+
| --- | --- | --- |
|
|
244
|
+
| `CIRCUIT_LOCKED` (info) | KiCad is the layout of record since `lockedAt` | Nothing; review in KiCad, not in tscircuit |
|
|
245
|
+
| `CIRCUIT_KICAD_STALE` (error) | The model added or removed a part, changed a land pattern, the outline, holes, layers or thickness, and KiCad lacks it | Step 6, or propose unlocking |
|
|
246
|
+
| `CIRCUIT_KICAD_MODEL_CHANGED` | Connections between existing parts changed in the model | Rewire in the KiCad schematic, Update PCB from Schematic, reroute |
|
|
247
|
+
| `CIRCUIT_KICAD_FIELDS` | MPN, manufacturer, value or LCSC changed in the model | Update those fields on the symbol, then Update PCB from Schematic |
|
|
248
|
+
| `CIRCUIT_KICAD_APPLIED` (info) | The model change is in KiCad too | Ask, then `circuit:lock --input refresh=true` |
|
|
249
|
+
| `CIRCUIT_KICAD_PART_MISSING` (error) | A part was deleted in KiCad | Restore it (Update PCB from Schematic brings the footprint back); remove a part only in the model |
|
|
250
|
+
| `CIRCUIT_KICAD_PART_EXTRA` | KiCad has a part the model lacks | Add it to the model (a fiducial or test point belongs there) or delete it in KiCad |
|
|
251
|
+
| `CIRCUIT_KICAD_FOOTPRINT_CHANGED` | A footprint was swapped in KiCad | Put the handed-off footprint back, or change the land pattern in the model first |
|
|
252
|
+
| `CIRCUIT_KICAD_NET_RENAMED` | A net was renamed in KiCad, same pins | Restore the model's net name |
|
|
253
|
+
| `CIRCUIT_KICAD_NET_CHANGED` (error) | A pin is on another net in KiCad | Undo it in KiCad; if the new connection is right, change the model first |
|
|
254
|
+
| `CIRCUIT_KICAD_PARITY` | Schematic and board disagree | Update PCB from Schematic; the DRC `schematic_parity[]` list names the parts |
|
|
255
|
+
| `CIRCUIT_KICAD_UNREADABLE` (error) | A KiCad file is missing or does not parse | Restore it from git; re-save from KiCad 10 |
|
|
256
|
+
|
|
257
|
+
## Hard rules
|
|
258
|
+
|
|
259
|
+
1. The model is the truth for parts and connections. Make those changes in
|
|
260
|
+
the UHD board module first; KiCad catches up by hand; nothing is written
|
|
261
|
+
back to UHD.
|
|
262
|
+
2. Locking, unlocking and `refresh=true` are the person's decisions: ask
|
|
263
|
+
before running any of them.
|
|
264
|
+
3. Never move a part the config fixes, never shrink a mounting hole or keep-out,
|
|
265
|
+
without the person agreeing and the config changing with it.
|
|
266
|
+
4. Reports and test exports go to a scratch folder, never to `out/` or into
|
|
267
|
+
`kicad/`.
|
|
268
|
+
5. One writer on `<b>.kicad_pcb` at a time.
|
|
269
|
+
6. Say where a fix belongs before editing (the model, the tscircuit stage, a
|
|
270
|
+
stack bug, then KiCad). Never fix in KiCad what belongs upstream: propose
|
|
271
|
+
unlock and re-lock, saying what would be lost.
|
|
272
|
+
7. A KiCad edit that must survive a re-lock is a documented post-lock step,
|
|
273
|
+
never a silent hand edit.
|
|
274
|
+
|
|
275
|
+
Source: derived from KiStack (American-Embedded/kistack @ 8494dbd, MIT), rewritten.
|