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
137 changes: 137 additions & 0 deletions docs/source/reference/package-apis/drivers/esp32.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# ESP32 driver

`jumpstarter-driver-esp32` provides functionality for flashing, monitoring, and controlling ESP32 devices using esptool and serial communication.

## Installation

```{code-block} console
:substitutions:
$ pip3 install --extra-index-url {{index_url}} jumpstarter-driver-esp32
```

## Configuration

Example configuration:

```yaml
export:
esp32:
type: jumpstarter_driver_esp32.driver.ESP32
config:
port: "/dev/ttyUSB0"
baudrate: 115200
chip: "esp32"
# Optional GPIO pins for hardware control
# reset_pin: 2
# boot_pin: 0
```

### Config parameters

| Parameter | Description | Type | Required | Default |
| ------------- | --------------------------------------------------------------------- | ---- | -------- | ------- |
| port | The serial port to connect to the ESP32 | str | yes | |
| baudrate | The baudrate for serial communication | int | no | 115200 |
| chip | The ESP32 chip type (esp32, esp32s2, esp32s3, esp32c3, etc.) | str | no | esp32 |
| reset_pin | GPIO pin number for hardware reset (if connected) | int | no | null |
| boot_pin | GPIO pin number for boot mode control (if connected) | int | no | null |
| check_present | Check if the serial port exists during exporter initialization | bool | no | True |

## API Reference

```{eval-rst}
.. autoclass:: jumpstarter_driver_esp32.client.ESP32Client()
:members: chip_info, reset, erase_flash, flash_firmware, flash_firmware_file, read_flash, enter_bootloader
```

### CLI

The ESP32 driver client comes with a CLI tool that can be used to interact with ESP32 devices:

```
jumpstarter ⚡ local ➤ j esp32
Usage: j esp32 [OPTIONS] COMMAND [ARGS]...

ESP32 client

Options:
--help Show this message and exit.

Commands:
bootloader Enter bootloader mode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯 awesome!

chip-id Get chip ID information
erase Erase the entire flash
flash Flash firmware to the device
info Get device information
read-flash Read flash contents
reset Reset the device
```

## Examples

### Getting device information

```{testcode}
:skipif: True
info = esp32.chip_info()
print(f"Connected to {info['chip_revision']}")
print(f"MAC Address: {info['mac_address']}")
print(f"Chip ID: {info['chip_id']}")
```

### Flashing firmware

```{testcode}
:skipif: True
# Flash firmware from a local file
result = esp32.flash_firmware_file("firmware.bin", address=0x1000)
print(result)
```

### Reading flash contents

```{testcode}
:skipif: True
# Read 1024 bytes from address 0x0
data = esp32.read_flash(address=0x0, size=1024)
print(f"Read {len(data)} bytes from flash")
```

### Device control

```{testcode}
:skipif: True
# Reset the device
result = esp32.reset()

# Enter bootloader mode
result = esp32.enter_bootloader()

# Erase entire flash
result = esp32.erase_flash()
```

### CLI Examples

```{code-block} console
# Get device information
$ j esp32 info

# Flash firmware to default app partition (0x10000)
$ j esp32 flash firmware.bin

# Flash firmware to specific address
$ j esp32 flash firmware.bin --address 0x1000

Comment on lines +116 to +125
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Double-check the default flash address matches the driver constant

This page states 0x10000 as the default (Line 125) and shows an explicit 0x1000 example (Line 129). Ensure the driver’s default matches what we document as “default”.


🏁 Script executed:

#!/bin/bash
# Verify any hardcoded/default flash address in code and docs
rg -nI -C2 -S -e '0x1000\b|0x10000\b|default.*address' \
  packages/jumpstarter-driver-esp32 jumpstarter docs packages | sed -n '1,200p'

Length of output: 5104


Align default flash address between docs and driver (0x1000 vs 0x10000)

Docs declare default 0x10000 (docs/source/reference/package-apis/drivers/esp32.md, ~lines 123–130) but the codebase contains conflicting defaults: an async implementation uses "async def flash_firmware(self, src: str, address: int = 0x1000)" while other functions/CLI/fallbacks use 0x10000 (e.g., "def flash_firmware(..., address: int = 0x10000)", "flash_firmware_file(..., address: int = 0x10000)", CLI --address default "0x10000", _parse_size fallback 0x10000). Decide the correct default, update the discrepant implementation or the docs to match, and centralize the value into a single constant used by code, CLI, and docs.

🤖 Prompt for AI Agents
In docs/source/reference/package-apis/drivers/esp32.md around lines 121–130 the
README shows a default flash address of 0x10000 but the codebase contains mixed
defaults (some functions use 0x1000 and others 0x10000). Pick the correct
canonical default (use 0x10000 to match CLI and most implementations unless
product/team decides otherwise), update the async flash_firmware signature to
use that value (or update the docs if you choose 0x1000), and centralize the
default by adding a single constant (e.g., ESP32_DEFAULT_FLASH_ADDRESS) in the
driver module used by all flash_firmware variants, flash_firmware_file, CLI
default parsing, and _parse_size fallback; then update docs to reference that
constant/default so code and docs stay consistent.

# Read flash contents
$ j esp32 read-flash 0x0 1024

# Save flash contents to file
$ j esp32 read-flash 0x0 1024 --output flash_dump.bin

# Reset the device
$ j esp32 reset

# Erase the entire flash
$ j esp32 erase
```
2 changes: 2 additions & 0 deletions docs/source/reference/package-apis/drivers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Drivers for debugging and programming devices:
* **[U-Boot](uboot.md)** (`jumpstarter-driver-uboot`) - Universal Bootloader
interface
* **[RideSX](ridesx.md)** (`jumpstarter-driver-ridesx`) - Flashing and power management for Qualcomm RideSX devices
* **[ESP32](esp32.md)** (`jumpstarter-driver-esp32`) - ESP32 development board support

### Utility Drivers

Expand All @@ -86,6 +87,7 @@ can.md
corellium.md
dutlink.md
energenie.md
esp32.md
flashers.md
http.md
http-power.md
Expand Down
1 change: 1 addition & 0 deletions packages/jumpstarter-all/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dependencies = [
"jumpstarter-driver-composite",
"jumpstarter-driver-corellium",
"jumpstarter-driver-dutlink",
"jumpstarter-driver-esp32",
"jumpstarter-driver-flashers",
"jumpstarter-driver-http",
"jumpstarter-driver-network",
Expand Down
51 changes: 51 additions & 0 deletions packages/jumpstarter-driver-esp32/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# ESP32 driver

`jumpstarter-driver-esp32` provides functionality for flashing, monitoring, and controlling ESP32 devices using esptool and serial communication.

## Installation

```{code-block} console
:substitutions:
$ pip3 install --extra-index-url {{index_url}} jumpstarter-driver-esp32
```

## Configuration

Example configuration:

```yaml
export:
esp32:
type: jumpstarter_driver_esp32.driver.ESP32
config:
port: "/dev/ttyUSB0"
baudrate: 115200
chip: "esp32"
serial:
type: jumpstarter_driver_pyserial.driver.PySerial
config:
url: "/dev/ttyUSB0"
baudrate: 115200
```

### Config parameters

| Parameter | Description | Type | Required | Default |
| ------------ | --------------------------------------------------------------------- | ---- | -------- | ----------- |
| port | The serial port to connect to the ESP32 | str | yes | |
| baudrate | The baudrate for serial communication | int | no | 115200 |
| chip | The ESP32 chip type (esp32, esp32s2, esp32s3, esp32c3, etc.) | str | no | esp32 |
| reset_pin | GPIO pin number for hardware reset (if connected) | int | no | null |
| boot_pin | GPIO pin number for boot mode control (if connected) | int | no | null |

## API Reference

```{autoclass} jumpstarter_driver_esp32.driver.ESP32
:members:
```

# Examples

```shell
$ j esp32 flash ESP32_GENERIC-20250911-v1.26.1.bin -a 0x1000
```
15 changes: 15 additions & 0 deletions packages/jumpstarter-driver-esp32/examples/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env python3
from jumpstarter.common.utils import env


def main():
with env() as client:
esp32 = client.esp32

info = esp32.chip_info()
print(f"Connected to {info['chip_revision']}")
print(f"MAC Address: {info['mac_address']}")


if __name__ == "__main__":
main()
15 changes: 15 additions & 0 deletions packages/jumpstarter-driver-esp32/examples/exporter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: jumpstarter.dev/v1alpha1
kind: ExporterConfig
metadata:
name: esp32
spec:
export:
esp32:
type: jumpstarter_driver_esp32.driver.ESP32
config:
port: "/dev/ttyUSB0"
baudrate: 115200
chip: "esp32"
# Optional GPIO pins for hardware control
# reset_pin: 2
# boot_pin: 0
Empty file.
Loading