Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,48 @@
name: CI

on:
workflow_dispatch:
push:
branches: [main]
branches: [main, stackup]
pull_request:
branches: [main]
branches: [main, stackup]

jobs:
stackup-check:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4

- name: Checkout Stackup KiCad plugin
uses: actions/checkout@v4
with:
repository: stackup-eda/stackup
ref: v0.1.3
path: stackup-tool

- name: Install Rust 1.96
run: rustup toolchain install 1.96.0 --profile minimal

- name: Check Stackup design
run: cargo +1.96.0 run --locked --manifest-path ci/stackup/Cargo.toml -- check PCB/stackup/board.kdl --locked

- name: Check purchasing BOM
run: cargo +1.96.0 run --locked --manifest-path ci/stackup/Cargo.toml -- bom PCB/stackup/board.kdl --locked -o /tmp/snips-bom.csv

- name: Install KiCad 10
run: |
sudo apt-get update
sudo apt-get install -y software-properties-common
sudo add-apt-repository --yes ppa:kicad/kicad-10.0-releases
sudo apt-get update
sudo apt-get install -y --install-recommends kicad

- name: Check PCB sync
run: |
/usr/bin/python3 ci/check_pcb_sync.py PCB/snips_controller.kicad_pcb \
--stackup ci/stackup/target/debug/snips-stackup-check \
--plugin-dir stackup-tool/kicad-plugin

native-tests:
runs-on: ubuntu-latest
steps:
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,9 @@ PCB/production/misc/*

# ERC report JSON scratch files (from kicad-cli sch erc)
PCB/erc*.json
PCB/full_erc*.json
PCB/full_erc*.json

# Local Stackup library checkout for development
manifest.local.kdl
.stackup/
ci/stackup/target/
26 changes: 13 additions & 13 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@
```
3. Once a PR lands, delete the local feature branch. This repo always squash or rebase merges — `main` never gets a merge commit for the PR, so `git branch -d` (and `--merged` checks) won't recognize the branch as merged even though its content has landed. Confirm via `git log --oneline` (look for the PR's commit/title on `main`) or `gh pr view <branch> --json state`, then use `git branch -D <branch>` to remove it.

## BOM Value fields

The fab's BOM shows only Designator, Footprint, Quantity and **Value** (never MF, MPN or LCSC), so every
component's Value is `<label> | <MPN> | <manufacturer> | <package>` (see `scripts/bom_values.py` for the
exact rules). Every board component needs `MF` and `Manufacturer_Part_Number`.

- After adding or changing a part, run `python3 scripts/bom_values.py --apply`, then `--check`. Close
the files in KiCad first (or reload after). `--check` also fails if the PCB copy of a part's Value,
MF, MPN or footprint differs from the schematic, so run Update PCB from Schematic before regenerating
production files.
- A new footprint must be added to `PACKAGES` in the script on purpose. Parts that are hand-sourced with
no known MPN go in `NO_MPN_OK`, so a gap is never silent.
## Purchasing BOM

The electrical design is the source for purchasing. Export its BOM with
`stackup bom PCB/stackup/board.kdl --locked -o snips-bom.csv`. The CSV has separate
references, quantity, value, footprint, manufacturer, MPN and distributor columns.
Keep `value=` human-readable; specify exact purchasing choices with `manufacturer=`,
`mpn=` and distributor fields on each placement. A `hand=#true` placement remains
in the purchasing BOM and is marked `DNP` for outsourced assembly.

- The circuit source is `PCB/stackup/board.kdl` and `PCB/stackup/parts.kdl`. Run
`stackup check PCB/stackup/board.kdl`, then sync the PCB with the Stackup KiCad plugin.
- The BOM scripts read Stackup's CSV through the Cargo-locked CLI, including
defaults from library parts. CI checks the export and PCB sync.
- Prefer common parts (several makers, broadly stocked, one package per name). The retired JLCPCB
Basic-library preference no longer applies.

14 changes: 4 additions & 10 deletions PCB/GPIO_table.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
# Snips Controller — ESP32-S3-WROOM-1 GPIO Table

> **⚠ Known kicaddy bug (2026-08-17):** the yaml's `footprint:` field is not
> currently applied by `kicaddy compile` — compiled `.kicad_sch` files have
> blank/wrong Footprint properties for most components right now. The
> `footprint:` values in `snips_controller.yaml` are still accurate as
> documentation of intent; they're just not making it into the compiled
> output yet. **Don't start PCB layout from the current compiled schematic's
> footprints** until this is fixed — assign footprints manually in the
> KiCad GUI in the meantime, or wait for the fix.
> The current circuit and footprint choices are in `PCB/stackup/board.kdl`
> and `PCB/stackup/parts.kdl`. References to the older YAML and KiCad schematic
> below describe the design history; use Stackup for changes.

> **MCU:** ESP32-S3-WROOM-1 module (pre-certified, integrated flash +
> crystal + WiFi/BT radio + PCB antenna). No external RF design, flash,
Expand Down Expand Up @@ -281,8 +276,7 @@ on VDD (10nF, 100pF, 2.2nF) rather than this board's usual single
in a preliminary-datasheet figure and should be visually re-checked
against the datasheet before fab.**

**Status: in the schematic/yaml**, on its own `Accelerometer` sheet
(`PCB/accelerometer.kicad_sch`), wired into `snips_controller.yaml`, with
**Status: in Stackup** (`PCB/stackup/board.kdl`), with
a hand-authored symbol + footprint (`SnipsControllers_Custom:QMA6100P`) —
pad geometry pulled from JLCPCB/LCSC's own EasyEDA component data (LCSC
C2887190) rather than estimated from the datasheet's low-resolution
Expand Down
15 changes: 10 additions & 5 deletions PCB/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

A wireless handheld controller for R2-D2 droid operation, designed for use at public events and conventions. Communicates with the droid via XBee3 Zigbee radio in a packetized state-report architecture.

The electrical design is in [Stackup KDL](stackup/board.kdl), using the pinned
Stackup library plus a [local thumbstick model](stackup/parts.kdl). The existing [KiCad PCB](snips_controller.kicad_pcb) is linked
through `snips_controller.stackup_sch`; sync it with the Stackup KiCad plugin. Run
`stackup check PCB/stackup/board.kdl` from the repository root before syncing.

## Hardware Overview

| Component | Part | Notes | Layout diagram |
Expand All @@ -12,7 +17,7 @@ A wireless handheld controller for R2-D2 droid operation, designed for use at pu
| Hall trigger | DRV5055A2 | Ratiometric linear hall effect, 3.3V | — |
| Thumbstick | GuliKit hall effect module | Native 3.3V, analog X/Y + click | — |
| Buttons | Omron B3F series | Tactile momentary clicky | — |
| RGB LED | SK6812 NeoPixel-compatible | RMT-driven, 3.3V native, single LED status indicator | — |
| RGB LED | SK6812 NeoPixel-compatible | RMT-driven status indicator; specified supply begins at 3.7 V, but board supplies 3.3 V | — |
| Charger | bq25185 | USB/DC input, power path, 4.2V/500mA | [diagram](diagrams/power_charger_layout.md) |
| Buck | TLV62569 | 3.3V output, 1A | [diagram](diagrams/power_buck_layout.md) |
| Battery | 18650 or 14500 Li-ion | Swappable single cell, TBD empirically | — |
Expand All @@ -27,9 +32,9 @@ against the actual component datasheet, not just the schematic. See
[`diagrams/README.md`](diagrams/README.md) for the full list and how the
files are organized.

- [Buck converter](diagrams/power_buck_layout.md) — `power_buck.kicad_sch`
- [Charger](diagrams/power_charger_layout.md) — `power_charger.kicad_sch`
- [Power latch](diagrams/power_control_layout.md) — `power_control.kicad_sch`
- [Buck converter](diagrams/power_buck_layout.md) — `/Power_Buck/*` nets in Stackup
- [Charger](diagrams/power_charger_layout.md) — `/Power_Charger/*` nets in Stackup
- [Power latch](diagrams/power_control_layout.md) — `/Power_Control/*` nets in Stackup

## GPIO Assignment

Expand Down Expand Up @@ -212,7 +217,7 @@ Recommended bringup order:
- Shutdown: firmware detects 3-second hold on pin 38 → graceful shutdown → pin 36 LOW → power cut
- bq25185 STAT1 → pin 39 (open-drain, 10kΩ pull-up to 3V3)
- Battery voltage sense → pin 7 via external R_VSYS1/R_VSYS2 divider (reads VSYS/3 via ADC1)
- All logic is 3.3V native — ESP32-S3-WROOM-1, DRV5055, GuliKit thumbstick, SK6812
- ESP32-S3-WROOM-1, DRV5055, and GuliKit thumbstick use the 3V3 rail. The SK6812 also uses it, but its 3.7 V minimum supply makes that LED connection out of specification.

No firmware ADC-gating workaround needed for battery sense — WiFi is
fully on-die on ESP32-S3 and doesn't share any exposed GPIO/ADC path
Expand Down
Loading
Loading