Compare commits

..

264 Commits

Author SHA1 Message Date
Frank
a67f590ee8 allow override for WLED_MAX_DIGITAL_CHANNELS
only one usecase:

WLED_MAX_DIGITAL_CHANNELS=0 on C5/C6 will prevent very frequent RMT timeout warnings.
2026-03-31 19:52:01 +02:00
Frank
65d7528af9 buildenv for P4 with 32MB flash 2026-03-30 16:41:10 +02:00
Frank
77a16f667a P4 buildenv cleanup
* removed unnecessary arduino.memory_type
* removed board_build.f_cpu (set in board manifest.json)
* added example debug flags
2026-03-30 15:58:30 +02:00
Frank
a454b31c9d restore lost build_flag for esp32dev_debug 2026-03-30 11:58:10 +02:00
Frank
ee8b019462 Merge branch 'V5' into V5-C6 2026-03-30 11:52:55 +02:00
Frank
2f402818a5 Merge branch 'main' into V5 2026-03-30 11:52:08 +02:00
Frank
7193790253 upgrade missing metadata workaround 2026-03-30 00:50:15 +02:00
Frank
1f536eed10 Merge branch 'V5' into V5-C6 2026-03-30 00:47:42 +02:00
Frank
b36ff623fb Merge branch 'main' into V5 2026-03-30 00:44:31 +02:00
Frank
10066ff608 wifi[band] fallback
show "not connected" instead of "unknown"
2026-03-29 23:03:21 +02:00
Frank
0b57cbcc17 update strapping pin info for -C61 2026-03-29 22:34:28 +02:00
Frank
e47b08938f minor improvements
* use WLED_HAVE_RTC_MEMORY_HEAP
* fix typo in comment
2026-03-29 16:04:49 +02:00
Frank
b63f2251f0 moving S3 buildenv back where it used to be 2026-03-29 15:44:48 +02:00
Frank
f4fbdbf367 Merge branch 'V5' into V5-C6 2026-03-29 15:34:11 +02:00
Frank
795c6893be ensure consistent inheritance of lib_ignore 2026-03-29 14:19:47 +02:00
Frank
97e1b8ee05 typo's in comments 2026-03-29 14:08:44 +02:00
Frank
be92bacc87 post-merge fixes 2026-03-29 13:49:38 +02:00
Frank
e04a156e78 Merge branch 'main' into V5 2026-03-29 13:30:21 +02:00
Frank
b541c1d284 Merge branch 'V5' into V5-C6 2026-03-28 11:07:21 +01:00
Frank Möhle
39335675c1 Clarify instruction on gathering information when unsure 2026-03-28 11:06:49 +01:00
Frank Möhle
8f951f5068 Update copilot instructions for clarity and guidance
Added instructions for handling uncertainty and providing references.
2026-03-28 11:06:49 +01:00
Will Tatam
0f538eb155 do not keep prompting if there was an error, e.g no wifi 2026-03-28 11:06:49 +01:00
Frank
3cb3ff5223 V5 build 2603281 2026-03-28 02:20:31 +01:00
Frank
e53500f042 V5 build 2603281 2026-03-28 02:19:39 +01:00
Frank
c312f51050 revive device fingerprint in V5
* mbedtls_sha1_... functions have different names
* use CONFIG_SOC_ADC_RTC_MAX_BITWIDTH
* legacy adc calibration API is not supported on new MCUs (-C5, -C6, -C61, -P4)
2026-03-28 01:25:43 +01:00
Will Tatam
7670246a3b do not keep prompting if there was an error, e.g no wifi 2026-03-28 00:22:46 +00:00
Frank
e362891b8f revive device fingerprint in V5
* mbedtls_sha1_... functions have different names
* use CONFIG_SOC_ADC_RTC_MAX_BITWIDTH
* legacy adc calibration API is not supported on new MCUs (-C5, -C6, -C61, -P4)
2026-03-28 00:54:18 +01:00
Frank
dfba1e97e6 C5: NTP temporarily disabled as it causes crashes
assert failed: udp_new_ip_type udp.c:1278 (Required to lock TCPIP core functionality!)
2026-03-27 21:26:48 +01:00
Frank
61f3c6c379 C5: AP mode needs WIFI_BAND_MODE_AUTO 2026-03-27 21:22:44 +01:00
Frank
9a07784c67 tiny change
debug output
2026-03-27 20:19:03 +01:00
Frank
33ffbd5927 clarify debug output
esp-idf, not esp32
2026-03-27 20:18:24 +01:00
Frank
0629720821 Use WLED_BOARD as the single node-type source of truth.
collapse to one assignment, and stop drifting when new boards might be added.
2026-03-27 19:47:59 +01:00
Frank
daed02723f add pin info for new MCU's
based on data sheets, still to be validated on each board
2026-03-27 19:37:20 +01:00
Frank
3bd5f03140 C6 workaround for " WLED_VERSION was not set"
temporary
2026-03-27 19:34:22 +01:00
Frank
96cd51aa77 prelim. pin validation for -C61
not tested, just a first impression from datasheets
2026-03-27 18:25:34 +01:00
Frank
72b47710af C5 buildenv cleanup
no special overrides remaining
c5 build compiles with the standard "CORE3" NeoPixelBus
2026-03-27 16:56:04 +01:00
Frank
dd048b8c23 fix for C5 build
ToDO: check if the special library list is still needed on -C5
2026-03-27 15:44:57 +01:00
Frank
40b4d55edf prefer softhack no_fastled (temporary)
temporary replacement until WLED has its own fastled-slim ready.

The softhack007 fork version is proven-in-use on the fork from @troyhacks, and completly removes any global functions or ISRs when compiling with -D FASTLED_NO_FASTLED
2026-03-27 15:35:53 +01:00
Frank
2a57177a2d revert UI hack 2026-03-27 14:42:42 +01:00
Frank
868fbf3714 revert hack in set_metadata.py 2026-03-27 14:39:02 +01:00
Frank
51af4ecb08 Merge branch 'V5' into V5-C6 2026-03-27 14:35:23 +01:00
Frank
758bdd537c replace preprocessor #error with static_assert
ensures that constexpr constants are handled properly.
2026-03-27 13:27:35 +01:00
Frank
e834de2212 make WLED_MAX_BUSSES constexpr
prevent macro expansion problems, because  WLED_MAX_ANALOG_CHANNELS is a constexpr now.
2026-03-27 13:20:23 +01:00
Frank
3a2674a1f1 toDO: clarify if the ipv6 DNS workaround is still necessary 2026-03-27 12:26:07 +01:00
Frank
eeeb93cdc5 Merge branch 'main' into V5 2026-03-27 12:19:56 +01:00
Will Miles
58239ced02 Fix RMT bus drivers for v5
Use a simpler shim in bus wrapper, and clean up the HI driver to
indicate that it's not v5 compatible (yet).
2026-03-26 18:43:04 -04:00
Will Miles
4f7b574d22 dynarray: Directly apply linker fix
Rather than append a linker file, we edit the upstream supplied ones to
add our section to the binaries.  Works better on all platforms.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-26 18:41:59 -04:00
Will Miles
b222940ad1 Env cleanup 2026-03-26 18:41:59 -04:00
Will Miles
0d539c524c Merge branch 'main' into V5 2026-03-25 19:29:45 -04:00
Frank
02fc15ffd1 Merge branch 'main' into V5 2026-03-11 18:15:09 +01:00
Frank
541eb72d67 Merge branch 'main' into V5 2026-03-10 21:19:30 +01:00
Frank Möhle
e0164fc502 Add esp32-C61 bootloader offset
C61 uses the same offset as C6
2026-03-10 20:05:45 +01:00
Frank Möhle
9e6c927d50 Fix preprocessor directive syntax for ESP32 2026-03-10 19:11:50 +01:00
Frank
49f2208a4e Merge branch 'main' into V5 2026-03-10 19:07:06 +01:00
Frank Möhle
bae62d2caf Use C3 defaults for all new MCUs (C5, C6, P4) 2026-03-10 19:06:14 +01:00
Will Tatam
493f0fe952 Merge branch 'main' into V5 2026-03-08 16:21:55 +00:00
Frank
2af98d49a1 build_unflags should always come from same origin as platform
fixes inconsistencies
2026-03-02 11:57:20 +01:00
Frank
e3bebc0674 build_unflags should always come from same origin as platform
fixes inconsistencies
2026-03-02 11:51:57 +01:00
Frank
fc2ffed61c -alpha-V5 --> -alphaV5
version tag renaming
2026-03-01 23:31:27 +01:00
Frank
1f4cadc629 -alpha-V5 --> -alphaV5
version tag renaming
2026-03-01 23:31:04 +01:00
Frank
27a6fadce9 bugfix: prevent array bounds violations due to short WS payload data
Guard against zero-length binary payloads before dereferencing data[0] or data[1]
2026-03-01 22:37:51 +01:00
Frank
1a91db1f01 bugfix: prevent array bounds violations due to short WS payload data
Guard against zero-length binary payloads before dereferencing data[0] or data[1]
2026-03-01 22:35:41 +01:00
Frank
d4b0360f8b bugfix: right shift on signed char is unsafe
Fix signed-byte handling in SHA256 hex conversion.

When bootloaderSHA256Cache bytes >= 0x80 are assigned to a signed char, they sign-extend to negative values. Right-shifting negative values produces incorrect results (e.g., 0xFF becomes -1, which shifts incorrectly). This causes wrong hex digit output for non-ASCII hash bytes.
2026-03-01 22:10:37 +01:00
Frank
80e81eeccc bugfix: right shift on signed char is unsafe
Fix signed-byte handling in SHA256 hex conversion.

When bootloaderSHA256Cache bytes >= 0x80 are assigned to a signed char, they sign-extend to negative values. Right-shifting negative values produces incorrect results (e.g., 0xFF becomes -1, which shifts incorrectly). This causes wrong hex digit output for non-ASCII hash bytes.
2026-03-01 22:10:11 +01:00
Frank
fc313e1e96 pioarduino 55.03.37 (-C5 and -P4 only) 2026-03-01 21:58:27 +01:00
Frank
511ff789b5 Merge branch 'V5' into V5-C6 2026-03-01 21:48:12 +01:00
Frank
8f44f1b395 bump build number to 2603011 2026-03-01 21:30:22 +01:00
Frank
19f7cb19a9 AsyncTCP @ 3.4.7 2026-03-01 21:29:52 +01:00
Frank
b4194b3a32 upgrade to latest V5 tasmota platform
solves "Don't know how to build from a source file with suffix `.o'." build errors
2026-03-01 21:05:44 +01:00
Will Tatam
6b7ecb969b Merge pull request #5401 from wled/dependabot/npm_and_yarn/minimatch-10.2.4
Bump minimatch from 10.2.2 to 10.2.4
2026-03-01 20:52:46 +01:00
Will Tatam
f1fe20d73e Merge pull request #5128 from willmmiles/cleanup-bootloader-sha
Cleanup bootloader SHA256 calculation from #4984
2026-03-01 20:52:09 +01:00
Will Tatam
4e81f272b8 Merge pull request #5393 from wled/dependabot/npm_and_yarn/multi-8e762eef80
Bump minimatch and nodemon
2026-03-01 20:52:09 +01:00
Will Tatam
b3e7e7e8c0 Merge pull request #5357 from netmindz/idf_4_4_8
Upgrade platform to 4.4.8
2026-03-01 20:52:09 +01:00
Frank
8fcdbe698f Merge branch 'V5' into V5-C6 2026-02-28 21:26:20 +01:00
Frank
82723a03aa Update package-lock.json
align version with package.json
2026-02-28 21:23:17 +01:00
Frank Möhle
dcf0a2aaea Update package.json with SemVer compliant version string
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-02-28 21:08:55 +01:00
Frank
85cff89bf0 dependancies update
* switch to FastLED "no fastled" fork - removes RMT driver conflicts, reduces firmware size
* update to latest "CORE3" NeoPixelBus
2026-02-28 20:53:45 +01:00
Frank
c76cb5cc9a dependancies update
* switch to FastLED "no fastled" fork - removes RMT driver conflicts, reduces firmware size
* update to latest "CORE3" NeoPixelBus
2026-02-28 20:37:47 +01:00
Frank
fb877adcb2 P4 buildenv update
${common.build_flags} was missing
2026-02-26 16:37:03 +01:00
Frank
2ce38700b1 P4 does not have on-chip WiFi, use ETH MAC instead 2026-02-25 11:52:47 +01:00
Frank
d3b8d9635e more typos and comment corrections 2026-02-25 01:09:19 +01:00
Frank
491546bad0 typo's 2026-02-25 00:56:03 +01:00
Frank
3abd8c7149 P4: auto-update esp-hosted WiFi coprocessor 2026-02-25 00:43:07 +01:00
Frank
21233894ff P4 buildenv update 2026-02-25 00:41:41 +01:00
Frank
aadabe9885 credits 2026-02-24 21:04:31 +01:00
Frank
5c9803db4b P4 buildenv update 2026-02-24 21:01:37 +01:00
Frank
ed0fadd80c esp32-P4 pins (will clean up later) 2026-02-24 20:57:47 +01:00
Frank
0c6c66b35b remove touchButtonISR() on boards that don't suport it
fixes compiler warning related to ignored attributes

wled00/button.cpp:399:31: warning: ignoring attribute 'section (".iram1.1")' because it conflicts with previous 'section (".iram1.0")' [-Wattributes]
  399 | void IRAM_ATTR touchButtonISR()
2026-02-24 18:40:46 +01:00
Frank
908e17bbfc 16.0-V5alpha --> 16.0-alpha-V5 2026-02-24 11:24:24 +01:00
Frank
2802f8cba6 adding monitor_filters 2026-02-23 23:14:25 +01:00
Frank
2820331b5e 16.0-V5alpha --> 16.0-alpha-V5 2026-02-23 23:12:51 +01:00
Frank
9959f75a8e (experimental) buildenv for P4
it compiles, but not yet usable !!!
2026-02-23 23:11:58 +01:00
Frank
a425b97a93 minor buildenv cleanup 2026-02-23 22:22:36 +01:00
Frank Möhle
cffc57e578 make LED settings work, by pretending to be a c3
temporary workaround, to prevent that more than the possible 2 digital outputs are configured by users
2026-02-20 20:41:34 +01:00
Frank
acc98d47e0 Merge branch 'V5' into V5-C6 2026-02-14 23:40:40 +01:00
Frank
6c0c2b3ff8 version bump 16.0-V5alpha
for V5 branch binaries
2026-02-14 23:39:52 +01:00
Frank
fb8c575def change version scheme to Major.minor, drop leading "0."
as agreed in #5249
2026-02-14 23:35:49 +01:00
Frank
1bda0bf639 Merge branch 'V5' into V5-C6 2026-02-12 19:11:49 +01:00
Frank Möhle
dfcec5c94b use correct function
Update ledcAttach to ledcAttachChannel
2026-02-12 18:16:44 +01:00
Frank Möhle
f2cbf0cc50 Add channel parameter to ledcAttach function
keep same behaviour as in previous V4 code
2026-02-12 18:10:40 +01:00
Frank
3de117ba23 typo 2026-02-12 11:16:41 +01:00
Frank
967f6ab2bd Merge branch 'V5' into V5-C6 2026-02-12 11:10:40 +01:00
Frank
993ab49b15 Merge branch 'main' into V5 2026-02-12 11:07:36 +01:00
Frank Möhle
f3f736d399 espalexa: Cleanup dummy macro for 8266 2026-02-11 17:19:26 +01:00
Frank
7ce497b1f7 fix broken ifdef chain in wled.h 2026-02-11 17:01:17 +01:00
Frank
c96e28924f espalexa: better handling of fake ESP_IDF_VERSION_VAL 2026-02-11 16:39:03 +01:00
Frank
c1dddeafc4 ermove duplicate extern references
these variables are defined in wled.h, which is included already.
2026-02-11 12:09:23 +01:00
Frank
4117d31cc0 add esp-idf managed folders to .gitignore 2026-02-11 10:53:26 +01:00
Frank
5e073ce76c add esp-idf managed folders to .gitignore 2026-02-11 10:48:33 +01:00
Frank
deaae112a3 missed one 2026-02-11 01:52:33 +01:00
Frank
ede8a14421 ifdef fixes
* shortened another mega-ifdef
* added missing CONFIG_IDF_TARGET_ESP32C61
2026-02-11 00:57:09 +01:00
Frank
46a1b2f190 clarification
according to espressif docs, this is "maximum TX power" not "TX power"
2026-02-11 00:34:16 +01:00
Frank
55eee941f7 support higher Tx power (V5 only)
allow max Tx power = 21 dBm if framework supports it.
If not supported, silently clamp to 19.5 dBm.
2026-02-11 00:28:28 +01:00
Frank
f8a6790e3c 5Ghz wifi scanning
* remove last scan results when changing band mode
* set band mode before starting a new scan
2026-02-10 23:56:22 +01:00
Frank
e046316545 add channel to wifi scan result list (wifi settings) 2026-02-10 23:47:34 +01:00
Frank
b730ce8850 removing another mega guard 2026-02-10 22:25:04 +01:00
Frank
f8df68cf82 tiny change 2026-02-10 22:18:33 +01:00
Frank
703b90fe88 Merge branch 'V5' into V5-C6 2026-02-10 21:47:51 +01:00
Frank
a8f9573fc3 nitpick
* remove duplicated -D WLED_DISABLE_INFRARED
* fix indentation in WLED::initConnection()
2026-02-10 21:40:43 +01:00
Frank
3243c88055 Merge branch 'main' into V5 2026-02-10 21:26:18 +01:00
Jonathan Davey
a39285a927 Add WiFi band preference for dual-band ESP32 chips (#5367)
Adds a user-configurable "WiFi band" dropdown to the WiFi settings
page: 2.4 GHz only, 5 GHz only, or Auto (both). Defaults to Auto.

Uses WiFi.setBandMode() from the Arduino ESP32 core (requires
IDF 5.4.2+), guarded by #ifdef SOC_WIFI_SUPPORT_5G. Replaces
the hardcoded WIFI_BAND_MODE_AUTO call in V5-C6 with a
user-selectable setting.

Changes:
- wled.h: new wifiBandMode variable (default WIFI_BAND_MODE_AUTO)
- cfg.cpp: serialize/deserialize with input validation (1-3 range)
- set.cpp: handle BM form param with validation, trigger reconnect
- xml.cpp: populate dropdown value, hide on non-5G chips
- wled.cpp: pass wifiBandMode to WiFi.setBandMode() in initConnection()
- settings_wifi.htm: dropdown in Experimental section

Tested on ESP32-C5 hardware - all three modes work correctly.
2026-02-10 21:06:02 +01:00
Frank
08ca41b96d expand chip-specific "if defined" to C61 and P4 (future support)
Main objective is to fnd out how far away we are from a build for the -P4. I'll clean up the "if def" mess later.
2026-02-10 19:55:36 +01:00
Frank
c6739d380f ToDo: adjust Wi-Fi stregth to match value allowed by V5 framework
change from uint8_t to int8_t (also verify backwards compatibility for V4)

V5 allows WIFI_POWER_21dBm = 84 ... WIFI_POWER_MINUS_1dBm = -4. Also check if the UI can handle it.
2026-02-10 18:54:19 +01:00
Frank
1009855e89 shorten some more ifdef chains in wled.h
plus: allow LOLIN_WIFI_FIX on all boards
2026-02-10 18:52:56 +01:00
Frank
546384bbba fixing minor errors 2026-02-10 16:54:52 +01:00
Frank
71cf78be59 Merge branch 'V5' into V5-C6 2026-02-10 16:51:03 +01:00
Frank
4f9c48fd39 consistency fix 2026-02-10 16:36:06 +01:00
Frank
cd911ae0db oopsie 2026-02-10 16:24:40 +01:00
Frank
d823ab4a94 replace some very long if defined() chains with flags from wled_boards.h
proof of concept.
2026-02-10 16:21:37 +01:00
Frank
edf0cbed4a adding wled_boards.h to reduce #if defined() .. clutter
This should be the central place to define per-board capability flags
2026-02-10 16:20:16 +01:00
Frank
7014d4f98b nitpick: fixing another case of "comparing unsigned to integer is undefined behaviour"
the new GCC is a bit more picky than older compiler versions
2026-02-10 14:20:18 +01:00
Frank
ed6b82b2f6 repeat WiFi.setBandMode() in initConnection()
lesson learned: repeat Wifi.setBandMode() after each start of STA interface
2026-02-10 13:30:00 +01:00
Frank
ab65e9fb5f C5: change NeoPixelBus reference to "wled-c5-stable" tag 2026-02-10 13:11:09 +01:00
Frank
b128585618 fix compiler warning "comparing signed with unsigned is undefined behaviour" 2026-02-10 12:53:51 +01:00
Frank
f02e6b6c02 proper wifi channel & band reporting
replace educated guess (ch > 33 -> 5Ghz) with direct info from Wifi Class
2026-02-10 12:53:04 +01:00
Frank
d3251c57f9 Use Wifi class method to activate 5Ghz Wifi
mixing esp-idf and arduino-syle WiFi = problems
2026-02-10 11:50:01 +01:00
Frank
b72568f5c8 ESP32-C5 does not support analog dithering (yet)
use official esp-idf API function (no dithering)
2026-02-10 11:47:39 +01:00
Frank Möhle
7b99f65341 Fix lost build_unflags in esp32dev_debug 2026-02-09 22:20:37 +01:00
Frank
6e70d0c45e clarification 2026-02-09 19:36:43 +01:00
Frank
e104529329 move 5Ghz init after WiFi.mode(WIFI_STA)
* setting the band mode fails if the driver is not initialized yet
* added error checking
2026-02-09 19:31:36 +01:00
Frank
576e82bcbd report errors from 5Ghz wifi config 2026-02-09 19:03:33 +01:00
Frank
5b46b9cb21 experimental: enable 5Ghz WiFi on C5
does not always work
2026-02-09 17:02:52 +01:00
Frank
d8616e69bf C5/C6 minor updates
* testing code to fake missing DeviceID (commented out)
* remove WLED_DISABLE_WEBSOCKETS
* use correct board.json for C5 "N8R4" (8MB with PSRAM)
2026-02-09 16:57:20 +01:00
Frank
8159768e81 ToDO: research how to set PWM duty cycle and hpoint for dithering
latest esp-idf 5.5.x, including C5
2026-02-09 12:19:32 +01:00
Frank Möhle
7370c100aa remove dead (and dangerous) mutex macros in bus_manager.cpp (#5364)
these macros are
* not used any more
* dangerous because they don't time out
* dangerous because they use an internal mutex of the ledc driver (not part of the LEDC API)
2026-02-09 11:51:12 +01:00
Frank
d7ab1f4691 Merge branch 'V5' into V5-C6 2026-02-09 00:57:26 +01:00
Frank
21d0af1094 Merge branch 'main' into V5 2026-02-09 00:56:41 +01:00
Frank
9d63296783 fix debug delay condition in wled.cpp
simplify and correct the condition. it was never correct to assume that all C3/S2 need a delay, because boards with UART-to-USB chip don't need any wait.
2026-02-09 00:16:42 +01:00
Frank
1800a32caf align index.js with chip types from nodestruct.h
with some "future support" for P4 and C61
2026-02-09 00:11:34 +01:00
Frank
be49f34a00 add include guard for esp_mac.h 2026-02-09 00:08:03 +01:00
Frank
9232bd4d76 correct straping pin comments in pinManager 2026-02-08 20:26:10 +01:00
Frank
3c24681881 ifdef guards alignment
* Add ESP32-C6 to the fast-path division guards
* exclude C6 and P4 from from digitalCount tracking (I2S memory calculation)
2026-02-08 20:20:28 +01:00
Frank
6b9f90c1dc remove outdated patched libs for C6 2026-02-08 19:15:10 +01:00
Frank
b30951e674 C6 buildenv cleanup
* re-enable alexa
* remove duplicate WLED_DISABLE_ESPNOW
2026-02-08 19:11:16 +01:00
Frank
0920f0fdcf extend some chip type guards for C6 and P4 2026-02-08 19:00:28 +01:00
Frank
8b98a7ac9e future support: adding C61 and P4 to esp32RMTInvertIdle() guard 2026-02-08 18:20:54 +01:00
Frank
e9b1a53149 PSRAM guard bugfix
accidentally used IDF_TARGET_.. instead of CONFIG_IDF_TARGET_..
2026-02-08 18:17:03 +01:00
Frank
20dd750b9b alexa build error was already solved in V5 branch 2026-02-08 17:49:06 +01:00
Frank
b860a1ad28 fix incorrect PSRAM warning on C5 and C6 2026-02-08 17:43:27 +01:00
Frank
a3a3547fa5 adding [env:esp32c5dev_8MB_qspi]
experimental buildenv for C5 with PSRAM and 8MB flash
2026-02-08 17:42:55 +01:00
Frank
a1a190510a simplify C5 buildenv
* removed flags that are inherited as-is from [esp32c5]
* slightly restructured buildenv
2026-02-08 17:33:18 +01:00
Frank
b2e0c243b7 simplify and correct some long ifdef chains
* C5: allow BOARD_HAS_PSRAM
* assign MIN_FRAME_DELAY based on number of CPU cores
2026-02-08 17:07:59 +01:00
Frank
16262ee424 platformio.ini: moving [esp32c5] upwards
so its between the generic sections for S3 and C6
2026-02-08 16:50:37 +01:00
Frank
6cefd14176 fix C5 build error
adjustment needed due to modified lib_deps hierarchy in V5
2026-02-08 16:43:39 +01:00
Frank
83c37f8245 Merge branch 'V5' into V5-C6 2026-02-08 16:14:24 +01:00
Frank Möhle
f0acc626bd Merge pull request #5355 from jonny190/ESP32-C5-V5
Add experimental ESP32-C5 support (WiFi 6 dual-band)
2026-02-08 15:54:36 +01:00
Jonny Davey
1a025f5636 Fix MAC address on ESP32-C5 and update NeoPixelBus fork
- Fix WiFi.macAddress() returning all zeros on ESP32-C5 by falling back
  to esp_read_mac() when WiFi netif is not yet created
- Update NeoPixelBus fork to latest with channel ctor overload fix
- Enable WLED_DEBUG, remove WLED_DISABLE_WEBSOCKETS for C5 build
2026-02-08 11:20:29 +00:00
Frank
4069260e61 remove double WLED_USE_SHARED_RMT in V5 core buildenv 2026-02-08 03:44:12 +01:00
Frank
1c09d34d12 bugfix 2026-02-08 03:39:32 +01:00
Frank
692c812934 buxfixes for generic S3 buildenv 2026-02-08 03:34:12 +01:00
Frank
9484b42b40 adding 8266 regression testing build
to check if 8266 code was broken accidentally
2026-02-08 03:26:22 +01:00
Frank
6dff1d2cb1 more V4 vs V5 compatibility fixes 2026-02-08 03:25:20 +01:00
Frank
929777507c 8266 dummy macro ESP_IDF_VERSION_VAL 2026-02-08 02:23:47 +01:00
Frank
d76bd5fe59 fix esp32dev_V4 build
* disable "temporary shim for NeoPixelBus CORE3" for V4
* better way to prevent compiling NeoEsp32RmtHIMethod
2026-02-08 01:54:47 +01:00
Frank
1b5f10ff6d temporarily remove esp_dmx from V4 2026-02-08 01:40:55 +01:00
Frank
97b2c7a44f bugfix:implicit capture of 'this' via '[=]' is deprecated in C++20 2026-02-08 01:40:05 +01:00
Frank
56beb3795e add esp32dev_V4, fix compatibility issues with V4, fix for deprecated udp.flush()
* add esp32dev_V4 for regression checking w.r.t. V4 framework
* bring back lost V4 code
* udp.flush() is deprecated --> udp.clear()
2026-02-08 01:24:47 +01:00
Frank
68a8812942 adding WLED_USE_SHARED_RMT for all V5 builds
plus
- re-enabled one S3 and one S2 build
- disabled c++20 deprecation warnings
- minor indentation fix
2026-02-08 00:35:59 +01:00
Jonny Davey
d2e6a568ba Use NeoPixelBus fork with ESP32-C5 bit-bang and I2S fixes
Replace upstream NeoPixelBus with jonny190/NeoPixelBus fork (d4bbe3f)
which adds C5 to the I2S exclusion guard and fixes the bit-bang LED
output method (cycle counter CSR 0xC00, GPIO register types).

Spell out C5 lib_deps explicitly to avoid pulling both the upstream
and fork NeoPixelBus, which causes duplicate compilation errors.

Upstream PR: https://github.com/netmindz/NeoPixelBus/pull/1
2026-02-07 21:52:22 +00:00
Will Tatam
0b248abd3b TODO: disabled NeoEsp32RmtMethodIsr 2026-02-07 19:36:34 +00:00
Will Tatam
a57e895bb9 Merge branch 'main' into V5 2026-02-07 19:28:12 +00:00
Jonny Davey
5137768a8f Address PR review: pin pioarduino, fix I2S1 remap, simplify arch check 2026-02-07 18:13:12 +00:00
Will Tatam
35706f0940 Apply suggestion from @coderabbitai[bot] for WiFi band
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-02-07 17:52:08 +00:00
Jonny Davey
11f5be1861 Removed Leftover file 2026-02-07 17:02:22 +00:00
Jonny Davey
8268c4a948 Applied changes based on comments on PR 2026-02-07 16:16:11 +00:00
Jonny Davey
01b1c51653 Add experimental ESP32-C5 support with WiFi 6 dual-band
ESP32-C5 is a RISC-V based SoC with WiFi 6 (2.4GHz + 5GHz) support.
Treats C5 similarly to C3 for hardware capabilities (2 RMT channels,
no parallel I2S for LEDs, similar GPIO restrictions).

Changes across 25 files:
- Add CONFIG_IDF_TARGET_ESP32C5 conditionals alongside C3/C6 checks
- Add [esp32c5] and [env:esp32c5dev] build environments in platformio.ini
- Uses pioarduino platform (Tasmota framework lacks C5 Arduino libs)
- Exclude esp_dmx library (doesn't support C5 UART registers yet)
- Fix LEDC register access for IDF 5.5.0 (duty_init vs duty)
- Guard mbedtls_sha1_shim for IDF 5.5.0 (SHA1 built-in)
- Add C5 chip identification (ID: 0x0017) in OTA and web UI

Known limitations:
- RMT LED output shows flush timeouts (needs NeoPixelBus C5 support)
- WiFi AP confirmed working on hardware
- esp_dmx/DMX input disabled
- Experimental: requires pioarduino community platform

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 13:37:50 +00:00
Frank Möhle
cf09c0dd1e Comment out '#pragma warning' suppression flag
Comment out the warning suppression for '#pragma warning' messages.
2026-02-07 01:32:05 +01:00
Frank Möhle
2f267a8a14 Merge pull request #5114 from karan-vk/esp32c6-fixes
Fix ESP32-C6 GPIO pin validation and improve runtime compatibility
2026-01-10 02:12:15 +01:00
Karan Vijayakumar
4ebbd866c4 Use Aircoookie/ESPAsyncWebServer v2.4.2 instead of softhack007 fork
- Upgrade to newer ESPAsyncWebServer that has deferResponse() and queue features
- Remove deferResponse() wrapper function from fcn_declare.h
- Remove AsyncWebServer constructor conditional from wled.h
- Revert json.cpp, set.cpp, wled_server.cpp to use native deferResponse()

This addresses @willmmiles feedback to use the proper library instead of workarounds.
2025-12-10 02:44:57 +09:00
Karan Vijayakumar
d2c13135b6 Fully revert .vscode/extensions.json to base branch 2025-12-10 02:44:01 +09:00
Karan Vijayakumar
e4d6848d1b Revert .vscode/extensions.json 2025-12-10 02:44:01 +09:00
Karan Vijayakumar
c92abb8dfc Address PR comments: cleanup and safety improvements
- Revert VSCode extension changes
- Remove unused QuickDebug dependency
- Revert GifDecoder hash to short form
- Harden selectedWiFi index calculation in network.cpp
2025-12-10 02:44:00 +09:00
Karan Vijayakumar
ec44fd167a Add ESP32-C6 pin validation for strapping and USB-JTAG pins 2025-12-10 02:41:34 +09:00
Karan Vijayakumar
d3e92f26c0 Fix ESP32-C6 runtime crash and improve compatibility
- Fix IPAddress comparison with 0U causing null pointer dereference in initConnection()
- Add bounds checking for selectedWiFi index before array access
- Add ESP32-C6 conditional for touch sensor exclusion (C6 has no capacitive touch)
- Add deferResponse() wrapper for C6's patched ESPAsyncWebServer
- Add early return in esp32RMTInvertIdle() for C6 (no RMT support)
- Add ESP32-C6 BitBang bus creation in bus_wrapper.h
- Update platformio.ini with proper C6 build flags and dependencies
- Use patched FastLED, AsyncTCP, and ESPAsyncWebServer forks for C6 support
2025-12-10 02:41:34 +09:00
Frank
f88fd073a3 temporary workaround for #5145 2025-12-02 00:00:31 +01:00
Frank
9f12301128 esp32c6 inherits build_unflags and lib_ignore from V5 buildenv 2025-12-01 23:59:50 +01:00
Frank
7b54be849f Merge branch 'V5' into V5-C6 2025-12-01 23:53:35 +01:00
Frank
29c7b50727 fix stupid warning for c files 2025-12-01 23:48:15 +01:00
Frank
5d54597ffc change dependancy logic for proper inheritance of build_unflags and lib_ignore
* esp32_idf_V5 has the main build_unflags and lib_ignore
* next level (esp32, esp32s3, esp32s2, esp32c3) inherits from esp32_idf_V5
* user buildenvs _only_ inherit from (esp32, esp32s3, esp32s2, esp32c3)
2025-12-01 23:47:37 +01:00
Frank
0b27bc37bd fix compiler warning for WLED_MAX_ANALOG_CHANNELS
in V5, LEDC_CHANNEL_MAX and LEDC_SPEED_MODE_MAX are enum constants, and the compiler does not allow a macro where enums are implicitly treated as int.
Solution: change into constexpr with static type cast => still computed by the compiler and does not create any local variable.
2025-12-01 23:41:12 +01:00
Frank
bc4b6b6a2b Merge branch 'V5' into V5-C6 2025-12-01 20:58:59 +01:00
copilot-swe-agent[bot]
8ea41cf2d2 Remove push trigger, only run usermods CI for external fork PRs
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
2025-12-01 20:53:44 +01:00
copilot-swe-agent[bot]
5ef41e7d3b Fix usermods.yml to only run for external fork PRs
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
2025-12-01 20:53:44 +01:00
Frank
2245e0e0df optional: newer tasmota core 2025-12-01 20:53:08 +01:00
Frank
5ecf76c1aa Merge branch 'V5' into V5-C6 2025-12-01 20:30:22 +01:00
Frank
e891c5c36a Merge branch 'main' into V5 2025-12-01 20:26:44 +01:00
Frank
c096c5bb8f fix for old-style WLED_RELEASE_NAME 2025-12-01 17:53:04 +01:00
Frank
c73935dd36 small fix
missing ||
2025-12-01 17:36:33 +01:00
Frank
3f441f0605 guess what ... more "C6 is like C3" ifdefs needed 2025-12-01 17:31:41 +01:00
Frank
2df4c58de8 disable touch button code on C6
similar to C3
2025-12-01 17:22:16 +01:00
Frank
1de36ca0da more "C6 is like C3" adjustments 2025-12-01 17:15:04 +01:00
Frank
70235450e8 treat C6 similar to C3
trying to reduce compile errors in bus_wrapper.h
... plus some preparation for P4 support
2025-12-01 17:03:44 +01:00
Frank
62ca377060 remove special FASTLED_NO_FASTLED hack
this was a temporary hack needed one year ago; FastLED should be compatible with -C6 now.
2025-12-01 16:29:51 +01:00
Frank
b2d659120e disable QuickEspNow - seems incompatible with -C6
also disabled some core debug flags
2025-12-01 15:56:57 +01:00
Frank
45d105ed4d Merge branch 'V5' into V5-C6 2025-12-01 15:41:07 +01:00
Frank
71920659e1 temporarily disable getDeviceId() feature for V5 builds
lots of deprecated functions and esp-idf structures ... Disabled until we find a way to make this work in V5
2025-12-01 15:18:56 +01:00
Frank
83b541e1ba fix broken indentation in platformio.ini, disable usermod builds
hoping that this will finally solve errors in the standard builds
2025-12-01 14:58:51 +01:00
Frank
2c7923e17d fix name clash in dmx_input.cpp
versionString was clashing with a structure defined in wled.h => build errors.
2025-12-01 14:43:33 +01:00
Frank
a55209415c Refactor software version label handling in DMX input
revert changes imported from main branch
2025-12-01 14:02:24 +01:00
Frank
6961059220 minor changes for consistency with other build envs 2025-12-01 01:58:12 +01:00
Frank
1bc63cac61 use the same lib_deps as the "main V5" branch 2025-12-01 01:37:57 +01:00
Frank
152bfd1543 Merge branch 'V5' into V5-C6 2025-12-01 01:23:15 +01:00
Frank
7e4661609c Merge branch 'main' into V5 2025-12-01 00:59:29 +01:00
Frank
ecfcd0da19 fix compiler warning "ESP32 redefined", add buildenv sanity check
* fix for warning: "ESP32" redefined
* wled.h: add sanity check to catch conflicting / missing defines
2025-12-01 00:41:29 +01:00
Frank
79e2128e71 add flag to disable the new arduino-esp32 RMT leds driver
causes conflicts with NeoPixelBus
2025-12-01 00:21:14 +01:00
Frank
9743775fb5 bring back lost esp_idf_v4 section (from main)
for back-to-back testing, and for compatibility with user-specific platformio_override.ini
2025-12-01 00:19:59 +01:00
Will Tatam
9f3e53a516 disable 8266 builds for now 2025-11-08 16:39:31 +00:00
Will Tatam
b51e80f5dd Safety check: ensure multiWiFi is never empty to prevent crashes during serialization 2025-11-08 16:28:19 +00:00
Will Tatam
d632cf8e8c improve esp32_dev env 2025-11-08 15:02:33 +00:00
Will Tatam
7c8b8fd0f3 NeoPixelBus CORE3 2025-11-08 15:02:09 +00:00
Frank
fa5aa586ec Update platformio.ini
* more debug output
* added my own fork of FastLED ( looks like more bugs to solve ....)
2025-11-08 14:17:43 +00:00
Will Tatam
db65e30ad5 use esp32_idf_V5.platform 2025-11-08 14:02:47 +00:00
Will Tatam
cf195af7c8 build only esp32c6dev_4MB 2025-11-08 13:54:39 +00:00
Frank
0f1055826b ESP32-C6 buildenv
due to Arduino 3.0.1, a few updated libraries are required:
* Tasmota Platform - official platfomio lacks arduino support for C6
* FastLED (latest + C6 build patches)
* AsyncTCP (latest + C6 build patches)
* AsyncWebServer (latest + C6 build patches)
* NeoPixelBus (lastest)
2025-11-08 13:41:08 +00:00
Will Tatam
96491255f1 Disable other envs to save CI build time 2025-11-08 13:33:18 +00:00
Will Tatam
36eaca6cb2 NeoEsp32RmtHI does not support V5 2025-11-08 13:24:39 +00:00
Will Tatam
0653854904 NeoEsp32RmtHI does not support V5 2025-11-08 13:03:55 +00:00
Will Tatam
51e1f4fc04 NeoEsp32RmtHI does not support V5 2025-11-08 12:49:52 +00:00
Will Tatam
2af23fc0cd AsyncTCP 3.4.7 does not support V5 2025-11-08 12:49:27 +00:00
Will Tatam
ce84a57a0d NeoEsp32RmtHI does not support V5 2025-11-08 12:44:26 +00:00
Will Tatam
8cad34e14a Merge branch 'main' into V5 2025-11-08 12:19:01 +00:00
Will Tatam
93821efb90 disable usermods build for now 2025-11-08 12:11:48 +00:00
Will Tatam
c5e2ec72bd WLED_DISABLE_INFRARED for 8266 2025-11-08 12:08:50 +00:00
Will Tatam
86679edd1f ESP-IDF fix for PWM_fan.cpp 2025-11-08 12:07:49 +00:00
Will Tatam
7a0325f88f WLED_DISABLE_INFRARED for 8266 2025-11-08 12:02:25 +00:00
Will Tatam
44a483f454 WLED_DISABLE_INFRARED for 8266 2025-11-08 11:55:01 +00:00
Will Tatam
41878f01f9 WLED_DISABLE_INFRARED for 8266 2025-11-08 11:51:08 +00:00
Will Tatam
906d4560a7 fix for pin usage logger 2025-11-08 11:43:38 +00:00
Will Tatam
5205110960 mbedtls_sha1_shim.cpp not required for 8266 2025-11-08 11:40:00 +00:00
Will Tatam
2f8882ee56 WLED_DISABLE_INFRARED for 8266 2025-11-08 11:39:02 +00:00
Will Tatam
d4bafec0f3 WLED_DISABLE_MQTT for 8266 2025-11-08 11:27:33 +00:00
Will Tatam
446c04380e fix for esp32_eth 2025-11-08 11:20:03 +00:00
Will Tatam
7daada1f3e fix for esp32_eth 2025-11-08 11:18:25 +00:00
Will Tatam
68dff2d392 mbedtls_sha1 workaround 2025-11-08 10:53:41 +00:00
Will Tatam
ec22c50813 Update DMX Input for latest esp_dmx 2025-11-08 10:38:19 +00:00
Will Tatam
81c92257da Update PlatformIO 2025-08-16 12:45:36 +01:00
Will Tatam
e4815d1ff5 Update PlatformIO 2025-08-16 12:36:41 +01:00
Will Tatam
bc19133e73 Update PlatformIO 2025-08-16 12:33:25 +01:00
Will Tatam
03a9d9e56f ledc changes for versions 2.X (based on ESP-IDF 4.4) to version 3.0 (based on ESP-IDF 5.1) - https://docs.espressif.com/projects/arduino-esp32/en/latest/migration_guides/2.x_to_3.0.html 2025-08-16 12:05:41 +01:00
Will Tatam
2c0259f214 Rename Network to WLEDNetwork to prevent clash 2025-08-16 11:57:50 +01:00
Will Tatam
1de8c2e79b Remove local copy of MQTT and disable for now in build 2025-08-16 11:57:20 +01:00
Will Tatam
07ab6aa3ea Rename Network to WLEDNetwork to prevent clash 2025-08-14 18:59:06 +01:00
Will Tatam
ba2b182bb3 Update platformio.ini for V5 2025-08-14 18:26:12 +01:00
Will Tatam
965e794094 Rename Network to WLEDNetwork to prevent clash 2025-08-14 18:25:39 +01:00
60 changed files with 1333 additions and 383 deletions

View File

@@ -1,7 +1,6 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"pioarduino.pioarduino-ide",
"platformio.platformio-ide"
],
"unwantedRecommendations": [

View File

@@ -29,6 +29,7 @@ License along with NeoPixel. If not, see
#pragma once
#if defined(ARDUINO_ARCH_ESP32)
#if !defined(WLED_USE_SHARED_RMT) // V5 fix: don't compile this file on unsupported platforms
// Use the NeoEspRmtSpeed types from the driver-based implementation
#include <NeoPixelBus.h>
@@ -467,3 +468,4 @@ typedef NeoEsp32RmtHI7Ws2805InvertedMethod NeoEsp32RmtHI7Ws2814InvertedMethod;
#endif // !defined(CONFIG_IDF_TARGET_ESP32C3)
#endif
#endif

View File

@@ -5,14 +5,16 @@
*
*/
#if defined(__XTENSA__) && defined(ESP32) && !defined(CONFIG_BTDM_CTRL_HLI)
#if defined(__XTENSA__) && defined(ESP32)
#include <freertos/xtensa_context.h>
#include "esp_idf_version.h"
#include "sdkconfig.h"
#include "soc/soc.h"
/* If the Bluetooth driver has hooked the high-priority interrupt, we piggyback on it and don't need this. */
#ifndef CONFIG_BTDM_CTRL_HLI
#if !defined(CONFIG_BTDM_CTRL_HLI) && ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
#include <freertos/xtensa_context.h>
#include "soc/soc.h"
/*
Select interrupt based on system check level
@@ -258,6 +260,5 @@ _highint_stack_switch:
.global ld_include_hli_vectors_rmt
ld_include_hli_vectors_rmt:
#endif // CONFIG_BTDM_CTRL_HLI
#endif // XTensa

View File

@@ -29,7 +29,7 @@ License along with NeoPixel. If not, see
#include <Arduino.h>
#if defined(ARDUINO_ARCH_ESP32)
#if defined(ARDUINO_ARCH_ESP32) && ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
#include <algorithm>
#include "esp_idf_version.h"
@@ -504,4 +504,4 @@ esp_err_t NeoEsp32RmtHiMethodDriver::WaitForTxDone(rmt_channel_t channel, TickTy
return rv;
}
#endif
#endif

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "wled",
"version": "17.0.0-dev",
"version": "17.0.0-devV5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "wled",
"version": "17.0.0-dev",
"version": "17.0.0-devV5",
"license": "ISC",
"dependencies": {
"clean-css": "^5.3.3",

View File

@@ -1,6 +1,6 @@
{
"name": "wled",
"version": "17.0.0-dev",
"version": "17.0.0-devV5",
"description": "Tools for WLED project",
"main": "tools/cdata.js",
"directories": {

View File

@@ -4,16 +4,69 @@
Import("env")
from pathlib import Path
platform = env.get("PIOPLATFORM")
script_file = Path(f"tools/dynarray_{platform}.ld")
if script_file.is_file():
linker_script = f"-T{script_file}"
if platform == "espressif32":
# For ESP32, the script must be added at the right point in the list
linkflags = env.get("LINKFLAGS", [])
idx = linkflags.index("memory.ld")
linkflags.insert(idx+1, linker_script)
env.Replace(LINKFLAGS=linkflags)
else:
# For other platforms, put it in last
env.Append(LINKFLAGS=[linker_script])
# Linker script fragment injected into the rodata output section of whichever
# platform we're building for. Placed just before the end-of-rodata marker so
# that the dynarray entries land in flash rodata and are correctly sorted.
DYNARRAY_INJECTION = (
"\n /* dynarray: WLED dynamic module arrays */\n"
" . = ALIGN(0x10);\n"
" KEEP(*(SORT_BY_INIT_PRIORITY(.dynarray.*)))\n"
" "
)
def inject_before_marker(path, marker):
"""Patch a linker script file in-place, inserting DYNARRAY_INJECTION before marker."""
original = path.read_text()
path.write_text(original.replace(marker, DYNARRAY_INJECTION + marker, 1))
if env.get("PIOPLATFORM") == "espressif32":
# Find sections.ld on the linker search path (LIBPATH).
sections_ld_path = None
for ld_dir in env.get("LIBPATH", []):
candidate = Path(str(ld_dir)) / "sections.ld"
if candidate.exists():
sections_ld_path = candidate
break
if sections_ld_path is not None:
# Inject inside the existing .flash.rodata output section, just before
# _rodata_end. IDF v5 enforces zero gaps between adjacent output
# sections via ASSERT statements, so INSERT AFTER .flash.rodata would
# fail. Injecting inside the section creates no new output section and
# leaves the ASSERTs satisfied.
build_dir = Path(env.subst("$BUILD_DIR"))
patched_path = build_dir / "dynarray_sections.ld"
import shutil
shutil.copy(sections_ld_path, patched_path)
inject_before_marker(patched_path, "_rodata_end = ABSOLUTE(.);")
# Replace "sections.ld" in LINKFLAGS with an absolute path to our
# patched copy. The flag may appear as a bare token, combined as
# "-Tsections.ld", or split across two tokens ("-T", "sections.ld").
patched_str = str(patched_path)
new_flags = []
skip_next = False
for flag in env.get("LINKFLAGS", []):
if skip_next:
new_flags.append(patched_str if flag == "sections.ld" else flag)
skip_next = False
elif flag == "-T":
new_flags.append(flag)
skip_next = True
else:
new_flags.append(flag.replace("sections.ld", patched_str))
env.Replace(LINKFLAGS=new_flags)
elif env.get("PIOPLATFORM") == "espressif8266":
# The ESP8266 framework preprocesses eagle.app.v6.common.ld.h into
# local.eagle.app.v6.common.ld in $BUILD_DIR/ld/ at build time. Register
# a post-action on that generated file so the injection happens after
# C-preprocessing but before linking.
build_ld = Path(env.subst("$BUILD_DIR")) / "ld" / "local.eagle.app.v6.common.ld"
def patch_esp8266_ld(target, source, env):
inject_before_marker(build_ld, "_irom0_text_end = ABSOLUTE(.);")
env.AddPostAction(str(build_ld), patch_esp8266_ld)

View File

@@ -0,0 +1,12 @@
# FastLED exports some weak cxx symbols as a way of managing integration with C-only
# projects that cause it to be preferentially linked instead of unused code being
# discarded like other libraries. This causes not only bloat of the final binaries
# but can incorrectly invoke some of their driver framework on some platforms.
#
# Solve this problem by moving the cxx library up in the linker command line, so
# that it will be chosen over FastLED's.
Import("env")
if "-lcxx" in env["LIBS"]:
env["LIBS"].remove("-lcxx")
env["LIBS"].insert(0, "-lcxx")

View File

@@ -80,8 +80,7 @@ def check_elf_modules(elf_path: Path, env, module_lib_builders) -> set[str]:
return found
DYNARRAY_SECTION = ".dtors" if env.get("PIOPLATFORM") == "espressif8266" else ".dynarray"
USERMODS_SECTION = f"{DYNARRAY_SECTION}.usermods.1"
USERMODS_SECTION = f".dynarray.usermods.1"
def count_usermod_objects(map_file: list[str]) -> int:
""" Returns the number of usermod objects in the usermod list """

View File

@@ -10,28 +10,37 @@
# ------------------------------------------------------------------------------
# CI/release binaries
default_envs = nodemcuv2
esp8266_2m
esp01_1m_full
nodemcuv2_160
esp8266_2m_160
esp01_1m_full_160
nodemcuv2_compat
esp8266_2m_compat
esp01_1m_full_compat
default_envs =
; nodemcuv2
; esp8266_2m
; esp01_1m_full
nodemcuv2_160 ;; 8266 regression test build
; esp8266_2m_160
; esp01_1m_full_160
; nodemcuv2_compat
; esp8266_2m_compat
; esp01_1m_full_compat
esp32dev_V4 ;; V4 regression test build
esp32dev
esp32dev_debug
esp32_eth
esp32_wrover
lolin_s2_mini
lolin_s2_mini ;; TODO: disabled NeoEsp32RmtMethodIsr
esp32c3dev
esp32c6dev_4MB
esp32c5dev
esp32p4_16MB ;; P4 360 Mhz 16MB flash - experimental
; esp32P4_400 ;; P4 rev3 400 Mhz - not usable yet
; esp32s3dev_16MB_opi ;; TODO: disabled NeoEsp32RmtMethodIsr
; esp32s3dev_8MB_opi ;; TODO: disabled NeoEsp32RmtMethodIsr
esp32s3_4M_qspi ;; TODO: disabled NeoEsp32RmtMethodIsr
esp32c3dev_qio
esp32S3_wroom2
esp32s3dev_16MB_opi
esp32s3dev_8MB_opi
esp32s3dev_8MB_qspi
esp32s3_4M_qspi
usermods
; esp32S3_wroom2 ;; TODO: disabled NeoEsp32RmtMethodIsr
; esp32s3dev_16MB_opi ;; TODO: disabled NeoEsp32RmtMethodIsr
esp32s3dev_8MB_opi ;; TODO: disabled NeoEsp32RmtMethodIsr
; esp32s3dev_8MB_qspi ;; TODO: disabled NeoEsp32RmtMethodIsr
; esp32s3_4M_qspi ;; TODO: disabled NeoEsp32RmtMethodIsr
; usermods ;; TODO: disabled until the core is building
src_dir = ./wled00
data_dir = ./wled00/data
@@ -130,6 +139,8 @@ ldscript_2m512k = eagle.flash.2m512.ld
ldscript_2m1m = eagle.flash.2m1m.ld
ldscript_4m1m = eagle.flash.4m1m.ld
default_usermods = ;; TODO: add back audioreactive once V5 compatible
[scripts_defaults]
extra_scripts =
pre:pio-scripts/set_metadata.py
@@ -139,6 +150,7 @@ extra_scripts =
pre:pio-scripts/user_config_copy.py
pre:pio-scripts/load_usermods.py
pre:pio-scripts/build_ui.py
;;post:pio-scripts/fastled_cxx_workaround.py
post:pio-scripts/validate_modules.py ;; double-check the build output usermods
; post:pio-scripts/obj-dump.py ;; convenience script to create a disassembly dump of the firmware (hardcore debugging)
@@ -161,33 +173,16 @@ upload_speed = 115200
# ------------------------------------------------------------------------------
lib_compat_mode = strict
lib_deps =
IRremoteESP8266 @ 2.8.2
https://github.com/Makuna/NeoPixelBus.git#a0919d1c10696614625978dd6fb750a1317a14ce
https://github.com/Aircoookie/ESPAsyncWebServer.git#v2.4.2
crankyoldgit/IRremoteESP8266 @ 2.9.0
;; neopixelbus dependancy moved into [8266] and [esp32_all_variants] sections
ESPAsyncWebServerWLED = git+https://github.com/Aircoookie/ESPAsyncWebServer#ac44e32abf2a69ae650412fb6bc193c59ccac38a
marvinroger/AsyncMqttClient @ 0.9.0
# for I2C interface
;Wire
# ESP-NOW library
;gmag11/QuickESPNow @ ~0.7.0
https://github.com/blazoncek/QuickESPNow.git#optional-debug
#For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
#TFT_eSPI
#For compatible OLED display uncomment following
#olikraus/U8g2 #@ ~2.33.15
#For Dallas sensor uncomment following
#paulstoffregen/OneWire @ ~2.3.8
#For BME280 sensor uncomment following
#BME280 @ ~3.0.0
;adafruit/Adafruit BMP280 Library @ 2.1.0
;adafruit/Adafruit CCS811 Library @ 1.0.4
;adafruit/Adafruit Si7021 Library @ 1.4.0
#For MAX1704x Lipo Monitor / Fuel Gauge uncomment following
; https://github.com/adafruit/Adafruit_BusIO @ 1.14.5
; https://github.com/adafruit/Adafruit_MAX1704X @ 1.0.2
#For MPU6050 IMU uncomment follwoing
;electroniccats/MPU6050 @1.0.1
# SHT85
;robtillaart/SHT85@~0.3.3
extra_scripts = ${scripts_defaults.extra_scripts}
@@ -215,13 +210,13 @@ build_flags =
-D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48 ;; in case of linker errors like "section `.text1' will not fit in region `iram1_0_seg'"
; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED ;; (experimental) adds some extra heap, but may cause slowdown
-D NON32XFER_HANDLER ;; ask forgiveness for PROGMEM misuse
lib_deps =
#https://github.com/lorol/LITTLEFS.git
ESPAsyncTCP @ 1.2.2
ESPAsyncUDP
ESP8266PWM
${env.lib_deps}
https://github.com/Makuna/NeoPixelBus.git#a0919d1c10696614625978dd6fb750a1317a14ce ;; standard NPB version used in main branch
;; compatibilty flags - same as 0.14.0 which seems to work better on some 8266 boards. Not using PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48
build_flags_compat =
@@ -255,20 +250,22 @@ lib_deps_compat =
[esp32_all_variants]
lib_deps =
esp32async/AsyncTCP @ 3.4.7
esp32async/AsyncTCP @ 3.4.10
bitbank2/AnimatedGIF@^1.4.7
https://github.com/Aircoookie/GifDecoder.git#bc3af189b6b1e06946569f6b4287f0b79a860f8e
NeoPixelBus = git+https://github.com/Makuna/NeoPixelBus#76afe832f74b0738a3fa1bba0caf389ade9e7693
build_flags =
-D CONFIG_ASYNC_TCP_USE_WDT=0
-D CONFIG_ASYNC_TCP_STACK_SIZE=8192
-D WLED_ENABLE_GIF
[esp32]
platform = ${esp32_idf_V4.platform}
platform = ${esp32_idf_V5.platform}
platform_packages =
build_unflags = ${common.build_unflags}
build_flags = ${esp32_idf_V4.build_flags}
lib_deps = ${esp32_idf_V4.lib_deps}
build_unflags = ${esp32_idf_V5.build_unflags}
build_flags = ${esp32_idf_V5.build_flags}
lib_deps = ${esp32_idf_V5.lib_deps}
lib_ignore = ${esp32_idf_V5.lib_ignore}
tiny_partitions = tools/WLED_ESP32_2MB_noOTA.csv
default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
@@ -302,12 +299,45 @@ lib_deps =
${esp32_all_variants.lib_deps}
https://github.com/someweisguy/esp_dmx.git#47db25d8c515e76fabcf5fc5ab0b786f98eeade0
${env.lib_deps}
lib_ignore =
[esp32_idf_V5]
;; build environment for ESP32 using ESP-IDF 5.3.4 / arduino-esp32 v3.1.10
platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.02.30/platform-espressif32.zip
platform_packages =
build_unflags = ${common.build_unflags}
-Wno-volatile ;; avoid warning on .c files: "-Wno-volatile only applies to c++ files"
build_flags = -g
;;-Wno-deprecated ;; disables a ton of warnings: implicit capture of 'this' via '[=]' is deprecated in C++20 [-Wdeprecated]
-Wshadow=compatible-local ;; emit warning in case a local variable "shadows" another local one
-DARDUINO_ARCH_ESP32
; -DESP32=ESP32 ;; disabled to avoid compiler warning: "ESP32" redefined
${esp32_all_variants.build_flags}
-D WLED_USE_SHARED_RMT ;; ToDO: check if NeoESP32RmtHI is still needed with V5 (see discussion in PR#4838)
-D WLED_DISABLE_INFRARED ;; TODO: remove once we have updated library for V5
-D WLED_DISABLE_MQTT ;; TODO: remove once we have updated library for V5
-D WLED_ENABLE_DMX_INPUT
-D ESP32_ARDUINO_NO_RGB_BUILTIN ;; avoids RMT driver abort on startup "E (98) rmt(legacy): CONFLICT! driver_ng is not allowed to be used with the legacy driver"
lib_deps =
${esp32_all_variants.lib_deps}
https://github.com/netmindz/esp_dmx/#esp-idf-v5-fixes
${env.lib_deps}
lib_ignore =
NeoESP32RmtHI
[v5_pioarduino_workaround]
# This is a disgusting workaround for a pioarduino "feature": if you don't ever mention lib_archive in your platformio.ini
# it forces it off globally, causing unused code from all libraries to be included even if you don't use it.
# This causes FastLED to activate its driver framework, stealing hardware resources we want to use.
# To work around this, all that we have to do is mention lib_archive in any section, even if it's never used; then
# pioarduino believes we know what we're doing, and lets us do what we want.
lib_archive = yes
[esp32s2]
;; generic definitions for all ESP32-S2 boards
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
build_unflags = ${common.build_unflags}
platform = ${esp32_idf_V5.platform}
platform_packages = ${esp32_idf_V5.platform_packages}
build_unflags = ${esp32_idf_V5.build_unflags}
build_flags = -g
-DARDUINO_ARCH_ESP32
-DARDUINO_ARCH_ESP32S2
@@ -317,16 +347,17 @@ build_flags = -g
-DARDUINO_USB_MODE=0 ;; this flag is mandatory for ESP32-S2 !
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_CDC_ON_BOOT
${esp32_idf_V4.build_flags}
${esp32_idf_V5.build_flags}
lib_deps =
${esp32_idf_V4.lib_deps}
${esp32_idf_V5.lib_deps}
lib_ignore = ${esp32_idf_V5.lib_ignore}
board_build.partitions = ${esp32.default_partitions} ;; default partioning for 4MB Flash - can be overridden in build envs
[esp32c3]
;; generic definitions for all ESP32-C3 boards
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
build_unflags = ${common.build_unflags}
platform = ${esp32_idf_V5.platform}
platform_packages = ${esp32_idf_V5.platform_packages}
build_unflags = ${esp32_idf_V5.build_unflags}
build_flags = -g
-DARDUINO_ARCH_ESP32
-DARDUINO_ARCH_ESP32C3
@@ -335,19 +366,20 @@ build_flags = -g
-DARDUINO_USB_MODE=1 ;; this flag is mandatory for ESP32-C3
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_CDC_ON_BOOT
${esp32_idf_V4.build_flags}
${esp32_idf_V5.build_flags}
lib_deps =
${esp32_idf_V4.lib_deps}
${esp32_idf_V5.lib_deps}
lib_ignore = ${esp32_idf_V5.lib_ignore}
board_build.partitions = ${esp32.default_partitions} ;; default partioning for 4MB Flash - can be overridden in build envs
board_build.flash_mode = qio
[esp32s3]
;; generic definitions for all ESP32-S3 boards
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
build_unflags = ${common.build_unflags}
platform = ${esp32_idf_V5.platform}
platform_packages = ${esp32_idf_V5.platform_packages}
build_unflags = ${esp32_idf_V5.build_unflags}
build_flags = -g
-DESP32
;; -DESP32 ;; disabled to avoid compiler warning: "ESP32" redefined
-DARDUINO_ARCH_ESP32
-DARDUINO_ARCH_ESP32S3
-DCONFIG_IDF_TARGET_ESP32S3=1
@@ -355,11 +387,231 @@ build_flags = -g
-DCO
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_MODE, ARDUINO_USB_CDC_ON_BOOT
${esp32_idf_V4.build_flags}
${esp32_idf_V5.build_flags}
lib_deps =
${esp32_idf_V4.lib_deps}
${esp32_idf_V5.lib_deps}
lib_ignore = ${esp32_idf_V5.lib_ignore}
board_build.partitions = ${esp32.large_partitions} ;; default partioning for 8MB flash - can be overridden in build envs
[esp32c5]
;; generic definitions for all ESP32-C5 boards
;; NOTE: ESP32-C5 requires pioarduino platform (Tasmota framework doesn't include C5 Arduino libs yet)
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.37/platform-espressif32.zip
platform_packages =
build_unflags = ${esp32_idf_V5.build_unflags}
-D WLED_ENABLE_DMX_INPUT ;; esp_dmx library doesn't support C5 UART registers yet
build_flags = -g
-Wshadow=compatible-local
-DARDUINO_ARCH_ESP32
-DARDUINO_ARCH_ESP32C5
-DCONFIG_IDF_TARGET_ESP32C5=1
-D CONFIG_ASYNC_TCP_USE_WDT=0
-DCO
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_MODE
;; ARDUINO_USB_CDC_ON_BOOT
${esp32_idf_V5.build_flags}
lib_deps =
${esp32_all_variants.lib_deps}
${env.lib_deps}
;; TODO: remove the temporarily Override below once NeoPixelBus has official support for -C5
;; NeoPixelBus = https://github.com/jonny190/NeoPixelBus.git#wled-c5-stable ;; jonny190 wled-c5-stable fork C5 support: I2S exclusion, bit-bang CSR/GPIO, channel ctor overload
lib_ignore = ${esp32_idf_V5.lib_ignore}
esp_dmx ;; esp_dmx library doesn't support C5 UART registers yet
[esp32c6]
;; generic definitions for all ESP32-C6 boards
platform = ${esp32_idf_V5.platform}
platform_packages = ${esp32_idf_V5.platform_packages}
;;platform_packages =
;; framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.1
;; framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.1/esp32-arduino-libs-3.0.1.zip
;; board = esp32-c6-devkitm-1 ;; board must be defined in the lower-level [env:*] buildenvs for C6-based boards
build_unflags = ${esp32_idf_V5.build_unflags}
build_flags = -g
-DARDUINO_ARCH_ESP32
-DARDUINO_ARCH_ESP32C6
-DCONFIG_IDF_TARGET_ESP32C6=1
-D CONFIG_ASYNC_TCP_USE_WDT=0
-DCO
-DARDUINO_USB_MODE=1 ;; this flag is - most likely - mandatory for ESP32-C6
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_CDC_ON_BOOT
${esp32_idf_V5.build_flags}
lib_deps = ${esp32_idf_V5.lib_deps}
lib_ignore = ${esp32_idf_V5.lib_ignore}
[esp32p4]
;; !! Important: if your board shows errors when trying to start WiFi, the C6 coprocessor might need a firmware update.
;; !! go here ==> https://esp32-c6-firmware-update.github.io/
;;
;; generic definitions for all ESP32-P4 boards. TODO: make wifi work by using esp-hosted networking
;; Using latest tasmota framework - older frameworks only have minimal support for P4
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.37/platform-espressif32.zip
platform_packages =
build_unflags = ${esp32_idf_V5.build_unflags}
-D WLED_ENABLE_DMX_INPUT ;; library not compatible with -P4
-D WLED_ENABLE_DMX ;; DMX serial out needs adaptations for P4 compatibility
build_flags = -g
-DARDUINO_ARCH_ESP32
-DARDUINO_ARCH_ESP32P4
-DCONFIG_IDF_TARGET_ESP32P4=1
-D CONFIG_ASYNC_TCP_USE_WDT=0
-DCO
-DARDUINO_USB_MODE=1 ;; this flag is - most likely - mandatory for ESP32-P4
-D WLED_DISABLE_INFRARED ;; library not compatible with -P4
-D WLED_DISABLE_ESPNOW ;; not yet tested
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_CDC_ON_BOOT
${esp32_idf_V5.build_flags}
lib_deps = ${esp32_idf_V5.lib_deps}
lib_ignore = ${esp32_idf_V5.lib_ignore}
IRremoteESP8266 ; TODo: remove once we have a version thats compatible
QuickEspNow ; ToDO: disabled until we find a compatible version
esp_dmx ; ToDO: disabled until we find a compatible version
# ------------------------------------------------------------------------------
# EXPERIMENTAL: WLED NEW MCU BUILDS (-C5, -C6, -P4)
# ------------------------------------------------------------------------------
[env:esp32c6dev_8MB]
;; ESP32-C6 "devkit C" with 8MB flash
extends = esp32c6
platform = ${esp32c6.platform}
platform_packages = ${esp32c6.platform_packages}
board = esp32-c6-devkitc-1
build_unflags = ${esp32c6.build_unflags}
;;-D CORE_DEBUG_LEVEL=0
;;-D NDEBUG
build_flags = ${common.build_flags} ${esp32c6.build_flags} -D WLED_RELEASE_NAME=\"ESP32-C6_8MB\"
-Wno-volatile -Wno-deprecated-declarations ;; silence compiler warnings
;; -Wno-cpp ;; silence '#pragma warning' messages
;;-D DEBUG -g3 -ggdb
;;-D CORE_DEBUG_LEVEL=4
-D WLED_WATCHDOG_TIMEOUT=0
;; -DLOLIN_WIFI_FIX ; might be needed on "-C6 mini"
;;-DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual CDC USB
-DARDUINO_USB_CDC_ON_BOOT=0 ;; for serial-to-USB chip
-D WLED_DISABLE_INFRARED ;; library not not compatible with -C6
-D WLED_DISABLE_ESPNOW ;; ToDO: temporarily disabled, until we find a solution for esp-now build errors with -C6
upload_speed = 460800
lib_deps = ${esp32c6.lib_deps}
lib_ignore = ${esp32c6.lib_ignore}
IRremoteESP8266 ; use with WLED_DISABLE_INFRARED for faster compilation
QuickEspNow ; ToDO: disabled until we find a compatible version
board_build.partitions = ${esp32.large_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.arduino.memory_type = qio_qspi
monitor_filters = esp32_exception_decoder
[env:esp32c6dev_4MB]
;; ESP32-C6 "devkit M" with 4MB flash
extends = env:esp32c6dev_8MB
board = esp32-c6-devkitm-1
board_build.partitions = ${esp32.default_partitions}
build_unflags = ${env:esp32c6dev_8MB.build_unflags} -D WLED_RELEASE_NAME=\"ESP32-C6_8MB\"
build_flags = ${env:esp32c6dev_8MB.build_flags} -D WLED_RELEASE_NAME=\"ESP32-C6_4MB\"
monitor_filters = esp32_exception_decoder
[env:esp32c5dev]
;; ESP32-C5 "devkit C" with 4MB flash, no PSRAM - EXPERIMENTAL
extends = esp32c5
board = esp32-c5-devkitc-1
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.arduino.memory_type = qio_qspi ;; flash config only, this board has no PSRAM
build_flags = ${common.build_flags} ${esp32c5.build_flags} -D WLED_RELEASE_NAME=\"ESP32-C5\"
-Wno-volatile -Wno-deprecated-declarations
-D WLED_WATCHDOG_TIMEOUT=0
-DARDUINO_USB_MODE=1 ;; this flag is mandatory for ESP32-C5
-DARDUINO_USB_CDC_ON_BOOT=0 ;; for serial-to-USB chip
-D WLED_DISABLE_INFRARED ;; library not compatible with -C5
-D WLED_DISABLE_ESPNOW ;; not yet tested
-D WLED_DEBUG
lib_ignore = ${esp32c5.lib_ignore}
IRremoteESP8266
QuickEspNow
board_build.partitions = ${esp32.big_partitions}
upload_speed = 460800
monitor_filters = esp32_exception_decoder
[env:esp32c5dev_8MB_qspi]
;; ESP32-C5 with 8MB flash and PSRAM - EXPERIMENTAL
extends = esp32c5
board = esp32-c5-devkitc1-n8r4
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.arduino.memory_type = qio_qspi ;; this board has PSRAM
build_flags = ${common.build_flags} ${esp32c5.build_flags} -D WLED_RELEASE_NAME=\"ESP32-C5_8MB_qspi\"
-Wno-volatile -Wno-deprecated-declarations
-D BOARD_HAS_PSRAM
-D WLED_WATCHDOG_TIMEOUT=0
-DARDUINO_USB_MODE=1 ;; this flag is mandatory for ESP32-C5
-DARDUINO_USB_CDC_ON_BOOT=0 ;; for serial-to-USB chip
-D WLED_DISABLE_INFRARED ;; library not compatible with -C5
-D WLED_DISABLE_ESPNOW ;; not yet tested
-D WLED_DEBUG
lib_ignore = ${esp32c5.lib_ignore}
IRremoteESP8266
QuickEspNow
board_build.partitions = ${esp32.large_partitions}
board_upload.flash_size = 8MB
board_upload.maximum_size = 8388608
upload_speed = 460800
monitor_filters = esp32_exception_decoder
[env:esp32p4_16MB]
;; (experimental) ESP32-P4 with 16 MB Flash, 32MB PSRAM
;; https://www.waveshare.com/esp32-p4-nano.htm
extends = esp32p4
platform = ${esp32p4.platform}
platform_packages = ${esp32p4.platform_packages}
board = esp32-p4-evboard ;; P4 eval board, 360Mhz
;; board = esp32-p4_r3-evboard ;; P4 eval board with "revision 3" CPU, 400Mhz
;; board = esp32-p4 ;; 360Mhz
;; board = esp32-p4_r3 ;; 400Mhz
board_build.flash_mode = qio
board_build.partitions = ${esp32.extreme_partitions} ;; for 16MB Flash
build_unflags = ${esp32p4.build_unflags}
;; -DCORE_DEBUG_LEVEL=0
;; -flto
build_flags = ${common.build_flags} ${esp32p4.build_flags} -D WLED_RELEASE_NAME=\"ESP32-P4_16MB\" -DBOARD_HAS_PSRAM
;; -D WLED_DEBUG
;; -DCORE_DEBUG_LEVEL=3 -g3 -ggdb -fno-lto
lib_ignore = ${esp32p4.lib_ignore}
upload_speed = 460800
monitor_filters = esp32_exception_decoder
[env:esp32p4_32MB]
;; (experimental) ESP32-P4 with 32 MB Flash, 32MB PSRAM
extends = esp32p4
board = esp32-p4-evboard ;; P4 eval board, 360Mhz
;;board = esp32-p4_r3-evboard ;; P4 eval board with "revision 3" CPU, 400Mhz
board_build.flash_mode = qio
board_build.partitions = tools/WLED_ESP32_32MB.csv
;;build_type = debug
build_unflags = ${esp32p4.build_unflags}
;; -DCORE_DEBUG_LEVEL=0
;; -flto
build_flags = ${common.build_flags} ${esp32p4.build_flags} -D WLED_RELEASE_NAME=\"ESP32-P4_32MB\" -DBOARD_HAS_PSRAM
-D WLED_DEBUG
;; -DCORE_DEBUG_LEVEL=3 -g3 -ggdb -fno-lto
upload_speed = 460800
monitor_filters = esp32_exception_decoder
# ------------------------------------------------------------------------------
# WLED BUILDS
@@ -390,7 +642,7 @@ extends = env:nodemcuv2
board_build.f_cpu = 160000000L
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266_160\" #-DWLED_DISABLE_2D
-D WLED_DISABLE_PARTICLESYSTEM2D
custom_usermods = audioreactive
custom_usermods = ${common.default_usermods}
[env:esp8266_2m]
board = esp_wroom_02
@@ -418,7 +670,7 @@ board_build.f_cpu = 160000000L
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP02_160\"
-D WLED_DISABLE_PARTICLESYSTEM1D
-D WLED_DISABLE_PARTICLESYSTEM2D
custom_usermods = audioreactive
custom_usermods = ${common.default_usermods}
[env:esp01_1m_full]
board = esp01_1m
@@ -453,35 +705,59 @@ build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=
-D WLED_DISABLE_PIXELFORGE
custom_usermods = audioreactive
[env:esp32dev]
[env:esp32dev_V4]
;; uses V4 framework - for checking that the code still builds in V4
board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
build_unflags = ${common.build_unflags}
custom_usermods = audioreactive
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32\" #-D WLED_DISABLE_BROWNOUT_DET
build_unflags = ${esp32_idf_V4.build_unflags}
-D WLED_ENABLE_DMX_INPUT ;; TODO: fix lots of compile errors in dmx_input.cpp
custom_usermods = ${common.default_usermods}
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_V4\" #-D WLED_DISABLE_BROWNOUT_DET
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
-D WLED_USE_ETHERNET -D RLYPIN=-1 -D BTNPIN=-1 ;; TODO: this is just for testing - remove before merging to main
lib_deps = ${esp32_idf_V4.lib_deps}
lib_ignore = ${esp32_idf_V4.lib_ignore}
esp_dmx ;; TODO: fix lots of compile errors in dmx_input.cpp
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.default_partitions}
board_build.flash_mode = dio
[env:esp32dev]
board = esp32dev
platform = ${esp32_idf_V5.platform}
platform_packages = ${esp32_idf_V5.platform_packages}
build_unflags = ${esp32_idf_V5.build_unflags}
custom_usermods = ${common.default_usermods}
build_flags = ${common.build_flags} ${esp32_idf_V5.build_flags} -D WLED_RELEASE_NAME=\"ESP32\" #-D WLED_DISABLE_BROWNOUT_DET
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
lib_deps = ${esp32_idf_V5.lib_deps}
lib_ignore = ${esp32_idf_V5.lib_ignore}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.default_partitions}
board_build.flash_mode = dio
[env:esp32dev_debug]
extends = env:esp32dev
build_type = debug
monitor_filters = esp32_exception_decoder
upload_speed = 921600
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags}
build_unflags = ${esp32_idf_V5.build_unflags}
-D WLED_RELEASE_NAME=\"ESP32\"
build_flags = ${common.build_flags} ${esp32_idf_V5.build_flags}
-D WLED_DEBUG
-D WLED_RELEASE_NAME=\"ESP32_DEBUG\"
-DARDUINO_USB_CDC_ON_BOOT=0
[env:esp32dev_8M]
board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_8M\" #-D WLED_DISABLE_BROWNOUT_DET
platform = ${esp32_idf_V5.platform}
platform_packages = ${esp32_idf_V5.platform_packages}
custom_usermods = ${common.default_usermods}
build_unflags = ${esp32_idf_V5.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V5.build_flags} -D WLED_RELEASE_NAME=\"ESP32_8M\" #-D WLED_DISABLE_BROWNOUT_DET
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
lib_deps = ${esp32_idf_V4.lib_deps}
lib_deps = ${esp32_idf_V5.lib_deps}
lib_ignore = ${esp32_idf_V5.lib_ignore}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.large_partitions}
board_upload.flash_size = 8MB
@@ -491,13 +767,14 @@ board_build.flash_mode = dio
[env:esp32dev_16M]
board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_16M\" #-D WLED_DISABLE_BROWNOUT_DET
platform = ${esp32_idf_V5.platform}
platform_packages = ${esp32_idf_V5.platform_packages}
custom_usermods = ${common.default_usermods}
build_unflags = ${esp32_idf_V5.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V5.build_flags} -D WLED_RELEASE_NAME=\"ESP32_16M\" #-D WLED_DISABLE_BROWNOUT_DET
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
lib_deps = ${esp32_idf_V4.lib_deps}
lib_deps = ${esp32_idf_V5.lib_deps}
lib_ignore = ${esp32_idf_V5.lib_ignore}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.extreme_partitions}
board_upload.flash_size = 16MB
@@ -507,33 +784,35 @@ board_build.flash_mode = dio
[env:esp32_eth]
board = esp32-poe
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
platform = ${esp32_idf_V5.platform}
platform_packages = ${esp32_idf_V5.platform_packages}
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32_Ethernet\" -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
-D SR_DMTYPE=-1 -D AUDIOPIN=-1 -D I2S_SDPIN=-1 -D I2S_WSPIN=-1 -D I2S_CKPIN=-1 -D MCLK_PIN=-1 ;; force AR to not allocate any PINs at startup
-D DATA_PINS=4 ;; default led pin = 16 conflicts with pins used for ethernet
; -D WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only => uncomment if your board uses ETH_CLOCK_GPIO0_OUT, ETH_CLOCK_GPIO16_OUT, ETH_CLOCK_GPIO17_OUT
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
lib_deps = ${esp32.lib_deps}
custom_usermods = ${common.default_usermods}
build_unflags = ${esp32_idf_V5.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V5.build_flags} -D WLED_RELEASE_NAME=\"ESP32_Ethernet\" -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
-D SR_DMTYPE=-1 -D AUDIOPIN=-1 -D I2S_SDPIN=-1 -D I2S_WSPIN=-1 -D I2S_CKPIN=-1 -D MCLK_PIN=-1 ;; force AR to not allocate any PINs at startup
-D DATA_PINS=4 ;; default led pin = 16 conflicts with pins used for ethernet
; -D WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only => uncomment if your board uses ETH_CLOCK_GPIO0_OUT, ETH_CLOCK_GPIO16_OUT, ETH_CLOCK_GPIO17_OUT
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
; -D WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only
lib_deps = ${esp32_idf_V5.lib_deps}
lib_ignore = ${esp32_idf_V5.lib_ignore}
board_build.partitions = ${esp32.default_partitions}
board_build.flash_mode = dio
[env:esp32_wrover]
extends = esp32_idf_V4
extends = esp32_idf_V5
board = ttgo-t7-v14-mini32
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.partitions = ${esp32.extended_partitions}
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_WROVER\"
custom_usermods = ${common.default_usermods}
build_unflags = ${esp32_idf_V5.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V5.build_flags} -D WLED_RELEASE_NAME=\"ESP32_WROVER\"
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue ;; Older ESP32 (rev.<3) need a PSRAM fix (increases static RAM used) https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/external-ram.html
-D DATA_PINS=25
lib_deps = ${esp32_idf_V4.lib_deps}
lib_deps = ${esp32_idf_V5.lib_deps}
[env:esp32c3dev]
extends = esp32c3
@@ -549,7 +828,7 @@ build_flags = ${common.build_flags} ${esp32c3.build_flags} -D WLED_RELEASE_NAME=
-DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual CDC USB
;-DARDUINO_USB_CDC_ON_BOOT=0 ;; for serial-to-USB chip
upload_speed = 460800
build_unflags = ${common.build_unflags}
build_unflags = ${esp32c3.build_unflags}
lib_deps = ${esp32c3.lib_deps}
board_build.flash_mode = dio ; safe default, required for OTA updates to 0.16 from older version which used dio (must match the bootloader!)
@@ -565,14 +844,15 @@ board_build.arduino.memory_type = qio_opi ;; use with PSRAM: 8MB or 16MB
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
custom_usermods = ${common.default_usermods}
build_unflags = ${esp32s3.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_16MB_opi\"
-D WLED_WATCHDOG_TIMEOUT=0
;-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
-D ARDUINO_USB_CDC_ON_BOOT=1 ;; -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
-DBOARD_HAS_PSRAM
lib_deps = ${esp32s3.lib_deps}
lib_ignore = ${esp32s3.lib_ignore}
board_build.partitions = ${esp32.extreme_partitions}
board_upload.flash_size = 16MB
board_upload.maximum_size = 16777216
@@ -587,14 +867,15 @@ board_build.arduino.memory_type = qio_opi ;; use with PSRAM: 8MB or 16MB
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
custom_usermods = ${common.default_usermods}
build_unflags = ${esp32s3.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_8MB_opi\"
-D WLED_WATCHDOG_TIMEOUT=0
;-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
-D ARDUINO_USB_CDC_ON_BOOT=1 ;; -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
-DBOARD_HAS_PSRAM
lib_deps = ${esp32s3.lib_deps}
lib_ignore = ${esp32s3.lib_ignore}
board_build.partitions = ${esp32.large_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = qio
@@ -621,8 +902,8 @@ platform_packages = ${esp32s3.platform_packages}
board = esp32s3camlcd ;; this is the only standard board with "opi_opi"
board_build.arduino.memory_type = opi_opi
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
custom_usermods = ${common.default_usermods}
build_unflags = ${esp32s3.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_WROOM-2\"
-D WLED_WATCHDOG_TIMEOUT=0
-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
@@ -633,6 +914,7 @@ build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=
;;-D WLED_DEBUG
-D SR_DMTYPE=1 -D I2S_SDPIN=13 -D I2S_CKPIN=14 -D I2S_WSPIN=15 -D MCLK_PIN=4 ;; I2S mic
lib_deps = ${esp32s3.lib_deps}
lib_ignore = ${esp32s3.lib_ignore}
board_build.partitions = ${esp32.extreme_partitions}
board_upload.flash_size = 16MB
@@ -662,14 +944,15 @@ board = lolin_s3_mini ;; -S3 mini, 4MB flash 2MB PSRAM
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
custom_usermods = ${common.default_usermods}
build_unflags = ${esp32s3.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_4M_qspi\"
-DARDUINO_USB_CDC_ON_BOOT=1 ;; -DARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
-DBOARD_HAS_PSRAM
-DLOLIN_WIFI_FIX ; seems to work much better with this
-D WLED_WATCHDOG_TIMEOUT=0
lib_deps = ${esp32s3.lib_deps}
lib_ignore = ${esp32s3.lib_ignore}
board_build.partitions = ${esp32.default_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = qio
@@ -682,8 +965,8 @@ board = lolin_s2_mini
board_build.partitions = ${esp32.default_partitions}
board_build.flash_mode = qio
board_build.f_flash = 80000000L
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
custom_usermods = ${common.default_usermods}
build_unflags = ${esp32s2.build_unflags}
build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S2\"
-DARDUINO_USB_CDC_ON_BOOT=1
-DARDUINO_USB_MSC_ON_BOOT=0
@@ -699,17 +982,20 @@ build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=
-D HW_PIN_MISOSPI=9
; -D STATUSLED=15
lib_deps = ${esp32s2.lib_deps}
lib_ignore = ${esp32s2.lib_ignore}
[env:usermods]
board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_USERMODS\"
platform = ${esp32_idf_V5.platform}
platform_packages = ${esp32_idf_V5.platform_packages}
build_unflags = ${esp32_idf_V5.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V5.build_flags} -D WLED_RELEASE_NAME=\"ESP32_USERMODS\"
-DTOUCH_CS=9
lib_deps = ${esp32_idf_V4.lib_deps}
lib_deps = ${esp32_idf_V5.lib_deps}
lib_ignore = ${esp32_idf_V5.lib_ignore}
monitor_filters = esp32_exception_decoder
board_build.flash_mode = dio
custom_usermods = * ; Expands to all usermods in usermods folder
;custom_usermods = * ; Expands to all usermods in usermods folder
custom_usermods = ; ToDO: fix usermods build once the main V5 build works without errors and warnings
board_build.partitions = ${esp32.extreme_partitions} ; We're gonna need a bigger boat

View File

@@ -1,20 +1,20 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile requirements.in
# pip-compile
#
ajsonrpc==1.2.0
# via platformio
anyio==4.8.0
anyio==4.10.0
# via starlette
bottle==0.13.2
bottle==0.13.4
# via platformio
certifi==2025.1.31
certifi==2025.8.3
# via requests
charset-normalizer==3.4.1
charset-normalizer==3.4.3
# via requests
click==8.1.8
click==8.1.7
# via
# platformio
# uvicorn
@@ -30,9 +30,9 @@ idna==3.10
# requests
marshmallow==3.26.1
# via platformio
packaging==24.2
packaging==25.0
# via marshmallow
platformio==6.1.17
platformio==6.1.18
# via -r requirements.in
pyelftools==0.32
# via platformio
@@ -44,15 +44,13 @@ semantic-version==2.10.0
# via platformio
sniffio==1.3.1
# via anyio
starlette==0.45.3
starlette==0.46.2
# via platformio
tabulate==0.9.0
# via platformio
typing-extensions==4.12.2
# via anyio
urllib3==2.5.0
# via requests
uvicorn==0.34.0
uvicorn==0.34.3
# via platformio
wsproto==1.2.0
# via platformio

View File

@@ -1,7 +1,7 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x220000,
app1, app, ota_1, 0x230000,0x220000,
spiffs, data, spiffs, 0x450000,0x3A0000,
app0, app, ota_0, 0x10000, 0x200000,
app1, app, ota_1, 0x210000,0x200000,
spiffs, data, spiffs, 0x410000,0x3E0000,
coredump, data, coredump,,64K
1 # Name, Type, SubType, Offset, Size, Flags
2 nvs, data, nvs, 0x9000, 0x5000,
3 otadata, data, ota, 0xe000, 0x2000,
4 app0, app, ota_0, 0x10000, 0x220000, app0, app, ota_0, 0x10000, 0x200000,
5 app1, app, ota_1, 0x230000,0x220000, app1, app, ota_1, 0x210000,0x200000,
6 spiffs, data, spiffs, 0x450000,0x3A0000, spiffs, data, spiffs, 0x410000,0x3E0000,
7 coredump, data, coredump,,64K

View File

@@ -1,9 +0,0 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x270000,
app1, app, ota_1, 0x280000,0x270000,
spiffs, data, spiffs, 0x4F0000,0x2FB000,
zb_storage, data, fat, 0x7EB000,0x4000,
zb_fct, data, fat, 0x7EF000,0x1000,
coredump, data, coredump,0x7F0000,0x10000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x270000
5 app1 app ota_1 0x280000 0x270000
6 spiffs data spiffs 0x4F0000 0x2FB000
7 zb_storage data fat 0x7EB000 0x4000
8 zb_fct data fat 0x7EF000 0x1000
9 coredump data coredump 0x7F0000 0x10000

View File

@@ -1,10 +0,0 @@
/* ESP32 linker script fragment to add dynamic array section to binary */
SECTIONS
{
.dynarray :
{
. = ALIGN(0x10);
KEEP(*(SORT_BY_INIT_PRIORITY(.dynarray.*)))
} > default_rodata_seg
}
INSERT AFTER .flash.rodata;

View File

@@ -129,11 +129,14 @@ class PWMFanUsermod : public Usermod {
if (pwmChannel == 255) { //no more free LEDC channels
deinitPWMfan(); return;
}
// configure LED PWM functionalitites
// configure LED PWM functionalitites - ESP-IDF 5.x API
#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
#endif
DEBUG_PRINTLN(F("Fan PWM sucessfully initialized."));
}

View File

@@ -196,7 +196,7 @@ class St7789DisplayUsermod : public Usermod {
// Check if values which are shown on display changed from the last time.
if ((((apActive) ? String(apSSID) : WiFi.SSID()) != knownSsid) ||
(knownIp != (apActive ? IPAddress(4, 3, 2, 1) : Network.localIP())) ||
(knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WLEDNetwork.localIP())) ||
(knownBrightness != bri) ||
(knownEffectSpeed != strip.getMainSegment().speed) ||
(knownEffectIntensity != strip.getMainSegment().intensity) ||

View File

@@ -874,7 +874,7 @@ class AudioReactive : public Usermod {
static const char _dynamics[];
static const char _frequency[];
static const char _inputLvl[];
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
#if defined(CONFIG_IDF_TARGET_ESP32) // analog mic is only supported on classic esp32
static const char _analogmic[];
#endif
static const char _digitalmic[];
@@ -1366,7 +1366,7 @@ class AudioReactive : public Usermod {
// Reset I2S peripheral for good measure
i2s_driver_uninstall(I2S_NUM_0); // E (696) I2S: i2s_driver_uninstall(2006): I2S port 0 has not installed
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5)
delay(100);
periph_module_reset(PERIPH_I2S0_MODULE); // not possible on -C3
#endif
@@ -1374,15 +1374,15 @@ class AudioReactive : public Usermod {
useBandPassFilter = false; // filter cuts lowest and highest frequency bands from FFT result (use on very noisy mic inputs)
useMicFilter = true; // filter fixes aliasing to base & highest frequency bands and reduces noise floor (recommended for all mic inputs)
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5)
if ((i2sckPin == I2S_PIN_NO_CHANGE) && (i2ssdPin >= 0) && (i2swsPin >= 0) && ((dmType == 1) || (dmType == 4)) ) dmType = 5; // dummy user support: SCK == -1 --means--> PDM microphone
#endif
switch (dmType) {
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3)
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32S3)
// stub cases for not-yet-supported I2S modes on other ESP32 chips
case 0: //ADC analog
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3)
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5)
case 5: //PDM Microphone
#endif
#endif
@@ -1411,7 +1411,7 @@ class AudioReactive : public Usermod {
delay(100);
if (audioSource) audioSource->initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin);
break;
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5)
case 5:
DEBUGSR_PRINT(F("AR: Generic PDM Microphone - ")); DEBUGSR_PRINTLN(F(I2S_PDM_MIC_CHANNEL_TEXT));
audioSource = new I2SSource(SAMPLE_RATE, BLOCK_SIZE, 1.0f/4.0f);
@@ -1428,7 +1428,7 @@ class AudioReactive : public Usermod {
if (audioSource) audioSource->initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin);
break;
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32S3)
// ADC over I2S is only possible on "classic" ESP32
case 0:
DEBUGSR_PRINTLN(F("AR: Analog Microphone (left channel only)."));
@@ -2006,7 +2006,7 @@ class AudioReactive : public Usermod {
top[FPSTR(_addPalettes)] = addPalettes;
#ifdef ARDUINO_ARCH_ESP32
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32S3)
JsonObject amic = top.createNestedObject(FPSTR(_analogmic));
amic["pin"] = audioPin;
#endif
@@ -2065,16 +2065,16 @@ class AudioReactive : public Usermod {
configComplete &= getJsonValue(top[FPSTR(_addPalettes)], addPalettes);
#ifdef ARDUINO_ARCH_ESP32
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32S3)
configComplete &= getJsonValue(top[FPSTR(_analogmic)]["pin"], audioPin);
#else
audioPin = -1; // MCU does not support analog mic
#endif
configComplete &= getJsonValue(top[FPSTR(_digitalmic)]["type"], dmType);
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3)
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32S3)
if (dmType == 0) dmType = SR_DMTYPE; // MCU does not support analog
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3)
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5)
if (dmType == 5) dmType = SR_DMTYPE; // MCU does not support PDM
#endif
#endif
@@ -2112,14 +2112,14 @@ class AudioReactive : public Usermod {
#ifdef ARDUINO_ARCH_ESP32
uiScript.print(F("uxp=ux+':digitalmic:pin[]';")); // uxp = shortcut for AudioReactive:digitalmic:pin[]
uiScript.print(F("dd=addDropdown(ux,'digitalmic:type');"));
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32S3)
uiScript.print(F("addOption(dd,'Generic Analog',0);"));
#endif
uiScript.print(F("addOption(dd,'Generic I2S',1);"));
uiScript.print(F("addOption(dd,'ES7243',2);"));
uiScript.print(F("addOption(dd,'SPH0654',3);"));
uiScript.print(F("addOption(dd,'Generic I2S with Mclk',4);"));
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32C61)
uiScript.print(F("addOption(dd,'Generic PDM',5);"));
#endif
uiScript.print(F("addOption(dd,'ES8388',6);"));
@@ -2155,7 +2155,7 @@ class AudioReactive : public Usermod {
uiScript.print(F("addInfo(uxp,0,'<i>sd/data/dout</i>','I2S SD');"));
uiScript.print(F("addInfo(uxp,1,'<i>ws/clk/lrck</i>','I2S WS');"));
uiScript.print(F("addInfo(uxp,2,'<i>sck/bclk</i>','I2S SCK');"));
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32S3)
uiScript.print(F("addInfo(uxp,3,'<i>only use -1, 0, 1 or 3</i>','I2S MCLK');"));
#else
uiScript.print(F("addInfo(uxp,3,'<i>master clock</i>','I2S MCLK');"));
@@ -2278,7 +2278,7 @@ const char AudioReactive::_config[] PROGMEM = "config";
const char AudioReactive::_dynamics[] PROGMEM = "dynamics";
const char AudioReactive::_frequency[] PROGMEM = "frequency";
const char AudioReactive::_inputLvl[] PROGMEM = "inputLevel";
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32S3)
const char AudioReactive::_analogmic[] PROGMEM = "analogmic";
#endif
const char AudioReactive::_digitalmic[] PROGMEM = "digitalmic";

View File

@@ -22,14 +22,14 @@
// see https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/chip-series-comparison.html#related-documents
// and https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/peripherals/i2s.html#overview-of-all-modes
#if defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(ESP8266) || defined(ESP8265)
#if defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(ESP8266) || defined(ESP8265)
// there are two things in these MCUs that could lead to problems with audio processing:
// * no floating point hardware (FPU) support - FFT uses float calculations. If done in software, a strong slow-down can be expected (between 8x and 20x)
// * single core, so FFT task might slow down other things like LED updates
#if !defined(SOC_I2S_NUM) || (SOC_I2S_NUM < 1)
#error This audio reactive usermod does not support ESP32-C2 or ESP32-C3.
#error This audio reactive usermod does not support your MCU yet.
#else
#warning This audio reactive usermod does not support ESP32-C2 and ESP32-C3.
#warning This audio reactive usermod does not support your MCU yet.
#endif
#endif

View File

@@ -234,11 +234,11 @@ class QuinLEDAnPentaUsermod : public Usermod
bool oledCheckForNetworkChanges()
{
if (lastKnownNetworkConnected != Network.isConnected() || lastKnownIp != Network.localIP()
if (lastKnownNetworkConnected != WLEDNetwork.isConnected() || lastKnownIp != WLEDNetwork.localIP()
|| lastKnownWiFiConnected != WiFi.isConnected() || lastKnownSsid != WiFi.SSID()
|| lastKnownApActive != apActive || lastKnownApSsid != apSSID || lastKnownApPass != apPass || lastKnownApChannel != apChannel) {
lastKnownNetworkConnected = Network.isConnected();
lastKnownIp = Network.localIP();
lastKnownNetworkConnected = WLEDNetwork.isConnected();
lastKnownIp = WLEDNetwork.localIP();
lastKnownWiFiConnected = WiFi.isConnected();
lastKnownSsid = WiFi.SSID();
lastKnownApActive = apActive;

View File

@@ -264,7 +264,7 @@ void FourLineDisplayUsermod::setup() {
// interfaces here
void FourLineDisplayUsermod::connected() {
knownSsid = WiFi.SSID(); //apActive ? apSSID : WiFi.SSID(); //apActive ? WiFi.softAPSSID() :
knownIp = Network.localIP(); //apActive ? IPAddress(4, 3, 2, 1) : Network.localIP();
knownIp = WLEDNetwork.localIP(); //apActive ? IPAddress(4, 3, 2, 1) : WLEDNetwork.localIP();
networkOverlay(PSTR("NETWORK INFO"),7000);
}

View File

@@ -61,10 +61,12 @@ extern byte realtimeMode; // used in getMappedPixelIndex()
#define WLED_FPS 42
#define FRAMETIME_FIXED (1000/WLED_FPS)
#define FRAMETIME strip.getFrameTime()
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#define MIN_FRAME_DELAY 2 // minimum wait between repaints, to keep other functions like WiFi alive
#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3)
#define MIN_FRAME_DELAY 3 // S2/C3 are slower than normal esp32, and only have one core
#if defined(ARDUINO_ARCH_ESP32)
#if (SOC_CPU_CORES_NUM < 2)
#define MIN_FRAME_DELAY 3 // S2/C3/C6/C5 are slower than normal esp32, and only have one core
#else
#define MIN_FRAME_DELAY 2 // classic esp32/S3/P4: minimum wait between repaints, to keep other functions like WiFi alive
#endif
#else
#define MIN_FRAME_DELAY 8 // 8266 legacy MIN_SHOW_DELAY
#endif

View File

@@ -29,9 +29,7 @@
19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25]}
*/
#if MAX_NUM_SEGMENTS < WLED_MAX_BUSSES
#error "Max segments must be at least max number of busses!"
#endif
static_assert(MAX_NUM_SEGMENTS >= WLED_MAX_BUSSES, "Max segments must be at least max number of busses!");
///////////////////////////////////////////////////////////////////////////////
@@ -1161,7 +1159,7 @@ void WS2812FX::finalizeInit() {
BusManager::removeAll();
// TODO: ideally we would free everything segment related here to reduce fragmentation (pixel buffers, ledamp, segments, etc) but that somehow leads to heap corruption if touchig any of the buffers.
unsigned digitalCount = 0;
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_HAS_PARALLEL_I2S)
// validate the bus config: count I2S buses and check if they meet requirements
unsigned i2sBusCount = 0;
@@ -1203,7 +1201,7 @@ void WS2812FX::finalizeInit() {
unsigned busMemUsage = bus.memUsage(); // does not include DMA/RMT buffer but includes pixel buffers (segment buffer + global buffer)
mem += busMemUsage;
// estimate maximum I2S memory usage (only relevant for digital non-2pin busses when I2S is enabled)
#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(ESP8266)
#if defined(WLED_HAS_PARALLEL_I2S)
bool usesI2S = (bus.iType & 0x01) == 0; // I2S bus types are even numbered, can't use bus.driverType == 1 as getI() may have defaulted to RMT
if (Bus::isDigital(bus.type) && !Bus::is2Pin(bus.type) && usesI2S) {
#ifdef NPB_CONF_4STEP_CADENCE
@@ -1341,8 +1339,8 @@ static uint8_t _add (uint8_t a, uint8_t b) { unsigned t = a + b; return t
static uint8_t _subtract (uint8_t a, uint8_t b) { return b > a ? (b - a) : 0; }
static uint8_t _difference(uint8_t a, uint8_t b) { return b > a ? (b - a) : (a - b); }
static uint8_t _average (uint8_t a, uint8_t b) { return (a + b) >> 1; }
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3)
static uint8_t _multiply (uint8_t a, uint8_t b) { return ((a * b) + 255) >> 8; } // faster than division on C3 but slightly less accurate
#if !defined(WLED_HAVE_FAST_int_DIVIDE)
static uint8_t _multiply (uint8_t a, uint8_t b) { return ((a * b) + 255) >> 8; } // faster than division on C3/C5 but slightly less accurate
#else
static uint8_t _multiply (uint8_t a, uint8_t b) { return (a * b) / 255; } // origianl uses a & b in range [0,1]
#endif
@@ -1352,7 +1350,7 @@ static uint8_t _darken (uint8_t a, uint8_t b) { return a < b ? a : b; }
static uint8_t _screen (uint8_t a, uint8_t b) { return 255 - _multiply(~a,~b); } // 255 - (255-a)*(255-b)/255
static uint8_t _overlay (uint8_t a, uint8_t b) { return b < 128 ? 2 * _multiply(a,b) : (255 - 2 * _multiply(~a,~b)); }
static uint8_t _hardlight (uint8_t a, uint8_t b) { return a < 128 ? 2 * _multiply(a,b) : (255 - 2 * _multiply(~a,~b)); }
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3)
#if !defined(WLED_HAVE_FAST_int_DIVIDE)
static uint8_t _softlight (uint8_t a, uint8_t b) { return (((b * b * (255 - 2 * a))) + ((2 * a * b + 256) << 8)) >> 16; } // Pegtop's formula (1 - 2a)b^2
#else
static uint8_t _softlight (uint8_t a, uint8_t b) { return (b * b * (255 - 2 * a) + 255 * 2 * a * b) / (255 * 255); } // Pegtop's formula (1 - 2a)b^2 + 2ab

View File

@@ -500,7 +500,7 @@ void ParticleSystem2D::applyGravity(PSparticle &part) {
// note: a coefficient smaller than 0 will speed them up (this is a feature, not a bug), coefficient larger than 255 inverts the speed, so don't do that
void ParticleSystem2D::applyFriction(PSparticle &part, const int32_t coefficient) {
// note: not checking if particle is dead can be done by caller (or can be omitted)
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ESP8266) // use bitshifts with rounding instead of division (2x faster)
#if !defined(WLED_HAVE_FAST_int_DIVIDE) // use bitshifts with rounding instead of division (2x faster)
int32_t friction = 256 - coefficient;
part.vx = ((int32_t)part.vx * friction + (((int32_t)part.vx >> 31) & 0xFF)) >> 8; // note: (v>>31) & 0xFF)) extracts the sign and adds 255 if negative for correct rounding using shifts
part.vy = ((int32_t)part.vy * friction + (((int32_t)part.vy >> 31) & 0xFF)) >> 8;
@@ -514,7 +514,7 @@ void ParticleSystem2D::applyFriction(PSparticle &part, const int32_t coefficient
// apply friction to all particles
// note: not checking if particle is dead is faster as most are usually alive and if few are alive, rendering is fast anyways
void ParticleSystem2D::applyFriction(const int32_t coefficient) {
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ESP8266) // use bitshifts with rounding instead of division (2x faster)
#if !defined(WLED_HAVE_FAST_int_DIVIDE) // use bitshifts with rounding instead of division (2x faster)
int32_t friction = 256 - coefficient;
for (uint32_t i = 0; i < usedParticles; i++) {
particles[i].vx = ((int32_t)particles[i].vx * friction + (((int32_t)particles[i].vx >> 31) & 0xFF)) >> 8; // note: (v>>31) & 0xFF)) extracts the sign and adds 255 if negative for correct rounding using shifts
@@ -927,7 +927,7 @@ void WLED_O2_ATTR ParticleSystem2D::collideParticles(PSparticle &particle1, PSpa
int32_t surfacehardness = max(collisionHardness, (int32_t)PS_P_MINSURFACEHARDNESS >> 1); // if particles are soft, the impulse must stay above a limit or collisions slip through at higher speeds, 170 seems to be a good value
int32_t impulse = (((((-dotProduct) << 15) / distanceSquared) * surfacehardness) >> 8); // note: inverting before bitshift corrects for asymmetry in right-shifts (is slightly faster)
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ESP8266) // use bitshifts with rounding instead of division (2x faster)
#if !defined(WLED_HAVE_FAST_int_DIVIDE) // use bitshifts with rounding instead of division (2x faster)
int32_t ximpulse = (impulse * dx + ((dx >> 31) & 0x7FFF)) >> 15; // note: extracting sign bit and adding rounding value to correct for asymmetry in right shifts
int32_t yimpulse = (impulse * dy + ((dy >> 31) & 0x7FFF)) >> 15;
#else
@@ -955,7 +955,7 @@ void WLED_O2_ATTR ParticleSystem2D::collideParticles(PSparticle &particle1, PSpa
if (collisionHardness < PS_P_MINSURFACEHARDNESS && (SEGMENT.call & 0x07) == 0) { // if particles are soft, they become 'sticky' i.e. apply some friction (they do pile more nicely and stop sloshing around)
const uint32_t coeff = collisionHardness + (255 - PS_P_MINSURFACEHARDNESS);
// Note: could call applyFriction, but this is faster and speed is key here
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ESP8266) // use bitshifts with rounding instead of division (2x faster)
#if !defined(WLED_HAVE_FAST_int_DIVIDE) // use bitshifts with rounding instead of division (2x faster)
particle1.vx = ((int32_t)particle1.vx * coeff + (((int32_t)particle1.vx >> 31) & 0xFF)) >> 8; // note: (v>>31) & 0xFF)) extracts the sign and adds 255 if negative for correct rounding using shifts
particle1.vy = ((int32_t)particle1.vy * coeff + (((int32_t)particle1.vy >> 31) & 0xFF)) >> 8;
particle2.vx = ((int32_t)particle2.vx * coeff + (((int32_t)particle2.vx >> 31) & 0xFF)) >> 8;
@@ -1408,7 +1408,7 @@ void ParticleSystem1D::applyGravity(PSparticle1D &part, PSparticleFlags1D &partF
// slow down particle by friction, the higher the speed, the higher the friction. a high friction coefficient slows them more (255 means instant stop)
// note: a coefficient smaller than 0 will speed them up (this is a feature, not a bug), coefficient larger than 255 inverts the speed, so don't do that
void ParticleSystem1D::applyFriction(int32_t coefficient) {
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ESP8266) // use bitshifts with rounding instead of division (2x faster)
#if !defined(WLED_HAVE_FAST_int_DIVIDE) // use bitshifts with rounding instead of division (2x faster)
int32_t friction = 256 - coefficient;
for (uint32_t i = 0; i < usedParticles; i++) {
if (particles[i].ttl)
@@ -1699,7 +1699,7 @@ void WLED_O2_ATTR ParticleSystem1D::collideParticles(uint32_t partIdx1, uint32_t
}
int32_t surfacehardness = max(collisionHardness, (int32_t)PS_P_MINSURFACEHARDNESS_1D); // if particles are soft, the impulse must stay above a limit or collisions slip through
// Calculate new velocities after collision note: not using dot product like in 2D as impulse is purely speed depnedent
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ESP8266) // use bitshifts with rounding instead of division (2x faster)
#if !defined(WLED_HAVE_FAST_int_DIVIDE) // use bitshifts with rounding instead of division (2x faster)
int32_t impulse = (dv * surfacehardness + ((dv >> 31) & 0xFF)) >> 8; // note: (v>>31) & 0xFF)) extracts the sign and adds 255 if negative for correct rounding using shifts
#else // division is faster on ESP32, S2 and S3
int32_t impulse = (dv * surfacehardness) / 255;
@@ -1720,7 +1720,7 @@ void WLED_O2_ATTR ParticleSystem1D::collideParticles(uint32_t partIdx1, uint32_t
if (collisionHardness < PS_P_MINSURFACEHARDNESS_1D && (SEGMENT.call & 0x07) == 0) { // if particles are soft, they become 'sticky' i.e. apply some friction
const uint32_t coeff = collisionHardness + (250 - PS_P_MINSURFACEHARDNESS_1D);
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ESP8266) // use bitshifts with rounding instead of division (2x faster)
#if !defined(WLED_HAVE_FAST_int_DIVIDE) // use bitshifts with rounding instead of division (2x faster)
particles[partIdx1].vx = ((int32_t)particles[partIdx1].vx * coeff + (((int32_t)particles[partIdx1].vx >> 31) & 0xFF)) >> 8; // note: (v>>31) & 0xFF)) extracts the sign and adds 255 if negative for correct rounding using shifts
particles[partIdx2].vx = ((int32_t)particles[partIdx2].vx * coeff + (((int32_t)particles[partIdx2].vx >> 31) & 0xFF)) >> 8;
#else // division is faster on ESP32, S2 and S3

View File

@@ -55,4 +55,4 @@ struct NodeStruct
};
typedef std::map<uint8_t, NodeStruct> NodesMap;
#endif // WLED_NODESTRUCT_H
#endif // WLED_NODESTRUCT_H

View File

@@ -453,8 +453,13 @@ BusPwm::BusPwm(const BusConfig &bc)
pinMode(_pins[i], OUTPUT);
#else
unsigned channel = _ledcStart + i;
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
ledcSetup(channel, _frequency, _depth - (dithering*4)); // with dithering _frequency doesn't really matter as resolution is 8 bit
ledcAttachPin(_pins[i], channel);
#else
ledcAttachChannel(_pins[i], _frequency, _depth - (dithering*4), channel);
// LEDC timer reset credit @dedehai
#endif
// LEDC timer reset credit @dedehai
uint8_t group = (channel / 8), timer = ((channel / 2) % 4); // same fromula as in ledcSetup()
ledc_timer_rst((ledc_mode_t)group, (ledc_timer_t)timer); // reset timer so all timers are almost in sync (for phase shift)
@@ -586,10 +591,20 @@ void BusPwm::show() {
unsigned ch = channel%8; // group channel
// directly write to LEDC struct as there is no HAL exposed function for dithering
// duty has 20 bit resolution with 4 fractional bits (24 bits in total)
#if defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32P4)
// the .duty_init.duty member seems to only affect fade operations, and its necessary to also trigger an update with
// LEDC.channel_group[gr].channel[ch].conf0.para_up = 1;
// --> research latest (V5.5.x) esp-idf documentation on how to set the duty cycle registers (by API calls?).
// https://docs.espressif.com/projects/esp-idf/en/v5.5.2/esp32c5/api-reference/peripherals/ledc.html#_CPPv424ledc_set_duty_and_update11ledc_mode_t14ledc_channel_t8uint32_t8uint32_t
// LEDC.channel_group[gr].channel[ch].duty_init.duty = duty << ((!dithering)*4); // C5 LEDC struct uses duty_init, but requires additional steps to activate
// TODO: find out if / how dithering support can be implemented on P4
ledc_set_duty_and_update((ledc_mode_t)gr, (ledc_channel_t)ch, duty >> bitShift, hPoint >> bitShift);
#else
LEDC.channel_group[gr].channel[ch].duty.duty = duty << ((!dithering)*4); // lowest 4 bits are used for dithering, shift by 4 bits if not using dithering
LEDC.channel_group[gr].channel[ch].hpoint.hpoint = hPoint >> bitShift; // hPoint is at _depth resolution (needs shifting if dithering)
ledc_update_duty((ledc_mode_t)gr, (ledc_channel_t)ch);
#endif
#endif // ESP32C5
#endif // 8266
if (!_reversed) hPoint += duty;
hPoint += deadTime; // offset to cascade the signals
@@ -624,7 +639,11 @@ void BusPwm::deallocatePins() {
#ifdef ESP8266
digitalWrite(_pins[i], LOW); //turn off PWM interrupt
#else
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
if (_ledcStart < WLED_MAX_ANALOG_CHANNELS) ledcDetachPin(_pins[i]);
#else
if (_ledcStart < WLED_MAX_ANALOG_CHANNELS) ledcDetach(_pins[i]);
#endif
#endif
}
#ifdef ARDUINO_ARCH_ESP32
@@ -745,7 +764,7 @@ size_t BusNetwork::getPins(uint8_t* pinArray) const {
#ifdef ARDUINO_ARCH_ESP32
void BusNetwork::resolveHostname() {
static std::shared_ptr<AsyncDNS> DNSlookup; // TODO: make this dynamic? requires to handle the callback properly
if (Network.isConnected()) {
if (WLEDNetwork.isConnected()) {
IPAddress clnt;
if (strlen(cmDNS) > 0) {
clnt = MDNS.queryHost(_hostname);
@@ -1266,6 +1285,10 @@ void BusManager::removeAll() {
// since I2S outputs are known only during config of buses, lets just assume RMT is used for digital buses
// unused RMT channels should have no effect
void BusManager::esp32RMTInvertIdle() {
#if defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32P4)
// ESP32-C5/C6/P4 use shared RMT method - idle level inversion not supported
return;
#else
bool idle_out;
unsigned rmt = 0;
unsigned u = 0;
@@ -1283,6 +1306,7 @@ void BusManager::esp32RMTInvertIdle() {
rmt_set_idle_level(ch, idle_out, lvl);
u++;
}
#endif
}
#endif

View File

@@ -5,6 +5,8 @@
//#define NPB_CONF_4STEP_CADENCE
#include "NeoPixelBus.h"
#include "wled_boards.h" // pull in board-specific capability defines
//Hardware SPI Pins
#define P_8266_HS_MOSI 13
#define P_8266_HS_CLK 14
@@ -231,7 +233,7 @@
typedef NeoEsp32I2s0Apa106Method X1Apa106Method;
typedef NeoEsp32I2s0Ws2805Method X1Ws2805Method;
typedef NeoEsp32I2s0Tm1914Method X1Tm1914Method;
#elif !defined(CONFIG_IDF_TARGET_ESP32C3)
#elif !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32C61) && !defined(CONFIG_IDF_TARGET_ESP32P4)
// regular ESP32 will use I2S1
typedef NeoEsp32I2s1Ws2812xMethod X1Ws2812xMethod;
typedef NeoEsp32I2s1Sk6812Method X1Sk6812Method;
@@ -245,7 +247,9 @@
#endif
// RMT driver selection
#if !defined(WLED_USE_SHARED_RMT) && !defined(__riscv)
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#define NeoEsp32RmtMethod(x) NeoEsp32RmtX ## x ## Method
#elif !defined(WLED_USE_SHARED_RMT) && !defined(__riscv)
#include <NeoEsp32RmtHIMethod.h>
#define NeoEsp32RmtMethod(x) NeoEsp32RmtHIN ## x ## Method
#else
@@ -453,7 +457,7 @@ class PolyBus {
case I_32_RN_TM1914_3: beginTM1914<B_32_RN_TM1914_3*>(busPtr); break;
case I_32_RN_SM16825_5: (static_cast<B_32_RN_SM16825_5*>(busPtr))->Begin(); break;
// I2S1 bus or parellel buses
#ifndef CONFIG_IDF_TARGET_ESP32C3
#if defined(WLED_HAS_PARALLEL_I2S)
case I_32_I2_NEO_3: if (_useParallelI2S) (static_cast<B_32_IP_NEO_3*>(busPtr))->Begin(); else (static_cast<B_32_I2_NEO_3*>(busPtr))->Begin(); break;
case I_32_I2_NEO_4: if (_useParallelI2S) (static_cast<B_32_IP_NEO_4*>(busPtr))->Begin(); else (static_cast<B_32_I2_NEO_4*>(busPtr))->Begin(); break;
case I_32_I2_400_3: if (_useParallelI2S) (static_cast<B_32_IP_400_3*>(busPtr))->Begin(); else (static_cast<B_32_I2_400_3*>(busPtr))->Begin(); break;
@@ -551,7 +555,7 @@ class PolyBus {
case I_32_RN_TM1914_3: busPtr = new B_32_RN_TM1914_3(len, pins[0], (NeoBusChannel)_rmtChannel++); break;
case I_32_RN_SM16825_5: busPtr = new B_32_RN_SM16825_5(len, pins[0], (NeoBusChannel)_rmtChannel++); break;
// I2S1 bus or paralell buses
#ifndef CONFIG_IDF_TARGET_ESP32C3
#if defined(WLED_HAS_PARALLEL_I2S)
case I_32_I2_NEO_3: if (_useParallelI2S) busPtr = new B_32_IP_NEO_3(len, pins[0]); else busPtr = new B_32_I2_NEO_3(len, pins[0]); break;
case I_32_I2_NEO_4: if (_useParallelI2S) busPtr = new B_32_IP_NEO_4(len, pins[0]); else busPtr = new B_32_I2_NEO_4(len, pins[0]); break;
case I_32_I2_400_3: if (_useParallelI2S) busPtr = new B_32_IP_400_3(len, pins[0]); else busPtr = new B_32_I2_400_3(len, pins[0]); break;
@@ -650,7 +654,7 @@ class PolyBus {
case I_32_RN_TM1914_3: (static_cast<B_32_RN_TM1914_3*>(busPtr))->Show(consistent); break;
case I_32_RN_SM16825_5: (static_cast<B_32_RN_SM16825_5*>(busPtr))->Show(consistent); break;
// I2S1 bus or paralell buses
#ifndef CONFIG_IDF_TARGET_ESP32C3
#if defined(WLED_HAS_PARALLEL_I2S)
case I_32_I2_NEO_3: if (_useParallelI2S) (static_cast<B_32_IP_NEO_3*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_NEO_3*>(busPtr))->Show(consistent); break;
case I_32_I2_NEO_4: if (_useParallelI2S) (static_cast<B_32_IP_NEO_4*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_NEO_4*>(busPtr))->Show(consistent); break;
case I_32_I2_400_3: if (_useParallelI2S) (static_cast<B_32_IP_400_3*>(busPtr))->Show(consistent); else (static_cast<B_32_I2_400_3*>(busPtr))->Show(consistent); break;
@@ -746,7 +750,7 @@ class PolyBus {
case I_32_RN_TM1914_3: return (static_cast<B_32_RN_TM1914_3*>(busPtr))->CanShow(); break;
case I_32_RN_SM16825_5: return (static_cast<B_32_RN_SM16825_5*>(busPtr))->CanShow(); break;
// I2S1 bus or paralell buses
#ifndef CONFIG_IDF_TARGET_ESP32C3
#if defined(WLED_HAS_PARALLEL_I2S)
case I_32_I2_NEO_3: if (_useParallelI2S) return (static_cast<B_32_IP_NEO_3*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_NEO_3*>(busPtr))->CanShow(); break;
case I_32_I2_NEO_4: if (_useParallelI2S) return (static_cast<B_32_IP_NEO_4*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_NEO_4*>(busPtr))->CanShow(); break;
case I_32_I2_400_3: if (_useParallelI2S) return (static_cast<B_32_IP_400_3*>(busPtr))->CanShow(); else return (static_cast<B_32_I2_400_3*>(busPtr))->CanShow(); break;
@@ -868,7 +872,7 @@ class PolyBus {
case I_32_RN_TM1914_3: (static_cast<B_32_RN_TM1914_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
case I_32_RN_SM16825_5: (static_cast<B_32_RN_SM16825_5*>(busPtr))->SetPixelColor(pix, Rgbww80Color(col.R*257, col.G*257, col.B*257, cctWW*257, cctCW*257)); break;
// I2S1 bus or paralell buses
#ifndef CONFIG_IDF_TARGET_ESP32C3
#if defined(WLED_HAS_PARALLEL_I2S)
case I_32_I2_NEO_3: if (_useParallelI2S) (static_cast<B_32_IP_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I2_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
case I_32_I2_NEO_4: if (_useParallelI2S) (static_cast<B_32_IP_NEO_4*>(busPtr))->SetPixelColor(pix, col); else (static_cast<B_32_I2_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
case I_32_I2_400_3: if (_useParallelI2S) (static_cast<B_32_IP_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast<B_32_I2_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
@@ -965,7 +969,7 @@ class PolyBus {
case I_32_RN_TM1914_3: col = (static_cast<B_32_RN_TM1914_3*>(busPtr))->GetPixelColor(pix); break;
case I_32_RN_SM16825_5: { Rgbww80Color c = (static_cast<B_32_RN_SM16825_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,max(c.WW,c.CW)/257); } break; // will not return original W
// I2S1 bus or paralell buses
#ifndef CONFIG_IDF_TARGET_ESP32C3
#if defined(WLED_HAS_PARALLEL_I2S)
case I_32_I2_NEO_3: col = (_useParallelI2S) ? (static_cast<B_32_IP_NEO_3*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_NEO_3*>(busPtr))->GetPixelColor(pix); break;
case I_32_I2_NEO_4: col = (_useParallelI2S) ? (static_cast<B_32_IP_NEO_4*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_NEO_4*>(busPtr))->GetPixelColor(pix); break;
case I_32_I2_400_3: col = (_useParallelI2S) ? (static_cast<B_32_IP_400_3*>(busPtr))->GetPixelColor(pix) : (static_cast<B_32_I2_400_3*>(busPtr))->GetPixelColor(pix); break;
@@ -1080,7 +1084,7 @@ class PolyBus {
case I_32_RN_TM1914_3: delete (static_cast<B_32_RN_TM1914_3*>(busPtr)); break;
case I_32_RN_SM16825_5: delete (static_cast<B_32_RN_SM16825_5*>(busPtr)); break;
// I2S1 bus or paralell buses
#ifndef CONFIG_IDF_TARGET_ESP32C3
#if defined(WLED_HAS_PARALLEL_I2S)
case I_32_I2_NEO_3: if (_useParallelI2S) delete (static_cast<B_32_IP_NEO_3*>(busPtr)); else delete (static_cast<B_32_I2_NEO_3*>(busPtr)); break;
case I_32_I2_NEO_4: if (_useParallelI2S) delete (static_cast<B_32_IP_NEO_4*>(busPtr)); else delete (static_cast<B_32_I2_NEO_4*>(busPtr)); break;
case I_32_I2_400_3: if (_useParallelI2S) delete (static_cast<B_32_IP_400_3*>(busPtr)); else delete (static_cast<B_32_I2_400_3*>(busPtr)); break;
@@ -1180,7 +1184,7 @@ class PolyBus {
case I_32_RN_TM1914_3: size += (static_cast<B_32_RN_TM1914_3*>(busPtr))->PixelsSize()*2; break;
case I_32_RN_SM16825_5: size += (static_cast<B_32_RN_SM16825_5*>(busPtr))->PixelsSize()*2; break;
// I2S1 bus or paralell buses (front + DMA; DMA = front * cadence, aligned to 4 bytes) not: for parallel I2S only the largest bus counts for DMA memory, this is not done correctly here, also assumes 3-step cadence
#ifndef CONFIG_IDF_TARGET_ESP32C3
#if defined(WLED_HAS_PARALLEL_I2S)
case I_32_I2_NEO_3: size += (_useParallelI2S) ? (static_cast<B_32_IP_NEO_3*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_NEO_3*>(busPtr))->PixelsSize()*4; break;
case I_32_I2_NEO_4: size += (_useParallelI2S) ? (static_cast<B_32_IP_NEO_4*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_NEO_4*>(busPtr))->PixelsSize()*4; break;
case I_32_I2_400_3: size += (_useParallelI2S) ? (static_cast<B_32_IP_400_3*>(busPtr))->PixelsSize()*4 : (static_cast<B_32_I2_400_3*>(busPtr))->PixelsSize()*4; break;
@@ -1260,7 +1264,7 @@ class PolyBus {
case I_32_RN_2805_5 : size = (size + 2*count)*2; break; // 5 channels
case I_32_RN_SM16825_5: size = (size + 2*count)*2*2; break; // 16bit, 5 channels
// I2S bus or paralell I2S buses (1x front, does not include DMA buffer which is front*cadence, a bit(?) more for LCD)
#ifndef CONFIG_IDF_TARGET_ESP32C3
#if defined(WLED_HAS_PARALLEL_I2S) || defined(CONFIG_IDF_TARGET_ESP32)
case I_32_I2_NEO_3 : // fallthrough
case I_32_I2_400_3 : // fallthrough
case I_32_I2_TM2_3 : // fallthrough

View File

@@ -109,7 +109,7 @@ bool isButtonPressed(uint8_t b)
break;
case BTN_TYPE_TOUCH:
case BTN_TYPE_TOUCH_SWITCH:
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32C61) && !defined(CONFIG_IDF_TARGET_ESP32P4)
#ifdef SOC_TOUCH_VERSION_2 //ESP32 S2 and S3 provide a function to check touch state (state is updated in interrupt)
if (touchInterruptGetLastStatus(pin)) return true;
#else
@@ -396,7 +396,9 @@ void handleOnOff(bool forceOff)
}
}
#ifdef SOC_TOUCH_VERSION_2 //ESP32 S2 and S3 provide a function to check touch state (state is updated in interrupt)
void IRAM_ATTR touchButtonISR()
{
// used for ESP32 S2 and S3: nothing to do, ISR is just used to update registers of HAL driver
}
#endif

View File

@@ -157,9 +157,17 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
noWifiSleep = !(wifi[F("sleep")] | !noWifiSleep); // inverted
//noWifiSleep = !noWifiSleep;
CJSON(force802_3g, wifi[F("phy")]); //force phy mode g?
#ifdef SOC_WIFI_SUPPORT_5G
CJSON(wifiBandMode, wifi[F("band")]);
if (wifiBandMode < WIFI_BAND_MODE_2G_ONLY || wifiBandMode > WIFI_BAND_MODE_AUTO) wifiBandMode = WIFI_BAND_MODE_AUTO;
#endif
#ifdef ARDUINO_ARCH_ESP32
CJSON(txPower, wifi[F("txpwr")]);
txPower = min(max((int)txPower, (int)WIFI_POWER_2dBm), (int)WIFI_POWER_19_5dBm);
#if defined(ARDUINO_ARCH_ESP32) && (ESP_IDF_VERSION_MAJOR > 4)
txPower = min(max((int)txPower, (int)WIFI_POWER_2dBm), (int)WIFI_POWER_21dBm); // V5 allows WIFI_POWER_21dBm = 84 ... WIFI_POWER_MINUS_1dBm = -4
#else
txPower = min(max((int)txPower, (int)WIFI_POWER_2dBm), (int)WIFI_POWER_19_5dBm);
#endif
#endif
JsonObject hw = doc[F("hw")];
@@ -659,6 +667,12 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
JsonObject if_ntp = interfaces[F("ntp")];
CJSON(ntpEnabled, if_ntp["en"]);
#ifdef CONFIG_IDF_TARGET_ESP32C5 // ToDO: esp32-c5 crashes on NTP requests
if (ntpEnabled) { DEBUG_PRINTLN("NTP disabled on -C5, as it leads to crashes"); }
// assert failed: udp_new_ip_type /IDF/components/lwip/lwip/src/core/udp.c:1278 (Required to lock TCPIP core functionality!)
ntpEnabled = false; // --> disable NTP support, until the crash is resolved
#warning "enabling NTP lead to crashes on -C5. NTP disabled"
#endif
getStringFromJson(ntpServerName, if_ntp[F("host")], 33); // "1.wled.pool.ntp.org"
CJSON(currentTimezone, if_ntp[F("tz")]);
CJSON(utcOffsetSecs, if_ntp[F("offset")]);
@@ -897,6 +911,9 @@ void serializeConfig(JsonObject root) {
JsonObject wifi = root.createNestedObject(F("wifi"));
wifi[F("sleep")] = !noWifiSleep;
wifi[F("phy")] = force802_3g;
#ifdef SOC_WIFI_SUPPORT_5G
wifi[F("band")] = wifiBandMode;
#endif
#ifdef ARDUINO_ARCH_ESP32
wifi[F("txpwr")] = txPower;
#endif

View File

@@ -65,8 +65,14 @@ constexpr size_t FIXED_PALETTE_COUNT = DYNAMIC_PALETTE_COUNT + FASTLED_PALETTE_C
#if !defined(LEDC_CHANNEL_MAX) || !defined(LEDC_SPEED_MODE_MAX)
#include "driver/ledc.h" // needed for analog/LEDC channel counts
#endif
#define WLED_MAX_ANALOG_CHANNELS (LEDC_CHANNEL_MAX*LEDC_SPEED_MODE_MAX)
#if defined(CONFIG_IDF_TARGET_ESP32C3) // 2 RMT, 6 LEDC, only has 1 I2S but NPB does not support it ATM
// define -> constexpr to avoid preprocessor errors and enum arithmetic warnings from newer compilers
#ifdef WLED_MAX_ANALOG_CHANNELS
#undef WLED_MAX_ANALOG_CHANNELS // avoid clash between macro name and constexpr constant
#endif
constexpr size_t WLED_MAX_ANALOG_CHANNELS = static_cast<size_t>(LEDC_CHANNEL_MAX) * static_cast<size_t>(LEDC_SPEED_MODE_MAX);
#if defined(CONFIG_IDF_TARGET_ESP32C3)
#define WLED_MAX_RMT_CHANNELS 2 // ESP32-C3 has 2 RMT output channels
#define WLED_MAX_I2S_CHANNELS 0 // I2S not supported by NPB
//#define WLED_MAX_ANALOG_CHANNELS 6
@@ -82,20 +88,32 @@ constexpr size_t FIXED_PALETTE_COUNT = DYNAMIC_PALETTE_COUNT + FASTLED_PALETTE_C
//#define WLED_MAX_ANALOG_CHANNELS 8
#define WLED_PLATFORM_ID 3 // used in UI to distinguish ESP type in UI, needs a proper fix!
#else
#define WLED_MAX_RMT_CHANNELS 8 // ESP32 has 8 RMT output channels
#define WLED_MAX_I2S_CHANNELS 8 // I2S parallel output supported by NPB
//#define WLED_MAX_ANALOG_CHANNELS 16
#define WLED_PLATFORM_ID 4 // used in UI to distinguish ESP type in UI, needs a proper fix!
#if defined(CONFIG_IDF_TARGET_ESP32) // classic esp32
#define WLED_MAX_RMT_CHANNELS 8 // ESP32 has 8 RMT output channels
#define WLED_MAX_I2S_CHANNELS 8 // I2S parallel output supported by NPB
//#define WLED_MAX_ANALOG_CHANNELS 16
#define WLED_PLATFORM_ID 4 // used in UI to distinguish ESP type in UI, needs a proper fix!
#else // all other risc-v based boards: same as C3
#define WLED_MAX_RMT_CHANNELS 2 // ESP32-C3 has 2 RMT output channels
#define WLED_MAX_I2S_CHANNELS 0 // I2S not supported by NPB
//#define WLED_MAX_ANALOG_CHANNELS 6
#define WLED_PLATFORM_ID 1 // used in UI to distinguish ESP types - falls back to "C3" until we have a proper fix!
#endif
#endif
#define WLED_MAX_TIMERS 64 // maximum number of timers
#define WLED_MAX_DIGITAL_CHANNELS (WLED_MAX_RMT_CHANNELS + WLED_MAX_I2S_CHANNELS)
#ifndef WLED_MAX_DIGITAL_CHANNELS
#define WLED_MAX_DIGITAL_CHANNELS (WLED_MAX_RMT_CHANNELS + WLED_MAX_I2S_CHANNELS)
#else
#warning "buildenv overrides WLED_MAX_DIGITAL_CHANNELS - please check that the value is correct"
#endif
#endif
// WLED_MAX_BUSSES was used to define the size of busses[] array which is no longer needed
// instead it will help determine max number of buses that can be defined at compile time
#ifdef WLED_MAX_BUSSES
#undef WLED_MAX_BUSSES
#endif
#define WLED_MAX_BUSSES (WLED_MAX_DIGITAL_CHANNELS+WLED_MAX_ANALOG_CHANNELS)
// define -> constexpr to align with definition of WLED_MAX_ANALOG_CHANNELS
constexpr size_t WLED_MAX_BUSSES = WLED_MAX_DIGITAL_CHANNELS + WLED_MAX_ANALOG_CHANNELS;
static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
// Maximum number of pins per output. 5 for RGBCCT analog LEDs.
@@ -517,8 +535,10 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
#define MAX_LEDS 1536 //can't rely on memory limit to limit this to 1536 LEDs
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
#define MAX_LEDS 2048 //due to memory constraints S2
#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61)
#define MAX_LEDS 4096
#else
#define MAX_LEDS 16384
#define MAX_LEDS 16384 // classic esp32, S3 and P4 can take more
#endif
#endif
@@ -527,15 +547,15 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
#ifdef ESP8266
#define MAX_LED_MEMORY (8*1024)
#else
#if defined(CONFIG_IDF_TARGET_ESP32S2)
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C61)
#ifndef BOARD_HAS_PSRAM
#define MAX_LED_MEMORY (28*1024) // S2 has ~170k of free heap after boot, using 28k is the absolute limit to keep WLED functional
#else
#define MAX_LED_MEMORY (48*1024) // with PSRAM there is more wiggle room as buffers get moved to PSRAM when needed (prioritize functionality over speed)
#endif
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#elif defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32P4)
#define MAX_LED_MEMORY (192*1024) // S3 has ~330k of free heap after boot
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
#define MAX_LED_MEMORY (100*1024) // C3 has ~240k of free heap after boot, even with 8000 LEDs configured (2D) there is 30k of contiguous heap left
#else
#define MAX_LED_MEMORY (85*1024) // ESP32 has ~160k of free heap after boot and an additional 64k of 32bit access memory that is used for pixel buffers
@@ -651,7 +671,7 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
#endif
// Defaults pins, type and counts to configure LED output
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3)
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32P4)
#ifdef WLED_ENABLE_DMX
#define DEFAULT_LED_PIN 1
#warning "Compiling with DMX. The default LED pin has been changed to pin 1."

View File

@@ -718,6 +718,7 @@ ${urows===""?'':'<tr><td colspan=2><hr style="height:1px;border-width:0;color:gr
${i.opt&0x100?inforow("Debug","<button class=\"btn btn-xs\" onclick=\"requestJson({'debug':"+(i.opt&0x0080?"false":"true")+"});\"><i class=\"icons "+(i.opt&0x0080?"on":"off")+"\">&#xe08f;</i></button>"):''}
${inforow("Build",i.vid)}
${inforow("Signal strength",i.wifi.signal +"% ("+ i.wifi.rssi, " dBm)")}
${i.wifi.band?inforow("WiFi band",i.wifi.band + " (Ch " + i.wifi.channel + ")"):""}
${inforow("Uptime",getRuntimeStr(i.uptime))}
${inforow("Time",i.time)}
${inforow("Free heap",(i.freeheap/1024).toFixed(1)," kB")}

View File

@@ -73,7 +73,7 @@
const option = cE("option");
option.setAttribute("value", networks[i].ssid);
option.textContent = `${networks[i].ssid} (${networks[i].rssi} dBm)`; // [${networks[i].bssid.replaceAll(':','')}]
option.textContent = `${networks[i].ssid} (${networks[i].rssi} dBm, Ch ${networks[i].channel})`; // [${networks[i].bssid.replaceAll(':','')}]
if (networks[i].ssid === input.value) {
option.setAttribute("selected", "selected");
@@ -276,7 +276,15 @@ Static subnet mask:<br>
Disable WiFi sleep: <input type="checkbox" name="WS"><br>
<i>Disabling WiFi sleep increases power consumption<br>
but can help with connectivity issues and sync.</i><br><br>
<div id="tx">Max. TX power: <select name="TX">
<div id="bm">WiFi band: <select name="BM">
<option value="1">2.4 GHz only</option>
<option value="2">5 GHz only</option>
<option value="3">Auto (both)</option>
</select><br></div>
<div id="tx">Max. TX power: <select name="TX"> <!-- V5 framework allows 84 = 21dBm ... -4 = Minus_1dBm -->
<option value="84">21 dBm</option>
<option value="82">20.5 dBm</option>
<option value="80">20 dBm</option>
<option value="78">19.5 dBm</option>
<option value="76">19 dBm</option>
<option value="74">18.5 dBm</option>

View File

@@ -1,6 +1,7 @@
#include "wled.h"
#ifdef WLED_ENABLE_DMX_INPUT
#pragma message "DMX physical input driver enabled"
#ifdef ESP8266
#error DMX input is only supported on ESP32
@@ -9,8 +10,8 @@
#include "dmx_input.h"
#include <rdm/responder.h>
void rdmPersonalityChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
void *context)
void rdmPersonalityChangedCb(dmx_port_t dmxPort, rdm_header_t *request_header,
rdm_header_t *response_header, void *context)
{
DMXInput *dmx = static_cast<DMXInput *>(context);
@@ -19,7 +20,7 @@ void rdmPersonalityChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
return;
}
if (header->cc == RDM_CC_SET_COMMAND_RESPONSE) {
if (response_header->cc == RDM_CC_SET_COMMAND_RESPONSE) {
const uint8_t personality = dmx_get_current_personality(dmx->inputPortNum);
DMXMode = std::min(DMX_MODE_PRESET, std::max(DMX_MODE_SINGLE_RGB, int(personality)));
configNeedsWrite = true;
@@ -27,8 +28,8 @@ void rdmPersonalityChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
}
}
void rdmAddressChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
void *context)
void rdmAddressChangedCb(dmx_port_t dmxPort, rdm_header_t *request_header,
rdm_header_t *response_header, void *context)
{
DMXInput *dmx = static_cast<DMXInput *>(context);
@@ -37,7 +38,7 @@ void rdmAddressChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
return;
}
if (header->cc == RDM_CC_SET_COMMAND_RESPONSE) {
if (response_header->cc == RDM_CC_SET_COMMAND_RESPONSE) {
const uint16_t addr = dmx_get_start_address(dmx->inputPortNum);
DMXAddress = std::min(512, int(addr));
configNeedsWrite = true;
@@ -47,14 +48,13 @@ void rdmAddressChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
static dmx_config_t createConfig()
{
dmx_config_t config;
config.pd_size = 255;
config.dmx_start_address = DMXAddress;
dmx_config_t config = DMX_CONFIG_DEFAULT;
config.model_id = 0;
config.product_category = RDM_PRODUCT_CATEGORY_FIXTURE;
config.software_version_id = VERSION;
strcpy(config.device_label, "WLED_MM");
#if 0
// softhack007: ToDO: current code from main does not work in V5 yet
const std::string dmxWledVersionString = "WLED_V" + std::to_string(VERSION);
strncpy(config.software_version_label, dmxWledVersionString.c_str(), 32);
config.software_version_label[32] = '\0'; // zero termination in case versionString string was longer than 32 chars
@@ -83,10 +83,51 @@ static dmx_config_t createConfig()
config.personality_count = 10;
// rdm personalities are numbered from 1, thus we can just set the DMXMode directly.
config.current_personality = DMXMode;
#else
// fallback code
const std::string DmxVersionString = "WLED_V" + std::to_string(VERSION);
config.software_version_label = DmxVersionString.c_str();
#endif
return config;
}
static dmx_personality_t personalities[10];
static void createPersonalities()
{
// Initialize personalities array
strncpy(personalities[0].description, "SINGLE_RGB", 32);
personalities[0].footprint = 3;
strncpy(personalities[1].description, "SINGLE_DRGB", 32);
personalities[1].footprint = 4;
strncpy(personalities[2].description, "EFFECT", 32);
personalities[2].footprint = 15;
strncpy(personalities[3].description, "MULTIPLE_RGB", 32);
personalities[3].footprint = std::min(512, int(strip.getLengthTotal()) * 3);
strncpy(personalities[4].description, "MULTIPLE_DRGB", 32);
personalities[4].footprint = std::min(512, int(strip.getLengthTotal()) * 3 + 1);
strncpy(personalities[5].description, "MULTIPLE_RGBW", 32);
personalities[5].footprint = std::min(512, int(strip.getLengthTotal()) * 4);
strncpy(personalities[6].description, "EFFECT_W", 32);
personalities[6].footprint = 18;
strncpy(personalities[7].description, "EFFECT_SEGMENT", 32);
personalities[7].footprint = std::min(512, strip.getSegmentsNum() * 15);
strncpy(personalities[8].description, "EFFECT_SEGMENT_W", 32);
personalities[8].footprint = std::min(512, strip.getSegmentsNum() * 18);
strncpy(personalities[9].description, "PRESET", 32);
personalities[9].footprint = 1;
}
void dmxReceiverTask(void *context)
{
DMXInput *instance = static_cast<DMXInput *>(context);
@@ -103,10 +144,11 @@ void dmxReceiverTask(void *context)
bool DMXInput::installDriver()
{
const auto config = createConfig();
createPersonalities();
DEBUG_PRINTF("DMX port: %u\n", inputPortNum);
if (!dmx_driver_install(inputPortNum, &config, DMX_INTR_FLAGS_DEFAULT)) {
if (!dmx_driver_install(inputPortNum, &config, personalities, 10)) {
DEBUG_PRINTF("Error: Failed to install dmx driver\n");
return false;
}
@@ -116,8 +158,14 @@ bool DMXInput::installDriver()
DEBUG_PRINTF("DMX enable pin is: %u\n", enPin);
dmx_set_pin(inputPortNum, txPin, rxPin, enPin);
// Set initial DMX start address and personality
dmx_set_start_address(inputPortNum, DMXAddress);
dmx_set_current_personality(inputPortNum, DMXMode);
// Register RDM callbacks for start address and personality changes
rdm_register_dmx_start_address(inputPortNum, rdmAddressChangedCb, this);
rdm_register_dmx_personality(inputPortNum, rdmPersonalityChangedCb, this);
rdm_register_dmx_personality(inputPortNum, 10, rdmPersonalityChangedCb, this);
initialized = true;
return true;
}
@@ -151,9 +199,9 @@ void DMXInput::init(uint8_t rxPin, uint8_t txPin, uint8_t enPin, uint8_t inputPo
const bool pinsAllocated = PinManager::allocateMultiplePins(pins, 3, PinOwner::DMX_INPUT);
if (!pinsAllocated) {
DEBUG_PRINTF("DMXInput: Error: Failed to allocate pins for DMX_INPUT. Pins already in use:\n");
DEBUG_PRINTF("rx in use by: %s\n", PinManager::getPinOwner(rxPin));
DEBUG_PRINTF("tx in use by: %s\n", PinManager::getPinOwner(txPin));
DEBUG_PRINTF("en in use by: %s\n", PinManager::getPinOwner(enPin));
DEBUG_PRINTF("rx in use by: %hhd\n", PinManager::getPinOwner(rxPin));
DEBUG_PRINTF("tx in use by: %hhd\n", PinManager::getPinOwner(txPin));
DEBUG_PRINTF("en in use by: %hhd\n", PinManager::getPinOwner(enPin));
return;
}
@@ -247,12 +295,11 @@ void DMXInput::enable()
bool DMXInput::isIdentifyOn() const
{
uint8_t identify = 0;
bool identify = false;
const bool gotIdentify = rdm_get_identify_device(inputPortNum, &identify);
// gotIdentify should never be false because it is a default parameter in rdm
// but just in case we check for it anyway
return bool(identify) && gotIdentify;
return identify && gotIdentify;
}
void DMXInput::checkAndUpdateConfig()
@@ -277,4 +324,4 @@ void DMXInput::checkAndUpdateConfig()
}
}
#endif
#endif

View File

@@ -42,12 +42,12 @@ private:
void updateInternal();
// is invoked whenver the dmx start address is changed via rdm
friend void rdmAddressChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
void *context);
friend void rdmAddressChangedCb(dmx_port_t dmxPort, rdm_header_t *request_header,
rdm_header_t *response_header, void *context);
// is invoked whenever the personality is changed via rdm
friend void rdmPersonalityChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
void *context);
friend void rdmPersonalityChangedCb(dmx_port_t dmxPort, rdm_header_t *request_header,
rdm_header_t *response_header, void *context);
/// The internal dmx task.
/// This is the main loop of the dmx receiver. It never returns.

View File

@@ -69,7 +69,7 @@ void handleDMXOutput()
}
void initDMXOutput() {
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2)
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32S2)
dmx.init(512); // initialize with bus length
#else
dmx.initWrite(512); // initialize with bus length

View File

@@ -20,15 +20,4 @@ Macros for generating a "dynamic array", a static array of objects declared in d
#define DYNARRAY_END(array_name) array_name##_end
#define DYNARRAY_LENGTH(array_name) (&DYNARRAY_END(array_name)[0] - &DYNARRAY_BEGIN(array_name)[0])
#ifdef ESP8266
// ESP8266 linker script cannot be extended with a unique section for dynamic arrays.
// We instead pack them in the ".dtors" section, as it's sorted and uploaded to the flash
// (but will never be used in the embedded system)
#define DYNARRAY_SECTION ".dtors"
#else /* ESP8266 */
// Use a unique named section; the linker script must be extended to ensure it's correctly placed.
#define DYNARRAY_SECTION ".dynarray"
#endif

View File

@@ -428,7 +428,7 @@ static void prepareArtnetPollReply(ArtPollReply *reply) {
reply->reply_opcode = ARTNET_OPCODE_OPPOLLREPLY;
IPAddress localIP = Network.localIP();
IPAddress localIP = WLEDNetwork.localIP();
for (unsigned i = 0; i < 4; i++) {
reply->reply_ip[i] = localIP[i];
}
@@ -503,7 +503,7 @@ static void prepareArtnetPollReply(ArtPollReply *reply) {
// A DMX to / from Art-Net device
reply->reply_style = 0x00;
Network.localMAC(reply->reply_mac);
WLEDNetwork.localMAC(reply->reply_mac);
for (unsigned i = 0; i < 4; i++) {
reply->reply_bind_ip[i] = localIP[i];

View File

@@ -3,6 +3,13 @@
#define WLED_FCN_DECLARE_H
#include <dynarray.h>
// dummy macro for 8266
#ifndef ARDUINO_ARCH_ESP32
#ifndef ESP_IDF_VERSION_VAL
#define ESP_IDF_VERSION_VAL(n1,n2,n3) 500
#endif
#endif
#include "colors.h"
/*
@@ -25,7 +32,9 @@ bool isButtonPressed(uint8_t b=0);
void handleButton();
void handleOnOff(bool forceOff = false);
void handleIO();
#ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a function to check touch state but need to attach an interrupt to do so
void IRAM_ATTR touchButtonISR();
#endif
//cfg.cpp
bool backupConfig();
@@ -452,8 +461,12 @@ uint8_t extractModeSlider(uint8_t mode, uint8_t slider, char *dest, uint8_t maxL
int16_t extractModeDefaults(uint8_t mode, const char *segVar);
void checkSettingsPIN(const char *pin);
uint16_t crc16(const unsigned char* data_p, size_t length);
#if !defined(ARDUINO_ARCH_ESP32) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(6, 0, 0)) // ToDO: verify that this works correctly in V5
String computeSHA1(const String& input);
String getDeviceId();
#endif
uint16_t beat88(uint16_t beats_per_minute_88, uint32_t timebase = 0);
uint16_t beat16(uint16_t beats_per_minute, uint32_t timebase = 0);
uint8_t beat8(uint16_t beats_per_minute, uint32_t timebase = 0);

View File

@@ -10,7 +10,7 @@
#define DIMPROV_PRINTF(x...)
#endif
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3)
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32S3) // ToDO check if C6, C61, P4 support this
#undef WLED_DISABLE_IMPROV_WIFISCAN
#define WLED_DISABLE_IMPROV_WIFISCAN
#endif
@@ -94,7 +94,7 @@ void handleImprovPacket() {
case ImprovRPCType::Request_State: {
unsigned improvState = 0x02; //authorized
if (WLED_WIFI_CONFIGURED) improvState = 0x03; //provisioning
if (Network.isConnected()) improvState = 0x04; //provisioned
if (WLEDNetwork.isConnected()) improvState = 0x04; //provisioned
sendImprovStateResponse(improvState, false);
if (improvState == 0x04) sendImprovIPRPCResult(ImprovRPCType::Request_State);
break;
@@ -178,10 +178,10 @@ void sendImprovRPCResult(ImprovRPCType type, uint8_t n_strings, const char **str
}
void sendImprovIPRPCResult(ImprovRPCType type) {
if (Network.isConnected())
if (WLEDNetwork.isConnected())
{
char urlStr[64];
IPAddress localIP = Network.localIP();
IPAddress localIP = WLEDNetwork.localIP();
unsigned len = sprintf(urlStr, "http://%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
if (len > 24) return; //sprintf fail?
const char *str[1] = {urlStr};

View File

@@ -697,7 +697,14 @@ void serializeInfo(JsonObject root)
root[F("cn")] = F(WLED_CODENAME);
root[F("release")] = releaseString;
root[F("repo")] = repoString;
#if !defined(ARDUINO_ARCH_ESP32) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(6, 0, 0)) // ToDO: verify that this works correctly in V5
root[F("deviceId")] = getDeviceId();
#else
//#if defined(ARDUINO_ARCH_ESP32) && !defined(WLED_DISABLE_OTA)
// fake 38char fingerprint from bootloaderSHA1. WARNING: only for testing, not suitable for production!
//root[F("deviceId")] = String("0000") + getBootloaderSHA256Hex().substring(4, 34) + String("0000");
//#endif
#endif
JsonObject leds = root.createNestedObject(F("leds"));
leds[F("count")] = strip.getLengthTotal();
@@ -792,7 +799,18 @@ void serializeInfo(JsonObject root)
int qrssi = WiFi.RSSI();
wifi_info[F("rssi")] = qrssi;
wifi_info[F("signal")] = getSignalQuality(qrssi);
wifi_info[F("channel")] = WiFi.channel();
int wifiChannel = WiFi.channel();
wifi_info[F("channel")] = wifiChannel;
if ((wifiChannel > 0) && (unsigned(WiFi.status()) < unsigned(WL_CONNECT_FAILED))) { // Wifi Status > 3 are error statuses (disconnected, stopped, signal lost)
#if defined(ARDUINO_ARCH_ESP32) && SOC_WIFI_SUPPORT_5G
auto wifiBand = WiFi.getBand();
wifi_info[F("band")] = wifiBand == WIFI_BAND_2G ? F("2.4GHz") : (wifiBand == WIFI_BAND_5G ? F("5GHz"): F("(other)"));
#else
wifi_info[F("band")] = F("2.4GHz");
#endif
} else {
wifi_info[F("band")] = F("not connected");
}
wifi_info[F("ap")] = apActive;
JsonObject fs_info = root.createNestedObject("fs");
@@ -887,9 +905,9 @@ void serializeInfo(JsonObject root)
root[F("product")] = F(WLED_PRODUCT_NAME);
root["mac"] = escapedMac;
char s[16] = "";
if (Network.isConnected())
if (WLEDNetwork.isConnected())
{
IPAddress localIP = Network.localIP();
IPAddress localIP = WLEDNetwork.localIP();
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
}
root["ip"] = s;
@@ -988,7 +1006,7 @@ void serializePalettes(JsonObject root, int page)
default:
if (i >= palettesCount) // custom palettes
setPaletteColors(curPalette, customPalettes[i - palettesCount]);
else if (i < DYNAMIC_PALETTE_COUNT + FASTLED_PALETTE_COUNT) // palette 6 - 12, fastled palettes
else if (i < int(DYNAMIC_PALETTE_COUNT + FASTLED_PALETTE_COUNT)) // palette 6 - 12, fastled palettes
setPaletteColors(curPalette, *fastledPalettes[i - DYNAMIC_PALETTE_COUNT]);
else {
memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[i - (DYNAMIC_PALETTE_COUNT + FASTLED_PALETTE_COUNT)])), sizeof(tcp));
@@ -1006,6 +1024,9 @@ void serializeNetworks(JsonObject root)
switch (status) {
case WIFI_SCAN_FAILED:
#if defined(SOC_WIFI_SUPPORT_5G) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2))
if (!WiFi.setBandMode(wifi_band_mode_t(wifiBandMode))) { DEBUG_PRINTLN(F("serializeNetworks(): WiFi band configuration failed!")); }
#endif
WiFi.scanNetworks(true);
return;
case WIFI_SCAN_RUNNING:
@@ -1090,6 +1111,21 @@ void serializePins(JsonObject root)
#elif defined(CONFIG_IDF_TARGET_ESP32) // ESP32 classic
if (gpio == 0) caps |= PIN_CAP_BOOT; // pull low to enter bootloader mode
if (gpio == 2 || gpio == 12) caps |= PIN_CAP_BOOTSTRAP; // note: if GPIO12 must be low at boot, (high=1.8V flash mode), GPIO 2 must be low or floating to enter bootloader mode
#elif defined(CONFIG_IDF_TARGET_ESP32C5)
if (gpio == 28) caps |= PIN_CAP_BOOT; // pull low to enter bootloader mode
if (gpio == 27) caps |= PIN_CAP_BOOTSTRAP; // must be high when GPIO28 is low for download mode
if (gpio == 2 || gpio == 3 || gpio == 7 || gpio == 25 || gpio == 26) caps |= PIN_CAP_BOOTSTRAP; // additional C5 strapping pins per Espressif boot configuration docs
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
if (gpio == 9) caps |= PIN_CAP_BOOT; // pull low to enter bootloader mode
if (gpio == 8) caps |= PIN_CAP_BOOTSTRAP; // must be high when GPIO9 is low for download mode
if (gpio == 4 || gpio == 5 || gpio == 15) caps |= PIN_CAP_BOOTSTRAP; // additional C6 strapping pins per Espressif strapping-pin docs
#elif defined(CONFIG_IDF_TARGET_ESP32C61)
if (gpio == 9) caps |= PIN_CAP_BOOT; // pull low to enter bootloader mode
if (gpio == 8) caps |= PIN_CAP_BOOTSTRAP; // must be high when GPIO9 is low for download mode
if (gpio == 7 || gpio == 3 || gpio == 4) caps |= PIN_CAP_BOOTSTRAP; // GPIO7, MTMS, and MTDI are also strapping pins
#elif defined(CONFIG_IDF_TARGET_ESP32P4)
if (gpio == 35) caps |= PIN_CAP_BOOT; // pull low to enter bootloader mode
if (gpio == 36) caps |= PIN_CAP_BOOTSTRAP; // must be high when GPIO35 is low for download mode
#endif
#else
// ESP8266: GPIO 0-16 + GPIO17=A0

View File

@@ -0,0 +1,51 @@
#include "wled.h"
#ifdef ESP32
// ESP32-C5 on pioarduino uses IDF 5.5+ which has SHA1 built-in, skip shim
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) && ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 5, 0)
#include "mbedtls/sha1.h"
#include "SHA1Builder.h"
// Wrapper functions to map mbedtls SHA1 calls to Arduino SHA1Builder
// This is needed because ESP-IDF 5.x disables SHA1 in mbedtls by default
struct mbedtls_sha1_context_wrapper {
SHA1Builder builder;
};
extern "C" {
void mbedtls_sha1_init(mbedtls_sha1_context *ctx) {
// Allocate wrapper
auto* wrapper = new mbedtls_sha1_context_wrapper();
*(void**)ctx = wrapper;
}
int mbedtls_sha1_starts(mbedtls_sha1_context *ctx) {
auto* wrapper = *(mbedtls_sha1_context_wrapper**)ctx;
wrapper->builder.begin();
return 0;
}
int mbedtls_sha1_update(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen) {
auto* wrapper = *(mbedtls_sha1_context_wrapper**)ctx;
wrapper->builder.add((const uint8_t*)input, ilen);
return 0;
}
int mbedtls_sha1_finish(mbedtls_sha1_context *ctx, unsigned char output[20]) {
auto* wrapper = *(mbedtls_sha1_context_wrapper**)ctx;
wrapper->builder.calculate();
wrapper->builder.getBytes(output);
return 0;
}
void mbedtls_sha1_free(mbedtls_sha1_context *ctx) {
auto* wrapper = *(mbedtls_sha1_context_wrapper**)ctx;
delete wrapper;
}
} // extern "C"
#endif
#endif

View File

@@ -148,10 +148,10 @@ const ethernet_settings ethernetBoards[] = {
// Gledopto Series With Ethernet
{
1, // eth_address,
5, // eth_power,
23, // eth_mdc,
33, // eth_mdio,
1, // eth_address,
5, // eth_power,
23, // eth_mdc,
33, // eth_mdio,
ETH_PHY_LAN8720, // eth_type,
ETH_CLOCK_GPIO0_IN // eth_clk_mode
},
@@ -231,6 +231,16 @@ bool initEthernet()
}
#endif
#if defined(ESP_IDF_VERSION) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
if (!ETH.begin( // parameter order in V5 has changed
(eth_phy_type_t) es.eth_type,
(int32_t) es.eth_address,
(int) es.eth_mdc,
(int) es.eth_mdio,
(int) es.eth_power,
(eth_clock_mode_t) es.eth_clk_mode
)) {
#else
if (!ETH.begin(
(uint8_t) es.eth_address,
(int) es.eth_power,
@@ -239,6 +249,7 @@ bool initEthernet()
(eth_phy_type_t) es.eth_type,
(eth_clock_mode_t) es.eth_clk_mode
)) {
#endif
DEBUG_PRINTLN(F("initE: ETH.begin() failed"));
// de-allocate the allocated pins
for (managed_pin_type mpt : pinsToAllocate) {
@@ -313,7 +324,7 @@ int findWiFi(bool doScan) {
} else if (status >= 0) { // status contains number of found networks (including duplicate SSIDs with different BSSID)
DEBUG_PRINTF_P(PSTR("WiFi: Found %d SSIDs. @ %lus\n"), status, millis()/1000);
int rssi = -9999;
int selected = selectedWiFi;
size_t selected = (static_cast<size_t>(selectedWiFi) < multiWiFi.size()) ? static_cast<size_t>(selectedWiFi) : 0; // ensure valid starting index
for (int o = 0; o < status; o++) {
DEBUG_PRINTF_P(PSTR(" SSID: %s (BSSID: %s) RSSI: %ddB\n"), WiFi.SSID(o).c_str(), WiFi.BSSIDstr(o).c_str(), WiFi.RSSI(o));
for (unsigned n = 0; n < multiWiFi.size(); n++)
@@ -403,7 +414,7 @@ void WiFiEvent(WiFiEvent_t event)
DEBUG_PRINTF_P(PSTR("WiFi-E: AP Client Connected (%d) @ %lus.\n"), (int)apClients, millis()/1000);
break;
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
DEBUG_PRINT(F("WiFi-E: IP address: ")); DEBUG_PRINTLN(Network.localIP());
DEBUG_PRINT(F("WiFi-E: IP address: ")); DEBUG_PRINTLN(WLEDNetwork.localIP());
break;
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
// followed by IDLE and SCAN_DONE

View File

@@ -197,7 +197,11 @@ void handleNetworkTime()
if (millis() - ntpPacketSentTime > 10000)
{
#ifdef ARDUINO_ARCH_ESP32 // I had problems using udp.flush() on 8266
while (ntpUdp.parsePacket() > 0) ntpUdp.flush(); // flush any existing packets
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
while (ntpUdp.parsePacket() > 0) ntpUdp.clear(); // flush() is deprecated in arduino-esp32 3.x.y
#else
while (ntpUdp.parsePacket() > 0) ntpUdp.flush(); // flush any existing packets
#endif
#endif
if (!ntpServerIP.fromString(ntpServerName)) // check if server is IP or domain
{
@@ -286,7 +290,11 @@ static bool checkNTPResponse()
int cb = ntpUdp.parsePacket();
if (cb < NTP_MIN_PACKET_SIZE) {
#ifdef ARDUINO_ARCH_ESP32 // I had problems using udp.flush() on 8266
if (cb > 0) ntpUdp.flush(); // this avoids memory leaks on esp32
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
if (cb > 0) ntpUdp.clear(); // flush() is deprecated in arduino-esp32 3.x.y
#else
if (cb > 0) ntpUdp.flush(); // this avoids memory leaks on esp32
#endif
#endif
return false;
}

View File

@@ -15,8 +15,8 @@ constexpr size_t METADATA_OFFSET = 256; // ESP32: metadata appears afte
// Bootloader is at fixed offset 0x1000 (4KB), 0x0000 (0KB), or 0x2000 (8KB), and is typically 32KB
// Bootloader offsets for different MCUs => see https://github.com/wled/WLED/issues/5064
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
constexpr size_t BOOTLOADER_OFFSET = 0x0000; // esp32-S3, esp32-C3 and (future support) esp32-c6
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61)
constexpr size_t BOOTLOADER_OFFSET = 0x0000; // esp32-S3, esp32-C3, esp32-c6, and (future support) esp32-c61
constexpr size_t BOOTLOADER_SIZE = 0x8000; // 32KB, typical bootloader size
#define BOOTLOADER_OTA_UNSUPPORTED // still needs validation on these platforms.
#elif defined(CONFIG_IDF_TARGET_ESP32P4) || defined(CONFIG_IDF_TARGET_ESP32C5)

View File

@@ -232,6 +232,49 @@ bool PinManager::isPinOk(byte gpio, bool output)
if (gpio > 21 && gpio < 33) return false; // 22 to 32: not connected + SPI FLASH
// JTAG: GPIO39-42 are usually used for inline debugging
// GPIO46 is input only and pulled down
#elif defined(CONFIG_IDF_TARGET_ESP32C5)
// strapping pins: (2), 7, 25, 26, 27, 28 (GPIO2 is not a strapping pin; it's used only for external JTAG when GPIO7 selects it)
// GPIO 0-15 directly usable, 16-22 are for SPI flash
if (gpio > 15 && gpio < 23) return false; // 16-22 SPI FLASH
#if ARDUINO_USB_CDC_ON_BOOT == 1 || ARDUINO_USB_DFU_ON_BOOT == 1
if (gpio == 13 || gpio == 14) return false; // 13-14 USB-JTAG
#endif
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
// strapping pins: 4, 5, 8, 9, 15 (GPIO4/MTMS and GPIO5/MTDI are also strapping pins)
// GPIO 0-23 directly usable, 24-30 are for SPI flash
if (gpio > 23 && gpio < 31) return false; // 24-30 SPI FLASH
#if ARDUINO_USB_CDC_ON_BOOT == 1 || ARDUINO_USB_DFU_ON_BOOT == 1
if (gpio == 12 || gpio == 13) return false; // 12-13 USB-JTAG
#endif
#elif defined(CONFIG_IDF_TARGET_ESP32C61) // prelim. entry for C61. ToDO: Validate pins
// strapping pins: MTMS, MTDI, GPIO7, GPIO8, GPIO9
// SPI flash/PSRAM interface: GPIO14-17 and GPIO19-21 (GPIO18 is free)
if (gpio > 13 && gpio < 18) return false; // 14-17 SPI FLASH
if (gpio > 18 && gpio < 22) return false; // 19-21 SPI FLASH
#if ARDUINO_USB_CDC_ON_BOOT == 1 || ARDUINO_USB_DFU_ON_BOOT == 1
if (gpio == 12 || gpio == 13) return false; // 12-13 USB-JTAG
#endif
#elif defined(CONFIG_IDF_TARGET_ESP32P4)
// based on P4 port by troyhacks https://github.com/troyhacks/WLED/tree/P4_experimental
// strapping pins: 34,35,36,37,38
// Hide all pins not available on connector except pins we need to assign to things later, like I2S
// TODO: this list is over-protective - clean up later.
if ( gpio == 9) return false; // I2S Sound Output Pin
if (gpio > 13 && gpio < 20) return false; // ESP-Hosted WiFi pins
#if ARDUINO_USB_CDC_ON_BOOT == 1 || ARDUINO_USB_DFU_ON_BOOT == 1
if (gpio > 23 && gpio < 26) return false; // USB Pins
#endif
if (gpio > 27 && gpio < 32) return false; // Ethernet pins
if (gpio > 33 && gpio < 36) return false; // Ethernet pins - boot button is on 35 and works... but messes with Ethernet if enabled in WLED
if (gpio > 38 && gpio < 45) return false; // SD1 Pins
if (gpio > 48 && gpio < 53) return false; // Ethernet pins & others
if ( gpio == 54) return false; // C6 WiFi EN pin
//
// 24-25 is is USB, but so is 26-27 but they're exposed on the header and work OK for pin outout.
// 6 is C5 wakeup - but works fine for pin outout.
// 45 is SD power but it's NC without hacking the board.
// 53 is for PA enable but it's exposed on header and works for WLED pin output. Best to not use it but left available.
// 54 is "C6 EN pin" so I guess we shouldn't touch it.
#else
if ((strncmp_P(PSTR("ESP32-U4WDH"), ESP.getChipModel(), 11) == 0) || // this is the correct identifier, but....
@@ -369,11 +412,20 @@ bool PinManager::isAnalogPin(byte gpio) {
#elif CONFIG_IDF_TARGET_ESP32S3
// ESP32-S3: ADC1 channels 0-9 (GPIO 1-10)
int adc_channel = digitalPinToAnalogChannel(gpio);
if (adc_channel >= 0 && adc_channel <= 9) return true;
if (adc_channel >= 0 && adc_channel <= 9) return true; // ADC-1
// ESP32-S3: ADC2 channels 0-9
if ((adc_channel >= SOC_ADC_CHANNEL_NUM(0)) && ((adc_channel - SOC_ADC_CHANNEL_NUM(0)) < SOC_ADC_CHANNEL_NUM(1))) return true; // ADC-2
#elif CONFIG_IDF_TARGET_ESP32C3
// ESP32-C3: ADC1 channels 0-4 (GPIO 0-4)
int adc_channel = digitalPinToAnalogChannel(gpio);
if (adc_channel >= 0 && adc_channel <= 4) return true;
#else // C5, C6, C61, P4 - use generic SOC capability macros
int adc_channel = digitalPinToAnalogChannel(gpio);
if ((adc_channel < 0) || (adc_channel >= (SOC_ADC_PERIPH_NUM * SOC_ADC_MAX_CHANNEL_NUM))) return false; // out of range
if (adc_channel < SOC_ADC_CHANNEL_NUM(0)) return true; // ADC-1
#if SOC_ADC_PERIPH_NUM > 1
if ((adc_channel >= SOC_ADC_CHANNEL_NUM(0)) && ((adc_channel - SOC_ADC_CHANNEL_NUM(0)) < SOC_ADC_CHANNEL_NUM(1))) return true; // ADC-2
#endif
#endif
#endif
return false; // not an analog pin if it doesn't have ADC capability, ESP8266 has only one ADC pin (A0) which is handled separately in button.cpp, so return false for all pins here

View File

@@ -118,11 +118,27 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
#ifdef ARDUINO_ARCH_ESP32
int tx = request->arg(F("TX")).toInt();
txPower = min(max(tx, (int)WIFI_POWER_2dBm), (int)WIFI_POWER_19_5dBm);
#if (ESP_IDF_VERSION_MAJOR > 4)
txPower = min(max((int)tx, (int)WIFI_POWER_2dBm), (int)WIFI_POWER_21dBm); // V5 allows WIFI_POWER_21dBm = 84 ... WIFI_POWER_MINUS_1dBm = -4
#else
txPower = min(max((int)tx, (int)WIFI_POWER_2dBm), (int)WIFI_POWER_19_5dBm);
#endif
#endif
force802_3g = request->hasArg(F("FG"));
noWifiSleep = request->hasArg(F("WS"));
#ifdef SOC_WIFI_SUPPORT_5G
if (request->hasArg(F("BM"))) {
int bm = request->arg(F("BM")).toInt();
if (bm >= WIFI_BAND_MODE_2G_ONLY && bm <= WIFI_BAND_MODE_AUTO) {
if (bm != wifiBandMode) {
forceReconnect = true;
WiFi.scanDelete();
}
wifiBandMode = bm;
}
}
#endif
#ifndef WLED_DISABLE_ESPNOW
bool oldESPNow = enableESPNow;
@@ -340,7 +356,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
PinManager::deallocatePin(buttons[i].pin, PinOwner::Button);
buttons[i].type = BTN_TYPE_NONE;
}
#ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state but need to attach an interrupt to do so
#ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a function to check touch state but need to attach an interrupt to do so
else touchAttachInterrupt(buttons[i].pin, touchButtonISR, touchThreshold << 4); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example, I measured changes of over 5000)
#endif
} else
@@ -532,6 +548,11 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
if (subPage == SUBPAGE_TIME)
{
ntpEnabled = request->hasArg(F("NT"));
#ifdef CONFIG_IDF_TARGET_ESP32C5 // ToDO: esp32-c5 crashes on NTP requests: assert failed: udp_new_ip_type udp.c:1278 (Required to lock TCPIP core functionality!)
if (ntpEnabled) { DEBUG_PRINTLN("NTP disabled on -C5, as it leads to crashes"); }
ntpEnabled = false;
#warning "enabling NTP lead to crashes on -C5. NTP disabled"
#endif
strlcpy(ntpServerName, request->arg(F("NS")).c_str(), 33);
useAMPM = !request->hasArg(F("CF"));
currentTimezone = request->arg(F("TZ")).toInt();

View File

@@ -11,7 +11,7 @@
// - - - - -
/* ----- LIBRARIES ----- */
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2)
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32S2)
#include <Arduino.h>

View File

@@ -17,7 +17,7 @@ Distributed as-is; no warranty is given.
#if defined(ARDUINO_ARCH_ESP32)
#include <Arduino.h>
#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#if !defined(ESP8266) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32C61) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#include "SparkFunDMX.h"
#include <HardwareSerial.h>

View File

@@ -76,7 +76,7 @@ bool ESPAsyncE131::initMulticast(uint16_t port, uint16_t universe, uint8_t n) {
ip4_addr_t ifaddr;
ip4_addr_t multicast_addr;
ifaddr.addr = static_cast<uint32_t>(Network.localIP());
ifaddr.addr = static_cast<uint32_t>(WLEDNetwork.localIP());
for (uint8_t i = 1; i < n; i++) {
multicast_addr.addr = static_cast<uint32_t>(IPAddress(239, 255,
(((universe + i) >> 8) & 0xff), (((universe + i) >> 0)

View File

@@ -18,6 +18,14 @@
#include "Arduino.h"
// dummy macro for 8266
#ifndef ARDUINO_ARCH_ESP32
#ifndef ESP_IDF_VERSION_VAL
#define ESP_IDF_VERSION_VAL(n1,n2,n3) 500
#define ESPALEXA_DEFINED_ESP_IDF_VERSION_VAL 1 // remember to undef this later
#endif
#endif
//you can use these defines for library config in your sketch. Just use them before #include <Espalexa.h>
//#define ESPALEXA_ASYNC
@@ -215,7 +223,7 @@ private:
void serveDescription()
{
EA_DEBUGLN("# Responding to description.xml ... #\n");
IPAddress localIP = Network.localIP();
IPAddress localIP = WLEDNetwork.localIP();
char s[16];
snprintf(s, sizeof(s), "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
char buf[1024];
@@ -251,10 +259,10 @@ private:
#ifdef ESPALEXA_ASYNC
if (serverAsync == nullptr) {
serverAsync = new AsyncWebServer(80);
serverAsync->onNotFound([=](AsyncWebServerRequest *request){server = request; serveNotFound();});
serverAsync->onNotFound([this](AsyncWebServerRequest *request){server = request; serveNotFound();}); // fix: implicit capture of "this"
}
serverAsync->onRequestBody([=](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){
serverAsync->onRequestBody([this](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){ // fix: implicit capture of "this"
char b[len +1];
b[len] = 0;
memcpy(b, data, len);
@@ -263,9 +271,9 @@ private:
EA_DEBUGLN(body);
});
#ifndef ESPALEXA_NO_SUBPAGE
serverAsync->on("/espalexa", HTTP_GET, [=](AsyncWebServerRequest *request){server = request; servePage();});
serverAsync->on("/espalexa", HTTP_GET, [this](AsyncWebServerRequest *request){server = request; servePage();});
#endif
serverAsync->on("/description.xml", HTTP_GET, [=](AsyncWebServerRequest *request){server = request; serveDescription();});
serverAsync->on("/description.xml", HTTP_GET, [this](AsyncWebServerRequest *request){server = request; serveDescription();}); // fix: implicit capture of "this"
serverAsync->begin();
#else
@@ -289,7 +297,7 @@ private:
//respond to UDP SSDP M-SEARCH
void respondToSearch()
{
IPAddress localIP = Network.localIP();
IPAddress localIP = WLEDNetwork.localIP();
char s[16];
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
@@ -344,7 +352,7 @@ public:
#ifdef ARDUINO_ARCH_ESP32
udpConnected = espalexaUdp.beginMulticast(IPAddress(239, 255, 255, 250), 1900);
#else
udpConnected = espalexaUdp.beginMulticast(Network.localIP(), IPAddress(239, 255, 255, 250), 1900);
udpConnected = espalexaUdp.beginMulticast(WLEDNetwork.localIP(), IPAddress(239, 255, 255, 250), 1900);
#endif
if (udpConnected){
@@ -379,7 +387,11 @@ public:
espalexaUdp.read(packetBuffer, packetSize);
packetBuffer[packetSize] = 0;
espalexaUdp.flush();
#if defined(ARDUINO_ARCH_ESP32) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
espalexaUdp.clear(); // flush() is deprecated in arduino-esp32 3.x.y
#else
espalexaUdp.flush();
#endif
if (!discoverable) return; //do not reply to M-SEARCH if not discoverable
const char* request = (const char *) packetBuffer;
@@ -627,4 +639,12 @@ public:
~Espalexa(){} //note: Espalexa is NOT meant to be destructed
};
// dummy macro cleanup
#ifndef ARDUINO_ARCH_ESP32
#ifdef ESPALEXA_DEFINED_ESP_IDF_VERSION_VAL
#undef ESP_IDF_VERSION_VAL
#undef ESPALEXA_DEFINED_ESP_IDF_VERSION_VAL
#endif
#endif
#endif

View File

@@ -1,6 +1,6 @@
#include "Network.h"
IPAddress NetworkClass::localIP()
IPAddress WLEDNetworkClass::localIP()
{
IPAddress localIP;
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
@@ -17,7 +17,7 @@ IPAddress NetworkClass::localIP()
return INADDR_NONE;
}
IPAddress NetworkClass::subnetMask()
IPAddress WLEDNetworkClass::subnetMask()
{
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
if (ETH.localIP()[0] != 0) {
@@ -30,7 +30,7 @@ IPAddress NetworkClass::subnetMask()
return IPAddress(255, 255, 255, 0);
}
IPAddress NetworkClass::gatewayIP()
IPAddress WLEDNetworkClass::gatewayIP()
{
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
if (ETH.localIP()[0] != 0) {
@@ -43,7 +43,7 @@ IPAddress NetworkClass::gatewayIP()
return INADDR_NONE;
}
void NetworkClass::localMAC(uint8_t* MAC)
void WLEDNetworkClass::localMAC(uint8_t* MAC)
{
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
// ETH.macAddress(MAC); // Does not work because of missing ETHClass:: in ETH.ccp
@@ -71,12 +71,12 @@ void NetworkClass::localMAC(uint8_t* MAC)
return;
}
bool NetworkClass::isConnected()
bool WLEDNetworkClass::isConnected()
{
return (WiFi.localIP()[0] != 0 && WiFi.status() == WL_CONNECTED) || isEthernet();
}
bool NetworkClass::isEthernet()
bool WLEDNetworkClass::isEthernet()
{
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
return (ETH.localIP()[0] != 0) && ETH.linkUp();
@@ -84,4 +84,4 @@ bool NetworkClass::isEthernet()
return false;
}
NetworkClass Network;
WLEDNetworkClass WLEDNetwork;

View File

@@ -8,7 +8,7 @@
#ifndef Network_h
#define Network_h
class NetworkClass
class WLEDNetworkClass
{
public:
IPAddress localIP();
@@ -19,6 +19,6 @@ public:
bool isEthernet();
};
extern NetworkClass Network;
extern WLEDNetworkClass WLEDNetwork;
#endif

View File

@@ -196,7 +196,7 @@ void notify(byte callMode, bool followUp)
#endif
{
DEBUG_PRINTLN(F("UDP sending packet."));
IPAddress broadcastIp = ~uint32_t(Network.subnetMask()) | uint32_t(Network.gatewayIP());
IPAddress broadcastIp = ~uint32_t(WLEDNetwork.subnetMask()) | uint32_t(WLEDNetwork.gatewayIP());
notifierUdp.beginPacket(broadcastIp, udpPort);
notifierUdp.write(udpOut, WLEDPACKETSIZE); // TODO: add actual used buffer size
notifierUdp.endPacket();
@@ -516,7 +516,7 @@ void handleNotifications()
}
}
localIP = Network.localIP();
localIP = WLEDNetwork.localIP();
//notifier and UDP realtime
if (!packetSize || packetSize > UDP_IN_MAXSIZE) return;
if (!isSupp && notifierUdp.remoteIP() == localIP) return; //don't process broadcasts we send ourselves
@@ -698,7 +698,7 @@ void sendSysInfoUDP()
{
if (!udp2Connected) return;
IPAddress ip = Network.localIP();
IPAddress ip = WLEDNetwork.localIP();
if (!ip || ip == IPAddress(255,255,255,255)) ip = IPAddress(4,3,2,1);
// TODO: make a nice struct of it and clean up
@@ -720,19 +720,7 @@ void sendSysInfoUDP()
data[x + 2] = ip[x];
}
memcpy((byte *)data + 6, serverDescription, 32);
#ifdef ESP8266
data[38] = NODE_TYPE_ID_ESP8266;
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
data[38] = NODE_TYPE_ID_ESP32C3;
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
data[38] = NODE_TYPE_ID_ESP32S3;
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
data[38] = NODE_TYPE_ID_ESP32S2;
#elif defined(ARDUINO_ARCH_ESP32)
data[38] = NODE_TYPE_ID_ESP32;
#else
data[38] = NODE_TYPE_ID_UNDEFINED;
#endif
data[38] = uint8_t(WLED_BOARD); // see wled_boards.h
if (bri) data[38] |= 0x80U; // add on/off state
data[39] = ip[3]; // unit ID == last IP number

View File

@@ -14,6 +14,11 @@
#endif
#include "mbedtls/sha1.h" // for SHA1 on ESP32
#include "esp_efuse.h"
#include "esp_chip_info.h"
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#include "SHA1Builder.h"
#include <esp_mac.h> // V5 requirement
#endif
#endif
@@ -737,17 +742,17 @@ int32_t hw_random(int32_t lowerlimit, int32_t upperlimit) {
// PSRAM compile time checks to provide info for misconfigured env
#if defined(BOARD_HAS_PSRAM)
#if defined(IDF_TARGET_ESP32C3) || defined(ESP8266)
#error "ESP32-C3 and ESP8266 with PSRAM is not supported, please remove BOARD_HAS_PSRAM definition"
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(ESP8266)
#error "ESP32-C3/C6 and ESP8266 with PSRAM is not supported, please remove BOARD_HAS_PSRAM definition"
#else
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32S3) // PSRAM fix only needed for classic esp32
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_IDF_TARGET_ESP32) // PSRAM fix only needed for classic esp32
// BOARD_HAS_PSRAM also means that compiler flag "-mfix-esp32-psram-cache-issue" has to be used for old "rev.1" esp32
#warning "BOARD_HAS_PSRAM defined, make sure to use -mfix-esp32-psram-cache-issue to prevent issues on rev.1 ESP32 boards \
see https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/external-ram.html#esp32-rev-v1-0"
#endif
#endif
#else
#if !defined(IDF_TARGET_ESP32C3) && !defined(ESP8266)
#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(ESP8266)
#pragma message("BOARD_HAS_PSRAM not defined, not using PSRAM.")
#endif
#endif
@@ -804,7 +809,7 @@ static void *validateFreeHeap(void *buffer) {
void *d_malloc(size_t size) {
void *buffer = nullptr;
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
#if defined(WLED_HAVE_RTC_MEMORY_HEAP)
// the newer ESP32 variants have byte-accessible fast RTC memory that can be used as heap, access speed is on-par with DRAM
// the system does prefer normal DRAM until full, since free RTC memory is ~7.5k only, its below the minimum heap threshold and needs to be allocated explicitly
// use RTC RAM for small allocations or if DRAM is running low to improve fragmentation
@@ -1242,6 +1247,8 @@ uint8_t perlin8(uint16_t x, uint16_t y, uint16_t z) {
return (((perlin3D_raw((uint32_t)x << 8, (uint32_t)y << 8, (uint32_t)z << 8, true) * 2015) >> 10) + 33168) >> 8; //scale to 16 bit, offset, then scale to 8bit
}
#if !defined(ARDUINO_ARCH_ESP32) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(6, 0, 0)) // ToDO: validate behaviour in V5
// Platform-agnostic SHA1 computation from String input
String computeSHA1(const String& input) {
#ifdef ESP8266
@@ -1251,11 +1258,19 @@ String computeSHA1(const String& input) {
unsigned char shaResult[20]; // SHA1 produces 20 bytes
mbedtls_sha1_context ctx;
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
mbedtls_sha1_init(&ctx);
mbedtls_sha1_starts_ret(&ctx);
mbedtls_sha1_update_ret(&ctx, (const unsigned char*)input.c_str(), input.length());
mbedtls_sha1_finish_ret(&ctx, shaResult);
mbedtls_sha1_free(&ctx);
#else
mbedtls_sha1_init(&ctx);
mbedtls_sha1_starts(&ctx);
mbedtls_sha1_update(&ctx, (const unsigned char*)input.c_str(), input.length());
mbedtls_sha1_finish(&ctx, shaResult);
mbedtls_sha1_free(&ctx);
#endif
// Convert to hexadecimal string
char hexString[41];
@@ -1269,17 +1284,29 @@ String computeSHA1(const String& input) {
}
#ifdef ESP32
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#include "esp_adc_cal.h" // deprecated API
//#include "esp_adc/adc_cali.h" // new API
//#include "esp_adc/adc_cali_scheme.h" // new API
#else
#include "esp_adc_cal.h"
#endif
String generateDeviceFingerprint() {
uint32_t fp[2] = {0, 0}; // create 64 bit fingerprint
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
esp_efuse_mac_get_default((uint8_t*)fp);
fp[1] ^= ESP.getFlashChipSize();
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
fp[0] ^= chip_info.full_revision | (chip_info.model << 16);
// mix in ADC calibration data:
#else
fp[0] ^= chip_info.revision | (chip_info.model << 16);
#endif
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
// mix in ADC calibration data - legacy adc calibration API is not supported on new MCUs (-C5, -C6, -C61, -P4)
esp_adc_cal_characteristics_t ch;
#if SOC_ADC_MAX_BITWIDTH == 13 // S2 has 13 bit ADC
#if (SOC_ADC_MAX_BITWIDTH == 13) || (CONFIG_SOC_ADC_RTC_MAX_BITWIDTH == 13) // S2 has 13 bit ADC
constexpr auto myBIT_WIDTH = ADC_WIDTH_BIT_13;
#else
constexpr auto myBIT_WIDTH = ADC_WIDTH_BIT_12;
@@ -1297,6 +1324,11 @@ String generateDeviceFingerprint() {
fp[1] ^= ch.high_curve[i];
}
}
#else
// some extra salt, instead of ADC calibration
fp[0] ^= chip_info.features | chip_info.cores << 16;
fp[1] ^= ESP.getFlashSourceFrequencyMHz() | ESP.getFlashClockDivider() << 8 ;
#endif
char fp_string[17]; // 16 hex chars + null terminator
sprintf(fp_string, "%08X%08X", fp[1], fp[0]);
return String(fp_string);
@@ -1334,4 +1366,5 @@ String getDeviceId() {
return cachedDeviceId;
}
#endif // V5/V6 workaround

View File

@@ -1,6 +1,13 @@
#define WLED_DEFINE_GLOBAL_VARS //only in one source file, wled.cpp!
#include "wled.h"
#include "wled_ethernet.h"
#ifdef ARDUINO_ARCH_ESP32
#include "esp_efuse.h"
#include "esp_chip_info.h"
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#include "esp_mac.h"
#endif
#endif
#include "ota_update.h"
#ifdef WLED_ENABLE_AOTA
#define NO_OTA_PORT
@@ -12,6 +19,10 @@
#include "soc/rtc_cntl_reg.h"
#endif
#if defined(CONFIG_IDF_TARGET_ESP32P4)
#include "WiFi.h" // WiFi library for network connectivity
#include "ESP_HostedOTA.h" // ESP-Hosted OTA update functionality
#endif
extern "C" void usePWMFixedNMI();
/*
@@ -47,7 +58,11 @@ void WLED::loop()
unsigned long loopMillis = millis();
size_t loopDelay = loopMillis - lastRun;
if (lastRun == 0) loopDelay=0; // startup - don't have valid data from last run.
if (loopDelay > 2) DEBUG_PRINTF_P(PSTR("Loop delayed more than %ums.\n"), loopDelay);
#if defined(ESP8266) || (SOC_CPU_CORES_NUM < 2)
if (loopDelay > 4) DEBUG_PRINTF_P(PSTR("Loop delayed more than %ums.\n"), loopDelay); // be a bit more relaxed on single-core MCUs
#else
if (loopDelay > 2) DEBUG_PRINTF_P(PSTR("Loop delayed more than %ums.\n"), loopDelay);
#endif
static unsigned long maxLoopMillis = 0;
static size_t avgLoopMillis = 0;
static unsigned long maxUsermodMillis = 0;
@@ -110,7 +125,7 @@ void WLED::loop()
{
if (apActive) dnsServer.processNextRequest();
#ifdef WLED_ENABLE_AOTA
if (Network.isConnected() && aOtaEnabled && !otaLock && correctPIN) ArduinoOTA.handle();
if (WLEDNetwork.isConnected() && aOtaEnabled && !otaLock && correctPIN) ArduinoOTA.handle();
#endif
handleNightlight();
yield();
@@ -281,11 +296,12 @@ void WLED::loop()
DEBUG_PRINTF_P(PSTR("PSRAM: Free: %7u bytes | Largest block: %6u bytes\n"), psram_free, psram_largest);
#endif
#if defined(CONFIG_IDF_TARGET_ESP32)
// 32-bit DRAM (not byte accessible, only available on ESP32)
// 32-bit DRAM aka IRAM (not byte accessible, only available on ESP32)
size_t dram32_free = heap_caps_get_free_size(MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL) - dram_free; // returns all 32bit DRAM, subtract 8bit DRAM
//size_t dram32_largest = heap_caps_get_largest_free_block(MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL); // returns largest DRAM block -> not useful
DEBUG_PRINTF_P(PSTR("DRAM 32-bit: Free: %7u bytes | Largest block: N/A\n"), dram32_free);
#else
#endif
#if defined(WLED_HAVE_RTC_MEMORY_HEAP)
// Fast RTC Memory (not available on ESP32)
size_t rtcram_free = heap_caps_get_free_size(MALLOC_CAP_RTCRAM);
size_t rtcram_largest = heap_caps_get_largest_free_block(MALLOC_CAP_RTCRAM);
@@ -312,7 +328,7 @@ void WLED::loop()
lastWifiState = WiFi.status();
DEBUG_PRINTF_P(PSTR("State time: %lu\n"), wifiStateChangedTime);
DEBUG_PRINTF_P(PSTR("NTP last sync: %lu\n"), ntpLastSyncTime);
DEBUG_PRINTF_P(PSTR("Client IP: %u.%u.%u.%u\n"), Network.localIP()[0], Network.localIP()[1], Network.localIP()[2], Network.localIP()[3]);
DEBUG_PRINTF_P(PSTR("Client IP: %u.%u.%u.%u\n"), WLEDNetwork.localIP()[0], WLEDNetwork.localIP()[1], WLEDNetwork.localIP()[2], WLEDNetwork.localIP()[3]);
if (loops > 0) { // avoid division by zero
DEBUG_PRINTF_P(PSTR("Loops/sec: %u\n"), loops / 30);
DEBUG_PRINTF_P(PSTR("Loop time[ms]: %u/%lu\n"), avgLoopMillis/loops, maxLoopMillis);
@@ -379,7 +395,7 @@ void WLED::setup()
Serial.setTimeout(50); // this causes troubles on new MCUs that have a "virtual" USB Serial (HWCDC)
#else
#endif
#if defined(WLED_DEBUG) && defined(ARDUINO_ARCH_ESP32) && (defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || ARDUINO_USB_CDC_ON_BOOT)
#if defined(WLED_DEBUG) && defined(ARDUINO_ARCH_ESP32) && ARDUINO_USB_CDC_ON_BOOT
delay(2500); // allow CDC USB serial to initialise
#endif
#if !defined(WLED_DEBUG) && defined(ARDUINO_ARCH_ESP32) && !defined(WLED_DEBUG_HOST) && ARDUINO_USB_CDC_ON_BOOT
@@ -389,13 +405,13 @@ void WLED::setup()
DEBUG_PRINTF_P(PSTR("---WLED %s %u INIT---\n"), versionString, VERSION);
DEBUG_PRINTLN();
#ifdef ARDUINO_ARCH_ESP32
DEBUG_PRINTF_P(PSTR("esp32 %s\n"), ESP.getSdkVersion());
DEBUG_PRINTF_P(PSTR("esp-idf %s\n"), ESP.getSdkVersion());
#if defined(ESP_ARDUINO_VERSION)
DEBUG_PRINTF_P(PSTR("arduino-esp32 v%d.%d.%d\n"), int(ESP_ARDUINO_VERSION_MAJOR), int(ESP_ARDUINO_VERSION_MINOR), int(ESP_ARDUINO_VERSION_PATCH)); // available since v2.0.0
#else
DEBUG_PRINTLN(F("arduino-esp32 v1.0.x\n")); // we can't say in more detail.
#endif
DEBUG_PRINTF_P(PSTR("CPU: %s rev.%d, %d core(s), %d MHz.\n"), ESP.getChipModel(), (int)ESP.getChipRevision(), ESP.getChipCores(), ESP.getCpuFreqMHz());
DEBUG_PRINTF_P(PSTR("\nCPU: %s rev.%d, %d core(s), %d MHz.\n"), ESP.getChipModel(), (int)ESP.getChipRevision(), ESP.getChipCores(), ESP.getCpuFreqMHz());
DEBUG_PRINTF_P(PSTR("FLASH: %d MB, Mode %d "), (ESP.getFlashChipSize()/1024)/1024, (int)ESP.getFlashChipMode());
#ifdef WLED_DEBUG
switch (ESP.getFlashChipMode()) {
@@ -419,7 +435,7 @@ void WLED::setup()
DEBUG_PRINTF_P(PSTR("esp8266 @ %u MHz.\nCore: %s\n"), ESP.getCpuFreqMHz(), ESP.getCoreVersion());
DEBUG_PRINTF_P(PSTR("FLASH: %u MB\n"), (ESP.getFlashChipSize()/1024)/1024);
#endif
DEBUG_PRINTF_P(PSTR("heap %u\n"), getFreeHeapSize());
DEBUG_PRINTF_P(PSTR("\nheap %u\n"), getFreeHeapSize());
#if defined(BOARD_HAS_PSRAM)
// if JSON buffer allocation fails requestJsonBufferLock() will always return false preventing crashes
@@ -469,6 +485,22 @@ void WLED::setup()
escapedMac = WiFi.macAddress();
escapedMac.replace(":", "");
escapedMac.toLowerCase();
#ifdef ARDUINO_ARCH_ESP32
// WiFi.macAddress() may return all zeros if the WiFi netif is not yet created
// (e.g. on ESP32-C5 where WiFi.mode() hasn't been called yet). Fall back to
// reading the base MAC directly from eFuse.
if (escapedMac == "000000000000") {
uint8_t mac[6] = {0};
#if defined(CONFIG_IDF_TARGET_ESP32P4) // P4 does not have on-chip WIFI, use ethernet MAC
esp_read_mac(mac, ESP_MAC_ETH);
#else
esp_read_mac(mac, ESP_MAC_WIFI_STA);
#endif
char buf[13];
sprintf(buf, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
escapedMac = buf;
}
#endif
WLED_SET_AP_SSID(); // otherwise it is empty on first boot until config is saved
multiWiFi.push_back(WiFiConfig(CLIENT_SSID,CLIENT_PASS)); // initialise vector with default WiFi
@@ -516,6 +548,14 @@ void WLED::setup()
#endif
WiFi.onEvent(WiFiEvent);
WiFi.mode(WIFI_STA); // enable scanning
#if defined(ARDUINO_ARCH_ESP32) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2))
// WiFi.setBandMode(WIFI_BAND_MODE_AUTO) can also be used without SOC_WIFI_SUPPORT_5G
if (!WiFi.setBandMode(WIFI_BAND_MODE_AUTO)) { // WIFI_BAND_MODE_AUTO = 5GHz+2.4GHz; WIFI_BAND_MODE_5G_ONLY, WIFI_BAND_MODE_2G_ONLY
DEBUG_PRINTLN(F("setup(): Wifi band configuration failed!\n"));
}
#endif
findWiFi(true); // start scanning for available WiFi-s
// all GPIOs are allocated at this point
@@ -582,7 +622,9 @@ void WLED::setup()
#endif
#if defined(ARDUINO_ARCH_ESP32) && defined(LWIP_IPV6)
#if ESP_IDF_VERSION_MAJOR < 5 // ToDO: clarify if esp-idf v5.x still needs this patch
installIPv6RABlocker(); // Work around unsolicited RA overwriting IPv4 DNS servers
#endif
#endif
#if WLED_WATCHDOG_TIMEOUT > 0
@@ -646,6 +688,16 @@ void WLED::initAP(bool resetAP)
}
DEBUG_PRINT(F("Opening access point "));
DEBUG_PRINTLN(apSSID);
#ifdef ARDUINO_ARCH_ESP32
// reset band mode to "auto" before starting AP
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2)
if (!WiFi.setBandMode(WIFI_BAND_MODE_AUTO)) {
DEBUG_PRINTLN(F("initAP(): Wifi band configuration failed!\n"));
}
#endif
#endif
WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255, 255, 255, 0));
WiFi.softAP(apSSID, apPass, apChannel, apHide);
#ifdef ARDUINO_ARCH_ESP32
@@ -707,10 +759,16 @@ void WLED::initConnection()
WiFi.setHostname(hostname);
#endif
if (multiWiFi[selectedWiFi].staticIP != 0U && multiWiFi[selectedWiFi].staticGW != 0U) {
WiFi.config(multiWiFi[selectedWiFi].staticIP, multiWiFi[selectedWiFi].staticGW, multiWiFi[selectedWiFi].staticSN, dnsAddress);
if (multiWiFi.empty()) { // guard: handle empty WiFi list safely
WiFi.config(IPAddress((uint32_t)0), IPAddress((uint32_t)0), IPAddress((uint32_t)0));
} else {
WiFi.config(IPAddress((uint32_t)0), IPAddress((uint32_t)0), IPAddress((uint32_t)0));
if (selectedWiFi >= multiWiFi.size()) selectedWiFi = 0; // guard: ensure valid index
if (multiWiFi[selectedWiFi].staticIP != IPAddress((uint32_t)0) &&
multiWiFi[selectedWiFi].staticGW != IPAddress((uint32_t)0)) { // guard: compare as IPAddress to avoid pointer overload
WiFi.config(multiWiFi[selectedWiFi].staticIP, multiWiFi[selectedWiFi].staticGW, multiWiFi[selectedWiFi].staticSN, dnsAddress);
} else {
WiFi.config(IPAddress((uint32_t)0), IPAddress((uint32_t)0), IPAddress((uint32_t)0));
}
}
lastReconnectAttempt = millis();
@@ -726,6 +784,11 @@ void WLED::initConnection()
DEBUG_PRINTLN(F("Access point disabled (init)."));
WiFi.softAPdisconnect(true);
WiFi.mode(WIFI_STA);
#if defined(SOC_WIFI_SUPPORT_5G) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2))
if (!WiFi.setBandMode((wifi_band_mode_t)wifiBandMode)) {
DEBUG_PRINTLN(F("initConnection(): WiFi band configuration failed!"));
}
#endif
}
}
@@ -817,7 +880,7 @@ void WLED::initInterfaces()
DEBUG_PRINTLN(F("Init STA interfaces"));
#ifndef WLED_DISABLE_HUESYNC
IPAddress ipAddress = Network.localIP();
IPAddress ipAddress = WLEDNetwork.localIP();
if (hueIP[0] == 0) {
hueIP[0] = ipAddress[0];
hueIP[1] = ipAddress[1];
@@ -903,7 +966,7 @@ void WLED::handleConnection()
if (stac != stacO) {
stacO = stac;
DEBUG_PRINTF_P(PSTR("Connected AP clients: %d\n"), (int)stac);
if (!Network.isConnected() && wifiConfigured) { // trying to connect, but not connected
if (!WLEDNetwork.isConnected() && wifiConfigured) { // trying to connect, but not connected
if (stac)
WiFi.disconnect(); // disable search so that AP can work
else
@@ -912,7 +975,7 @@ void WLED::handleConnection()
}
}
if (!Network.isConnected()) {
if (!WLEDNetwork.isConnected()) {
if (interfacesInited) {
if (scanDone && multiWiFi.size() > 1) {
DEBUG_PRINTLN(F("WiFi scan initiated on disconnect."));
@@ -956,10 +1019,37 @@ void WLED::handleConnection()
} else if (!interfacesInited) { //newly connected
DEBUG_PRINTLN();
DEBUG_PRINT(F("Connected! IP address: "));
DEBUG_PRINTLN(Network.localIP());
DEBUG_PRINTLN(WLEDNetwork.localIP());
#ifdef ARDUINO_ARCH_ESP32
esp_wifi_set_storage(WIFI_STORAGE_RAM); // disable further updates of NVM credentials to prevent wear on flash (same as WiFi.persistent(false) but updates immediately, arduino wifi deficiency workaround)
#endif
DEBUG_PRINT(F("Channel: ")); DEBUG_PRINT(WiFi.channel());
#if defined(ARDUINO_ARCH_ESP32) && SOC_WIFI_SUPPORT_5G
auto wifiBand = WiFi.getBand();
DEBUG_PRINT(wifiBand == WIFI_BAND_2G ? F(" (2.4GHz)") : (wifiBand == WIFI_BAND_5G ? F(" (5GHz)"): F(" (other)")));
#else
DEBUG_PRINT(F(" (2.4GHz)"));
#endif
DEBUG_PRINTLN();
#if defined(CONFIG_IDF_TARGET_ESP32P4)
// directly after connection, attempt to update the ESP-Hosted Wi-Fi co-processor firmware
if (!apActive && !improvActive) {
// This function will:
// - Check if ESP-Hosted is initialized
// - Verify if an update is available
// - Download and install the firmware update if needed
if (updateEspHostedSlave()) {
// Restart the host ESP32 after successful update
// This is currently required to properly activate the new firmware on the ESP-Hosted co-processor
// ESP.restart();
doReboot = true; // schedule reboot
}
}
#endif
if (improvActive) {
if (improvError == 3) sendImprovStateResponse(0x00, true);
sendImprovStateResponse(0x04);
@@ -981,7 +1071,7 @@ void WLED::handleConnection()
}
// If status LED pin is allocated for other uses, does nothing
// else blink at 1Hz when Network.isConnected() is false (no WiFi, ?? no Ethernet ??)
// else blink at 1Hz when WLEDNetwork.isConnected() is false (no WiFi, ?? no Ethernet ??)
// else blink at 2Hz when MQTT is enabled but not connected
// else turn the status LED off
#if defined(STATUSLED)
@@ -995,7 +1085,7 @@ void WLED::handleStatusLED()
}
#endif
if (Network.isConnected()) {
if (WLEDNetwork.isConnected()) {
c = RGBW32(0,255,0,0);
ledStatusType = 2;
} else if (WLED_MQTT_CONNECTED) {

View File

@@ -7,7 +7,7 @@
*/
// version code in format yymmddb (b = daily build)
#define VERSION 2602141
#define VERSION 2603281
//uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG
@@ -75,6 +75,18 @@
// Library inclusions.
#include <Arduino.h>
// buildenv sanity check
#if !defined(ESP32) && !defined(ESP8266)
#error neither ESP32 nor ESP8266 defined. Please fix your build environment.
#endif
#if defined(ESP8266) && (defined(ARDUINO_ARCH_ESP32) || defined(ESP32))
#error both ESP8266 and ESP32/ARDUINO_ARCH_ESP32 defined. Please fix your build environment.
#endif
#if (defined(ARDUINO_ARCH_ESP32) && !defined(ESP32)) || (defined(ESP32) && !defined(ARDUINO_ARCH_ESP32))
#error either ESP32 or ARDUINO_ARCH_ESP32 not defined. Please fix your build environment.
#endif
#ifdef ESP8266
#include <ESP8266WiFi.h>
#ifdef WLED_ENABLE_WPA_ENTERPRISE
@@ -124,6 +136,8 @@
#include "my_config.h"
#endif
#include "wled_boards.h" // pull in board-specific capability defines
#include <ESPAsyncWebServer.h>
#include <WiFiUdp.h>
#include <DNSServer.h>
@@ -142,7 +156,9 @@
#endif
#ifdef WLED_ENABLE_DMX
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2)
#if defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32P4)
#error "DMX output is not supported on ESP32-C5/C6/P4 (esp_dmx library excluded)"
#elif defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3)|| defined(CONFIG_IDF_TARGET_ESP32S2)
#include "src/dependencies/dmx/ESPDMX.h"
#else //ESP32
#include "src/dependencies/dmx/SparkFunDMX.h"
@@ -315,7 +331,9 @@ WLED_GLOBAL bool rlyOpenDrain _INIT(RLYODRAIN);
#define IRTYPE 0
#endif
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || (defined(RX) && defined(TX))
// RX and TX: use "default" pins for 8266 and classic esp32
// except when arduino-esp32 has explicitly defined RX and TX (some arduino variants don't define RX and TX)
#if defined(ARDUINO_ARCH_ESP32) && (!defined(CONFIG_IDF_TARGET_ESP32) || (defined(RX) && defined(TX)))
// use RX/TX as set by the framework - these boards do _not_ have RX=3 and TX=1
constexpr uint8_t hardwareRX = RX;
constexpr uint8_t hardwareTX = TX;
@@ -375,11 +393,14 @@ WLED_GLOBAL bool noWifiSleep _INIT(false);
#endif
WLED_GLOBAL bool force802_3g _INIT(false);
#endif // WLED_SAVE_RAM
#ifdef ARDUINO_ARCH_ESP32
#if defined(LOLIN_WIFI_FIX) && (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
#ifdef SOC_WIFI_SUPPORT_5G
WLED_GLOBAL byte wifiBandMode _INIT((byte)WIFI_BAND_MODE_AUTO); // default for dual-band chips (1=2.4G, 2=5G, 3=Auto)
#endif
#if defined(ARDUINO_ARCH_ESP32)
#if defined(LOLIN_WIFI_FIX) // extend this fix to all esp32 boards
WLED_GLOBAL uint8_t txPower _INIT(WIFI_POWER_8_5dBm);
#else
WLED_GLOBAL uint8_t txPower _INIT(WIFI_POWER_19_5dBm);
WLED_GLOBAL uint8_t txPower _INIT(WIFI_POWER_19_5dBm); // ToDO: change to int8_t; V5 allows WIFI_POWER_21dBm = 84 ... WIFI_POWER_MINUS_1dBm = -4. Also check if the UI can handle it.
#endif
#endif
#define WLED_WIFI_CONFIGURED isWiFiConfigured()
@@ -454,7 +475,9 @@ WLED_GLOBAL bool arlsDisableGammaCorrection _INIT(true); // activate if
WLED_GLOBAL bool arlsForceMaxBri _INIT(false); // enable to force max brightness if source has very dark colors that would be black
#ifdef WLED_ENABLE_DMX
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2)
#if defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32P4)
#error "DMX output is not supported on ESP32-C5/C6/P4 (esp_dmx library excluded)"
#elif defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2)
WLED_GLOBAL DMXESPSerial dmx;
#else //ESP32
WLED_GLOBAL SparkFunDMX dmx;
@@ -1022,7 +1045,7 @@ WLED_GLOBAL volatile uint8_t jsonBufferLock _INIT(0);
WLED_GLOBAL unsigned loops _INIT(0);
#endif
#define WLED_CONNECTED (Network.isConnected())
#define WLED_CONNECTED (WLEDNetwork.isConnected())
#ifndef WLED_AP_SSID_UNIQUE
#define WLED_SET_AP_SSID() do { \

152
wled00/wled_boards.h Normal file
View File

@@ -0,0 +1,152 @@
/*
WLED board capabilities: uses CONFIG_IDF_TARGET_... to extract board capability flags.
You can still use CONFIG_IDF_TARGET_ in the source code; this file provides shortcuts for repeating capability checks.
*/
#pragma once
#ifndef WLED_BOARDS_H
#define WLED_BOARDS_H
#include "NodeStruct.h" // to get generic NODE_TYPE_IDs
/*
* Structure: the below part uses isolated "#if defined()" instead of a chain of if ... elif ... else
* so that the constant WLED_BOARD will be set exactly once unless there are conflicting build_flags.
* In case that several blocks are active, it causes a compiler error to easily spot the problem
* "error: redefinition of 'constexpr const unsigned int WLED_BOARD'"
*/
/* TODO: add
WLED_HAVE_TOUCH (for button.cpp)
WLED_HAVE_I2S0_LEDS (for bus_wrapper.h)
WLED_HAVE_I2S1_LEDS (for bus_wrapper.h)
(find a name) // On ESP32-C3/C5/C6 only the first 2 RMT channels are usable for transmitting (bus_wrapper.h)
(find a name) // ESP32, S3, P4 can use SparkFunDMX (wled.h, dmx_output.cpp)
WLED_ALLOW_LOLIN_WIFI_FIX // (wled.h)
*/
#if defined(ESP8266)
// Capabilities of good-old 8266
// has no FPU
// bitshift with rounding is faster than integer division
// no byte-accessible fast RTC memory (newer esp32 variants only)
// no parallel I2S LEDs driver
constexpr unsigned WLED_BOARD = NODE_TYPE_ID_ESP8266;
// sanity check for esp32
#if defined(ARDUINO_ARCH_ESP32) || defined(ESP32)
#error "ARDUINO_ARCH_ESP32 or ESP32 is defined together with ESP8266. Please fix your buildenv."
#endif
#endif
#if CONFIG_IDF_TARGET_ESP32
// Capabilities of classic ESP32 and classic PICO-D4/D2/D3
#define WLED_HAVE_FAST_FLOAT 1 // has an FPU for fast floating point (single precision)
#define WLED_HAVE_FAST_int_DIVIDE 1 // integer division is fast (no need to use bitshifts with rounding instead of integer division)
// no byte-accessible fast RTC memory (newer esp32 variants only)
#define WLED_HAVE_IRAM_32BIT_HEAP 1 // only classic ESP32 has "32bit accessible only" aka IRAM type heap
#define WLED_HAS_PARALLEL_I2S 1 // classic esp32 has I2S parallel leds driver (NeoPixelBus)
constexpr unsigned WLED_BOARD = NODE_TYPE_ID_ESP32;
// sanity checks
#if (SOC_CPU_CORES_NUM < 2)
#error "ESP32 single-core is not supported."
#endif
#endif
#if CONFIG_IDF_TARGET_ESP32S3
// Capabilities of ESP32-S3
#define WLED_HAVE_FAST_FLOAT 1 // has an FPU for fast floating point (single precision)
#define WLED_HAVE_FAST_int_DIVIDE 1 // integer division is fast (no need to use bitshifts with rounding instead of integer division)
#define WLED_HAVE_RTC_MEMORY_HEAP 1 // has byte-accessible fast RTC memory that can be used as heap
// no 4byte-accessible IRAM heap
#define WLED_HAS_PARALLEL_I2S 1 // esp32-S3 supports I2S parallel leds driver (NeoPixelBus)
constexpr unsigned WLED_BOARD = NODE_TYPE_ID_ESP32S3;
// sanity checks
#if (SOC_CPU_CORES_NUM < 2)
#error "ESP32-S3 single-core is not supported."
#endif
#endif
#if CONFIG_IDF_TARGET_ESP32S2
// Capabilities of ESP32-S2
// has no FPU
#define WLED_HAVE_FAST_int_DIVIDE 1 // integer division is fast (no need to use bitshifts with rounding instead of integer division)
#define WLED_HAVE_RTC_MEMORY_HEAP 1 // has byte-accessible fast RTC memory that can be used as heap
// no 4byte-accessible IRAM heap
#define WLED_HAS_PARALLEL_I2S 1 // esp32-S2 supports I2S parallel leds driver (NeoPixelBus)
constexpr unsigned WLED_BOARD = NODE_TYPE_ID_ESP32S2;
#endif
#if CONFIG_IDF_TARGET_ESP32C3
// Capabilities of ESP32-C3
// has no FPU
// bitshift with rounding is faster than integer division
#define WLED_HAVE_RTC_MEMORY_HEAP 1 // has byte-accessible fast RTC memory that can be used as heap
// no 4byte-accessible IRAM heap
// no parallel I2S LEDs driver
constexpr unsigned WLED_BOARD = NODE_TYPE_ID_ESP32C3;
#endif
#if CONFIG_IDF_TARGET_ESP32C5
// Capabilities of ESP32-C5
// has no FPU
// bitshift with rounding is faster than integer division
#define WLED_HAVE_RTC_MEMORY_HEAP 1 // has byte-accessible fast RTC memory that can be used as heap
// no 4byte-accessible IRAM heap
// no parallel I2S LEDs driver
constexpr unsigned WLED_BOARD = NODE_TYPE_ID_ESP32C5;
#endif
#if CONFIG_IDF_TARGET_ESP32C6
// Capabilities of ESP32-C6
// has no FPU
// bitshift with rounding is faster than integer division
#define WLED_HAVE_RTC_MEMORY_HEAP 1 // has byte-accessible fast RTC memory that can be used as heap
// no 4byte-accessible IRAM heap
// no parallel I2S LEDs driver
constexpr unsigned WLED_BOARD = NODE_TYPE_ID_ESP32C6;
#endif
#if CONFIG_IDF_TARGET_ESP32C61
// Capabilities of ESP32-C61
// has no FPU
// bitshift with rounding is faster than integer division
#define WLED_HAVE_RTC_MEMORY_HEAP 1 // has byte-accessible fast RTC memory that can be used as heap
// no 4byte-accessible IRAM heap
// no parallel I2S LEDs driver
constexpr unsigned WLED_BOARD = NODE_TYPE_ID_ESP32C61;
#endif
#if CONFIG_IDF_TARGET_ESP32P4
// Capabilities of ESP32-P4
#define WLED_HAVE_FAST_FLOAT 1 // has an FPU for fast floating point (single precision)
// TBC: is bitshift with rounding is faster than integer division ?
#define WLED_HAVE_FAST_int_DIVIDE 1 // integer division is fast (no need to use bitshifts with rounding instead of integer division)
#define WLED_HAVE_RTC_MEMORY_HEAP 1 // TBC: does it have byte-accessible fast RTC memory that can be used as heap ?
// no 4byte-accessible IRAM heap
// no parallel I2S LEDs driver
#define WLED_HAS_PARALLEL_PARLIO 1 // (unsupported) P4 allows parallel leds driving with PARLIO unit
constexpr unsigned WLED_BOARD = NODE_TYPE_ID_ESP32P4;
// sanity checks
#if (SOC_CPU_CORES_NUM < 2)
#error "ESP32-P4 single-core is not supported."
#endif
#endif
// sanity check: the constexpr assignment below will fail when WLED_BOARD is not set by the previous blocks
constexpr unsigned wled_boards_sanity_check = 0 + WLED_BOARD;
#endif // WLED_BOARDS_H

View File

@@ -4,7 +4,8 @@
#ifndef WLED_VERSION
#warning WLED_VERSION was not set - using default value of 'dev'
#define WLED_VERSION dev
//#define WLED_VERSION dev
#define WLED_VERSION 17.0.0-devV5 // ToDO: remove once that set_metadata.py is fixed
#endif
#ifndef WLED_RELEASE_NAME
#warning WLED_RELEASE_NAME was not set - using default value of 'Custom'

View File

@@ -60,7 +60,7 @@ static bool inSubnet(const IPAddress &ip, const IPAddress &subnet, const IPAddre
}
static bool inSameSubnet(const IPAddress &client) {
return inSubnet(client, Network.localIP(), Network.subnetMask());
return inSubnet(client, WLEDNetwork.localIP(), WLEDNetwork.subnetMask());
}
static bool inLocalSubnet(const IPAddress &client) {

View File

@@ -93,11 +93,11 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
handleE131Packet((e131_packet_t*)&data[offset], client->remoteIP(), P_ARTNET);
break;
case BINARY_PROTOCOL_DDP:
if (len < 10 + offset) return; // DDP header is 10 bytes (+1 protocol byte)
if (len < size_t(10 + offset)) return; // DDP header is 10 bytes (+1 protocol byte)
size_t ddpDataLen = (data[8+offset] << 8) | data[9+offset]; // data length in bytes from DDP header
uint8_t flags = data[0+offset];
if ((flags & DDP_FLAGS_TIME) ) ddpDataLen += 4; // timecode flag adds 4 bytes to data length
if (len < (10 + offset + ddpDataLen)) return; // not enough data, prevent out of bounds read
if (len < size_t(10 + offset + ddpDataLen)) return; // not enough data, prevent out of bounds read
// could be a valid DDP packet, forward to handler
handleE131Packet((e131_packet_t*)&data[offset], client->remoteIP(), P_DDP);
}

View File

@@ -263,6 +263,11 @@ void getSettingsJS(byte subPage, Print& settingsScript)
#endif
printSetFormCheckbox(settingsScript,PSTR("FG"),force802_3g);
printSetFormCheckbox(settingsScript,PSTR("WS"),noWifiSleep);
#ifdef SOC_WIFI_SUPPORT_5G
printSetFormValue(settingsScript,PSTR("BM"),wifiBandMode);
#else
settingsScript.print(F("gId('bm').style.display='none';"));
#endif
#ifndef WLED_DISABLE_ESPNOW
printSetFormCheckbox(settingsScript,PSTR("RE"),enableESPNow);
@@ -283,14 +288,14 @@ void getSettingsJS(byte subPage, Print& settingsScript)
settingsScript.print(F("gId('ethd').style.display='none';"));
#endif
if (Network.isConnected()) //is connected
if (WLEDNetwork.isConnected()) //is connected
{
char s[32];
IPAddress localIP = Network.localIP();
IPAddress localIP = WLEDNetwork.localIP();
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
if (Network.isEthernet()) strcat_P(s ,PSTR(" (Ethernet)"));
if (WLEDNetwork.isEthernet()) strcat_P(s ,PSTR(" (Ethernet)"));
#endif
printSetClassElementHTML(settingsScript,PSTR("sip"),0,s);
} else