diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e02c033 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,26 @@ +# Repository Guide + +## Scope + +- This is one bare-metal C++ firmware target for the Electrosmith Daisy Patch. Application code is under `src/`; `lib/libDaisy` and `lib/daisySP` are recursive git submodules, not packages owned by this repository. +- Root CI only builds the firmware. Tests, formatters, and workflows found below `lib/` belong to the vendored submodules; there is no root application test or lint target. + +## Build And Flash + +- Initialize all nested dependencies after a non-recursive clone with `git submodule update --init --recursive`. +- The build requires the `arm-none-eabi-*` toolchain on `PATH`, or its binary directory passed as `GCC_PATH=...`. CI uses Arm GCC `9-2019-q4`. +- From a clean checkout, run `make lib && make`. `make lib` builds both submodule libraries; subsequent application-only changes normally need only `make`. Artifacts are `build/droplets.{elf,hex,bin}`. +- `make clean` removes only the root `build/`; it does not clean or rebuild either library. +- Do not use the README's `make deploy`: `APP_TYPE = BOOT_SRAM`, but that target invokes the incompatible OpenOCD `program` recipe and fails. After building, enter Daisy bootloader mode and run `make program-dfu` (requires `dfu-util`); it writes `build/droplets.bin` at `0x90040000`. + +## Source Wiring + +- `src/main.cpp` owns startup and dispatch: the foreground loop handles controls, OLED drawing, and non-audio outputs, while the Daisy audio callback calls each active droplet's `Process` method. +- Split mode runs left and right droplets against the same audio buffers. Use the `Droplet` state helpers and `GetChannelMin()`/`GetChannelMax()` plus screen bounds rather than hard-coded full-device ranges, or one side can overwrite the other. +- The root Makefile discovers only `src/*.cpp` and `src/*/*.cpp`. Sources nested more deeply are silently excluded. Object names are flattened into `build/`, so C++ source basenames must be unique across those directories. + +## Adding A Droplet + +- Run `./create-new-droplet.sh PascalCaseName`; the script only copies and substitutes the template and does not register the result. +- Complete all registration points: add a `MenuState` in `src/menu_item.h`, append its visible item in `Menu::Menu` in `src/menu.cpp`, include its header in `src/main.h`, and add construction in `GetDroplet` in `src/main.cpp`. +- Implement all three `DropletState` layouts. `Droplet::UpdateState` recalculates channel/display bounds, then calls `SetControls()` and `UpdateStateCallback()` when switching between full and split modes.