You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
FastLED's ESP32 I2S parallel driver is incompatible with Arduino ESP32 Core 3.0+ (ESP-IDF 5.1+) due to a complete architectural redesign of the I2S driver that occurred in ESP-IDF 5.0. The fundamental issue is that FastLED uses direct low-level register access (soc/i2s_struct.h, soc/i2s_reg.h) and configures I2S in LCD parallel mode - an approach that worked reliably with ESP-IDF 4.4 but conflicts with the new channel-based API architecture introduced in ESP-IDF 5.0.
Key Finding: The I2S LCD mode that FastLED depends on is no longer implemented by the I2S driver in ESP-IDF 5.0+. The official documentation explicitly states: "LCD/Camera mode is only supported on I2S0 over a parallel bus. These two modes are not implemented by the I2S driver" and redirects users to dedicated LCD interface drivers instead.
Critical Discovery: While soc/i2s_struct.h register headers still exist in ESP-IDF 5.x (confirmed to be present in master branch as of 2025), the ESP-IDF hardware abstraction layer (HAL/LL) is marked as experimental and "does not adhere to API name changing restrictions," meaning register layouts and access patterns can change between non-major releases.
Recommended Path Forward: The most viable solution is to continue using low-level register access via HAL/LL layers with conditional compilation for ESP-IDF 5.x, but this requires significant testing and carries ongoing maintenance burden as the HAL/LL API is experimental. Alternative approaches (rewriting for high-level API or switching peripherals) are less viable due to the removal of I2S LCD mode support.
Research Findings
ESP-IDF 5.0/5.1 I2S Driver Redesign
The I2S driver underwent a complete ground-up rewrite starting in ESP-IDF 5.0, which carries forward to 5.1 used by Arduino Core 3.0. This was not a simple API update but a fundamental architectural change.
Official ESP-IDF 5.x Documentation: "LCD/Camera mode is only supported on I2S0 over a parallel bus. These two modes are not implemented by the I2S driver. Please refer to I80 Interfaced LCD for more information."
ESP-IDF 4.4: I2S driver directly supported LCD parallel mode via i2s_config_t with mode I2S_MODE_MASTER | I2S_MODE_TX
ESP-IDF 5.0+: LCD mode removed from I2S driver entirely - redirected to dedicated LCD interface
Impact on FastLED: The core functionality FastLED depends on (parallel 24-bit output via I2S LCD mode) is no longer officially supported by the I2S driver
5. ADC/DAC Mode Also Removed
ESP-IDF 5.0+ removed ADC/DAC modes from I2S driver, requiring separate peripheral drivers for audio routing.
6. State Machine Enforcement
The new driver implements strict state transitions:
soc/i2s_struct.h - Confirmed present in ESP-IDF master branch (2025)
soc/i2s_reg.h - Register definitions
soc/gpio_sig_map.h - Signal routing
rom/lldesc.h - DMA descriptor structures
However, the ESP-IDF Hardware Abstraction Layer documentation warns:
"Hardware abstraction API (excluding the driver and xxx_types.h) should be considered an experimental feature... does not adhere to the API name changing restrictions."
This means:
✅ Register headers are still available
⚠️ Register layouts may change between non-major releases
⚠️ No stability guarantees for low-level access
⚠️ HAL/LL API is experimental
Arduino ESP32 Core 3.0 Implementation
Arduino ESP32 Core 3.0 is based on ESP-IDF 5.1.4 and inherits all the I2S driver changes from ESP-IDF 5.0+.
Migration Guide Findings
The official Arduino ESP32 migration guide provides minimal detail on I2S:
"The I2S driver has been completely redesigned and refactored to use the new ESP-IDF driver. For more information about the new API, check I2S documentation."
Unlike other peripherals (Timer, LEDC, RMT) where specific removed/new APIs are enumerated, the I2S section lacks detail, suggesting substantial architectural modifications requiring complete API specification review rather than incremental updates.
Version Compatibility Matrix
Arduino Core
PlatformIO
ESP-IDF
I2S LCD Mode
Status
2.0.17
espressif32@6.4.0
4.4.7
✅ Available
✅ FastLED Works
2.0.18
espressif32@6.5.0
4.4.8
✅ Available
✅ FastLED Works
3.0.0
espressif32@6.6.0
5.1.4
❌ Removed
⚠️ FastLED Issues
3.0.1
espressif32@6.7.0
5.1.4
❌ Removed
⚠️ FastLED Issues
3.0.2+
espressif32@6.8.0+
5.1.4+
❌ Removed
⚠️ FastLED Issues
3.2.0
espressif32@?
5.x
❌ Removed
⚠️ Needs Testing
Note: Arduino Core 3.2.0 was mentioned in FastLED release notes as "now known to work" with auto-error on known bad versions, but I2S driver compatibility with Core 3.x is still problematic.
Issue #5238: "[ESP32-S2] How do I use the I2S to control a 8-bit parallel LCD?" - User directed away from I2S to dedicated LCD driver
Multiple users: Reported conflicts when mixing legacy and new I2S drivers
2. Arduino-ESP32 Repository
Issue #10786 (Dec 2024): Legacy driver conflicts - "Starting with ESP-IDF v5, new drivers have appeared... Mixing new and legacy drivers can cause malfunctions"
Issue #11004 (Feb 2025): "I2S failed to set up tx callback" with errors like "gdma_register_tx_event_callbacks(464): user context not in internal RAM"
Issue #11058: "I2S issues in v3.1.3" affecting ESP32-S3
Issue #8796: "3.0.0 version Migration related issues"
3. FastLED Repository
No specific GitHub issues found linking "ESP32 I2S" with "Arduino Core 3.0" in search results
FastLED wiki and release notes mention ESP32-Arduino Core version compatibility
Community relies heavily on staying on Arduino Core 2.0.17 for I2S support
ESP32 Forum Discussions
Forum Thread: "I2S v5.1 upgrade: conflicts" (esp32.com/viewtopic.php?t=35239)
User upgraded to ESP-IDF v5.1 by replacing driver/i2s.h with driver/i2s_std.h
Received error: "CONFLICT! The new i2s driver can't work along with the legacy i2s driver"
Issue: Cannot mix old and new driver code in same project
Resolution: Complete rewrite required; no incremental migration path
Forum Thread: "API 5.x I2S legacy issue" (esp32.com/viewtopic.php?t=35422)
Similar conflicts reported
Legacy API warnings can be suppressed with CONFIG_I2S_SUPPRESS_DEPRECATE_WARN
But mixing APIs causes runtime conflicts
Forum Discussions on I2S Parallel/LCD Mode:
Multiple threads (dating back to IDF v4.x) discuss using I2S parallel mode for LED displays
Community projects like esp_i2s_parallel (TobleMiner) widely referenced
No clear migration path to ESP-IDF 5.x for these parallel output use cases
Third-Party Library Experience
esp_i2s_parallel (TobleMiner/esp_i2s_parallel)
Popular component for parallel I2S output using LCD mode and DMA
Targets ESP-IDF 4.x (version not explicitly stated in README)
No ESP-IDF 5.x compatibility information
Transmit-only due to LCD mode limitations
Key differences between I2S0/I2S1:
I2S0: 8-bit samples must be extended to 16-bit, limited to peripheral_clk / 4
For I2S0: i2s_base_pin_index = I2S0O_DATA_OUT0_IDX (routes to pins DATA0-DATA23)
7. Bit Encoding for LED Timing
Sophisticated pulse-width encoding to match LED chipset timing (WS2812, APA102, etc.):
// Each LED data bit encoded as multiple I2S pulses// Example: WS2812 at 8MHz I2S clock (125ns per pulse)// "1" bit: 875ns HIGH → encoded as 7 pulses HIGH (7 * 125ns = 875ns)// "0" bit: 375ns HIGH → encoded as 3 pulses HIGH (3 * 125ns = 375ns)// i2s_esp32dev.cpp (lines 190-340)voidi2s_define_bit_patterns(const ChipsetTiming& TIMING) {
// Calculate optimal clock divider for chipset timing// Generate pulse patterns for "1" and "0" bits// Transpose 8x8 matrices for parallel output
}
8. ESP-IDF 5.0 Partial Compatibility Patch
FastLED includes a minimal patch for ESP-IDF 5.0:
// i2s_esp32dev.cpp (lines 23-28)
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
// Patches the i2s driver for compatibility with ESP-IDF v5.0.// This has only been compile tested. If there are issues then please file a bug.
#include"soc/gpio_periph.h"
#definegpio_matrix_out esp_rom_gpio_connect_out_signal
#endif
Critical Note: Comment states "This has only been compile tested" - runtime testing unconfirmed.
Compatibility Issues Identified
Issue 1: I2S LCD Mode Removed from Driver API
Problem: FastLED relies on i2s->conf2.lcd_en = 1 to enable LCD parallel mode, but this mode is no longer implemented by the I2S driver in ESP-IDF 5.0+.
Evidence:
ESP-IDF 5.x documentation: "LCD/Camera mode... not implemented by the I2S driver"
Redirects users to I80 Interfaced LCD driver instead
New I2S driver focuses on audio modes (Standard, PDM, TDM) only
Impact: Even if low-level registers still exist, the hardware initialization and DMA routing for LCD mode may not work as expected with the new driver architecture.
Issue 2: Potential Register Layout Changes
Problem: While soc/i2s_struct.h still exists, the HAL/LL API is marked experimental with no stability guarantees.
Evidence:
ESP-IDF docs: "Hardware abstraction API... does not adhere to API name changing restrictions"
Register layouts may change between non-major releases
i2s_dev_t structure fields could be reorganized
Risk Assessment:
Low risk for ESP-IDF 5.1.4 (Arduino Core 3.0) - register layouts likely stable within 5.x series
Medium risk for future ESP-IDF 6.x - potential breaking changes to register structures
Ongoing maintenance burden - must track ESP-IDF register changes
Issue 3: GPIO Matrix Function Renamed
Problem: gpio_matrix_out() function renamed in ESP-IDF 5.0+.
#include"hal/i2s_hal.h"#include"hal/i2s_ll.h"// Access HAL context (abstraction over registers)i2s_hal_context_thal_ctx;
i2s_hal_init(&hal_ctx, 0); // I2S0// Use LL functions for register accessi2s_ll_tx_enable(&hal_ctx);
i2s_ll_tx_start(&hal_ctx);
// ... (exact functions require ESP-IDF source code analysis)
Key API Differences
Operation
ESP-IDF 4.4
ESP-IDF 5.0+
Install driver
i2s_driver_install()
i2s_new_channel()
Configure mode
i2s_config_t (unified)
i2s_channel_init_std_mode() etc.
Set GPIO pins
i2s_set_pin()
GPIO config in std_cfg.gpio_cfg
Write data
i2s_write()
i2s_channel_write()
Start transmission
i2s_start() (if using direct regs)
i2s_channel_enable()
LCD mode enable
i2s_config_t.mode flags
❌ Not available (removed)
Direct register access
i2s_dev_t *i2s = &I2S0;
⚠️ Experimental HAL/LL only
Proposed Solutions
Solution 1: Use HAL/LL Layer with Conditional Compilation
Feasibility: Medium-High Complexity: 7/10 Maintenance Burden: High
Approach
Continue using low-level register access but migrate from direct i2s_dev_t structures to ESP-IDF HAL/LL functions. Add conditional compilation for ESP-IDF 5.x.
Pros
✅ Maintains FastLED's precision timing control
✅ Supports up to 24 parallel LED strips (vs 8 for RMT)
✅ Register headers (soc/i2s_struct.h) confirmed to still exist in ESP-IDF 5.x
✅ No fundamental architectural changes required
✅ Can keep existing bit encoding and DMA management logic
✅ Backward compatible with ESP-IDF 4.4 via #if ESP_IDF_VERSION >= ...
Cons
❌ HAL/LL API is experimental - no stability guarantees
❌ Register layouts may change in future ESP-IDF releases
❌ Requires deep ESP-IDF source code analysis to find correct LL functions
❌ Ongoing maintenance burden for each ESP-IDF major version
❌ I2S LCD mode is "not implemented by I2S driver" - uncertain if registers still work
❌ Potential conflicts with new I2S driver if both are used
❌ Limited documentation - HAL/LL APIs not in public docs
Implementation Steps
Research ESP-IDF 5.x HAL/LL I2S APIs
Examine components/hal/esp32/include/hal/i2s_ll.h in ESP-IDF source
Identify LL functions for:
Peripheral enable/reset (periph_module_enable)
Clock configuration (clkm_conf, sample_rate_conf)
LCD mode enable (conf2.lcd_en)
DMA setup (out_link.addr, out_link.start)
Interrupt configuration
Verify Register Availability
Confirm i2s_dev_t structure in ESP-IDF 5.1.4 has:
conf.tx_start, conf.tx_reset, etc.
conf2.lcd_en, conf2.lcd_tx_wrx2_en
clkm_conf, sample_rate_conf
Check for renamed or removed fields
Test LCD Mode Hardware
Create minimal test program using direct registers on ESP-IDF 5.1
Verify LCD mode still functions at hardware level
Test on ESP32 (original), ESP32-S2, ESP32-S3
Implement Conditional Compilation
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
// Use HAL/LL functions or adapted register access
#include"hal/i2s_ll.h"
#include"hal/i2s_hal.h"voidi2s_init_idf5(int i2s_device) {
// ESP-IDF 5.x initialization using HAL/LL or direct registers// ...
}
#else// Use existing ESP-IDF 4.4 codevoidi2s_init_idf4(int i2s_device) {
// Current FastLED implementation// ...
}
#endifvoidi2s_init(int i2s_device) {
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
i2s_init_idf5(i2s_device);
#elsei2s_init_idf4(i2s_device);
#endif
}
Test with WiFi/Bluetooth active (high interrupt load)
Test multiple DMA buffer sizes
Verify no conflicts with Arduino libraries using I2S
Test on multiple ESP32 variants
Code Example: Adapted Register Access
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
voidi2s_init_idf5(int i2s_device) {
i2s_dev_t *i2s = (i2s_device == 0) ? &I2S0 : &I2S1;
// Enable peripheral (function moved in IDF 5.x)if (i2s_device == 0) {
periph_module_enable(PERIPH_I2S0_MODULE);
} else {
periph_module_enable(PERIPH_I2S1_MODULE);
}
// Reset - verify register fields still existi2s_reset();
i2s_reset_dma();
i2s_reset_fifo();
// Check if LCD mode registers still accessible
i2s->conf2.lcd_en = 1;
// If this causes crash or doesn't work, LCD mode is truly unusable// Continue with existing FastLED logic// ...
}
#endif
Risk Mitigation
Runtime detection: Check if LCD mode actually works by verifying register writes
Fallback mechanism: If LCD mode fails, disable I2S driver with clear error message
Version pinning: Document tested ESP-IDF/Arduino Core versions
Community testing: Beta release for Arduino Core 3.x users to report issues
Estimated Effort
Research/prototyping: 16-24 hours
Implementation: 24-40 hours
Testing across platforms: 16-24 hours
Documentation: 8 hours
Total: 64-96 hours (8-12 developer days)
Solution 2: Migrate to High-Level I2S API (Standard Mode)
Feasibility: Low Complexity: 9/10 Maintenance Burden: Medium
Approach
Rewrite I2S driver to use new ESP-IDF 5.x channel-based API with Standard mode, abandoning LCD parallel mode.
Pros
✅ Uses officially supported API with stability guarantees
✅ Future-proof against ESP-IDF changes
✅ No conflicts with other I2S users
✅ Automatic DMA management by driver
✅ Better error handling and state management
Cons
❌ LCD mode is removed - Standard/PDM/TDM modes don't provide parallel output
❌ Standard I2S is serial (2 channels: BCLK, DOUT) not parallel (24 channels)
❌ Cannot achieve same parallel strip count as LCD mode
❌ Timing precision may be different
❌ Complete rewrite required
❌ Fundamentally incompatible with parallel LED driving requirements
Verdict
Not Viable: Standard I2S mode is for audio (serial stereo data), not parallel multi-pin output. This would require abandoning parallel LED support entirely or finding alternative peripheral.
Solution 3: Use Alternative Peripheral (Dedicated LCD Driver)
Feasibility: Low-Medium Complexity: 8/10 Maintenance Burden: Medium
Approach
Since ESP-IDF 5.x directs LCD mode users to "I80 Interfaced LCD" driver, investigate using this for parallel LED output.
Pros
✅ Officially supported in ESP-IDF 5.x
✅ Designed for parallel data transmission
✅ DMA-based transfers
✅ Stable API going forward
Cons
❌ I80 LCD driver is for display panels with specific protocol (Command/Data signals)
❌ Timing requirements different from WS2812/APA102 LED protocols
❌ May not support continuous streaming like I2S
❌ Likely limited to 16-bit parallel (vs I2S 24-bit)
❌ Significant architectural changes required
❌ Uncertain if clock precision matches LED requirements (nanosecond-level timing)
Verdict
Low Viability: I80 LCD driver is purpose-built for LCD panels, not general parallel GPIO output with arbitrary timing. Would require extensive testing to determine if it can meet LED timing requirements.
Solution 4: Hybrid Approach - RMT + GPIO Expander
Feasibility: Medium Complexity: 7/10 Maintenance Burden: Low
Approach
Use FastLED's RMT driver (already works with Arduino Core 3.0) combined with external GPIO expander chip for more strips.
Pros
✅ RMT driver fully compatible with Arduino Core 3.0
✅ No ESP-IDF version issues
✅ Clean, maintainable solution
✅ Official peripheral support
✅ Can mix different LED chipsets per strip
Cons
❌ ESP32 RMT has only 8 channels (vs 24 for I2S parallel)
❌ Requires external hardware (GPIO expander IC)
❌ Increased BOM cost
❌ Additional wiring complexity
❌ May not achieve same refresh rates as I2S
Verdict
Viable Alternative: For users who can accept 8 strips or add external hardware. Not a drop-in replacement for I2S parallel mode.
Solution 5: Stay on Arduino Core 2.0.17 (Recommended Short-Term)
Feasibility: High Complexity: 0/10 (no code changes) Maintenance Burden: None (until Core 2.x EOL)
Approach
Document Arduino Core 2.0.17 as maximum supported version for I2S users. Update ESP32_I2S_ISSUES.md with clear compatibility matrix.
Pros
✅ Requires no code changes
✅ Works reliably with I2S parallel mode
✅ Well-tested configuration
✅ No new bugs introduced
✅ Clear user guidance
Cons
❌ Misses ESP-IDF 5.x features and improvements
❌ Eventually Core 2.x will be unmaintained
❌ Doesn't solve long-term compatibility
❌ Users on Core 3.x cannot use I2S
Verdict
Best Short-Term Solution: Document this clearly while working on Solution 1 for long-term fix.
Recommended Path Forward
Phase 1: Immediate Actions (Short-Term)
Update Documentation
Enhance ESP32_I2S_ISSUES.md with findings from this report
Add explicit compatibility matrix for Arduino Core versions
Document I2S LCD mode removal in ESP-IDF 5.0+
Recommend Arduino Core 2.0.17 for I2S users
Add Arduino Core 3.x Detection Warning
#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 3
#ifdef FASTLED_ESP32_I2S
#warning "I2S parallel mode has compatibility issues with Arduino Core 3.0+. \
See ESP32_I2S_ISSUES.md for details. Recommend using RMT driver or \
downgrading to Arduino Core 2.0.17."#endif#endif
Tag with "esp32", "i2s", "arduino-core-3", "help-wanted"
Link to this investigation report
Phase 2: Research & Prototyping (Medium-Term)
Goal: Determine if Solution 1 (HAL/LL layer) is viable
ESP-IDF Source Code Analysis
Clone ESP-IDF 5.1.4 source
Examine components/hal/esp32/include/hal/i2s_ll.h
Document available LL functions for I2S configuration
Check if LCD mode registers still exist and are accessible
Hardware Testing
Create minimal test program on ESP-IDF 5.1.4 (no Arduino)
Use direct register access to enable LCD mode
Configure I2S for parallel output
Drive single LED strip to verify hardware functionality
Critical Test: Does i2s->conf2.lcd_en = 1 still work?
Conflict Testing
Test if direct register manipulation conflicts with new I2S driver
Create program that uses both high-level I2S API (for audio) and low-level registers (for LEDs)
Document any conflicts or shared state issues
Prototype Implementation
Create experimental branch: feature/esp-idf-5-i2s
Implement ESP-IDF 5.x code path using HAL/LL or direct registers
Test compilation on Arduino Core 3.0, 3.1, 3.2
Request community beta testing
Decision Point: If hardware tests show LCD mode registers don't work or conflict with new driver, abandon Solution 1 and recommend permanent migration to RMT.
Phase 3: Implementation (Long-Term)
If Solution 1 is viable:
Full Implementation
Complete ESP-IDF 5.x I2S driver code
Add comprehensive conditional compilation
Maintain backward compatibility with ESP-IDF 4.4
Update ESP32-S3 variant for GDMA compatibility
Testing Matrix
Test on Arduino Core 2.0.17, 3.0.0, 3.1.x, 3.2.x
Test on ESP32, ESP32-S2, ESP32-S3
Test with/without WiFi/Bluetooth
Test with multiple DMA buffer configurations
Verify no conflicts with Arduino I2S examples
Documentation
Update platform README
Add Arduino Core 3.x setup guide
Document limitations and known issues
Create migration guide for users on Core 2.x
Release
Merge to main branch
Release notes highlighting ESP-IDF 5.x support
Announce to community for broader testing
If Solution 1 is NOT viable:
Deprecate I2S Driver
Add deprecation warnings for FASTLED_ESP32_I2S
Update documentation to recommend RMT
Keep I2S code for ESP-IDF 4.4 users only
Enhance RMT Driver
Optimize RMT performance
Add documentation for GPIO expander use
Provide migration guide from I2S to RMT
Testing Checklist
If implementing Solution 1, the following tests are required:
Compilation Tests
Compiles on Arduino Core 2.0.17 (ESP-IDF 4.4)
Compiles on Arduino Core 3.0.0 (ESP-IDF 5.1.4)
Compiles on Arduino Core 3.1.x
Compiles on Arduino Core 3.2.x
Compiles on ESP32 (original)
Compiles on ESP32-S2
Compiles on ESP32-S3
No deprecation warnings (or warnings suppressible)
Low-level HAL functions for I2S (not in public docs)
Appendix
ESP-IDF Version Differences Summary Table
Feature
ESP-IDF 4.4
ESP-IDF 5.0+
Impact on FastLED
I2S Driver API
Unified driver/i2s.h
Mode-specific headers
Must adapt includes
LCD Parallel Mode
✅ Supported
❌ Removed from I2S
Critical Issue
Register Headers
Available
✅ Still available
✅ Can continue using
HAL/LL API Stability
N/A
⚠️ Experimental
Maintenance burden
gpio_matrix_out() Function
Available
Renamed
✅ Already patched
periph_ctrl.h Location
Public driver/
Private esp_private/
✅ Already patched
DMA Descriptor (lldesc_t)
Available
✅ Still available
✅ Can continue using
Initialization Pattern
Single function
Multi-step (alloc/init/enable)
Must adapt for 5.x
Channel Control
Controller-level
Independent TX/RX
N/A (FastLED TX only)
Register Access Macros
Expression-capable
Statement-only
⚠️ Needs verification
Testing Platforms Reference
Platform
I2S Units
DMA Type
Arduino Core 2.0.17
Arduino Core 3.0+
ESP32
I2S0, I2S1
Legacy
✅ Tested
⚠️ Needs testing
ESP32-S2
I2S0 only
Legacy
✅ Tested
⚠️ Needs testing
ESP32-S3
I2S0, I2S1
GDMA
✅ Tested
⚠️ Needs testing
ESP32-C3
I2S0 only
GDMA
Limited support
⚠️ Needs testing
Key Quotes from Research
ESP-IDF Documentation on LCD Mode Removal:
"LCD/Camera mode is only supported on I2S0 over a parallel bus. These two modes are not implemented by the I2S driver. Please refer to I80 Interfaced LCD for details."
— ESP-IDF 5.x I2S Documentation
ESP-IDF Documentation on HAL/LL Stability:
"Hardware abstraction API (excluding the driver and xxx_types.h) should be considered an experimental feature... does not adhere to the API name changing restrictions."
— ESP-IDF Hardware Abstraction Guide
FastLED Code Comment on ESP-IDF 5.0 Patch:
"Patches the i2s driver for compatibility with ESP-IDF v5.0. This has only been compile tested. If there are issues then please file a bug."
— src/platforms/esp/32/drivers/i2s/i2s_esp32dev.cpp lines 23-25
User Experience on ESP32 Forum:
"CONFLICT! The new i2s driver can't work along with the legacy i2s driver"
— ESP32.com forum thread on I2S v5.1 upgrade
Arduino ESP32 Migration Guide on I2S:
"The I2S driver has been completely redesigned and refactored to use the new ESP-IDF driver."
— Arduino ESP32 Core 3.0 Migration Guide
Document Version: 1.0 Research Date: 2025-01-11 Author: FastLED Investigation Agent (Claude) Status: Initial Research Complete
Next Steps for Maintainers
Review this report and decide on implementation priority for Solution 1
Assign developer to Phase 2 (Research & Prototyping)
Create GitHub issue linking to this report for community visibility
Set up testing environment with Arduino Core 3.x and ESP-IDF 5.1.4
Establish success criteria for hardware tests before committing to full implementation
If you have questions or need clarification on any findings, please reference specific section numbers in this report.
ESP32 I2S Investigation Report
disclaimer: AI generated, contains misinformation
Executive Summary
FastLED's ESP32 I2S parallel driver is incompatible with Arduino ESP32 Core 3.0+ (ESP-IDF 5.1+) due to a complete architectural redesign of the I2S driver that occurred in ESP-IDF 5.0. The fundamental issue is that FastLED uses direct low-level register access (
soc/i2s_struct.h,soc/i2s_reg.h) and configures I2S in LCD parallel mode - an approach that worked reliably with ESP-IDF 4.4 but conflicts with the new channel-based API architecture introduced in ESP-IDF 5.0.Key Finding: The I2S LCD mode that FastLED depends on is no longer implemented by the I2S driver in ESP-IDF 5.0+. The official documentation explicitly states: "LCD/Camera mode is only supported on I2S0 over a parallel bus. These two modes are not implemented by the I2S driver" and redirects users to dedicated LCD interface drivers instead.
Critical Discovery: While
soc/i2s_struct.hregister headers still exist in ESP-IDF 5.x (confirmed to be present in master branch as of 2025), the ESP-IDF hardware abstraction layer (HAL/LL) is marked as experimental and "does not adhere to API name changing restrictions," meaning register layouts and access patterns can change between non-major releases.Recommended Path Forward: The most viable solution is to continue using low-level register access via HAL/LL layers with conditional compilation for ESP-IDF 5.x, but this requires significant testing and carries ongoing maintenance burden as the HAL/LL API is experimental. Alternative approaches (rewriting for high-level API or switching peripherals) are less viable due to the removal of I2S LCD mode support.
Research Findings
ESP-IDF 5.0/5.1 I2S Driver Redesign
The I2S driver underwent a complete ground-up rewrite starting in ESP-IDF 5.0, which carries forward to 5.1 used by Arduino Core 3.0. This was not a simple API update but a fundamental architectural change.
What Changed in ESP-IDF 5.0
1. Driver Architecture: Controller-Based → Channel-Based
i2s_chan_handle_thandles2. Header File Reorganization
3. Initialization Pattern Completely Changed
ESP-IDF 4.4 Pattern:
ESP-IDF 5.0+ Pattern:
4. LCD Mode Removed from I2S Driver
This is the most critical issue for FastLED:
i2s_config_twith modeI2S_MODE_MASTER | I2S_MODE_TX5. ADC/DAC Mode Also Removed
ESP-IDF 5.0+ removed ADC/DAC modes from I2S driver, requiring separate peripheral drivers for audio routing.
6. State Machine Enforcement
The new driver implements strict state transitions:
7. DMA Buffer Management
While both versions use DMA, the management approach differs:
lldesc_tdma_buffer_size = dma_frame_num * slot_num * slot_bit_width / 8What Did NOT Change (Important for Solutions)
Low-Level Register Headers Still Exist:
soc/i2s_struct.h- Confirmed present in ESP-IDF master branch (2025)soc/i2s_reg.h- Register definitionssoc/gpio_sig_map.h- Signal routingrom/lldesc.h- DMA descriptor structuresHowever, the ESP-IDF Hardware Abstraction Layer documentation warns:
This means:
Arduino ESP32 Core 3.0 Implementation
Arduino ESP32 Core 3.0 is based on ESP-IDF 5.1.4 and inherits all the I2S driver changes from ESP-IDF 5.0+.
Migration Guide Findings
The official Arduino ESP32 migration guide provides minimal detail on I2S:
Unlike other peripherals (Timer, LEDC, RMT) where specific removed/new APIs are enumerated, the I2S section lacks detail, suggesting substantial architectural modifications requiring complete API specification review rather than incremental updates.
Version Compatibility Matrix
Note: Arduino Core 3.2.0 was mentioned in FastLED release notes as "now known to work" with auto-error on known bad versions, but I2S driver compatibility with Core 3.x is still problematic.
Community Experience
GitHub Issues Found
1. ESP-IDF Repository
2. Arduino-ESP32 Repository
3. FastLED Repository
ESP32 Forum Discussions
Forum Thread: "I2S v5.1 upgrade: conflicts" (esp32.com/viewtopic.php?t=35239)
driver/i2s.hwithdriver/i2s_std.hForum Thread: "API 5.x I2S legacy issue" (esp32.com/viewtopic.php?t=35422)
CONFIG_I2S_SUPPRESS_DEPRECATE_WARNForum Discussions on I2S Parallel/LCD Mode:
esp_i2s_parallel(TobleMiner) widely referencedThird-Party Library Experience
esp_i2s_parallel (TobleMiner/esp_i2s_parallel)
peripheral_clk / 4peripheral_clk / 2in 8-bit modeOther LED Matrix Projects:
Technical Analysis
Current FastLED Implementation
FastLED's I2S driver (
src/platforms/esp/32/drivers/i2s/i2s_esp32dev.{h,cpp}) uses a sophisticated low-level approach:1. Direct Register Access
FastLED includes low-level headers and directly manipulates I2S peripheral registers:
2. LCD Parallel Mode Configuration
FastLED configures I2S in LCD mode for 24-bit parallel output:
3. Clock Configuration via Register Fields
Precise clock timing calculated for LED chipset requirements:
4. Manual DMA Descriptor Management
FastLED manually creates and links DMA descriptors:
5. Custom Interrupt Handler
Direct ISR registration for DMA completion events:
6. GPIO Matrix Routing
Manual signal routing to arbitrary GPIO pins:
For I2S0:
i2s_base_pin_index = I2S0O_DATA_OUT0_IDX(routes to pins DATA0-DATA23)7. Bit Encoding for LED Timing
Sophisticated pulse-width encoding to match LED chipset timing (WS2812, APA102, etc.):
8. ESP-IDF 5.0 Partial Compatibility Patch
FastLED includes a minimal patch for ESP-IDF 5.0:
Critical Note: Comment states "This has only been compile tested" - runtime testing unconfirmed.
Compatibility Issues Identified
Issue 1: I2S LCD Mode Removed from Driver API
Problem: FastLED relies on
i2s->conf2.lcd_en = 1to enable LCD parallel mode, but this mode is no longer implemented by the I2S driver in ESP-IDF 5.0+.Evidence:
Impact: Even if low-level registers still exist, the hardware initialization and DMA routing for LCD mode may not work as expected with the new driver architecture.
Issue 2: Potential Register Layout Changes
Problem: While
soc/i2s_struct.hstill exists, the HAL/LL API is marked experimental with no stability guarantees.Evidence:
i2s_dev_tstructure fields could be reorganizedRisk Assessment:
Issue 3: GPIO Matrix Function Renamed
Problem:
gpio_matrix_out()function renamed in ESP-IDF 5.0+.Current Workaround:
Status: ✅ Already patched, but indicates broader API instability
Issue 4: Peripheral Control Header Moved
Problem:
periph_ctrl.hmoved to private API in ESP-IDF 5.0+.Current Workaround:
Status: ✅ Already handled
Issue 5: Register Access Macro Changes
Problem: ESP-IDF 5.0+ changed register access macros to statement-only (not expressions).
Evidence (ESP-IDF migration guide):
Affected Macros:
REG_WRITE,REG_SET_BIT,REG_CLR_BIT,SET_PERI_REG_BITS, etc.Impact on FastLED: Code like this may break:
Risk:⚠️ Needs verification - this could cause compilation errors or unexpected behavior
Issue 6: Conflict with New I2S Driver
Problem: Community reports that new I2S driver conflicts with direct register manipulation.
Evidence:
Impact: If Arduino Core 3.0 internally uses the new I2S driver (even for unrelated audio tasks), it might conflict with FastLED's register access.
Risk:⚠️ HIGH - This could be the primary cause of runtime issues
Issue 7: DMA GDMA Migration
Problem: ESP32-S3 and newer chips use GDMA (General DMA) instead of legacy DMA engine.
Evidence from Arduino-ESP32 Issue #11004:
Impact: DMA descriptor format and management may differ between ESP32 (legacy DMA) and ESP32-S3 (GDMA).
FastLED Status: Has separate ESP32-S3 implementation (
clockless_i2s_esp32s3.{h,cpp}) but may need ESP-IDF 5.x updates.Register/API Differences: IDF 4.4 vs 5.1
Header Files Comparison
driver/i2s.hdriver/i2s_std.h/i2s_pdm.h/i2s_tdm.hdriver/deprecated/driver/i2s.hsoc/i2s_struct.hsoc/i2s_struct.hsoc/i2s_reg.hsoc/i2s_reg.hrom/lldesc.hrom/lldesc.hsoc/gpio_sig_map.hsoc/gpio_sig_map.hdriver/periph_ctrl.hesp_private/periph_ctrl.hgpio_matrix_out()esp_rom_gpio_connect_out_signal()I2S Configuration Register Access
ESP-IDF 4.4 - Direct Register Access (FastLED's Approach):
ESP-IDF 5.0+ - High-Level Channel API (Official Approach):
ESP-IDF 5.0+ - HAL/LL Low-Level Access (Potential FastLED Path):
Key API Differences
i2s_driver_install()i2s_new_channel()i2s_config_t(unified)i2s_channel_init_std_mode()etc.i2s_set_pin()std_cfg.gpio_cfgi2s_write()i2s_channel_write()i2s_start()(if using direct regs)i2s_channel_enable()i2s_config_t.modeflagsi2s_dev_t *i2s = &I2S0;Proposed Solutions
Solution 1: Use HAL/LL Layer with Conditional Compilation
Feasibility: Medium-High
Complexity: 7/10
Maintenance Burden: High
Approach
Continue using low-level register access but migrate from direct
i2s_dev_tstructures to ESP-IDF HAL/LL functions. Add conditional compilation for ESP-IDF 5.x.Pros
soc/i2s_struct.h) confirmed to still exist in ESP-IDF 5.x#if ESP_IDF_VERSION >= ...Cons
Implementation Steps
Research ESP-IDF 5.x HAL/LL I2S APIs
components/hal/esp32/include/hal/i2s_ll.hin ESP-IDF sourceperiph_module_enable)clkm_conf,sample_rate_conf)conf2.lcd_en)out_link.addr,out_link.start)Verify Register Availability
i2s_dev_tstructure in ESP-IDF 5.1.4 has:conf.tx_start,conf.tx_reset, etc.conf2.lcd_en,conf2.lcd_tx_wrx2_enclkm_conf,sample_rate_confTest LCD Mode Hardware
Implement Conditional Compilation
Handle Arduino Core Detection
Comprehensive Testing
Code Example: Adapted Register Access
Risk Mitigation
Estimated Effort
Solution 2: Migrate to High-Level I2S API (Standard Mode)
Feasibility: Low
Complexity: 9/10
Maintenance Burden: Medium
Approach
Rewrite I2S driver to use new ESP-IDF 5.x channel-based API with Standard mode, abandoning LCD parallel mode.
Pros
Cons
Verdict
Not Viable: Standard I2S mode is for audio (serial stereo data), not parallel multi-pin output. This would require abandoning parallel LED support entirely or finding alternative peripheral.
Solution 3: Use Alternative Peripheral (Dedicated LCD Driver)
Feasibility: Low-Medium
Complexity: 8/10
Maintenance Burden: Medium
Approach
Since ESP-IDF 5.x directs LCD mode users to "I80 Interfaced LCD" driver, investigate using this for parallel LED output.
Pros
Cons
Verdict
Low Viability: I80 LCD driver is purpose-built for LCD panels, not general parallel GPIO output with arbitrary timing. Would require extensive testing to determine if it can meet LED timing requirements.
Solution 4: Hybrid Approach - RMT + GPIO Expander
Feasibility: Medium
Complexity: 7/10
Maintenance Burden: Low
Approach
Use FastLED's RMT driver (already works with Arduino Core 3.0) combined with external GPIO expander chip for more strips.
Pros
Cons
Verdict
Viable Alternative: For users who can accept 8 strips or add external hardware. Not a drop-in replacement for I2S parallel mode.
Solution 5: Stay on Arduino Core 2.0.17 (Recommended Short-Term)
Feasibility: High
Complexity: 0/10 (no code changes)
Maintenance Burden: None (until Core 2.x EOL)
Approach
Document Arduino Core 2.0.17 as maximum supported version for I2S users. Update
ESP32_I2S_ISSUES.mdwith clear compatibility matrix.Pros
Cons
Verdict
Best Short-Term Solution: Document this clearly while working on Solution 1 for long-term fix.
Recommended Path Forward
Phase 1: Immediate Actions (Short-Term)
Update Documentation
ESP32_I2S_ISSUES.mdwith findings from this reportAdd Arduino Core 3.x Detection Warning
Create Known Issues List
Phase 2: Research & Prototyping (Medium-Term)
Goal: Determine if Solution 1 (HAL/LL layer) is viable
ESP-IDF Source Code Analysis
components/hal/esp32/include/hal/i2s_ll.hHardware Testing
i2s->conf2.lcd_en = 1still work?Conflict Testing
Prototype Implementation
feature/esp-idf-5-i2sDecision Point: If hardware tests show LCD mode registers don't work or conflict with new driver, abandon Solution 1 and recommend permanent migration to RMT.
Phase 3: Implementation (Long-Term)
If Solution 1 is viable:
Full Implementation
Testing Matrix
Documentation
Release
If Solution 1 is NOT viable:
Deprecate I2S Driver
Enhance RMT Driver
Testing Checklist
If implementing Solution 1, the following tests are required:
Compilation Tests
Functional Tests
Stability Tests
DMA Buffer Tests
Conflict Tests
Platform-Specific Tests
References
Official Documentation
ESP-IDF Documentation:
Arduino ESP32 Documentation:
GitHub Issues/PRs
ESP-IDF Repository:
Arduino-ESP32 Repository:
FastLED Repository:
src/platforms/esp/32/drivers/i2s/src/platforms/esp/32/README.mdForum Discussions
ESP32 Forums:
Random Nerd Tutorials:
Code Examples
Third-Party Libraries:
ESP-IDF Examples:
esp-idf/examples/peripherals/i2s/i2s_basic/i2s_std/Technical References
Register Header Files (ESP-IDF Source):
components/soc/esp32/include/soc/i2s_struct.hcomponents/hal/esp32/include/hal/i2s_ll.hAppendix
ESP-IDF Version Differences Summary Table
driver/i2s.hgpio_matrix_out()Functionperiph_ctrl.hLocationdriver/esp_private/lldesc_t)Testing Platforms Reference
Key Quotes from Research
ESP-IDF Documentation on LCD Mode Removal:
ESP-IDF Documentation on HAL/LL Stability:
FastLED Code Comment on ESP-IDF 5.0 Patch:
User Experience on ESP32 Forum:
Arduino ESP32 Migration Guide on I2S:
Document Version: 1.0
Research Date: 2025-01-11
Author: FastLED Investigation Agent (Claude)
Status: Initial Research Complete
Next Steps for Maintainers
If you have questions or need clarification on any findings, please reference specific section numbers in this report.