Skip to content

Commit 6902ea9

Browse files
Copilotsofthack007
andauthored
docs: add octal PSRAM/flash guidance and P4 hex PSRAM to esp-idf.instructions.md
Agent-Logs-Url: https://github.com/MoonModules/WLED-MM/sessions/d43d1936-b9de-4ca5-881d-c2cf3e29f53f Co-authored-by: softhack007 <91616163+softhack007@users.noreply.github.com>
1 parent 73c1f75 commit 6902ea9

1 file changed

Lines changed: 28 additions & 5 deletions

File tree

.github/esp-idf.instructions.md

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,36 @@ WLED validates at compile time that exactly one target is defined and that it is
9494

9595
### PSRAM capability macros
9696

97-
For PSRAM DMA and access patterns:
97+
For PSRAM presence, mode, and DMA access patterns:
9898

9999
| Macro | Meaning |
100100
|---|---|
101101
| `CONFIG_SPIRAM` / `BOARD_HAS_PSRAM` | PSRAM is present in the build configuration |
102-
| `CONFIG_SOC_PSRAM_DMA_CAPABLE` | PSRAM buffers can be used with DMA (ESP32-S3) |
103-
| `CONFIG_SOC_MEMSPI_FLASH_PSRAM_INDEPENDENT` | SPI flash and PSRAM on separate buses (no contention) |
102+
| `CONFIG_SPIRAM_MODE_QUAD` | Quad-SPI PSRAM (standard, used on ESP32 classic and some S2/S3 boards) |
103+
| `CONFIG_SPIRAM_MODE_OCT` | Octal-SPI PSRAM — 8 data lines, DTR mode. Used on ESP32-S3 with octal PSRAM (e.g. N8R8 / N16R8 modules). Reserves GPIO 33–37 for the PSRAM bus — **do not allocate these pins** when this macro is defined. `wled.cpp` uses this to gate GPIO reservation. |
104+
| `CONFIG_SPIRAM_MODE_HEX` | Hex-SPI (16-line) PSRAM — future interface on ESP32-P4 running at up to 200 MHz. Used in `json.cpp` to report the PSRAM mode. |
105+
| `CONFIG_SOC_PSRAM_DMA_CAPABLE` | PSRAM buffers can be used with DMA (ESP32-S3 with octal PSRAM) |
106+
| `CONFIG_SOC_MEMSPI_FLASH_PSRAM_INDEPENDENT` | SPI flash and PSRAM on separate buses (no speed contention) |
107+
108+
#### Detecting octal/hex flash
109+
110+
On ESP32-S3 modules with OPI flash (e.g. N8R8 modules where the SPI flash itself runs in Octal-PI mode), the build system sets:
111+
112+
| Macro | Meaning |
113+
|---|---|
114+
| `CONFIG_ESPTOOLPY_FLASHMODE_OPI` | Octal-PI flash mode. On S3, implies GPIO 33–37 are used by the flash/PSRAM interface — the same GPIO block as octal PSRAM. `wled.cpp` uses `CONFIG_ESPTOOLPY_FLASHMODE_OPI \|\| (CONFIG_SPIRAM_MODE_OCT && BOARD_HAS_PSRAM)` to decide whether to reserve these GPIOs. `json.cpp` uses this to report the flash mode string as `"🚀OPI"`. |
115+
| `CONFIG_ESPTOOLPY_FLASHMODE_HEX` | Hex flash mode (ESP32-P4). Reported as `"🚀🚀HEX"` in `json.cpp`. |
116+
117+
**Pattern used in WLED-MM** (from `wled.cpp`) to reserve the octal-bus GPIOs on S3:
118+
```cpp
119+
#if defined(CONFIG_IDF_TARGET_ESP32S3)
120+
#if CONFIG_ESPTOOLPY_FLASHMODE_OPI || (CONFIG_SPIRAM_MODE_OCT && defined(BOARD_HAS_PSRAM))
121+
// S3: GPIO 33-37 are used by the octal PSRAM/flash bus
122+
managed_pin_type pins[] = { {33, true}, {34, true}, {35, true}, {36, true}, {37, true} };
123+
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
124+
#endif
125+
#endif
126+
```
104127

105128
---
106129

@@ -355,14 +378,14 @@ WLED-MM provides convenience wrappers with automatic fallback. **Always prefer t
355378
### PSRAM guidelines
356379

357380
- **Check availability**: always test `psramFound()` before assuming PSRAM is present.
358-
- **DMA compatibility**: on ESP32 (classic), PSRAM buffers are **not DMA-capable** — use `d_malloc_only()` to allocate DMA buffers in DRAM only. On ESP32-S3 with octal PSRAM, PSRAM buffers *can* be used with DMA when `CONFIG_SOC_PSRAM_DMA_CAPABLE` is defined.
381+
- **DMA compatibility**: on ESP32 (classic), PSRAM buffers are **not DMA-capable** — use `d_malloc_only()` to allocate DMA buffers in DRAM only. On ESP32-S3 with octal PSRAM (`CONFIG_SPIRAM_MODE_OCT`), PSRAM buffers *can* be used with DMA when `CONFIG_SOC_PSRAM_DMA_CAPABLE` is defined.
359382
- **JSON documents**: use the `PSRAMDynamicJsonDocument` allocator (defined in `wled.h`) to put large JSON documents in PSRAM:
360383
```cpp
361384
PSRAMDynamicJsonDocument doc(16384); // allocated in PSRAM if available
362385
```
363386
- **Fragmentation**: PSRAM allocations fragment less than DRAM because the region is larger. But avoid mixing small and large allocations in PSRAM — small allocations waste the MMU page granularity.
364387
- **Heap validation**: use `d_measureHeap()` and `d_measureContiguousFreeHeap()` to monitor remaining DRAM. Allocations that would drop free DRAM below `MIN_HEAP_SIZE` should go to PSRAM instead.
365-
- **Performance**: PSRAM access is 3–10× slower than DRAM on ESP32/S2 (SPI bus). On ESP32-S3 with octal PSRAM, the penalty is smaller (~2×). Keep hot-path data in DRAM.
388+
- **Performance**: PSRAM access is 3–10× slower than DRAM on ESP32/S2 (quad-SPI bus). On ESP32-S3 with octal PSRAM (`CONFIG_SPIRAM_MODE_OCT`), the penalty is smaller (~2×) because the 8-line DTR bus runs at up to 120 MHz. On ESP32-P4 with hex PSRAM (`CONFIG_SPIRAM_MODE_HEX`), the 16-line bus runs at 200 MHz, further reducing the gap. Keep hot-path data in DRAM regardless.
366389
367390
### Pattern: preference-based allocation
368391

0 commit comments

Comments
 (0)