fix(esp32s3): stop tulip.wifi() crashing with "No free interrupt inputs for AES interrupt"#1018
fix(esp32s3): stop tulip.wifi() crashing with "No free interrupt inputs for AES interrupt"#1018bwhitman wants to merge 2 commits into
Conversation
Wi-Fi's WPA2 handshake triggers a hardware-AES op. With IDF's default CONFIG_MBEDTLS_AES_USE_INTERRUPT=y, the driver calls esp_intr_alloc() to grab a dedicated AES interrupt, but the RGB LCD (GDMA bounce buffers), I2S audio, USB host (ESP_INTR_FLAG_LEVEL1) and the Wi-Fi/BT MAC have already claimed the few free low-priority interrupt slots on the ESP32-S3. The alloc fails with "No free interrupt inputs for AES interrupt" and esp_aes_intr_alloc() then calls abort() — so tulip.wifi() crashes every time on TULIP4_R11. Set CONFIG_MBEDTLS_AES_USE_INTERRUPT=n so the hardware AES accelerator busy-waits/polls for completion instead of needing its own interrupt. The only cost is the CPU busy-waiting during long AES ops (TLS); DMA still does the work and audio runs on its own core. Lands in the shared esp32s3 sdkconfig.tulip, so it covers every ESP32-S3 board and AMYboard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🔌 AMYboard PR previewEditor + flasher: https://amyboard-pr-1018.vercel.app/editor/ This preview bundles this PR's firmware — its flasher only flashes this build (not the release). Rebuilt on every push; removed when the PR closes. The hardware CI has been kicked off and should return within a few minutes, stand by! |
🌷 Tulip Web PR previewTulip Web: https://tulip-pr-1018.vercel.app/run/ Firmware (this PR build):
On-device OTA: Rebuilt on every push; removed when the PR closes. |
…mment The Tulip Web PR-preview comment only pointed at `tulip.upgrade(pr=N)`, which needs Wi‑Fi — unhelpful when the PR itself is a Wi‑Fi fix and the board can't get online. Surface direct download links to each firmware file bundled at /firmware/, ordered full -> app -> sys with a per-file note, so a user can USB-flash the full image (at 0x0, no Wi‑Fi) straight from the comment. The flatten step now emits the bundled .bin filenames as an output; the comment step renders one link per file. Web-only PRs (no firmware bundled) fall back to the previous behavior with no firmware section. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🎛️ HW CI (physical bench)AMYboard (USB-MIDI + AMY Tulip (TULIP4_R11; serial-REPL audio + WiFi screenshot): ✅ PASS — flashed this PR’s firmware; all checks matched the references. ⬇️ Artifacts: recordings · screenshot · serial logs · run logs Self-hosted bench. Audio spectral-compared to |
Problem
A TULIP4_R11 user reports
tulip.wifi("ssid", "pass")crashes every time with:This is a tulipcc/IDF-config bug — deterministic, reproducible for anyone on this firmware — not a user issue.
Root cause
Wi-Fi's WPA2 handshake triggers a hardware-AES operation. On the ESP32-S3, IDF's default
CONFIG_MBEDTLS_AES_USE_INTERRUPT=ymakes the AES driver allocate a dedicated interrupt for it (esp_aes_intr_alloc()→esp_intr_alloc(ETS_AES_INTR_SOURCE, …)).But by the time Wi-Fi starts, tulipcc has already consumed the few free low-priority interrupt slots:
esp32s3_display.c)ESP_INTR_FLAG_LEVEL1(usb_host.c:526)active(True)runsSo
esp_intr_allocreturnsESP_ERR_NOT_FOUND, IDF logs"No free interrupt inputs for AES interrupt", andesp_aes_intr_alloc()then callsabort()— fatal by design. Nothing in tulipcc overrode the default, and this likely surfaced with the ESP-IDF 5.4.1 bump (older IDF busy-waited instead of using an interrupt).Fix
One line in the shared
tulip/esp32s3/boards/sdkconfig.tulip(included by every ESP32-S3 board and AMYboard):The hardware AES accelerator now busy-waits/polls for completion instead of needing its own interrupt — removing the allocation that was aborting. The only cost is the CPU busy-waiting during long AES ops (TLS); DMA still does the work and audio runs on its own core. This is Espressif's recommended remedy for interrupt exhaustion.
Testing
This PR exercises the exact crash path on real hardware. The AMYboard PR preview workflow rebuilds the TULIP4_R11 firmware with this fix (it triggers on
tulip/esp32s3/**), and HW CI then flashes that build onto the physical Tulip and runstulip_hwci.py --require-wifi, which callstulip.wifi(...)on-device (tulip_hwci.py:285). Before this fix that step crashes; with it, Wi-Fi should connect and the screenshot upload should pass.🤖 Generated with Claude Code