Files
PlantCtrl/AGENTS.md

5.2 KiB

AGENTS.md

Repository Overview

PlantCtrl is a mixed-discipline repo: two embedded Rust firmware targets, a shared crate, KiCad hardware, and a Hugo site.

Top-level layout:

  • Software/MainBoard/rust: main firmware (plant-ctrl2) for ESP32-C6 controller board.
  • Software/CAN_Sensor: sensor firmware (bms) for CH32V203C8T6 (CAN sensor / BMS board).
  • Software/Shared/canapi: shared crate for CAN protocol/serialization — consumed by both firmware targets.
  • Hardware: KiCad PCB designs and 3D case files.
  • DataSheets: reference material; treat as source data, not generated output.
  • website: Hugo site (Blowfish theme via git submodule at website/themes/blowfish).
  • bin: helper scripts and dev tooling.

Critical Constraints

  • No Cargo workspace — each project has its own Cargo.toml and Cargo.lock. Run checks with --manifest-path.
  • Both firmware targets require nightly toolchain (rust-toolchain.toml). Main board uses build-std = ["alloc", "core"] in .cargo/config.toml.
  • no_std/no_main — both firmware crates are bare-metal. Do not introduce std-only dependencies.
  • Main board clippy rules (src/main.rs): #![deny(clippy::mem_forget, clippy::unwrap_used, clippy::expect_used, clippy::panic)]. Do not add #[allow(...)] without explicit user request.
  • mcutie (src/mcutie_3_0_0/): vendored sub-crate with #![deny(unreachable_pub)] and #![warn(missing_docs)].
  • Flash layout (main board partitions.csv): 16 MB total — ota_0 (3968K), ota_1 (3968K), storage (8M LittleFS), nvs (16K), otadata (8K), phy_init (4K).
  • CH32V203C8T6 memory (CAN_Sensor/memory.x): 64 KB flash, 20 KB RAM. Tight budget — avoid allocations.
  • ESP IDF config (sdkconfig.defaults): CONFIG_ESP_MAIN_TASK_STACK_SIZE=50000, CONFIG_FREERTOS_HZ=1000, CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y.

Firmware Build & Flash

Main Board (ESP32-C6)

# Quick check (no build):
cargo check --manifest-path Software/MainBoard/rust/Cargo.toml

# Full build + flash + monitor:
bash Software/MainBoard/rust/flash.sh

# Build only (no flash):
cargo build --release --manifest-path Software/MainBoard/rust/Cargo.toml

# Build OTA image without flashing:
bash Software/MainBoard/rust/image_build.sh

# Erase OTA data partition (recover from bad flash):
bash Software/MainBoard/rust/erase_ota.sh

flash.sh rebuilds the webpack frontend (src_webpack/) then flashes via espflash at 921600 baud. The frontend is bundled into the firmware binary — do not run npm separately unless modifying src_webpack/.

Sensor Board (CH32V203C8T6)

cargo check --manifest-path Software/CAN_Sensor/Cargo.toml
cargo build --release --manifest-path Software/CAN_Sensor/Cargo.toml
# Flash:
wchisp flash Software/CAN_Sensor/target/riscv32imc-unknown-none-elf/release/bms

Runner is preconfigured in .cargo/config.toml as wchisp flash. Debug via openocd + gdb (scripts in CAN_Sensor/bin/). See CAN_Sensor/README.md for MCU unlock steps.

Shared Crate

cargo check --manifest-path Software/Shared/canapi/Cargo.toml

Cross-impact

Any change to canapi (IDs, frame layout, serialization) must be checked against both firmware targets. The crate uses bincode for serialization.

Architecture Notes

  • Main board entry: Software/MainBoard/rust/src/main.rs#[esp_rtos::main] async entry, Embassy executor, ESP-HAL.
  • HAL layer: src/hal/mod.rs defines PlantHal trait; esp.rs and v4_hal.rs are concrete implementations.
  • mcutie: src/mcutie_3_0_0/ is a vendored MQTT/HA client library.
  • Webserver: src/webserver/ serves OTA, logs, static files over HTTP. Frontend in src_webpack/.
  • Sensor entry: Software/CAN_Sensor/src/main.rs#[embassy_executor::main] async entry, CH32-HAL, CAN + USB CDC.
  • Both targets: Embassy executor, heapless for heapless data structures, option-lock for optional state.

Website

cd website
npm run dev    # starts Hugo dev server with Blowfish theme

Theme is a git submodule. Do not edit website/themes/ directly — make customizations in assets/ or config/ instead.

Working Rules

  • Keep changes tightly scoped to the user request; this repo spans hardware, firmware, and website code.
  • Preserve existing file structure and naming unless the user explicitly asks for restructuring.
  • Avoid mass formatting or opportunistic cleanup in KiCad files, lockfiles, generated assets, or vendored dependencies.
  • Do not edit dependency directories (website/themes, src_webpack/node_modules) unless explicitly asked.
  • When touching firmware code, keep resource usage and target constraints in mind; avoid unnecessary allocations or feature creep.
  • Shared protocol or serialization changes must be checked for impact across both firmware targets.

Validation

  • Use the narrowest relevant check first.
  • Embedded firmware may require target-specific toolchains or hardware-adjacent tooling. If you cannot run a meaningful validation step, say so explicitly and describe the likely prerequisite.

Handoff Expectations

  • Summarize what changed, where it changed, and any validation performed.
  • Call out follow-up work when a change likely affects both firmware targets, hardware assumptions, or the website.