Building a USB Power Delivery Trigger HAT
Overview
This tutorial walks through a USB Power Delivery trigger HAT for Raspberry Pi. The HAT negotiates a fixed USB-C PD voltage with a trigger controller such as a CH224K, FP28XX, or PD2001, then routes the negotiated rail to a terminal block with input filtering and a status LED.
Use this pattern when you want a small board that can request 5V, 9V, 12V, 15V, or 20V from a USB-C power supply and expose that output to external hardware.
Circuit Requirements
The HAT needs to:
- negotiate a USB-C PD fixed voltage profile from a compliant charger
- expose the negotiated rail on a screw terminal or pluggable terminal block
- show a power-good status LED once negotiation succeeds
- include bulk and local decoupling capacitors close to the PD controller
- keep the Raspberry Pi GPIO header mechanically compatible with the HAT outline
How the PD Trigger Works
A USB PD trigger controller sits between the USB-C connector and the output rail. The controller listens on the CC pins, requests a configured voltage profile, and then connects VBUS once the supply accepts the request.
Most small PD trigger controllers expose configuration pins. The exact truth
table depends on the controller family, so always check the datasheet for the
part you place. The schematic uses pull-down resistors on CFG1, CFG2, and
CFG3 as a visible starting point for voltage selection.
Building the Circuit Step by Step
Step 1: Start with a Raspberry Pi HAT outline
RaspberryPiHatBoard gives the design a HAT-sized PCB and the standard
40-pin Raspberry Pi connector.
import { RaspberryPiHatBoard } from "@tscircuit/common"
export default () => <RaspberryPiHatBoard name="HAT1" />
Step 2: Add the USB-C input and PD trigger
The USB-C connector routes CC1 and CC2 to the trigger controller. VBUS is
kept on a named net so it can feed the filters, LED, and output terminal.
Step 3: Configure the requested voltage
The three configuration resistors represent the fixed-voltage selection network. Populate the pull-up or pull-down pattern required by your chosen controller. For a production board, label the requested voltage on the silkscreen.
<resistor name="R1" resistance="10k" footprint="0402" />
<resistor name="R2" resistance="10k" footprint="0402" />
<resistor name="R3" resistance="10k" footprint="0402" />
<trace from=".R1 > .pin1" to=".U1 .CFG1" />
<trace from=".R2 > .pin1" to=".U1 .CFG2" />
<trace from=".R3 > .pin1" to=".U1 .CFG3" />
Step 4: Add filtering and output terminals
Use a bulk capacitor for load steps and a small ceramic capacitor near the PD
controller. The terminal block exports VOUT and GND.
import { RaspberryPiHatBoard } from "@tscircuit/common"
export default () => (
<RaspberryPiHatBoard name="HAT1">
<capacitor name="C1" capacitance="10uF" footprint="0603" pcbX={6} pcbY={-6} />
<capacitor name="C2" capacitance="100nF" footprint="0402" pcbX={10} pcbY={-6} />
<connector
name="J2"
footprint="pinrow2"
pinLabels={{
pin1: ["VOUT"],
pin2: ["GND"],
}}
pcbX={24}
pcbY={0}
/>
<trace from="net.VBUS_IN" to=".C1 > .pos" />
<trace from="net.VBUS_IN" to=".C2 > .pin1" />
<trace from=".C1 > .neg" to="net.GND" />
<trace from=".C2 > .pin2" to="net.GND" />
<trace from="net.VBUS_IN" to=".J2 .VOUT" />
<trace from="net.GND" to=".J2 .GND" />
</RaspberryPiHatBoard>
)
Step 5: Add a power-good LED
Many PD trigger controllers expose a PG or PWR_OK signal. Route it through a
current-limiting resistor to an LED so the user can see whether negotiation
succeeded.
<resistor name="R4" resistance="2.2k" footprint="0402" />
<led name="LED1" color="green" footprint="0603" />
<trace from=".U1 .PG" to=".R4 > .pin1" />
<trace from=".R4 > .pin2" to=".LED1 .pos" />
<trace from=".LED1 .neg" to="net.GND" />
Bill of Materials
| Ref | Part | Notes |
|---|---|---|
| J1 | USB-C receptacle | 16-pin SMD USB-C connector |
| U1 | CH224K, FP28XX, or PD2001 | USB PD trigger controller |
| R1-R3 | 10k resistors | Voltage profile configuration network |
| C1 | 10uF ceramic capacitor | Bulk input/output filtering |
| C2 | 100nF ceramic capacitor | Local decoupling near controller |
| R4 | 2.2k resistor | Status LED current limit |
| LED1 | Green 0603 LED | Power-good indicator |
| J2 | 2-position terminal block | Negotiated voltage output |
Testing Procedure
- Inspect the USB-C connector pins for solder bridges before plugging in a charger.
- Power the board from a current-limited USB-C PD supply.
- Confirm the status LED turns on after negotiation.
- Measure
VOUTtoGNDat the terminal block and confirm it matches the configured voltage profile. - Add a small load first, then increase load current while checking connector, controller, and terminal temperatures.
- If the output is used near the Raspberry Pi, confirm the negotiated voltage is not accidentally routed into the Pi 5V rail unless the design explicitly supports that power path.
Optional Raspberry Pi Monitor
If your PD controller exposes PG to a GPIO pin through a safe 3.3V-compatible
level, you can monitor negotiation status from Linux:
from gpiozero import DigitalInputDevice
from signal import pause
POWER_GOOD_PIN = 17
pg = DigitalInputDevice(POWER_GOOD_PIN, pull_up=False)
pg.when_activated = lambda: print("USB PD output is ready")
pg.when_deactivated = lambda: print("USB PD output dropped")
pause()
Layout Guidance
- Keep the USB-C connector, PD controller, and input capacitors close together.
- Route VBUS with a wide trace or copper pour sized for the expected current.
- Put the terminal block near the board edge for strain relief and access.
- Keep CC traces short and away from noisy switching nodes.
- Clearly mark the configured voltage on silkscreen before ordering boards.
Next Steps
- Add solder jumpers or a DIP switch for selectable 5V, 9V, 12V, 15V, and 20V profiles.
- Add an eFuse or resettable fuse between VBUS and the terminal block.
- Add test points for
VBUS,GND,CC1,CC2, andPG. - Create a separate version that back-powers the Raspberry Pi through a protected 5V path.