1 · Platform Detection
Explicit Detection
| Keywords/Patterns | Platform |
|---|---|
| Raspberry Pi, RPi, BCM2835, BCM2711, BCM2712, config.txt, dtoverlay, gpiozero, RPi.GPIO, pigpio, /boot/firmware/ | RPi |
| ESP32, ESP-IDF, WROOM, WROVER, menuconfig, sdkconfig, Arduino (with ESP context), esp_err_t, gpio_config(), ESP32-S2, S3, C3, C6 | ESP32 |
Model/Variant Detection
RPi Variants:
| Identifier | Models Covered | Key Differences |
|---|---|---|
| rpi3 | Pi 3B/3B+ | UART/BT conflict on mini-UART, 2× PWM channels, config at /boot/config.txt |
| rpi4 | Pi 4B | 4× PWM channels, dual SPI, config at /boot/firmware/config.txt |
| rpi5 | Pi 5 | RP1 southbridge (different peripheral base), 4× PWM, config at /boot/firmware/config.txt |
| rpi_zero2w | Zero 2W | Same SoC as Pi 3, UART/BT conflict, limited current budget |
ESP32 Variants:
| Identifier | Key Differences |
|---|---|
| esp32 | 34 GPIO, dual-core, ADC2 conflicts with WiFi, Hall sensor on GPIO36/39 |
| esp32s2 | 43 GPIO, single-core, no Bluetooth, native USB, no ADC2/WiFi conflict |
| esp32s3 | 45 GPIO, dual-core, BLE5, native USB, no ADC2/WiFi conflict |
| esp32c3 | 22 GPIO, single-core RISC-V, BLE5 only, no ADC2/WiFi conflict |
| esp32c6 | 30 GPIO, RISC-V, WiFi 6, 802.15.4, no ADC2/WiFi conflict |
ESP32 Modules:
| Module | Additional Reserved Pins |
|---|---|
| WROOM | GPIO6–11 (flash SPI) |
| WROVER | GPIO6–11 (flash SPI) + GPIO16–17 (PSRAM) |
Ambiguity Rules
- If platform cannot be determined from context: ask the user. NEVER silently default to a platform.
- If platform is detected but variant is unknown: ask the user for model/variant. Default to most conservative variant if user declines (rpi3 for RPi, esp32 + WROOM for ESP32).
- Unsupported platforms (RP2040/Pico, STM32, Arduino AVR, BeagleBone): state that the platform is not yet supported, list supported platforms, offer to help if user switches.
2 · Reference Loading
ALWAYS load the platform pin database. Load other files only when their trigger condition is met.
| File | Trigger |
|---|---|
| references/platforms/rpi-pins.md | Platform is RPi (any variant) |
| references/platforms/esp32-pins.md | Platform is ESP32 (any variant) |
| references/platforms/esp32-specifics.md | ESP32 detected AND any of: strapping pins mentioned, deep sleep, flash/PSRAM, ADC2, boot issues |
| references/platforms/rpi-overlays.md | RPi detected AND any of: device tree, dtoverlay, overlay, kernel module, /boot/ config |
| references/protocol-quick-ref.md | Any protocol mentioned: I2C, SPI, UART, PWM, 1-Wire, CAN, Modbus, ADC, DAC |
| references/electrical-constraints.md | Current limits, voltage levels, pull-ups/pull-downs, power supply, level shifting mentioned |
| references/common-devices.md | Specific sensor, module, display, or breakout board mentioned by name or part number |
3 · Core Workflow
Step 1 — Parse
Extract from the user's request:
- Target platform and variant (or flag as unknown)
- Required protocols and their quantities (e.g., "2× I2C", "1× SPI")
- Named devices/modules (e.g., "BME280", "SSD1306", "NeoPixel")
- Existing pin commitments ("I'm already using GPIO17 for...")
- Special requirements (deep sleep wake, interrupt-capable, analog input, high-speed)
- Framework preference (gpiozero, RPi.GPIO, Arduino, ESP-IDF) or "not specified"
Step 2 — Detect
Apply Section 1 rules. Result: confirmed platform + variant + module type, OR ask the user.
Step 3 — Load
Apply Section 2 table. Load all triggered reference files before proceeding.
Step 4 — Gather
If any critical information is missing (platform, protocol count, or device identity), ask ONE concise follow-up question covering all gaps. If information is merely ambiguous but reasonable defaults exist, proceed and list assumptions in the output. Never ask more than one follow-up message.
Step 5 — Generate
Assign pins using platform-specific strategy:
RPi strategy:
- Assign hardware-native pins first (I2C → GPIO2/3, SPI0 → GPIO7–11, UART → GPIO14/15)
- Prefer GPIO12/13 for hardware PWM
- Never assign GPIO0 or GPIO1 (I2C EEPROM reserved)
- Use clean GPIOs for general digital I/O: 5, 6, 16, 17, 22, 23, 24, 25, 26, 27
- Note all pins that pull high/low at boot
- Track cumulative current draw against 50mA GPIO budget
ESP32 strategy:
- Never assign flash SPI pins (GPIO6–11; also GPIO16–17 on WROVER)
- Warn if assigning strapping pins (GPIO0, 2, 5, 12, 15) — add boot-state note for each
- Elevate GPIO12 (MTDI) to a stronger warning: wrong state at boot can set flash voltage to 1.8V and brick the module
- Use conventional I2C pins (GPIO21 SDA, GPIO22 SCL) unless conflict exists
- Use native SPI pins: VSPI (GPIO5/18/19/23) or HSPI (GPIO12/13/14/15) — note strapping overlap on HSPI
- If WiFi is enabled, avoid ADC2 channels entirely (esp32 variant only)
- Assign input-only pins (GPIO34–39) only for inputs, never outputs or bidirectional
- Prefer RTC-capable GPIOs for deep-sleep wake sources
- Reserve GPIO1/3 (UART0 TX/RX) for debug serial unless user explicitly reassigns
- Note that any output-capable GPIO supports PWM via LEDC — no dedicated PWM pins needed
Step 6 — Validate
Invoke the validation script:
python scripts/validate_pinmap.py --format json <<'EOF'
<input JSON>
EOF
If validation returns errors: reassign conflicting pins and re-validate. Loop a maximum of 3 times. If still failing after 3 attempts, present the best result with remaining warnings explained.
If validation returns warnings only: include warnings in output, proceed.
Step 7 — Output
Generate the response using Section 4 format. Then invoke the generation script:
python scripts/generate_config.py --format json --framework <framework> <<'EOF'
<input JSON>
EOF
Include all script outputs in the structured response.
4 · Output Format
Pin Assignment Table
- RPi columns: Function | GPIO (BCM) | Physical Pin | Alt Mode | Notes
- ESP32 columns: Function | GPIO | Notes | Strapping? | RTC Channel?
- Sort by function group (I2C, SPI, UART, PWM, digital I/O, analog)
Configuration
- RPi: config.txt lines (dtoverlay, dtparam, gpio= directives). Note correct path for variant.
- ESP32: menuconfig/sdkconfig.defaults lines (if Arduino: note that most config is in code)
Initialization Code
- RPi: provide both gpiozero and RPi.GPIO versions unless user specified one
- ESP32: provide both Arduino and ESP-IDF versions unless user specified one
- Always include: pin mode setup, pull-up/pull-down config, protocol init with correct pins, brief comments
Wiring Notes
- Human-readable wiring instructions using physical pin numbers AND GPIO numbers
- Include: pull-up resistor values for I2C/1-Wire, power rail connections, level shifter notes if mixing voltages, decoupling caps for sensitive devices
Warnings
- Pin conflicts detected during validation
- Strapping pin usage (ESP32)
- Current budget concerns
- UART/Bluetooth conflicts (RPi 3/4/Zero2W)
- PWM/audio conflicts (RPi)
- ADC2/WiFi conflicts (ESP32)
- Deprecated library warnings (e.g., RPi.GPIO on Pi 5)
Alternatives
- For every conflict that was auto-resolved, explain: original pin → replacement pin and why
- If multiple valid assignments exist, briefly note the top alternative
5 · Critical Rules
Universal
- Always present GPIO numbers prominently — never reference physical pin numbers only
- Never silently assign a reserved or restricted pin — always warn
- Check I2C device address collisions when multiple I2C devices share a bus
- Include pull-up/pull-down notes for every protocol that requires them
- Respect per-platform current limits and warn when cumulative draw approaches budget
- Warn about deprecated libraries (RPi.GPIO on Pi 5 has limited support; suggest gpiozero or lgpio)
- If the user's request exceeds available pins, say so and suggest multiplexing (I2C expander, SPI daisy-chain)