Skip to content

feat(ecad): Update ECAD to support latest atopile and fix some bugs - #119

Open
finger563 wants to merge 31 commits into
mainfrom
feat/ecad-update
Open

feat(ecad): Update ECAD to support latest atopile and fix some bugs#119
finger563 wants to merge 31 commits into
mainfrom
feat/ecad-update

Conversation

@finger563

Copy link
Copy Markdown
Contributor
  • feat(ecad): Update ecad / atopile and improve workflow
  • add step file to repo
  • add box-3 step file
  • improve workflow

Description

Motivation and Context

How has this been tested?

Screenshots (if appropriate, e.g. schematic, board, console logs, lab pictures):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation Update
  • Hardware (schematic, board, system design) change
  • Software change

Checklist:

  • My change requires a change to the documentation.
  • I have added / updated the documentation related to this change via either README or WIKI

Software

  • I have added tests to cover my changes.
  • I have updated the .github/workflows/build.yml file to add my new test to the automated cloud build github action.
  • All new and existing tests passed.
  • My code follows the code style of this project.

Hardware

  • I have updated the design files (schematic, board, libraries).
  • I have attached the PDFs of the SCH / BRD to this PR
  • I have updated the design output (GERBER, BOM) files.

Copilot AI review requested due to automatic review settings July 11, 2026 00:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@finger563 finger563 self-assigned this Jul 11, 2026
@finger563 finger563 added documentation Improvements or additions to documentation enhancement New feature or request hardware ci continuous integration electronics atopile labels Jul 11, 2026
@github-actions

github-actions Bot commented Jul 11, 2026

Copy link
Copy Markdown

ESP-IDF Size Report for 'Esp Box Emu'

Metric Base PR Delta
FLASH 3,137,688 bytes (49.87%) 3,137,688 bytes (49.87%) 0 bytes (0.00%)
DRAM 178,931 bytes (52.36%) 178,931 bytes (52.36%) 0 bytes (0.00%)
IRAM 0 bytes 0 bytes 0 bytes
RAM (DRAM+IRAM) 178,931 bytes 178,931 bytes 0 bytes (0.00%)

FLASH uses app .bin size or json2 flash sum. RAM sums DRAM+IRAM via idf_size. Percentages shown when totals are available.
DRAM/IRAM usage does not include memory used by the heap allocator at runtime.
This report was generated by esp-idf-size-delta.

finger563 and others added 12 commits July 12, 2026 22:14
packages.atopileapi.com no longer resolves (taken down in the 0.16
platform migration, like the components API), so dependency resolution
of atopile/ti-tps63020@0.4.0 fails in CI and on any machine without a
warm .ato/modules. Commit the installed package (sans .cache) so
`ato build` finds it via its installed-package path and never contacts
the dead registry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ato validates installed packages against the file hashes in
.package_meta.json; git's CRLF->LF normalization of the STEP files
changed their bytes on checkout, making CI fail with "Package has
local modifications". Exempt ecad/.ato/modules from text normalization
and re-commit the original bytes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ization

The atopile-kicad docker image sets ATO_FROZEN=1, silently forcing CI
builds into frozen mode, which fails on phantom in-memory diffs
(locked-attribute defaults, arc direction normalization) that never
reach the file on disk. Pass ATO_FROZEN=0 from the workflow — we verify
layout stability ourselves via canonicalize + git diff.

Also re-serialize box-emu-base.kicad_pcb through the same container
build + canonicalize pipeline CI runs: the file had last been written
by desktop KiCad (zone refills), whose s-expr dialect differs from
atopile's writer, so CI's rebuild produced an 8k-line formatting diff.
Verified idempotent across two container builds; DRC unchanged
(265 violations / 0 unconnected, same accepted classes).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
finger563 and others added 11 commits July 29, 2026 08:38
Add scripts/tidy-silkscreen.py: auto-places every visible reference
label in the nearest clear spot around its footprint (avoiding pads,
vias, silk/fab artwork, bare-copper membrane fingers, board edges and
the other labels), normalized to upright 0/90 orientation and
consistent 1.0/0.8/0.7 mm sizes. Applied to all 9 boards; the two
labels the search could not fit (R8 in the button pocket) were placed
by hand. Outline-footprint REF** markers hidden. Layouts re-serialized
via the container build + canonicalize pipeline; DRC unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The first tidy pass under-estimated text extents (~40% smaller than
KiCad's rendered bounding boxes), so labels still collided with pads,
neighboring parts and each other. tidy-silkscreen.py now measures the
actual text bbox at each candidate position, adds pad-union part bodies
as obstacles, caps blanket-sized artwork bboxes (membrane outline
polylines), and gains a --verify mode that reports any label
overlapping copper, artwork or another label. All 9 boards re-placed
and verified clean; layouts re-serialized via the container build +
canonicalize pipeline; DRC unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ized

Rework the label placer for readability rather than any-free-spot:
gap from the part body is hard-capped (~1.2 mm; a bounded straggler
pass for pullups buried in the membrane fields), slots score by side
preference (above > below > sides), lateral slide and size, tented vias
count as soft cost instead of hard obstacles (freeing space in the
via-dense io region), and row/column clusters of passives get their
labels snapped into alignment. Fixes an anchor bug where non-center
text justification offset the real text from the checked position.
All 9 boards verify clean; every label except four membrane-pocket
pullups sits within 1.5 mm of its part (previously up to 13 mm).
DRC unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
R8/R9/R10 (down/left/right button pullups) sat inside the d-pad
membrane outline where the rubber membrane rests on the board; no
components may live there. Relocated all three to the clear corridor
south of the membrane next to R11 (up), tapping their button nets on
the existing dive-fan vias / new tap vias on the B-layer verticals,
with a shared 3.3V feed spur off the io bus. The now-unused west-side
3.3V feed tree (nw vertical, west bus run, lp1/dnp1 chains, 32 items)
is removed. Verified: no component intrudes on any membrane region
(d-pad blob, A/B / X/Y capsules, start/select strip; C4 clears the
d-pad corner arc by 0.25mm), labels re-placed and overlap-clean, DRC
unchanged on all boards.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rints

The 4 exterior pads on the d-pad, A/B/X/Y, and start/select button
footprints (used to solder an ALPS tactile switch in place of the
membrane) were F.Cu-only, so soldermask covered them. Add F.Mask
openings in the part libraries and all board instances. Paste is
intentionally omitted so membrane builds stay flat.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… picker for new parts

Design-review fixes:
- 10k pullups on SD CS/DAT3, DAT1, DAT2 (hold lines high during boot
  and in SPI mode per SD spec); placed north of the socket pin row and
  fed from the 3v3 trunk
- 22uF 0805 bulk capacitor on the carrier 3v3 rail next to the uSD
  socket (rail arrives over dock contacts; SD write bursts previously
  saw only 100nF locally)
- DRV2605 IN_TRIG grounded per TI datasheet (I2C-trigger-only use),
  routed through the VSSOP interior to a new ground via
- AW9523 P1_6/P1_7 left as firmware-configured outputs; card-detect
  intentionally not wired (no expander pin reachable in the routed
  layout, and firmware probes the card over SPI)
- ground stitch via added for the C13 pocket the new 3v3 feeds enclosed

Build infra: teach parts-cache-server to answer parametric passive
queries from a pinned value table, and freshen the EasyEDA cache
timestamps (touch-parts-cache.py) so builds with new components work
against the dead component APIs.

DRC baselines unchanged: base 264/0, box-emu 265/0, box-3-emu 270/2
(known tab-bus INTN/io10 gaps).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The io10/CS finger (A1) was enclosed by the tab bus, leaving the SD
card unusable on box-3-emu. Route it out the west side of A1, along a
new front-copper lane above the MOSI tab bus (inside the 0.5mm edge
clearance), down the east flank, and under the SCLK/DATA verticals to
the existing io10 artery. The gnd stitch via at the tab west end moves
0.35mm west to clear the new exit.

INTN (B5) remains unconnected on box-3: every corridor between the
finger and the io expander is closed by the 5V/3v3/I2C arteries, the
membrane pad fields, and the button distribution tracks; freeing one
would cascade into power-artery rework. Firmware should poll the
AW9523 over I2C on box-3 (box-emu keeps interrupt-driven input).

box-3-emu DRC: 270 violations (baseline classes), unconnected 2 -> 1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The in-container build step freshens the EasyEDA cache timestamps as
root; the export step then re-runs the script as the runner user and
died on PermissionError. Skip files that are already fresh and warn
instead of failing when a stale file is unwritable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Box-3 now gets interrupt-driven button input like box-emu, instead of
having to poll the expander over I2C:

- Relocate R13 (SCL pullup) from the saturated pocket west of the SCL
  artery to open ground east of it, fed by a via on the artery and the
  existing 3v3 F diagonal (replicated on all three boards so the shared
  box group stays sync-consistent).
- Restack the box-3 connector neck: SCL horizontal drops to y0.48 and
  SDA's artery entry moves east with an F-hop over the b-net via,
  opening a lane under the finger pads.
- INTN escapes B5 south under the pads, runs the corridor between the
  SCL and 3v3 arteries at x-8.35, and lands on the existing fragment
  to U2 pad 22 (io21 on the dock, same as box-emu).
- The corridor's caged ground stitch via moves onto C4's ground pad
  where clearances allow, letting INTN run straight.
- Ground-pour cleanup: island removal (0.8mm2) on gnd_f, a keepout over
  the dead USB sliver field, and stitch vias for the SD-area pocket.

DRC: base 264/0, box-emu 265/0, box-3-emu 270/0 - first time box-3 has
zero unconnected items; all remaining violations are the accepted
baseline classes. pcbnew connectivity reports 0 on all three.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…hain

Box-3's entire 3v3 rail was fed through a single 0.25mm, ~25mm B.Cu
snake from the A17/B17 fingers, threading between the DRV2605 supply
pins before reaching the 0.8mm artery - roughly 50 milliohms for a rail
that carries SD write bursts and haptic motor current. Widen every span
to the clearance-limited maximum (mostly 0.5mm, 0.3mm past the USB
data pair, 0.25mm only beside H1's through-hole pad where 0.215mm
gap is all the room there is), and widen the shared U1-area F.Cu chain
to 0.5mm on all three boards. Feed resistance drops to ~12 milliohms.

DRC baselines unchanged (264/265/270), 0 unconnected everywhere.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
JLCPCB's standard process wicks solder from reflowed pads into via
barrels, so via-in-pad needs the paid filled/capped process. Relocate
every offending via out of its pad with a short connecting trace:
21 shared instances (bypass caps, pullups, switches, USB shell, SD
shell, qwiic, charger STAT, divider) plus the box-emu J3 and box-3
CN3 power-finger vias. C13 flips 180 so its ground pad escapes south
to C14; R11 shifts 0.35mm west to free the up-net junction; the
DRV2605 REG (hv) wrap reroutes west to make room beside C2.

A physical_hole_clearance rule in each board's .kicad_dru now flags
any via hole within 0.1mm of an SMD pad, with documented exceptions:
the AW9523 thermal pad (stitching vias are standard practice), gnd
card-edge fingers (no paste/reflow; dimple on redundant ground mating
surfaces is acceptable), and C3's 85um same-net corner graze (any
relocation severs the only ground-pour channel through that neck).

Ground-pour integrity reverified after the churn: several relocations
had orphaned the central gnd island (the old SW9 and C2 vias doubled
as pour stitches); connectivity now reports 0 unconnected on all
three boards by both kicad-cli DRC and pcbnew's engine.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

atopile ci continuous integration documentation Improvements or additions to documentation electronics enhancement New feature or request hardware

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants