TinyPPS is a pocket-sized programmable power supply built on the USB Power Delivery (PD) standard and the USB Programmable Power Supply (PPS) feature. It transforms a standard USB-C PD charger into a flexible bench-style power source by negotiating selectable output voltages and current limits directly with the charger.
TinyPPS takes advantage of pin-compatible USB PD sink ICs (AP33772 and AP33772S), providing two feature sets within a single firmware, depending on the selected IC:
| Feature | With AP33772s | With AP33772 |
|---|---|---|
| Supported PDO profiles | fixed PDO, PPS | fixed PDO, PPS |
| Output voltage range | 3.3 - 21V | 3.3 - 21V |
| Max output current* | 5A | 5A |
| PPS voltage step size | 100mV/Step | 20mV/Step |
| Programmable current limit | 250mA/Step | 50mA/Step |
| User-switchable output | ✅ | ✅ |
| Over Voltage Protection (OVP) | ✅ → Hard Reset and Auto Restart | ✅ → Auto Restart |
| Over Current Protection (OCP) | ✅ → Output Disable | ✅ → Auto Restart |
| Under Voltage Protection (UVP) | ✅ → Output Disable | ❌ |
| Over temperature protection (OTP)** | ✅ → Output Disable | ✅ → Output Disable |
| Short-Circuit Protection (SCP) | ✅ → Output Disable | ✅ → Output Disable |
*charger and cable dependent
**OTP is set to 85°C
Huge thank you to PCBWay for sponsoring this project!

The firmware is written in C++ using the Raspberry Pi Pico SDK. No external dependencies are used.
Configuring the build using CMake:
cd firmware
cmake -G Ninja -S . -B buildBuilding the firmware:
cmake --build buildThere are two options to flash RP2040:
- Via USB by pressing the
BOOTbutton during power on. On a PC a new virtual drive calledRPI-RP2should appear. Then, drag and drop a .uf2 file onto the drive. - Via SWD interface by attaching a debugger like Raspberry Pi Debug Probe to the "DBG" connector and then using OpenOCD.
cmake --build build --target flash
The firmware unit tests are written using the GoogleTest (gtest) framework. On Apple Silicon (macOS arm64), the build system hooks directly into LLVM tools (llvm-cov and llvm-profdata) to generate visual, line-by-line code coverage metrics.
Ensure the Xcode Command Line Tools are installed to access the coverage processing binaries:
xcode-select --installTo configure the project with test coverage hooks enabled, pass the ENABLE_COVERAGE and Debug flags to CMake:
cd test
# 1. Configure the build directory
cmake -B build -DENABLE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug
# 2. Compile the test executable
cmake --build build --target run_testsTo run the full test suite manually from the build directory:
./build/run_testsBecause the suite uses GoogleTest, specific firmware modules can be isolated using the --gtest_filter flag:
./build/run_tests --gtest_filter="Ina226TestSuite*.*"When configuring the build with -DENABLE_COVERAGE=ON on an Apple Silicon Mac, CMake exposes an automated custom target. This target automatically triggers the test suite, captures runtime mapping profiles, filters out internal gtest dependencies, and renders an interactive HTML report.
Run the following command from test directory:
cmake --build build --target generate_coverage_htmlOnce execution completes, your default web browser will automatically open the local report located at:
build/coverage_html/index.html
Schematic and PCB are designed in KiCAD 10.
Key components:
- The device is based on the RP2040 microcontroller and AP33772(S) USB PD sink controller.
- A 0.96 in 128×64 SSD1306 OLED is added to display the UI.
- A EC11 rotary encoder is added for user input.
- INA226 is used for measuring current and voltage. While AP33772s provides these features, INA226 gives more precise measurements.
- LM73100 replaces the back-to-back NMOS switch and provides short circuit protection.
- 74LVC1G08GW,125 single 2-input AND gate is used for output enable.
3D model is made with Autodesk Fusion 360.
The case is 3D printed with ABS so it can handle higher tempeatures.


