Skip to content
Open
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
116 changes: 108 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,113 @@
# RP2040 Zero

A tiny development board for the RP2040 microcontroller in the [xiao form factor](https://files.seeedstudio.com/wiki/XIAO/Seeed-Studio-XIAO-Series-SOM-Datasheet.pdf)

- RP2040 Microcontroller with 20 GPIO broken out
- USB-C Port
- 5V to 3.3V Converter using RT9013-33 LDO Regulator
- A configurable multicolor LED (WS2812B)
- Flash Memory (W25Q16JVUXIQ)
A tiny development board for the RP2040 microcontroller in the [Xiao form factor](https://files.seeedstudio.com/wiki/XIAO/Seeed-Studio-XIAO-Series-SOM-Datasheet.pdf). Implemented in the [tscircuit](https://tscircuit.com) framework.

Based on the [Waveshare RP2040-Zero](https://www.waveshare.com/wiki/RP2040-Zero) board.

- https://www.waveshare.com/wiki/RP2040-Zero [(schematic)](https://files.waveshare.com/upload/4/4c/RP2040_Zero.pdf)
- [Waveshare RP2040-Zero wiki](https://www.waveshare.com/wiki/RP2040-Zero) — [Schematic (PDF)](https://files.waveshare.com/upload/4/4c/RP2040_Zero.pdf)

---

## Features

- **RP2040** microcontroller with 20 GPIO broken out (GPIO0–16, GPIO26–29)
- **Power**: 5 V from USB (VSYS) → RT9013-33 LDO → 3.3 V rail; input/output decoupling
- **USB**: Micro-B connector; D+/D- with 22 Ω series resistors (signal integrity/ESD); VBUS → VSYS
- **Flash**: W25Q16JVUXIQ (QSPI) for program storage
- **Crystal**: 12 MHz oscillator (ABM8 27.2 MHz or equivalent) for system clock
- **Buttons**: BOOTSEL (QSPI_SS_N, for USB boot) and RESET (RUN to GND); RUN has 10 kΩ pull-up to 3V3
- **Power LED**: Green indicator from 3.3 V rail
- **Status LED**: WS2812B addressable RGB on GPIO16
- **SWD debug header**: 4-pin (SWDIO, SWCLK, GND, 3V3) for CMSIS-DAP / J-Link
- **Pin header**: Xiao-style stamp (VSYS, GND, 3V3, GP29–GP26, GP15–GP0)

## Board dimensions and layers

- **21 mm × 17.5 mm** (Xiao form factor)
- **2-layer** stack (`layers={2}`), **double-sided assembly**.
- **Top layer** (correct PCB positions): USB connector (left), RP2040 (center), flash & crystal (near IC), pin header (right).
- **Bottom layer** (correct PCB positions): power LDO & caps, BOOTSEL/RESET keys, power LED, WS2812B, SWD header.
- Anchor **bottom_left** so coordinates are `pcbX=0..21`, `pcbY=0..17.5` (mm).

---

## Validation (Fixes #2)

1. **Install**
```bash
npm install
```

2. **Run dev server**
```bash
npm run dev
```
Open the URL shown in the terminal (e.g. http://localhost:3000).

3. **Build**
```bash
npm run build
```

4. **Verify**
- PCB renders with correct outline and footprints
- Schematic loads with all nets connected
- No TypeScript errors
- All circuits present: power, USB, RP2040, flash, crystal, keys, power LED, WS2812B, SWD header, pinout

---

## Project structure

```
├── index.tsx # Entry: exports RP2040ZeroBoard
├── src/
│ └── RP2040ZeroBoard.tsx # Board definition (21×17.5 mm), composes all circuits
├── lib/
│ ├── RP2040Circuit.tsx # RP2040 + decoupling, full pin mapping
│ ├── PowerCircuit.tsx # VSYS → 3.3 V LDO, decoupling
│ ├── UsbCircuit.tsx # USB connector + 22 Ω on D+/D-
│ ├── FlashCircuit.tsx # W25Q16 QSPI flash
│ ├── CrystalCircuit.tsx # 12 MHz crystal
│ ├── KeyCircuit.tsx # BOOTSEL, RESET
│ ├── PowerLedCircuit.tsx# Power-on green LED
│ ├── LedCircuit.tsx # WS2812B on GPIO16
│ ├── SwdCircuit.tsx # SWD debug header
│ ├── PinOutCircuit.tsx # Xiao header pinout
│ └── VoltageRegulator.tsx# (legacy) LDO; use PowerCircuit for full power tree
└── imports/ # Part definitions (RP2040, W25Q16, RT9013, etc.)
```

---

## Nets (main)

| Net | Description |
|--------|--------------------|
| VSYS | 5 V from USB |
| V3_3 | 3.3 V regulated |
| V1_1 | RP2040 internal 1.1 V core |
| GND | Ground |
| USB_DP, USB_DM | USB data to RP2040 |
| GPIO0–16, GPIO26–29 | GPIO to header |
| QSPI_SS_N, QSPI_SCLK, QSPI_SD0–SD3 | Flash QSPI |
| SWDIO, SWCLK | SWD debug |
| RUN | Reset pin (pulled high via R_RUN) |
| XIN, XOUT | Crystal |

---

## Recommended future updates

Optional improvements to get even closer to production or reference designs:

| Priority | Update | Why |
|----------|--------|-----|
| **Done** | RUN pull-up (10 kΩ to 3V3) | RUN must be high when RESET is released; was floating. |
| **High** | **Test points** | Add small test points on GND, 3V3, VSYS (and optionally SWDIO/SWCLK) for scope/probe during bring-up. |
| **High** | **Silkscreen / fabrication** | Use `silkscreentext` or `fabricationnotetext` for board name, revision (e.g. "RP2040-Zero v1.0"), and any fab notes (finish, stack). |
| **Medium** | **USB TVS** | Add a TVS diode (e.g. USBLC6-2SC6 style) on USB_DP/USB_DM to GND for ESD; 22 Ω series R already in place. |
| **Medium** | **Config / constants** | Centralize net names or key values (e.g. `NETS.ts` or `boardConstants.ts`) to avoid typos and simplify changes. |
| **Low** | **CHANGELOG** | Add a `CHANGELOG.md` for version history and "Fixes #2" release note. |
| **Low** | **XiaoBoard wrapper** | If `@tscircuit/common` (or equivalent) provides `<XiaoBoard variant="RP2040" />`, switch to it for standard mechanical/header layout. |
| **Low** | **Fuse / PTC on VBUS** | Optional polyfuse or PTC on USB VBUS for overcurrent protection (match real RP2040-Zero if present). |
19 changes: 2 additions & 17 deletions index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
import { VoltageRegulator } from "./lib/VoltageRegulator"
import { RP2040 } from "./imports/RP2040"
import { PinOutCircuit } from "./lib/PinOutCircuit"
import { LedCircuit } from "./lib/LedCircuit"
import { FlashCircuit } from "./lib/FlashCircuit"
import { CrystalCircuit } from "./lib/CrystalCircuit"
import { RP2040Circuit } from "./lib/RP2040Circuit"
import { RP2040ZeroBoard } from "./src/RP2040ZeroBoard"

export default () => (
<board routingDisabled schMaxTraceDistance={5}>
<VoltageRegulator />
<PinOutCircuit />
<LedCircuit />
<FlashCircuit />
<CrystalCircuit />
<RP2040Circuit />
</board>
)
export default () => <RP2040ZeroBoard />
5 changes: 3 additions & 2 deletions lib/CrystalCircuit.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { ABM8_272_T3 } from "../imports/ABM8_272_T3"
import type { GroupProps } from "@tscircuit/props"

export const CrystalCircuit = () => (
<group>
export const CrystalCircuit = (props: GroupProps) => (
<group {...props}>
<resistor
name="R8"
resistance="1k"
Expand Down
7 changes: 4 additions & 3 deletions lib/FlashCircuit.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { W25Q16JVUXIQ } from "../imports/W25Q16JVUXIQ"
import type { GroupProps } from "@tscircuit/props"

export const FlashCircuit = () => (
<group>
export const FlashCircuit = (props: GroupProps) => (
<group {...props}>
<capacitor
name="C3"
capacitance="1uF"
Expand All @@ -19,7 +20,7 @@ export const FlashCircuit = () => (
GND: "net.GND",
VCC: "C3.1",
HOLD_N: "net.QSPI_SD3",
CLK: "net.QSPI_CLK",
CLK: "net.QSPI_SCLK",
DI: "net.QSPI_SD0",
}}
/>
Expand Down
21 changes: 18 additions & 3 deletions lib/KeyCircuit.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
import { TS_1187A_B_A_B } from "../imports/TS_1187A_B_A_B"

export const KeyCircuit = () => (
<group>
/**
* BOOTSEL (SW1): QSPI_SS_N pulled high via R2; when pressed, pulls to GND for USB boot.
* RESET (SW2): RUN to GND when pressed. R_RUN pulls RUN high (3V3) when released so the chip runs.
*/
export const KeyCircuit = (props: React.ComponentProps<"group">) => (
<group {...props}>
<resistor
name="R2"
resistance="1k"
footprint="0402"
connections={{
pin1: "net.QSPI_SS_N",
pin2: "net.BOOTSEL_NODE",
}}
/>
<resistor
name="R_RUN"
resistance="10k"
footprint="0402"
connections={{
pin1: "net.V3_3",
pin2: "net.RUN",
}}
/>
<TS_1187A_B_A_B
name="SW1"
connections={{
pin1: "R2.2",
pin1: "net.BOOTSEL_NODE",
pin2: "net.GND",
}}
/>
Expand Down
7 changes: 4 additions & 3 deletions lib/LedCircuit.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { WS2812B_2020 } from "../imports/WS2812B_2020"
import type { GroupProps } from "@tscircuit/props"

export const LedCircuit = () => (
<group>
export const LedCircuit = (props: GroupProps) => (
<group {...props}>
<WS2812B_2020
name="L1"
connections={{
VDD: "net.V3V3",
VDD: "net.V3_3",
GND: "net.GND",
DI: "net.GPIO16",
}}
Expand Down
5 changes: 3 additions & 2 deletions lib/PinOutCircuit.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const PinOutCircuit = () => (
export const PinOutCircuit = (props: React.ComponentProps<"chip">) => (
<chip
name="P1"
footprint="stampboard_left9_right9_bottom5_top0_p2.54mm_innerhole_h23.8mm_showpinlabels"
Expand Down Expand Up @@ -59,7 +59,7 @@ export const PinOutCircuit = () => (
pin23: "GP0",
}}
connections={{
V5: "net.V5_5",
V5: "net.VSYS",
GND: "net.GND",
V3_3: "net.V3_3",
GP29: "net.GPIO29",
Expand All @@ -83,5 +83,6 @@ export const PinOutCircuit = () => (
GP1: "net.GPIO1",
GP0: "net.GPIO0",
}}
{...props}
/>
)
57 changes: 57 additions & 0 deletions lib/PowerCircuit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { RT9013_33GB } from "../imports/RT9013_33GB"
import type { GroupProps } from "@tscircuit/props"

/**
* Power circuit: 5V USB input (VSYS), 3.3V regulator, decoupling capacitors.
*/
export const PowerCircuit = (groupProps: GroupProps) => (
<group {...groupProps}>
<capacitor
name="C6"
schOrientation="vertical"
footprint="0402"
capacitance="2.2uF"
connections={{ pin1: "net.VSYS", pin2: "net.GND" }}
/>
<capacitor
name="C1"
schOrientation="vertical"
footprint="0402"
capacitance="2.2uF"
connections={{ pin1: "net.VSYS", pin2: "net.GND" }}
/>
<capacitor
name="C2"
schOrientation="vertical"
footprint="0402"
capacitance="2.2uF"
connections={{ pin1: "net.VSYS", pin2: "net.GND" }}
/>
<capacitor
name="C5"
schOrientation="vertical"
footprint="0402"
capacitance="1uF"
connections={{ pin1: "net.V3_3", pin2: "net.GND" }}
/>
<capacitor
name="C4"
capacitance="10uF"
footprint="0402"
schOrientation="vertical"
connections={{
pin1: "net.V3_3",
pin2: "net.GND",
}}
/>
<RT9013_33GB
name="U1"
connections={{
VIN: ["C6.1", "C1.1", "C2.1", "net.VSYS"],
GND: ["C6.2", "C1.2", "C2.2", "net.GND"],
EN: "U1.VIN",
VOUT: ["net.V3_3", "C5.1", "C4.1"],
}}
/>
</group>
)
27 changes: 27 additions & 0 deletions lib/PowerLedCircuit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Power-on indicator LED: V3_3 → resistor → LED → GND.
*/
export const PowerLedCircuit = (props: React.ComponentProps<"group">) => (
<group {...props}>
<resistor
name="R_PWR_LED"
resistance="2.2k"
footprint="0402"
schOrientation="vertical"
connections={{
pin1: "net.V3_3",
pin2: "net.LED_PWR_ANODE",
}}
/>
<led
name="LED_PWR"
color="green"
footprint="0402"
schOrientation="vertical"
connections={{
pin1: "net.LED_PWR_ANODE",
pin2: "net.GND",
}}
/>
</group>
)
Loading