chore(build): scaffold ESP-IDF project for BOX-3
Context: New firmware "Lisael Box" targeting the ESP32-S3-BOX-3 (8MB PSRAM, 16MB flash, LCD+touch, ES8311 codec, microSD). Establish the ESP-IDF 5.4/5.5 build skeleton before adding modules. Approach: Standard IDF project layout with a single big factory app (4MB) since the binary links the esp-box BSP, LVGL 9 and ESP-ADF. ESP-ADF is not a managed component, so the top-level CMake injects $ADF_PATH/components via EXTRA_COMPONENT_DIRS and warns clearly when ADF_PATH is unset. Changes: - top-level CMakeLists with ADF_PATH wiring - partitions.csv (16MB: factory 4MB + FAT storage) - sdkconfig.defaults (+ .esp32s3: octal PSRAM, 16MB, 240MHz, LVGL/PSRAM) - main/CMakeLists, idf_component.yml (esp-box-3 ^3.2, built-in json) - Kconfig.projbuild (Wi-Fi, weather lat/lon, child volume cap) - lisael_config.h shared constants, .gitignore Impact: Buildable skeleton; modules added in following commits. Not yet compiled (no IDF/ADF/board available) - see README.
This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
|||||||
|
# ESP-IDF build artifacts
|
||||||
|
/build/
|
||||||
|
sdkconfig
|
||||||
|
sdkconfig.old
|
||||||
|
|
||||||
|
# Managed components are fetched by the component manager
|
||||||
|
/managed_components/
|
||||||
|
**/managed_components/
|
||||||
|
dependencies.lock
|
||||||
|
|
||||||
|
# Editor / OS
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Python venv occasionally created by tooling
|
||||||
|
.venv/
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Lisael Box — top-level project CMake for ESP-IDF 5.4/5.5
|
||||||
|
# Target: ESP32-S3-BOX-3
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
# --- ESP-ADF integration -----------------------------------------------------
|
||||||
|
# ESP-ADF is NOT a managed component: it is installed separately and exposed via
|
||||||
|
# the ADF_PATH environment variable (see README "Installer ESP-ADF").
|
||||||
|
# We add its component tree to EXTRA_COMPONENT_DIRS so that audio_pipeline,
|
||||||
|
# http_stream, esp_decoder, fatfs_stream, i2s_stream etc. become available.
|
||||||
|
#
|
||||||
|
# If ADF_PATH is unset the project still configures, but the audio modules that
|
||||||
|
# need ADF will fail to link. We surface a clear message instead of a cryptic
|
||||||
|
# "component not found" error.
|
||||||
|
if(DEFINED ENV{ADF_PATH})
|
||||||
|
set(ADF_COMPONENTS "$ENV{ADF_PATH}/components")
|
||||||
|
if(EXISTS "${ADF_COMPONENTS}")
|
||||||
|
list(APPEND EXTRA_COMPONENT_DIRS "${ADF_COMPONENTS}")
|
||||||
|
message(STATUS "Lisael Box: ESP-ADF components from ${ADF_COMPONENTS}")
|
||||||
|
else()
|
||||||
|
message(WARNING "Lisael Box: ADF_PATH set but ${ADF_COMPONENTS} not found")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(WARNING
|
||||||
|
"Lisael Box: ADF_PATH not set. Audio streaming (webradio / SD playback) "
|
||||||
|
"will not link. Run '. $ADF_PATH/export.sh' or export ADF_PATH. "
|
||||||
|
"See README.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(lisael_box)
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
# Lisael Box — main component.
|
||||||
|
#
|
||||||
|
# ESP-ADF components (audio_pipeline, esp-adf-libs, audio_stream, esp_decoder,
|
||||||
|
# audio_board ...) are resolved at configure time from ADF_PATH via
|
||||||
|
# EXTRA_COMPONENT_DIRS (top-level CMakeLists.txt). They are listed in REQUIRES
|
||||||
|
# so the linker pulls them in; if ADF_PATH is missing the build fails loudly
|
||||||
|
# in the audio sources only.
|
||||||
|
#
|
||||||
|
# The audio REQUIRES are guarded: when ADF is absent we still let the UI / net
|
||||||
|
# layers build for inspection. Set LISAEL_WITH_ADF=OFF to compile without audio
|
||||||
|
# (UI/clock/breathing only) for quick syntax checks on a machine without ADF.
|
||||||
|
|
||||||
|
set(srcs
|
||||||
|
"app_main.c"
|
||||||
|
"net/wifi.c"
|
||||||
|
"net/sntp_time.c"
|
||||||
|
"net/weather.c"
|
||||||
|
"ui/ui.c"
|
||||||
|
"ui/fr_date.c"
|
||||||
|
"ui/icons.c"
|
||||||
|
"modes/home.c"
|
||||||
|
"modes/radio.c"
|
||||||
|
"modes/soundbox.c"
|
||||||
|
"modes/calm.c"
|
||||||
|
"modes/clock.c"
|
||||||
|
"modes/games.c"
|
||||||
|
"audio/audio_player.c"
|
||||||
|
"audio/radio_pipeline.c"
|
||||||
|
"audio/sd_player.c"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(reqs
|
||||||
|
nvs_flash
|
||||||
|
esp_wifi
|
||||||
|
esp_event
|
||||||
|
esp_netif
|
||||||
|
esp-tls
|
||||||
|
esp_http_client
|
||||||
|
mbedtls # esp_crt_bundle_attach (CA bundle for HTTPS)
|
||||||
|
esp-box-3 # BSP: display, touch, codec, sdcard, sensors
|
||||||
|
json # IDF built-in cJSON component (provides cJSON.h)
|
||||||
|
fatfs
|
||||||
|
esp_driver_i2c
|
||||||
|
esp_driver_tsens # driver/temperature_sensor.h (internal die temp)
|
||||||
|
)
|
||||||
|
|
||||||
|
# ESP-ADF audio components. Names follow the ADF master component tree.
|
||||||
|
# Guarded so a no-ADF inspection build still configures.
|
||||||
|
if(DEFINED ENV{ADF_PATH})
|
||||||
|
list(APPEND reqs
|
||||||
|
audio_pipeline
|
||||||
|
audio_stream
|
||||||
|
esp-adf-libs
|
||||||
|
audio_sal
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
idf_component_register(
|
||||||
|
SRCS ${srcs}
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES ${reqs}
|
||||||
|
)
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
menu "Lisael Box configuration"
|
||||||
|
|
||||||
|
menu "Wi-Fi"
|
||||||
|
config LISAEL_WIFI_SSID
|
||||||
|
string "Wi-Fi SSID"
|
||||||
|
default "myssid"
|
||||||
|
help
|
||||||
|
SSID (network name) the box connects to at boot. Stored as a
|
||||||
|
build-time default; the runtime value can also be provisioned
|
||||||
|
into NVS later (see net/wifi.c).
|
||||||
|
|
||||||
|
config LISAEL_WIFI_PASSWORD
|
||||||
|
string "Wi-Fi password"
|
||||||
|
default "mypassword"
|
||||||
|
help
|
||||||
|
WPA2 passphrase for the SSID above. Leave the defaults and
|
||||||
|
override via NVS provisioning if you do not want creds in the
|
||||||
|
binary.
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
menu "Weather (open-meteo.com)"
|
||||||
|
config LISAEL_WEATHER_LAT
|
||||||
|
string "Default latitude"
|
||||||
|
default "48.8566"
|
||||||
|
help
|
||||||
|
Latitude used for the open-meteo forecast when none is stored
|
||||||
|
in NVS. Default is Paris, France.
|
||||||
|
|
||||||
|
config LISAEL_WEATHER_LON
|
||||||
|
string "Default longitude"
|
||||||
|
default "2.3522"
|
||||||
|
help
|
||||||
|
Longitude used for the open-meteo forecast when none is stored
|
||||||
|
in NVS. Default is Paris, France.
|
||||||
|
|
||||||
|
config LISAEL_WEATHER_CITY
|
||||||
|
string "City label"
|
||||||
|
default "Paris"
|
||||||
|
help
|
||||||
|
Human-readable city name shown on the home screen next to the
|
||||||
|
temperature.
|
||||||
|
|
||||||
|
config LISAEL_WEATHER_REFRESH_MIN
|
||||||
|
int "Refresh interval (minutes)"
|
||||||
|
range 5 180
|
||||||
|
default 30
|
||||||
|
help
|
||||||
|
How often the weather task re-fetches the forecast.
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
menu "Audio"
|
||||||
|
config LISAEL_VOLUME_MAX_PERCENT
|
||||||
|
int "Maximum volume (child cap, percent)"
|
||||||
|
range 10 100
|
||||||
|
default 60
|
||||||
|
help
|
||||||
|
Hard cap on output volume. The volume UI never lets the value
|
||||||
|
exceed this, to protect a child's hearing.
|
||||||
|
|
||||||
|
config LISAEL_VOLUME_DEFAULT_PERCENT
|
||||||
|
int "Default volume at boot (percent)"
|
||||||
|
range 5 100
|
||||||
|
default 35
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endmenu
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Managed component dependencies for Lisael Box.
|
||||||
|
# Fetched automatically into managed_components/ on `idf.py build`.
|
||||||
|
#
|
||||||
|
# NOTE: ESP-ADF is NOT listed here — it is not distributed via the component
|
||||||
|
# registry. It is installed separately and pulled in through ADF_PATH /
|
||||||
|
# EXTRA_COMPONENT_DIRS (see top-level CMakeLists.txt and README).
|
||||||
|
#
|
||||||
|
# Versions below reflect the esp-box-3 BSP v3.2.x line, which itself depends on
|
||||||
|
# LVGL 9.x, esp_lvgl_port ^2 and esp_codec_dev ~1.5. We let the BSP pin the
|
||||||
|
# exact transitive versions; we only state the top-level ones we use directly.
|
||||||
|
# Per repo supply-chain policy these should eventually be mirrored/pinned by
|
||||||
|
# hash against the audited baseline — TODO before any production build.
|
||||||
|
dependencies:
|
||||||
|
idf:
|
||||||
|
version: ">=5.4"
|
||||||
|
|
||||||
|
# Board support package for the ESP32-S3-BOX-3: display, touch, ES8311 codec,
|
||||||
|
# ES7210 mic, microSD, IMU, buttons. Pulls esp_lvgl_port, lvgl, esp_codec_dev,
|
||||||
|
# esp_lcd_ili9341, button, icm42670, aht30 transitively.
|
||||||
|
espressif/esp-box-3: "^3.2.0"
|
||||||
|
|
||||||
|
# JSON parsing (manifest.json, open-meteo replies) uses the cJSON shipped with
|
||||||
|
# ESP-IDF as the built-in "json" component — no managed dependency needed.
|
||||||
|
# (REQUIRES json in main/CMakeLists.txt.)
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// Lisael Box — shared compile-time configuration and small helpers.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
// --- Timezone (Europe/Paris with EU DST rules) ------------------------------
|
||||||
|
// CET-1CEST,M3.5.0,M10.5.0/3 : last Sunday of March 02:00 -> +1, last Sunday
|
||||||
|
// of October 03:00 -> back. Set with setenv("TZ", ...) + tzset() in sntp_time.c.
|
||||||
|
#define LISAEL_TZ "CET-1CEST,M3.5.0,M10.5.0/3"
|
||||||
|
|
||||||
|
// --- NVS namespace / keys ----------------------------------------------------
|
||||||
|
#define LISAEL_NVS_NS "lisael"
|
||||||
|
#define LISAEL_NVS_WIFI_SSID "wifi_ssid"
|
||||||
|
#define LISAEL_NVS_WIFI_PASS "wifi_pass"
|
||||||
|
#define LISAEL_NVS_LAT "lat"
|
||||||
|
#define LISAEL_NVS_LON "lon"
|
||||||
|
#define LISAEL_NVS_VOLUME "volume"
|
||||||
|
|
||||||
|
// --- Audio volume (child-safe) ----------------------------------------------
|
||||||
|
#define LISAEL_VOLUME_MAX CONFIG_LISAEL_VOLUME_MAX_PERCENT
|
||||||
|
#define LISAEL_VOLUME_DEFAULT CONFIG_LISAEL_VOLUME_DEFAULT_PERCENT
|
||||||
|
|
||||||
|
// --- Weather -----------------------------------------------------------------
|
||||||
|
#define LISAEL_WEATHER_REFRESH_MIN CONFIG_LISAEL_WEATHER_REFRESH_MIN
|
||||||
|
|
||||||
|
// --- Display geometry (ESP32-S3-BOX-3 LCD) ----------------------------------
|
||||||
|
#define LISAEL_SCREEN_W 320
|
||||||
|
#define LISAEL_SCREEN_H 240
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Lisael Box partition table — ESP32-S3-BOX-3 (16 MB flash)
|
||||||
|
#
|
||||||
|
# Single factory app, deliberately large (4 MB) because the firmware links
|
||||||
|
# ESP-ADF (audio pipeline + decoders), LVGL 9 and the esp-box BSP, which is a
|
||||||
|
# big binary. No OTA partitions for now (kept simple); switch to a dual-OTA
|
||||||
|
# layout later if remote updates are needed — there is plenty of headroom.
|
||||||
|
#
|
||||||
|
# The "sounds" / audio assets live on the physical microSD card mounted by the
|
||||||
|
# BSP (FATFS), NOT in flash — so no large data partition is needed here.
|
||||||
|
#
|
||||||
|
# All offsets/sizes aligned to 0x1000 (4 KB). Bootloader + partition table sit
|
||||||
|
# below 0x10000.
|
||||||
|
#
|
||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
|
phy_init, data, phy, 0xf000, 0x1000,
|
||||||
|
factory, app, factory, 0x10000, 0x400000,
|
||||||
|
storage, data, fat, 0x410000, 0x100000,
|
||||||
|
Can't render this file because it contains an unexpected character in line 8 and column 7.
|
@@ -0,0 +1,28 @@
|
|||||||
|
# Lisael Box — committed defaults (target-independent).
|
||||||
|
# Target-specific overrides live in sdkconfig.defaults.esp32s3.
|
||||||
|
# Regenerate sdkconfig with: idf.py set-target esp32s3 && idf.py reconfigure
|
||||||
|
|
||||||
|
# --- Partition table ---------------------------------------------------------
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
|
|
||||||
|
# --- Logging / build ---------------------------------------------------------
|
||||||
|
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_PERF=y
|
||||||
|
|
||||||
|
# --- FreeRTOS ----------------------------------------------------------------
|
||||||
|
# 1 kHz tick gives smoother LVGL animations (bubble breathing, transitions).
|
||||||
|
CONFIG_FREERTOS_HZ=1000
|
||||||
|
|
||||||
|
# --- mbedTLS / TLS -----------------------------------------------------------
|
||||||
|
# open-meteo.com is HTTPS; webradio streams may be HTTPS too. Use the global
|
||||||
|
# CA store bundle so we don't have to embed individual certs.
|
||||||
|
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y
|
||||||
|
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y
|
||||||
|
|
||||||
|
# --- HTTP client -------------------------------------------------------------
|
||||||
|
CONFIG_ESP_TLS_INSECURE=n
|
||||||
|
|
||||||
|
# --- esp-box BSP -------------------------------------------------------------
|
||||||
|
# SD card mount point used throughout the firmware (see audio/sd_player.c).
|
||||||
|
CONFIG_BSP_SD_MOUNT_POINT="/sdcard"
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Lisael Box — ESP32-S3-BOX-3 specific defaults.
|
||||||
|
# Applied automatically on top of sdkconfig.defaults when target == esp32s3.
|
||||||
|
|
||||||
|
# --- Flash: 16 MB on the BOX-3 ----------------------------------------------
|
||||||
|
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||||
|
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
||||||
|
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
||||||
|
|
||||||
|
# --- PSRAM: 8 MB octal SPI on the BOX-3 -------------------------------------
|
||||||
|
# Required for the LVGL framebuffer(s) and ESP-ADF ring buffers.
|
||||||
|
CONFIG_SPIRAM=y
|
||||||
|
CONFIG_SPIRAM_MODE_OCT=y
|
||||||
|
CONFIG_SPIRAM_SPEED_80M=y
|
||||||
|
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
|
||||||
|
CONFIG_SPIRAM_RODATA=y
|
||||||
|
# Let malloc() fall back to PSRAM for large allocations (LVGL buffers, decoders).
|
||||||
|
CONFIG_SPIRAM_USE_MALLOC=y
|
||||||
|
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=4096
|
||||||
|
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
|
||||||
|
|
||||||
|
# --- CPU ---------------------------------------------------------------------
|
||||||
|
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||||
|
|
||||||
|
# --- LVGL (esp_lvgl_port / lvgl 9) ------------------------------------------
|
||||||
|
# Use PSRAM for the LVGL draw buffers so the 320x240x16bpp framebuffer fits.
|
||||||
|
CONFIG_LV_MEM_CUSTOM=y
|
||||||
|
CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM=y
|
||||||
|
|
||||||
|
# --- Main task ---------------------------------------------------------------
|
||||||
|
# app_main runs BSP + LVGL bring-up; give it a comfortable stack.
|
||||||
|
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
|
||||||
|
|
||||||
|
# --- Audio: ESP-ADF decoders need a decent heap; keep DMA in internal RAM ---
|
||||||
|
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096
|
||||||
Reference in New Issue
Block a user