m5stack-core 0.4.0

Board support crate for M5Stack Fire27 and CoreS3 (ESP32/ESP32-S3)
[package]
name = "m5stack-core"
version = "0.4.0"
edition = "2024"
rust-version = "1.86"
license = "MIT OR Apache-2.0"
description = "Board support crate for M5Stack Fire27 and CoreS3 (ESP32/ESP32-S3)"
repository = "https://github.com/emobotics-dev/m5stack-core"
readme = "README.md"
keywords = ["esp32", "m5stack", "embedded", "bsp", "embassy"]
categories = ["embedded", "no-std", "hardware-support"]
# Dev-only infrastructure — irrelevant to a published-crate consumer.
exclude = [".github/", ".devcontainer/"]

[lib]
test = false
bench = false

[features]
# The `esp-bootloader-esp-idf?/<chip>` arms only bite when the optional dep is
# already on (via `heap`) — `init_heap`'s `#[ram(reclaimed)]` region needs the
# esp-idf bootloader crate in the graph; a heap-free build never pulls it.
fire27 = ["esp-hal/esp32", "esp-radio/esp32", "esp-sync/esp32", "esp-bootloader-esp-idf?/esp32", "esp-rtos?/esp32"]
cores3 = ["esp-hal/esp32s3", "esp-radio/esp32s3", "esp-sync/esp32s3", "esp-bootloader-esp-idf?/esp32s3", "esp-rtos?/esp32s3"]
# Enables the masked 1-Wire ROM search (driver::onewire::Search::new_with_mask),
# constraining enumeration to addresses matching fixed bits under a mask.
search-masks = []
# HIL serial-cmd driver — exposes a Read endpoint over UART0 (fire27) or
# USB-Serial-JTAG (cores3). Paired with `alternator-regulator/serial-cmd`.
serial-cmd = []
# Export the `#[panic_handler]` symbol from the BSP (body = io::console::on_panic
# — RTC breadcrumb + best-effort print + halt). Off by default so a consumer can
# provide its own; a binary opts in instead of hand-rolling the one-line wrapper.
panic-handler = []
# Multicore app-core harness (board::run_app_core): parks + starts the APP core
# on an esp-rtos InterruptExecutor with the waiti idle loop, encapsulating the
# park_core JTAG-reset workaround. Pulls esp-rtos (its embassy InterruptExecutor).
multicore = ["dep:esp-rtos"]
# Console serial transport (UART0 / USB-Serial-JTAG): the TX drain + RX half +
# `console::install`'s `Some(serial)` path + the panic transport print. With it
# OFF (R9 production backstop) none of those symbols link: `log!` is a no-op into
# the ring, `install` can only register the backend, and `on_panic` still writes
# the RTC breadcrumb and halts (RWDT recovers) — just with no serial surface.
console-serial = []
# Global-heap ownership (the `mem` module): `mem::init_heap(profile, psram)`
# declares the esp-alloc DRAM regions (HIL-proven per-board sizes) so a binary
# never calls `esp_alloc::heap_allocator!` itself. PSRAM-free, so a board with
# no external RAM (or that just doesn't want it) enables only this.
heap = ["dep:esp-alloc", "dep:allocator-api2", "dep:esp-bootloader-esp-idf"]
# External PSRAM heap support (the PSRAM region + the `psram_box`/`psram_vec`
# checked allocators). Implies `heap`. Enabling it activates a build-time guard
# requiring opt-level > 0 (build.rs) and the compile-time `PsramSafe` atomic
# check (uses the `esp` nightly auto-trait features).
psram = ["heap"]
# On-board ILI9342C panel bring-up (board::display) and the display/SD-card
# device construction on the shared SPI2 bus (board::spi2::Spi2Parts::finish).
display = ["dep:lcd-async", "dep:embassy-embedded-hal"]
# Debounced front-panel button driver (io::buttons::Buttons, Fire27 hardware).
# The unified ButtonEvent types and the CoreS3 touch emulation need no feature.
buttons = ["dep:async-button"]

# --- Radio (driver::radio) — orthogonal to the chip features; combine per app.
# The radio is shared, so `coex` is required to run BLE and WiFi at once.
ble      = ["esp-radio/ble"]                                  # driver::radio::ble (BleRadio → BleConnector)
wifi     = ["esp-radio/wifi"]                                 # driver::radio::wifi (controller + scan)
wifi-sta = ["wifi", "dep:embassy-net"] # STA + DHCP embassy_net::Stack
wifi-ap  = ["wifi", "dep:embassy-net"] # reserved for AP mode (not yet implemented)
coex     = ["esp-radio/coex", "wifi", "ble"]                  # software WiFi/BLE coexistence (extra RAM)

[dependencies]
# esp-hal family — stock crates.io versions so the crate publishes. The whole
# family is version-locked together, so they are pinned exactly; local and
# example builds are redirected to the emobotics fork (a coherent snapshot of
# the same versions, plus SPI/DMA patches the examples need) via the rev-pinned
# [patch.crates-io] below, which `cargo publish` ignores.
esp-alloc           = { version = "=0.10.0", optional = true }
esp-hal             = { version = "=1.1.1", features = ["unstable"] }
esp-radio           = { version = "=0.18.0", features = ["esp-alloc", "unstable"] }
esp-sync            = { version = "=0.2.1" }
# Bootloader integration — needed only by the `heap` feature: `init_heap`'s
# `#[ram(reclaimed)]` region requires the esp-idf bootloader crate in the graph
# (it also backs the future `app_desc!`). Stock for publish; patched to the fork
# below for local/example builds so it unifies with the examples' copy (a
# `links` crate must resolve to a single version).
esp-bootloader-esp-idf = { version = "=0.5.0", optional = true }
# Multicore harness only (board::run_app_core): esp-rtos's embassy
# InterruptExecutor. Stock for publish, patched to the fork below for local
# builds so it unifies with the examples' copy.
esp-rtos             = { version = "=0.3.0", optional = true, features = ["embassy"] }
# Pinned (and referenced via `use esp_rom_sys as _` in lib.rs so it survives
# `cargo package`): esp-hal 1.1.0 calls esp_rom_sys::init_syscall_table, added
# in 0.1.4, but only constrains it to ~0.1 — without this pin a stock resolve
# drifts to 0.1.1 (which lacks the function) and esp-hal fails to compile.
esp-rom-sys         = { version = "=0.1.4" }

# embedded-hal family
embedded-hal        = "1.0.0"
embedded-io-async   = "0.7.0"

# Embassy
embassy-executor    = { version = "0.10.0", features = ["nightly"] }
embassy-futures     = "0.1"
embassy-net         = { version = "0.8.0", optional = true, default-features = false, features = ["dhcpv4", "proto-ipv4", "medium-ethernet", "tcp", "udp", "dns"] }
embassy-sync        = "0.8"
embassy-time        = "0.5.0"

# misc
allocator-api2      = { version = "0.3.0", default-features = false, features = ["alloc"], optional = true }
async-button        = { version = "0.2.0", optional = true }
embassy-embedded-hal = { version = "0.6.0", optional = true, features = ["time"] }
fixed               = "1.29.0"
lcd-async           = { version = "0.1.3", optional = true }
heapless            = { version = "0.9.1", features = ["nightly"] }
log                 = "0.4"
static_cell         = { version = "2.1.1", features = ["nightly"] }
thiserror-no-std    = "2.0.2"

# Local/example builds only: redirect the esp-hal family the library declares
# (stock, above) to the emobotics fork at a pinned rev — a coherent snapshot of
# those versions with the SPI/DMA patches the examples need. Pinned to a rev,
# not the floating `local` branch, so builds are reproducible. `cargo publish`
# ignores [patch], so downstream consumers resolve the stock crates.io versions.
[patch.crates-io]
esp-hal     = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0" }
esp-radio   = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0" }
esp-sync    = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0" }
esp-alloc   = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0" }
esp-rom-sys = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0" }
esp-bootloader-esp-idf = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0" }
esp-rtos    = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0" }

[workspace]
members = ["examples/common", "examples/demos"]

# Shared example dependencies — referenced by the example crates via
# `<dep>.workspace = true` so the esp-hal fork rev (and the rest) is stated
# once. Chip features (esp32/esp32s3) and `optional` are applied per-member.
# The library itself (above) does NOT use these — it depends on stock crates.io
# esp-hal redirected by [patch.crates-io]; the examples pull fork crates that
# are not on the patch list (esp-rtos, esp-bootloader-esp-idf, esp-backtrace,
# esp-println), so they declare the fork explicitly.
[workspace.dependencies]
# esp-hal family (emobotics fork, pinned rev)
esp-alloc            = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0", features = ["internal-heap-stats"] }
esp-backtrace        = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0", features = ["panic-handler", "custom-halt", "colors", "println"] }
esp-bootloader-esp-idf = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0" }
esp-hal              = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0", features = ["unstable"] }
esp-println          = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0", features = ["log-04", "colors", "timestamp"], default-features = false }
esp-rtos             = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0", features = ["embassy", "esp-radio"] }
esp-sync             = { git = "https://github.com/emobotics-dev/esp-hal.git", rev = "b7a4c74a024383cb9808453cf3e34296c5e870b0" }
# CoreS3 logging/panic (USB-Serial-JTAG)
panic-halt           = "1.0.0"
rtt-target           = { version = "0.6.2", features = ["log"] }
# Embassy
embassy-embedded-hal = { version = "0.6.0", features = ["time"] }
embassy-executor     = { version = "0.10.0", features = ["nightly"] }
embassy-futures      = "0.1"
embassy-net          = { version = "0.8.0", default-features = false, features = ["dhcpv4", "proto-ipv4", "medium-ethernet", "tcp", "udp", "dns"] }
embassy-sync         = "0.8"
embassy-time         = "0.5.0"
# Display
embedded-graphics    = "0.8.1"
lcd-async            = "0.1.1"
# BLE (coex)
trouble-host         = { version = "0.6.0", features = ["default-packet-pool-mtu-255", "scan", "derive"] }
# LVGL (lvgl feature, demos only)
oxivgl               = { version = "0.5.0", features = ["esp-hal", "log-04"] }
oxivgl-sys           = { version = "0.2.1", default-features = false }
# misc
embedded-hal         = "1.0.0"
heapless             = "0.9.1"
log                  = "0.4"
static_cell          = { version = "2.1.1", features = ["nightly"] }

[profile.dev]
opt-level = "s"

[profile.release]
codegen-units = 1
debug = 2
debug-assertions = false
incremental = false
lto = "fat"
opt-level = "s"
overflow-checks = true