# Device Envoy Completeness
| led_strip | [x] | [x] | [x] | [x] | ? | [x] | [x] | [x] |
| led_strip_spi | *na* | [x] | [x] | [x] | ? | [x] | [x] | [x] |
| led2d | [x] | [x] | [x] | [x] | ? | [x] | [x] | [x] |
| audio_player | [x] | [x] | [x] | [x] | ? | [x] | [90%](#note-audio-player) | [x] |
| ir | [x] | [x] | [x] | [x] | ? | [x] | [x] | [x] |
| ir/mapping | [x] | [x] | [x] | [x] | ? | [x] | [x] | [x] |
| ir/kepler | [x] | [x] | [x] | [x] | ? | [x] | [x] | [x] |
| flash_block | [x] | [x] | [x] | [x] | ? | *na* | [x] | [x] |
| button | [x] | [x] | [x] | [x] | ? | [x] | [x] | [x] |
| servo | [x] | [x] | [x] | [x] | ? | [x] | [75%](#note-servo-density) | [x] |
| servo_player | [x] | [x] | [x] | [x] | ? | [x] | [75%](#note-servo-density) | [x] |
| wifi_auto | [x] | [x] | [x] | [x] | ? | *na* | [x](#note-wifi-auto-eff) | ? |
| led4 | [x] | [x] | [x] | [x] | ? | [2] ([note](#note-runtime-pool-limit-2)) | [x] | [2] ([note](#note-runtime-pool-limit-2)) |
| lcd_text | [x] | [x] | [x] | [x] | ? | [x] | [x] | [x] |
| clock_sync | [x] | [x] | [x] | [x] | [ ] | [2] ([note](#note-runtime-pool-limit-2)) | [x] | [2] ([note](#note-runtime-pool-limit-2)) |
| led | [x] | [x] | [x] | [x] | ? | [x] | [x] | [x] |
| rfid | [x] | [x] | [x] | [x] | ? | [2] ([note](#note-rfid)) | [x](#note-rfid) | [x](#note-rfid) |
## Key
- `Submodule`: Device abstraction module.
- `Rp`: Implemented in `device-envoy-rp`.
- `Esp`: Implemented in `device-envoy-esp`.
- `Trait`: Core trait surface exists in `device-envoy-core`.
- `TDTest`: Trait documentation includes a doc test.
- `EspPar`: ESP docs are on par with RP docs.
- `PoolInd`: Any number can be created independent of any `pool_size`.
- `Eff`: Efficiency of resource usage.
- `Own`: Ownership safety against hardware contention.
## Notes
### Note: audio-player
`audio_player`: Effectively 100% efficient on ESP for its chosen resource model (`I2S0` + DMA). On RP it is not 100% because the current implementation uses one PIO state machine (`sm0`) per instance rather than spreading across all four state machines. In principle a PIO block can run up to four independent programs, but practical multi-I2S constraints (timing/clocking, DMA feed pressure, pin routing, jitter risk) make full four-stream utilization non-trivial for reliable audio.
### Note: servo-player-own
`servo_player`: Marked `Own [ ]` because the generated static/task pattern can still be contended at runtime (for example repeated `new` on one generated type) rather than always being rejected by the compiler.
### Note: wifi-auto-eff
`wifi_auto`: Marked `Eff [x]` under the current RP design assumption because it takes a whole PIO block and the remaining state machines are not treated as practically shareable for this abstraction.
### Note: servo-density
`servo` / `servo_player`: Marked `75%` because ESP currently enforces unique LEDC timer claims per generated type. This is safe, but not timer-dense. In principle, multiple channels could share one timer when PWM base settings match, improving density.
### Note: runtime-pool-limit-2
`led4` and `clock_sync`: Runtime task pools are set to `pool_size = 2` for their task paths, so two instances are supported concurrently. A third `new(...)` call may still compile if resources exist, but it is expected to fail at runtime with task spawn busy/full behavior.
### Note: rfid
`rfid`: Marked `Eff [x]` and `Own [x]` because hardware resources are passed as owned tokens (SPI peripheral + GPIO + DMA), preventing unsafe sharing at compile time in safe Rust. `PoolInd` is `[2]` because the RFID polling task runs with `pool_size = 2`, so two concurrent instances are supported; a third concurrent spawn is expected to fail at runtime.