Flashing Zap Firmware
This guide covers the process of flashing Sourceful Zap firmware to ESP32-C3 devices using the sequential flasher tool.
Overview
The Sourceful Zap flasher is a standalone tool for flashing firmware to ESP32-C3 devices sequentially on a single serial port. It automatically extracts device serial numbers and public keys from the flashed firmware.
Prerequisites
- Python 3.8+
- USB access to your serial device
- ESP32-C3 devices with USB connector
- uv package manager (recommended)
Installation
Option A: Using uv (Recommended)
# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone the flasher repository
git clone https://github.com/srcfl/srcful-zap-x-firmware.git
cd srcful-zap-x-firmware
# uv automatically creates venv and installs dependencies
uv sync
Option B: Traditional pip
# Create and activate virtual environment
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
Firmware Setup
Place your Sourceful Zap firmware binaries in a directory. Expected structure:
c3_1_1_0/ # Or any directory name
├── bootloader.bin
├── partition-table.bin
└── zap-idf.bin # Main firmware file
Flashing Process
Quick Start
# Fast mode - auto-detects everything
uv run flasher.py
# Quiet mode for production
uv run flasher.py --quiet
# Specify binary directory
uv run flasher.py --bin-dir c3_1_1_0
Advanced Usage
# Safer mode with flash erase (slower but more reliable)
uv run flasher.py --erase
# Specify port manually
uv run flasher.py --port /dev/cu.usbmodem101
# Manual file specification
uv run flasher.py --files \
0x0:c3_1_1_0/bootloader.bin \
0x8000:c3_1_1_0/partition-table.bin \
0x10000:c3_1_1_0/zap-idf.bin
# Debug mode to test setup
uv run flasher.py --debug
Available Options
--list-ports— Show available serial ports--chip esp32c3— Force chip type (usually auto-detected)--verify-flash— Verify flash after writing--timeout 30— Serial read timeout in seconds--output-base my_batch— Custom output file prefix--quiet— Minimal output for production use--erase— Perform flash erase before writing (slower but more reliable)
Flashing Workflow
- Connect ESP32-C3 device via USB to computer
- Monitor CSV file to verify information is being captured
- Watch terminal for "Device flashed successfully!" message
- Flash - Tool automatically erases (optional), flashes firmware, and resets
- Extract - Captures serial number and public key from device output
- Save - Appends results to CSV file
- Disconnect device and connect the next one
- Repeat until done (Ctrl+C to stop)
Output Files
The tool creates timestamped files:
CSV File: flash_results_YYYYMMDD_HHMMSS.csv
- Columns:
ecc_serial,mac_eth0,mac_wlan0,helium_public_key,full_public_key - Ready for import into spreadsheets
- Send completed CSV file to provisioning team
JSON File: flash_results_YYYYMMDD_HHMMSS.json
- Detailed per-device information including full serial output
Example CSV Output
ecc_serial,mac_eth0,mac_wlan0,helium_public_key,full_public_key
zap-000058b868e385a0,,,,1d28faa8df6ed0b194839503c49c74aeff710825d45f7f4f8eb328963b9a6634...
zap-0000c4458290a994,,,,df592f4cbd88f2aab7abad0c750cad0b822dc28bd649b6450d3e40668ced4015...
Performance
- Fast mode (default): ~15-20 seconds per device
- With erase: ~25-30 seconds per device
- Bottlenecks: Device boot time (~10s) and serial communication
Features
- 🚀 Fast: No flash erase by default (2-3x faster)
- 📁 Standalone: Works with binary files, no PlatformIO required
- 🔍 Auto-detection: Automatically finds binary files and serial ports
- 📊 Data extraction: Captures device serial numbers and public keys
- 📝 Output formats: CSV and JSON result files
- 🔄 Sequential processing: Flash multiple devices one by one
Troubleshooting
Permission Issues
macOS: No additional setup needed
Linux: Add user to dialout group
sudo usermod -aG dialout $USER
# Then logout and login again
Common Issues
Port busy
- Close other serial monitors, Arduino IDE, or PlatformIO terminals
Auto-detect fails
- Use
--port /dev/cu.usbmodem101to specify manually - Use
--list-portsto see available ports
No device output
- Try
--erasefor a clean flash - Check USB cable and connection
Wrong binary files
- Use
--debugto check file detection - Verify binary directory structure
Debug Commands
# Test setup without flashing
uv run flasher.py --debug
# Test device connection
uv run flasher.py --test-connection --port /dev/cu.usbmodem101
# List available ports
uv run flasher.py --list-ports
File Structure
zap-flasher/
├── flasher.py # Main script
├── pyproject.toml # uv project configuration
├── requirements.txt # Python dependencies
├── README.md # Documentation
├── c3_1_1_0/ # Firmware binaries
│ ├── bootloader.bin
│ ├── partition-table.bin
│ └── zap-idf.bin
└── flash_results_*.csv # Generated result files
Development
# Install in development mode
uv sync --dev
# Run tests (if any)
uv run pytest
# Format code
uv run black flasher.py
# Type checking
uv run mypy flasher.py
Next Steps
After flashing devices:
- Send CSV file to provisioning team
- See Packaging Guide for packaging instructions
Related Documentation
- Zap for Developers - Understanding the Zap platform
- Data Models - Device and DER hierarchy