Skip to content

ESP32-S3 BZM TFT35 GT911 — Factory App Flash Tools

ESP32-S3 BZM TFT35 GT911 — Factory App Flash Tools

Section titled “ESP32-S3 BZM TFT35 GT911 — Factory App Flash Tools”

Flash-tools sub-module of the esp32s3_bzm_tft35_gt911 factory application.
Two Python scripts handle every production and development flashing workflow for this board: a full-featured multi-mode orchestrator (flash_all.py) and a focused single-partition utility (flash_factory.py).


  1. Purpose and Scope
  2. Module Architecture
  3. Script Reference
  4. Flash Mode Reference
  5. ESP32-S3 Flash Memory Layout
  6. Port and Offset Auto-Detection
  7. Data Flow
  8. Dependencies
  9. Usage Examples
  10. Cross-Board Consistency
  11. Related Modules

The flash-tools sub-module provides host-side Python scripts used at production time and during firmware development to program the ESP32-S3 BZM TFT35 GT911 board over USB-UART.

The two scripts cover three distinct lifecycle phases:

PhaseScriptWhat is written to flash
Initial provisioningflash_all.py --recoveryCustom bootloader + partition table + factory recovery app
Complete re-flashflash_all.py --full --fw <bin>Bootloader + partition table + factory recovery app + main firmware
Firmware update (dev)flash_all.py --fw <bin>Main firmware binary only (app0 slot)
Factory-only re-flashflash_factory.pyFactory recovery partition only

Both scripts rely on esptool (invoked as python -m esptool) and auto-detect the serial port and factory-partition offset where possible, requiring no hand-crafted commands in the common case.


2.1 Position in the Factory App Module Tree

Section titled “2.1 Position in the Factory App Module Tree”

esp32s3_bzm_tft35_gt911_factory_app

(parent module)

esp32s3_bzm_tft35_gt911_factory_app_display

ST7796 driver · GFX renderer

esp32s3_bzm_tft35_gt911_factory_app_input

Buttons · Encoder · GT911 touch

esp32s3_bzm_tft35_gt911_factory_app_recovery

Recovery UI · OTA restore · SD update

esp32s3_bzm_tft35_gt911_factory_app_flash_tools

flash_all.py · flash_factory.py

esp32s3_bzm_tft35_gt911_build

build_one.py · common.py · variants.py

esp32s3_bzm_tft35_gt911_bsp

board_init · LVGL flush · touch callbacks

ESP32-S3 Flash (8 MB)

Python Libraries

Host Machine (Python 3)

reads

reads

reads

reads

reads

reads

reads

invokes

invokes

uses

uses

USB-UART 460800 baud

flash_all.py

flash_factory.py

partitions*.csv

installer/bootloader.bin

installer/partitions.bin

installer/factory.bin

firmware.bin

esptool (pip)

pyserial

0x001000 - Bootloader

0x00C000 - Partition table

0x020000 - app0 (main firmware)

0x7A0000 - factory (recovery)


3.1 flash_all.py — Multi-Mode Orchestrator

Section titled “3.1 flash_all.py — Multi-Mode Orchestrator”

Location: boards/esp32s3_bzm_tft35_gt911/Factory/tools/flash_all.py

The primary flashing tool, covering all deployment scenarios through mutually exclusive modes.

flash_all.py [--port PORT] [--baud BAUD] <MODE> [--fw-file FILE]
Modes (mutually exclusive, one required):
--recovery Bootloader + partitions + factory
--full Bootloader + partitions + factory + firmware
--fw FILE / --firmware FILE Firmware only (app0)
ArgumentDefaultDescription
--port / -pauto-detectSerial port (e.g., /dev/ttyUSB0, COM3)
--baud460800UART baud rate passed to esptool
--recovery—Production initial-setup mode
--full—Full re-flash mode; requires --fw-file or --fw
--fw FILE / --firmware FILE—Dev firmware-only mode
--fw-file FILE—Firmware binary path (alternative form for --full)
FunctionPurpose
main()Argument parsing, mode dispatch, orchestration
find_factory_offset()Parses partitions*.csv for the factory entry offset
find_esp32_port()Scans serial ports; matches CP210x, CH340, CH910, FTDI descriptors
check_file(path, name)Validates existence of a required binary and prints its size
flash(port, baud, files)Builds and runs the esptool write_flash command
BAUD_RATE = "460800"
BOOTLOADER_BIN = "installer/bootloader.bin"
PARTITIONS_BIN = "installer/partitions.bin"
FACTORY_BIN = "installer/factory.bin"
BOOTLOADER_OFFSET = "0x1000"
PARTITIONS_OFFSET = "0xC000"
APP0_OFFSET = "0x20000"

The factory partition offset is not hardcoded for the flash command; it is always resolved by find_factory_offset() at runtime, with a fallback of 0x7A0000 for 8 MB flash layouts.


3.2 flash_factory.py — Factory-Partition Utility

Section titled “3.2 flash_factory.py — Factory-Partition Utility”

Location: boards/esp32s3_bzm_tft35_gt911/Factory/tools/flash_factory.py

A focused single-purpose script that flashes only the factory (recovery) partition. Intended for:

  • Re-programming the recovery partition without disturbing the main firmware.
  • Production-line workflows where only the recovery image has been updated.
flash_factory.py [--port PORT] [--bin FILE] [--baud BAUD] [--offset OFFSET]
ArgumentDefaultDescription
--port / -pauto-detectSerial port
--bin / -binstaller/factory.binBinary to flash
--baud460800UART baud rate
--offset / -oauto-detect from CSVFactory partition offset
FunctionPurpose
main()Argument parsing, file validation, esptool invocation
find_factory_offset()Searches partitions*.csv and boards/*/partitions*.csv for the factory sub-type
find_esp32_port()Same port-detection heuristic as flash_all.py

Difference from flash_all.py: When find_factory_offset() finds no CSV match, flash_factory.py returns None and exits with an actionable error, requiring the user to pass --offset manually. flash_all.py silently falls back to 0x7A0000.


No

Yes

--recovery

OK

--full

OK

--fw FILE

OK

Fail

Fail

Fail

python flash_all.py

Parse arguments

Port specified?

Auto-detect USB-UART port

Mode?

find_factory_offset

Verify:

bootloader.bin

partitions.bin

factory.bin

Flash:

0x1000 bootloader

0xC000 partitions

auto factory

find_factory_offset

Verify:

bootloader.bin

partitions.bin

factory.bin

firmware.bin

Flash:

0x1000 bootloader

0xC000 partitions

auto factory

0x20000 firmware

Verify:

firmware.bin

Flash:

0x20000 firmware

Exit 1

Done / Exit 0


The address constants used by these scripts correspond to the fixed partition layout agreed between the bootloader and the partition CSV.

┌──────────────────────────────────────────────────────────────┐
│ Address Region Script constant │
├──────────────────────────────────────────────────────────────┤
│ 0x000000 (unused by these scripts) │
│ 0x001000 Bootloader ← BOOTLOADER_OFFSET │
│ 0x00C000 Partition table ← PARTITIONS_OFFSET │
│ 0x010000 OTA data (otadata) │
│ 0x020000 app0 / main firmware ← APP0_OFFSET │
│ ... Filesystem partitions │
│ 0x7A0000 factory / recovery ← find_factory_offset() │
│ (8 MB layout default) │
└──────────────────────────────────────────────────────────────┘

Note: The factory partition offset is read dynamically from partitions*.csv at runtime. The value 0x7A0000 is the fallback for an 8 MB flash layout. Always verify the correct offset against the CSV shipped with the build before using --offset overrides, especially if the board uses a 4 MB flash (typical fallback: 0x320000).


Both scripts share the same heuristic: iterate serial.tools.list_ports.comports() and match against known ESP32 USB-UART chip descriptors.

Matched keywords: CP210, CH340, CH910, FTDI, USB Serial, USB-SERIAL

Yes

No

No more ports

Yes

No

list_ports.comports

Description matches

known ESP32 chip?

Return port.device

Next port

Any port listed?

Return ports[0].device

(first available fallback)

Exit 1:

no port detected

Use --port to specify

find_factory_offset() walks CSV files matched by glob patterns, parses each non-comment line as a comma-separated partition descriptor, and returns the offset field of the first entry whose sub-type column equals factory (case-insensitive).

Search patterns (in order):

  1. partitions*.csv
  2. boards/*/partitions*.csv
  3. boards/*/*/partitions*.csv (flash_factory.py only)

Yes

No

Yes

No

No match in any file

Glob patterns:

partitions*.csv

boards/*/partitions*.csv

Iterate matching files

Open CSV file

Read line

Comment or blank?

Split by comma → parts[]

parts[2].lower()

== 'factory'?

Return parts[3]

(offset string)

flash_all.py → '0x7A0000' (fallback)

flash_factory.py → None → Exit 1


7.1 End-to-End Flash Sequence (--full mode)

Section titled “7.1 End-to-End Flash Sequence (--full mode)”
ESP32-S3 Boardesptoolpartitions*.csvinstaller/ directoryflash_all.pyDeveloper / CIESP32-S3 Boardesptoolpartitions*.csvinstaller/ directoryflash_all.pyDeveloper / CIpython flash_all.py --full --fw firmware.binParse arguments & validate modeAuto-detect serial portfind_factory_offset()offset (e.g. "0x7A0000")check_file(bootloader.bin)check_file(partitions.bin)check_file(factory.bin)check_file(firmware.bin)All files verifiedesptool --chip esp32 --port <port> --baud 460800write_flash 0x1000 bootloader.bin0xC000 partitions.bin0x7A0000 factory.bin 0x20000 firmware.binUSB-UART @ 460800 baudFlash ACKsubprocess exit 0"Flash successful!"

7.2 Factory-Only Sequence (flash_factory.py)

Section titled “7.2 Factory-Only Sequence (flash_factory.py)”
ESP32-S3 Boardesptoolpartitions*.csvflash_factory.pyOperatorESP32-S3 Boardesptoolpartitions*.csvflash_factory.pyOperatorpython flash_factory.pyAuto-detect serial portfind_factory_offset()offsetVerify factory.bin exists & print sizeesptool --port <port> --baud 460800write_flash <offset> factory.binUSB-UART @ 460800 baudFlash ACKsubprocess exit 0"Factory partition flashed successfully!"
DependencyVersionPurpose
Python 3≥ 3.7Script interpreter
esptool≥ 4.xFlash write via python -m esptool
pyserial≥ 3.xSerial port enumeration (serial.tools.list_ports)

Install with:

Terminal window
pip install esptool pyserial

All binary inputs are expected in the installer/ directory relative to the script location unless overridden via CLI.

FileProduced byDescription
installer/bootloader.binESP-IDF factory app buildCustom bootloader with OTA-data backup hooks
installer/partitions.binESP-IDF factory app buildCompiled binary partition table
installer/factory.binESP-IDF factory app buildRecovery / factory application binary
<firmware>.binMain pendant firmware buildMain pendant application; path supplied by caller

The installer/ directory and its binaries are generated by the build pipeline described in esp32s3_bzm_tft35_gt911_build.md.

Both scripts search for partitions*.csv to resolve the factory partition offset dynamically. This CSV is part of the board’s ESP-IDF project and is also consumed by the build system. No CSV is required at flash time if --offset is supplied manually.


9.1 First-Time Board Provisioning (Recovery Mode)

Section titled “9.1 First-Time Board Provisioning (Recovery Mode)”

Programs the bootloader, partition table, and factory recovery app. The main firmware slot is left unprogrammed; the board will boot into the recovery UI on first power-up.

Terminal window
cd boards/esp32s3_bzm_tft35_gt911/Factory/tools
# Auto-detect port
python flash_all.py --recovery
# Specify port explicitly (Linux / macOS)
python flash_all.py --recovery --port /dev/ttyUSB0
# Specify port explicitly (Windows)
python flash_all.py --recovery --port COM3

Programs all partitions including the main firmware. Used for production final programming or complete board restore.

Terminal window
# Using --fw-file
python flash_all.py --full --fw-file ../../build/esp32s3_bzm_tft35_gt911.bin
# Using short alias --fw with explicit port
python flash_all.py --full --fw ../../build/esp32s3_bzm_tft35_gt911.bin --port COM4

Flashes only the main firmware binary to the app0 slot at 0x20000. Fastest iteration path during development; leaves the factory partition, partition table, and bootloader intact.

Terminal window
python flash_all.py --fw build/output/firmware.bin

Re-programs just the recovery/factory partition — for example after an update to the recovery UI or factory app behavior.

Terminal window
cd boards/esp32s3_bzm_tft35_gt911/Factory/tools
# Auto-detect everything
python flash_factory.py
# Override offset for a non-standard layout
python flash_factory.py --offset 0x320000
# Specify a custom binary and port
python flash_factory.py --bin /path/to/new_factory.bin --port COM5

When USB adapters or cables are unreliable at 460800 baud:

Terminal window
python flash_all.py --recovery --baud 115200
python flash_factory.py --baud 230400

The flash-tool pattern (flash_all.py + flash_factory.py) is replicated identically across every board variant in this repository. All variants share the same function signatures, chip-detection heuristics, and installer/ directory conventions.

Shared Flash Tool Pattern

flash_all.py + flash_factory.py

esp32_2432s028r/Factory/tools/

esp32_3248s035c/Factory/tools/

esp32_3248s035r/Factory/tools/

esp32s3_4827s043c/Factory/tools/

esp32s3_8048s043c/Factory/tools/

esp32s3_8048s050c/Factory/tools/

esp32s3_8048s070c/Factory/tools/

esp32s3_8048_touch_lcd_7/Factory/tools/

esp32s3_hmi43v3/Factory/tools/

esp32s3_zx3d50ce02s_usrc_4832/Factory/tools/

pibot_pendant_v1_0/Factory/tools/

esp32s3_bzm_tft35_gt911/Factory/tools/

← this module

Board-specific differences are limited to:

  • Factory partition offset — resolved from each board’s own partitions*.csv.
  • Chip target string — flash_all.py passes --chip esp32; esptool’s auto-detect handles ESP32-S3 transparently without a board-specific override.

ModuleDocumentationRelationship
Factory recovery applicationesp32s3_bzm_tft35_gt911_factory_app_recovery.mdProduces installer/factory.bin that these scripts flash; implements the OTA restore and SD-update UI
Factory display subsystemesp32s3_bzm_tft35_gt911_factory_app_display.mdST7796 SPI display driver and GFX renderer linked into factory.bin
Factory input subsystemesp32s3_bzm_tft35_gt911_factory_app_input.mdButtons, rotary encoder, and GT911 touch linked into factory.bin
Board build systemesp32s3_bzm_tft35_gt911_build.mdGenerates all installer/ binaries consumed by these scripts
Board support packageesp32s3_bzm_tft35_gt911_bsp.mdBSP used by the main firmware binary that --fw / --full modes write to app0
Factory bootloaderfactory_bootloader.mdCustom bootloader written at 0x1000; implements OTA-data backup triggered by button press at boot
General tools guidetools.mdProject-wide tools reference including flash helpers, WebSocket test, and bridge scripts
Factory documentationdocs/Factory/High-level factory process and provisioning workflow documentation