Flashing Zap Firmware

Guide to 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

# 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:

c3_1_1_0/
├── bootloader.bin
├── partition-table.bin
└── zap-idf.bin

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

Available Options

OptionDescription
--list-portsShow available serial ports
--chip esp32c3Force chip type
--verify-flashVerify flash after writing
--timeout 30Serial read timeout (seconds)
--output-base my_batchCustom output file prefix
--quietMinimal output for production
--eraseFlash erase before writing

Flashing Workflow

  1. Connect ESP32-C3 device via USB
  2. Monitor CSV file to verify information capture
  3. Watch terminal for "Device flashed successfully!" message
  4. Flash - Tool erases (optional), flashes firmware, and resets
  5. Extract - Captures serial number and public key
  6. Save - Appends results to CSV file
  7. Disconnect device and connect next one
  8. Repeat until done (Ctrl+C to stop)

Output Files

CSV File: flash_results_YYYYMMDD_HHMMSS.csv

ecc_serial,mac_eth0,mac_wlan0,helium_public_key,full_public_key
zap-000058b868e385a0,,,,1d28faa8df6ed0b194839503c49c74aeff710825...
zap-0000c4458290a994,,,,df592f4cbd88f2aab7abad0c750cad0b822dc28b...

JSON File: flash_results_YYYYMMDD_HHMMSS.json

  • Detailed per-device information including full serial output

Performance

ModeTime per Device
Fast (default)~15-20 seconds
With erase~25-30 seconds

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: Finds binary files and serial ports
  • Data extraction: Captures 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

ProblemSolution
Port busyClose other serial monitors, Arduino IDE
Auto-detect failsUse --port to specify manually
No device outputTry --erase for clean flash
Wrong binary filesUse --debug to check file detection

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

Next Steps

After flashing devices:

  1. Send CSV file to provisioning team
  2. Package devices for shipping