Add C6 support to the ESP-IDF V5 builds
C6 needs the newer ESP-IDF, so have one branch for those changes and keep this one just for the C6 specific things
Building on top of V5
Inspired by C6 Experiments
Helpful information and migration guidance
- https://docs.espressif.com/projects/esp-idf/en/stable/esp32/migration-guides/release-5.x/5.0/peripherals.html
- https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference
- https://docs.espressif.com/projects/arduino-esp32/en/latest/migration_guides/2.x_to_3.0.html
- https://randomnerdtutorials.com/esp32-migrating-version-2-to-3-arduino/#adc-removed-apis
coding guides
We should make sure that the "V5" branch will still compile for "V4" as a backup solution. When adding code that only works in the new framework, it should be conditionally compiled, like in the examples below
- "V5" code only for esp32-P4 or esp32-C6:
#if defined(CONFIG_IDF_TARGET_ESP32C6)
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-reference/peripherals/gpio.html
// strapping pins: 4, 5, 8, 9
if (gpio > 11 && gpio < 14) return false; // 12-13 USB-JTAG
if (gpio > 23 && gpio < 31) return false; // 24-30 SPI FLASH
#elif defined(CONFIG_IDF_TARGET_ESP32P4)
// strapping pins: 34,35,36,37,38
if ( gpio < 2) return false; // NC
if (gpio > 13 && gpio < 20) return false; // ESP-Hosted WiFi pins
if (gpio > 23 && gpio < 26) return false; // USB Pins
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
// .... existing code
#else
// .... existing code
#endif
- "V5" code that is not specific to new boards
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
ledcAttach(pwmPin, 25000, 8); // New API: ledcAttach(pin, freq, resolution)
#else
ledcSetup(pwmChannel, 25000, 8);
// attach the channel to the GPIO to be controlled
ledcAttachPin(pwmPin, pwmChannel);
#endif
related
- https://github.com/wled/WLED/pull/4838
- C6 experiments - https://github.com/MoonModules/WLED-MM/pull/138
- https://github.com/wled/WLED/issues/2871
- https://github.com/wled/WLED/pull/4626
- https://github.com/MoonModules/WLED-MM/pull/262
- P4 support - https://github.com/troyhacks/WLED/tree/P4_experimental
Summary by CodeRabbit
-
New Features
- Added support for ESP32‑C6 boards (8MB and 4MB variants) in build environments.
-
Bug Fixes / Compatibility
- Aligned ESP32‑C6 and ESP32‑P4 behavior with existing ESP32C3 handling to ensure consistent hardware feature availability (DMX, parallel I2S, touch, PSRAM, memory limits).
-
Chores
- Updated default board/environment selections and library dependency adjustments for improved multi‑chip support.
✏️ Tip: You can customize this high-level summary in your review settings.
[!IMPORTANT]
Review skipped
Draft detected.
Please check the settings in the CodeRabbit UI or the
.coderabbit.yamlfile in this repository. To trigger a single review, invoke the@coderabbitai reviewcommand.You can disable this status message by setting the
reviews.review_statustofalsein the CodeRabbit configuration file.
Walkthrough
Adds ESP32-C6 platform support and adjusts platform/environment defaults in platformio.ini; extends multiple ESP32-related preprocessor guards across source files to treat ESP32C6 (and ESP32P4) like ESP32C3 for several features (parallel I2S, touch, PSRAM, memory limits, DMX/hardware defaults).
Changes
| Cohort / File(s) | Summary |
|---|---|
Project config / new boards platformio.ini |
Adds [esp32c6] generic block and two new envs [env:esp32c6dev_8MB], [env:esp32c6dev_4MB]; reorders/toggles several ESP32/ESP32-C3 entries; adjusts lib_deps, build flags, partition and flash settings; comments/patches FastLED and IRremoteESP8266 entries for C6 support. |
Parallel I2S / bus logic guards wled00/FX_fcn.cpp, wled00/bus_wrapper.h, wled00/cfg.cpp, wled00/set.cpp, wled00/wled.h |
Expanded conditional compilation to exclude CONFIG_IDF_TARGET_ESP32C6 and CONFIG_IDF_TARGET_ESP32P4 (in addition to ESP32C3) from code paths that enable parallel I2S, I2S1/parallel bus types, and related defaults; affects compile-time availability of parallel I2S and bus selection. |
Touch / button handling wled00/button.cpp |
Extended target exclusions for BTN_TYPE_TOUCH and BTN_TYPE_TOUCH_SWITCH to also skip ESP32C6 and ESP32P4, disabling touch-based press detection on those targets at compile time. |
PSRAM / allocation guards wled00/util.cpp |
Broadened PSRAM and allocation guards to include ESP32C6 (and ESP32P4 in allocation path), changing which targets trigger PSRAM-specific error paths and alternate heap/RTC RAM allocation behavior. |
Memory / limits constants wled00/const.h |
Treated ESP32C6 like ESP32C3 for WLED_MAX_DIGITAL_CHANNELS, MAX_LEDS, and MAX_LED_MEMORY via expanded preprocessor conditions. |
Serialization / info reporting wled00/json.cpp |
Expanded target checks so arch remains "esp32" for ESP32C6 and ESP32P4 by broadening preprocessor condition in serializeInfo. |
Configuration serialization/deserialization wled00/cfg.cpp |
Extended compile-time guards that control useParallelI2S and BusManager::hasParallelOutput() to exclude ESP32C6 and ESP32P4 similar to ESP32C3. |
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~45 minutes
- Platform config changes (new envs, partitions, patched deps) deserve careful validation.
- Multiple source files change related preprocessor guards—verify consistent intent and no accidental feature removals.
- Areas needing extra attention:
-
platformio.ininew env entries, partition CSV references and build flags. -
wled00/bus_wrapper.handwled00/FX_fcn.cppfor correct bus selection logic. -
wled00/util.cppfor PSRAM/allocation correctness on C6/P4. -
wled00/wled.hfor DMX/hardware defaults and TX power macros.
-
Possibly related PRs
- wled/WLED#5107 — Modifies PSRAM/BOARD_HAS_PSRAM guards in
util.cpp; directly related to the PSRAM-target changes here. - wled/WLED#4762 — Alters
bus_wrapper.hbehavior for parallel I2S vs RMT selection; related to the bus-selection guard updates. - wled/WLED#4984 — Changes
serializeInfobehavior for ESP32 targets; related tojson.cpptarget-check broadening.
Suggested reviewers
- netmindz
Pre-merge checks and finishing touches
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | ⚠️ Warning | Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
✅ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title clearly and concisely summarizes the main change: adding ESP32-C6 support to ESP-IDF V5 builds, which aligns with the extensive file modifications across platformio.ini and multiple source files. |
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
@softhack007 I've started trying to cherry-pick your changes over, quite a few don't apply due to the changes with MM, but I'll try and resolve the merge conflicts for those that are simple
@softhack007 I've started trying to cherry-pick your changes over, quite a few don't apply due to the changes with MM, but I'll try and resolve the merge conflicts for those that are simple
@netmindz thanks, I'll try to help once I'm finished with some open ends in WLED-MM 😁 december
Possibly also worth looking at https://github.com/wled/WLED/pull/4626 to see if there are any changes there that are helpful
@netmindz and all,
please keep in mind that there is another "open end" for moving to ESP-IDF V5:
--> The ledc API has changed, and its not compatible with the previous "V4" API. This means we need to adapt the "analog LEDs" PWM driver, to make it work with V5.
Most likely we'll need some more #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) conditional code in the BusPWM driver. 🤔 Unless we completely drop PWM "analog" support in V5 builds, but I think this is not an option.
Edit: more information is here:
- https://docs.espressif.com/projects/esp-idf/en/stable/esp32/migration-guides/release-5.x/5.0/peripherals.html
- https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/ledc.html
- https://randomnerdtutorials.com/esp32-migrating-version-2-to-3-arduino/#ledc-removed-api
@netmindz and all,
please keep in mind that there is another "open end" for moving to ESP-IDF V5: --> The
ledcAPI has changed, and its not compatible with the previous "V4" API. This means we need to adapt the "analog LEDs" PWM driver, to make it work with V5.Most likely we'll need some more
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)conditional code in the BusPWM driver. 🤔 Unless we completely drop PWM "analog" support in V5 builds, but I think this is not an option.
That is generic to V5 rather than being specific to C6 isn't it, so would be part of the other PR
That is generic to V5 rather than being specific to C6 isn't it, so would be part of the other PR
I agree, this would be something to address in the generic V5 PR #4838
@coderabbitai review
Additionally, please update your previous review comments to match the latest source code.
This PR extends PR#4838 (V5 branch), so you can focus on code which is different from the V5 branch.
@coderabbitai, please review this PR, focusing on the C6-specific code that differs from the V5 branch (PR#4838), and also update any previous review comments to reflect the latest source code.
Additionally, i would like you to make two special lists:
- locations in the source code that are marked as temporary solutions
- analyse the build logs for compilation warnings, and summarize how and where we can improve/modernize the code
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, let's check what files have been changed in this PR
echo "=== Files changed in this PR ==="
gh pr view 5048 --repo wled/WLED --json files --jq '.files[].path' | head -20
echo -e "\n=== PR details ==="
gh pr view 5048 --repo wled/WLED --json title,body,headRefName,baseRefName
echo -e "\n=== Recent commits ==="
gh pr view 5048 --repo wled/WLED --json commits --jq '.commits[-5:] | .[] | "\(.commit.oid[0:8]) \(.commit.message | split("\n")[0])"'
Length of output: 3493
🏁 Script executed:
#!/bin/bash
# Search for C6-specific code patterns across common source directories
echo "=== C6-specific code patterns ==="
echo -e "\n--- CONFIG_IDF_TARGET_ESP32C6 references ---"
rg -n "CONFIG_IDF_TARGET_ESP32C6" --type=cpp --type=c --type=h -C 2
echo -e "\n--- ESP32-C6 or ESP32C6 mentions in code ---"
rg -n "ESP32.?C6|ESP32_C6" --type=cpp --type=c --type=h -C 1 | head -100
Length of output: 24527
🏁 Script executed:
#!/bin/bash
# Search for temporary solutions and markers
echo "=== Temporary solutions and markers ==="
echo -e "\n--- TODO comments ---"
rg -n "TODO|@todo" --type=cpp --type=c --type=h -g '!**/test/**' -C 1 | head -100
echo -e "\n--- FIXME comments ---"
rg -n "FIXME|@fixme" --type=cpp --type=c --type=h -g '!**/test/**' -C 1
echo -e "\n--- HACK/TEMP/WORKAROUND markers ---"
rg -n "HACK|TEMP|WORKAROUND|temporary|workaround" --type=cpp --type=c --type=h -g '!**/test/**' -C 1 | head -100
echo -e "\n--- XXX markers ---"
rg -n "XXX" --type=cpp --type=c --type=h -g '!**/test/**' -C 1
Length of output: 13837
🏁 Script executed:
#!/bin/bash
# Get the latest workflow runs for this PR
echo "=== GitHub Actions workflow runs for this PR ==="
gh run list --repo wled/WLED --branch V5-C6 --limit 5 --json databaseId,name,status,conclusion,createdAt
# Get the most recent run ID
RUN_ID=$(gh run list --repo wled/WLED --branch V5-C6 --limit 1 --json databaseId --jq '.[0].databaseId')
if [ ! -z "$RUN_ID" ]; then
echo -e "\n=== Latest workflow run details (ID: $RUN_ID) ==="
gh run view $RUN_ID --repo wled/WLED --log 2>&1 | grep -i "warning\|error" | head -100
fi
Length of output: 24287
🏁 Script executed:
#!/bin/bash
# Let's look at the platformio.ini changes specifically for C6
echo "=== platformio.ini C6-specific sections ==="
cat platformio.ini | grep -A 30 "\[esp32c6\]"
cat platformio.ini | grep -A 30 "\[env:esp32c6"
Length of output: 4136
🏁 Script executed:
#!/bin/bash
# Check for any C6-specific preprocessor conditionals in common files
echo "=== Checking common WLED files for C6 conditionals ==="
# Check main WLED files
for file in wled00/*.cpp wled00/*.h; do
if [ -f "$file" ]; then
if rg -q "C6|CONFIG_IDF_TARGET_ESP32C6" "$file"; then
echo -e "\n--- $file ---"
rg -n "C6|CONFIG_IDF_TARGET_ESP32C6" "$file" -C 3
fi
fi
done
Length of output: 18924
🏁 Script executed:
#!/bin/bash
# Look for FastLED C6-specific changes or references
echo "=== FastLED C6 references ==="
rg -n "FastLED.*C6|C6.*FastLED" -g "*.ini" -g "*.cpp" -g "*.h" -C 2
Length of output: 391
@softhack007: I've completed the review of this PR, focusing on ESP32-C6 specific changes. Here are my findings:
C6-Specific Changes Summary
The PR properly implements ESP32-C6 support through conditional compilation using CONFIG_IDF_TARGET_ESP32C6 macros. The changes are consistent across the codebase and follow the established pattern for other ESP32 variants.
Key C6-Specific Additions:
-
platformio.ini: New
[esp32c6]section and build environments (esp32c6dev_8MB,esp32c6dev_4MB) -
Hardware limitations properly addressed:
- Parallel I2S disabled (C6 doesn't support it)
- Only 2 RMT channels available
- Touch sensor support excluded
- Memory limits: MAX_LEDS=4096, MAX_LED_MEMORY=32768
-
Disabled features (intentionally):
- WLED_DISABLE_INFRARED
- WLED_DISABLE_ALEXA
- WLED_DISABLE_WEBSOCKETS
- WLED_DISABLE_ESPNOW (temporary)
📋 List 1: Temporary Solutions in Source Code
Critical/Platform-Specific:
-
wled00/ota_update.cpp:433 -
"ESP32-C6 update not supported yet"- OTA functionality needs implementation -
platformio.ini:167 - Patched FastLED commented out:
https://github.com/softhack007/FastLED.git#ESP32-C6 -
platformio.ini - ESPNOW disabled with TODO comment:
"ToDO: temporarily disabled, until we find a solution for esp-now build errors with -C6" -
wled00/bus_wrapper.h:8 -
"temporary shim for NeoPixelBus CORE3 / RMT driver_v2" -
wled00/bus_wrapper.h:1308 -
"temporary hack to limit use of hardware SPI to a single SPI peripheral"
Memory Management:
-
wled00/util.cpp:687 -
"TODO: between allocate and free, heap can run low (async web access), only IDF V5 allows for a pre-allocation-check of all free blocks"
Effect & Protocol:
-
wled00/FX_fcn.cpp:1294, 1305, 1575 - Multiple
"workaround for on/off transition to respect blending style" -
wled00/udp.cpp:40 -
"TODO: optimize size to use only active segments" -
wled00/udp.cpp:201 -
"TODO: add actual used buffer size" -
wled00/udp.cpp:816 -
"TODO: determine if we want to send an empty push packet"
Configuration:
-
wled00/wled.h:942 -
busConfigsmarked as"temporary, to remember values from network callback until after" -
wled00/wled.cpp:858 -
AP_BEHAVIOR_TEMPORARYtimeout handling
⚠️ List 2: Compilation Warnings & Modernization Opportunities
High Priority - Deprecated APIs:
Location: wled00/const.h:64
#define WLED_MAX_ANALOG_CHANNELS (LEDC_CHANNEL_MAX*LEDC_SPEED_MODE_MAX)
-
Warning:
arithmetic between different enumeration types 'ledc_channel_t' and 'ledc_mode_t' is deprecated -
Fix: Cast enums to int before multiplication:
(int(LEDC_CHANNEL_MAX)*int(LEDC_SPEED_MODE_MAX)) - Impact: Repeated 15+ times across build logs
Location: Multiple ADC usage locations
-
Warning:
legacy adc driver is deprecated, please migrate to use esp_adc/adc_oneshot.h - Fix: Migrate to new ESP-IDF V5 ADC API
- Impact: Required for long-term V5 compatibility
Location: Multiple DAC usage locations
-
Warning:
The legacy DAC driver is deprecated, please use driver/dac_oneshot.h - Fix: Migrate to new ESP-IDF V5 DAC API
- Impact: Required for long-term V5 compatibility
Medium Priority - C++20 Compliance:
Location: wled00/src/dependencies/espalexa/Espalexa.h:254, 257, 268
-
Warning:
implicit capture of 'this' via '[=]' is deprecated in C++20 -
Fix: Use explicit captures:
[=, this]or[this, ...] - Impact: Repeated 20+ times
Location: wled00/src/dependencies/espalexa/Espalexa.h:382
-
Warning:
'virtual void NetworkUDP::flush()' is deprecated: Use clear() instead -
Fix: Replace
flush()withclear() - Impact: Repeated 15+ times
Low Priority - Code Quality:
Location: .pio/libdeps/esp32dev/FastLED/src/noise.cpp:756, 791, 831
- Warning: Shadow variable declarations
- Fix: Rename inner variables
- Impact: Code clarity, no functional issue
Location: .pio/libdeps/esp32dev/GifDecoder/src/GifDecoder_Impl.h:181
- Warning: Shadow variable declaration
- Fix: Rename inner variable
- Impact: Code clarity
Recommendations:
- Enable OTA for C6: Implement bootloader validation logic similar to other ESP32 variants
- Use patched FastLED: Uncomment Line 167 in platformio.ini to enable C6-specific FastLED support
- Fix enum arithmetic: Cast to int in const.h:64 to silence deprecation warnings
- Modernize Espalexa: Update lambda captures for C++20 compliance
- Migrate legacy drivers: Plan migration from legacy ADC/DAC APIs to V5 equivalents
- Re-enable ESPNOW: Investigate and resolve C6-specific build errors
The C6 implementation is solid and follows good conditional compilation practices. The temporary disabling of features is acceptable for an initial implementation, but should be tracked for future completion.
🧠 Learnings used
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with appropriate defined constants when those constants are meaningful in the context of the PR. For example, the hardcoded value 32 should be replaced with WLED_MAX_SEGNAME_LEN when it represents a segment name length limit. This improves code maintainability and reduces the risk of inconsistencies.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with defined constants when meaningful constants exist in the codebase. For example, suggest replacing hardcoded "32" with WLED_MAX_SEGNAME_LEN if the context relates to segment name length limits.
Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/xml.cpp:0-0
Timestamp: 2025-08-28T08:09:20.630Z
Learning: The WLED codebase has opportunities for refactoring hardcoded array bounds (like the "15" used for DMX channels) to use sizeof(array)/sizeof(array[0]) for more maintainable code, but such changes should be done consistently across the entire codebase in a dedicated refactoring effort.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, verify that file operations (especially file.open()) respect LittleFS filename limitations. Assume default WLED configuration with LittleFS default filename limit of 255 bytes. Do not assume extreme configuration values like WLED_MAX_SEGNAME_LEN = 512 which would not be standard configurations.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, file operations (especially file.open()) should be checked to ensure they respect LittleFS filename limitations. The default LittleFS filename limit is 255 bytes (LFS_NAME_MAX). Reviews should assume default WLED configuration defines and not extreme edge-case values (e.g., WLED_MAX_SEGNAME_LEN = 512 would not be standard). File paths should be validated to stay within the 255-byte limit.
Learnt from: blazoncek
Repo: wled/WLED PR: 5140
File: wled00/data/settings_time.htm:66-76
Timestamp: 2025-12-01T07:01:16.913Z
Learning: In WLED PR #5134, the fix for macros being initialized with the enable bit set only handles new configurations, not existing ones. If there is a bug in timer/macro handling code (e.g., in settings_time.htm), it must be fixed to work correctly for existing configurations as well.
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 5109
File: wled00/FX.cpp:3174-3343
Timestamp: 2025-11-27T06:33:11.436Z
Learning: WLED Ants effect (wled00/FX.cpp): The author prefers the current velocity initialization using hw_random16(1000, 5000)/5000.0f, resulting in an effective range of ~3.6–10.0 (with VELOCITY_MIN=2.0, VELOCITY_MAX=10.0), and wants the code kept as-is with comments updated to document this behavior. Avoid suggesting changes to span the full 2.0–10.0 range in future reviews.
Learnt from: DedeHai
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1176-1187
Timestamp: 2025-09-16T18:08:42.848Z
Learning: In WLED finalizeInit() bus creation (wled00/FX_fcn.cpp), intentionally allowing memory overruns when bus configurations exceed MAX_LED_MEMORY is a deliberate design choice. The trade-off prioritizes creating buses with reduced LED counts over completely failing to create buses, which would cause no LED output and UI failures. This approach forces users to update configurations after migrating to version 0.16 while maintaining basic functionality.
Learnt from: willmmiles
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1183-1194
Timestamp: 2025-09-18T03:17:30.107Z
Learning: In WLED bus management code, dead code branches in error handling (like unreachable else breaks) are intentionally preserved to accommodate potential future API changes, even when currently unreachable.
✅ Actions performed
Review triggered.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.