Skip to content

`factory_core` Module Overview

factory_core is the application logic layer of the factory recovery firmware. It runs as a standalone ESP-IDF app from the dedicated factory flash partition — entirely separate from the main firmware and independent of LVGL. Its responsibilities are:

  • Present an interactive recovery menu on the display immediately after power-on in recovery mode.
  • Flash new firmware (esp3dfw.bin) or UI resources (ui_resources.bin) from an SD card to OTA partitions.
  • Switch the active boot partition (app0 / app1) and restart.
  • Restore the ESP32 OTA data sector from a backup written by the main firmware before it handed over to recovery.

The module is deliberately minimal: no heap-based UI framework, no background tasks, single app_main FreeRTOS task, static buffers throughout.


Factory_Application_&_Bootloader
└── factory_app (ESP32 boards) / factory_app_core (ESP32-S3 boards)
└── factory_core ◄── this module
├── factory_app_entry
├── factory_menu_system
├── factory_update_actions
│ ├── factory_update_actions_otadata
│ ├── factory_update_actions_sd_flash
│ └── factory_update_actions_dispatch
├── factory_visual_feedback
├── factory_snapshot
└── factory_input_dispatch

Support modules consumed by factory_core but outside it:

factory_graphics · factory_buttons · factory_touch
factory_encoder · factory_buzzer · factory_sdcard
factory_lcd_drivers · factory_logging

Board BSP

(LCD driver, GPIO)

factory_graphics

(gfx.c - raw pixel layer)

factory_buttons

factory_encoder

factory_touch

factory_buzzer

factory_sdcard

sdcard_mount/unmount

factory_app_entry

app_main()

factory_menu_system

draw_menu, menu_move

factory_update_actions

action_sd_update

restore_otadata_from_backup

factory_visual_feedback

draw_progress, draw_result

factory_snapshot

snapshot_check

factory_input_dispatch

dispatch_button

touch_hint_hit_test

SD Card / MenuButtons/Encoder/Touch/BuzzerBoard LCD Driveresp_flash OTA APIapp_mainFreeRTOSSD Card / MenuButtons/Encoder/Touch/BuzzerBoard LCD Driveresp_flash OTA APIapp_mainFreeRTOSapp_main() invokedfactory_log_silence_sd_stack()restore_otadata_from_backup()<board>_init() + backlight ONgfx_init()buttons_init(), encoder_init(), touch_init()buzzer_init()esp_partition_find_first("app1") → has_app1 flagprobe_sd_files()draw_menu()enter infinite event loop

Yes

No

delta

0

BTN_1/2/3

none

new press

vbtn

no press

Loop

ENABLE_SNAPSHOT?

snapshot_check

GPIO0 debounce

encoder_read

menu_move ±1

button_wait_press 100ms

dispatch_button

touch_read

touch_hint_hit_test

draw_button_hint_pressed

buzzer_beep_short

80ms delay

draw_button_hints

dispatch_button vbtn

DONE

No

Yes

Yes

No

restore_otadata_from_backup

magic @ 0xB040

== 0xAA55AA55?

return false - skip

Read entries from 0xB000 and 0xB020

Both all 0xFF?

Erase backup sector 0xB000

Erase 0x10000 + 0x11000

Write entries back

return true


Sub-modulePathResponsibility
factory_app_entryboards/*/Factory/main/main.c::app_mainHardware init, OTA restore, menu bootstrap, infinite event loop
factory_menu_systemmain.c::draw_menu, menu_move, menu_select, …Render scrollable recovery menu; handle navigation; show status
factory_update_actionsmain.c::action_sd_update, action_sd_update_res, boot_partition, …Flash firmware/resources from SD; switch boot partition; OTA data restore
factory_visual_feedbackmain.c::draw_flashing_screen, draw_progress, draw_result, …Progress bar, flashing warning screen, success/failure banner, SD indicators
factory_snapshotmain.c::snapshot_check, snapshot_take, snap_find_next_numberDev tool: GPIO0 triggered full-screen raw RGB565 capture to SD (compile-time opt-in)
factory_input_dispatchmain.c::dispatch_button, touch_hint_hit_testNormalize encoder / physical button / touchscreen into button_id_t; route to menu or update actions

The module is duplicated per board. All boards share identical logic; differences are limited to LCD driver, screen dimensions, and IO expander initialization.

BoardDisplayBusSpecial
esp32_2432s028rILI9341SPI—
esp32_3248s035c/rST7796SPI—
esp32s3_4827s043cILI9485SPI—
esp32s3_8048s043c/050c/070cST7262RGB—
esp32s3_8048_touch_lcd_7ST7262RGBCH422G IO expander for SD_CS
esp32s3_bzm_tft35_gt911ST7796SPI—
esp32s3_hmi43v3RM68120I80—
esp32s3_zx3d50ce02s_usrc_4832ST7796I80—
pibot_pendant_v1_0ILI9341SPIPhysical buttons + encoder + potentiometer

Key Constants (all boards, must match esp444.cpp)

Section titled “Key Constants (all boards, must match esp444.cpp)”
ConstantValueDescription
OTADATA_OFFSET0x10000Live OTA data partition address
OTADATA_BACKUP_OFFSET0xB000Pre-partition-table backup sector
BACKUP_MAGIC0xAA55AA55Validates a real backup exists
FW_FILENAME/sdcard/esp3dfw.binFirmware binary input
RES_FILENAME/sdcard/ui_resources.binUI resources binary input

CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED=y is required in the factory sdkconfig because the backup sector at 0xB000 lies below the first partition table entry.


DocumentTopic
docs/Factory/factory_app_technical_doc.mdFactory app design, bootloader integration
docs/features/feature_resource_matrix.mdPartition layout and OTA slot strategy
docs/architecture/display_drivers.mdSPI / I80 / RGB driver architecture, orientation/rotation
docs/guides/esp32_memory_constraints.mdHeap constraints informing the static-buffer approach
docs/hardware/pibot-cnc-pendant-hardware-documentation.mdPhysical button and encoder wiring for pibot_pendant_v1_0