"):''}
${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")}
@@ -1096,6 +1097,8 @@ function btype(b)
case 34: return "ESP32-S3";
case 5:
case 35: return "ESP32-C3";
+ case 36: return "ESP32-C6";
+ case 41: return "ESP32-C5";
case 1:
case 82: return "ESP8266";
}
diff --git a/wled00/dmx_output.cpp b/wled00/dmx_output.cpp
index eace2145e6..f7b87cb048 100644
--- a/wled00/dmx_output.cpp
+++ b/wled00/dmx_output.cpp
@@ -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_ESP32S2)
dmx.init(512); // initialize with bus length
#else
dmx.initWrite(512); // initialize with bus length
diff --git a/wled00/improv.cpp b/wled00/improv.cpp
index 1eb83627db..d94cf35381 100644
--- a/wled00/improv.cpp
+++ b/wled00/improv.cpp
@@ -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)
#undef WLED_DISABLE_IMPROV_WIFISCAN
#define WLED_DISABLE_IMPROV_WIFISCAN
#endif
diff --git a/wled00/json.cpp b/wled00/json.cpp
index 22ebcf7b03..dded3ea75e 100644
--- a/wled00/json.cpp
+++ b/wled00/json.cpp
@@ -796,7 +796,12 @@ 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();
+ constexpr int WIFI_5GHZ_MIN_CHANNEL = 36;
+ int wifiChannel = WiFi.channel();
+ wifi_info[F("channel")] = wifiChannel;
+ if (wifiChannel > 0) {
+ wifi_info[F("band")] = (wifiChannel >= WIFI_5GHZ_MIN_CHANNEL) ? F("5GHz") : F("2.4GHz");
+ }
wifi_info[F("ap")] = apActive;
JsonObject fs_info = root.createNestedObject("fs");
@@ -811,7 +816,7 @@ void serializeInfo(JsonObject root)
wifi_info[F("txPower")] = (int) WiFi.getTxPower();
wifi_info[F("sleep")] = (bool) WiFi.getSleep();
#endif
- #if !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32P4)
+ #if defined(CONFIG_IDF_TARGET_ESP32)
root[F("arch")] = "esp32";
#else
root[F("arch")] = ESP.getChipModel();
diff --git a/wled00/mbedtls_sha1_shim.cpp b/wled00/mbedtls_sha1_shim.cpp
index 8561afcfc3..a009553bee 100644
--- a/wled00/mbedtls_sha1_shim.cpp
+++ b/wled00/mbedtls_sha1_shim.cpp
@@ -1,6 +1,7 @@
#include "wled.h"
#ifdef ESP32
-#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
+// 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"
diff --git a/wled00/ota_update.cpp b/wled00/ota_update.cpp
index 2f758b2c79..6748e6e7b1 100644
--- a/wled00/ota_update.cpp
+++ b/wled00/ota_update.cpp
@@ -410,6 +410,7 @@ bool verifyBootloaderImage(const uint8_t* &buffer, size_t &len, String* bootload
// 0x000C = ESP32-C2
// 0x000D = ESP32-C6
// 0x0010 = ESP32-H2
+ // 0x0017 = ESP32-C5
#if defined(CONFIG_IDF_TARGET_ESP32)
if (chipId != 0x0000) {
@@ -435,6 +436,13 @@ bool verifyBootloaderImage(const uint8_t* &buffer, size_t &len, String* bootload
}
*bootloaderErrorMsg = "ESP32-S3 update not supported yet";
return false;
+ #elif defined(CONFIG_IDF_TARGET_ESP32C5)
+ if (chipId != 0x0017) {
+ *bootloaderErrorMsg = "Chip ID mismatch - expected ESP32-C5 (0x0017), got 0x" + String(chipId, HEX);
+ return false;
+ }
+ *bootloaderErrorMsg = "ESP32-C5 update not supported yet";
+ return false;
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
if (chipId != 0x000D) {
*bootloaderErrorMsg = "Chip ID mismatch - expected ESP32-C6 (0x000D), got 0x" + String(chipId, HEX);
diff --git a/wled00/pin_manager.cpp b/wled00/pin_manager.cpp
index 729e845039..cf7d492527 100644
--- a/wled00/pin_manager.cpp
+++ b/wled00/pin_manager.cpp
@@ -232,6 +232,13 @@ 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, 27, 28
+ // 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: 8, 9, 15
// GPIO 0-23 directly usable, 24-30 are for SPI flash
diff --git a/wled00/set.cpp b/wled00/set.cpp
index b1831cf9e7..45107492f0 100644
--- a/wled00/set.cpp
+++ b/wled00/set.cpp
@@ -155,7 +155,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
Bus::setCCTBlend(cctBlending);
Bus::setGlobalAWMode(request->arg(F("AW")).toInt());
strip.setTargetFps(request->arg(F("FR")).toInt());
- #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32P4)
+ #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32P4)
useParallelI2S = request->hasArg(F("PR"));
#endif
diff --git a/wled00/src/dependencies/dmx/ESPDMX.cpp b/wled00/src/dependencies/dmx/ESPDMX.cpp
index a80cad71c8..b1a613375a 100644
--- a/wled00/src/dependencies/dmx/ESPDMX.cpp
+++ b/wled00/src/dependencies/dmx/ESPDMX.cpp
@@ -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_ESP32S2)
#include
diff --git a/wled00/src/dependencies/dmx/SparkFunDMX.cpp b/wled00/src/dependencies/dmx/SparkFunDMX.cpp
index 064b9ff620..a180869b80 100644
--- a/wled00/src/dependencies/dmx/SparkFunDMX.cpp
+++ b/wled00/src/dependencies/dmx/SparkFunDMX.cpp
@@ -17,7 +17,7 @@ Distributed as-is; no warranty is given.
#if defined(ARDUINO_ARCH_ESP32)
#include
-#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S2)
+#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#include "SparkFunDMX.h"
#include
diff --git a/wled00/udp.cpp b/wled00/udp.cpp
index c1e4951b42..477acf2da1 100644
--- a/wled00/udp.cpp
+++ b/wled00/udp.cpp
@@ -722,6 +722,10 @@ void sendSysInfoUDP()
memcpy((byte *)data + 6, serverDescription, 32);
#ifdef ESP8266
data[38] = NODE_TYPE_ID_ESP8266;
+ #elif defined(CONFIG_IDF_TARGET_ESP32C5)
+ data[38] = NODE_TYPE_ID_ESP32C5;
+ #elif defined(CONFIG_IDF_TARGET_ESP32C6)
+ data[38] = NODE_TYPE_ID_ESP32C6;
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
data[38] = NODE_TYPE_ID_ESP32C3;
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
diff --git a/wled00/util.cpp b/wled00/util.cpp
index a391d536b8..2237512457 100644
--- a/wled00/util.cpp
+++ b/wled00/util.cpp
@@ -633,8 +633,8 @@ 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(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) || defined(ESP8266)
- #error "ESP32-C3 and ESP8266 with PSRAM is not supported, please remove BOARD_HAS_PSRAM definition"
+ #if defined(IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) || defined(ESP8266)
+ #error "ESP32-C3/C5 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
// BOARD_HAS_PSRAM also means that compiler flag "-mfix-esp32-psram-cache-issue" has to be used for old "rev.1" esp32
@@ -694,7 +694,7 @@ static void *validateFreeHeap(void *buffer) {
void *d_malloc(size_t size) {
void *buffer;
- #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32P4)
+ #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32P4)
// 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 to improve fragmentation or if DRAM is running low
diff --git a/wled00/wled.cpp b/wled00/wled.cpp
index d41c75465e..c5a5594b79 100644
--- a/wled00/wled.cpp
+++ b/wled00/wled.cpp
@@ -1,6 +1,9 @@
#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_mac.h"
+#endif
#include "ota_update.h"
#ifdef WLED_ENABLE_AOTA
#define NO_OTA_PORT
@@ -351,7 +354,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) && (defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || 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
@@ -442,6 +445,18 @@ 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};
+ esp_read_mac(mac, ESP_MAC_WIFI_STA);
+ 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
@@ -873,6 +888,9 @@ void WLED::handleConnection()
DEBUG_PRINTLN();
DEBUG_PRINT(F("Connected! IP address: "));
DEBUG_PRINTLN(WLEDNetwork.localIP());
+ #if defined(CONFIG_IDF_TARGET_ESP32C5)
+ { constexpr int kFirst5GHzChannel = 36; int32_t ch = WiFi.channel(); DEBUG_PRINTF_P(PSTR("WiFi channel: %d (%s)\n"), ch, (ch >= kFirst5GHzChannel) ? "5GHz" : "2.4GHz"); }
+ #endif
if (improvActive) {
if (improvError == 3) sendImprovStateResponse(0x00, true);
sendImprovStateResponse(0x04);
diff --git a/wled00/wled.h b/wled00/wled.h
index 9046a36557..e53781b575 100644
--- a/wled00/wled.h
+++ b/wled00/wled.h
@@ -154,7 +154,9 @@
#endif
#ifdef WLED_ENABLE_DMX
- #if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32S2)
+ #if defined(CONFIG_IDF_TARGET_ESP32C5)
+ #error "DMX output is not supported on ESP32-C5 (esp_dmx library excluded)"
+ #elif defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32S2)
#include "src/dependencies/dmx/ESPDMX.h"
#else //ESP32
#include "src/dependencies/dmx/SparkFunDMX.h"
@@ -327,7 +329,7 @@ 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_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32P4) || defined(CONFIG_IDF_TARGET_ESP32S2) || (defined(RX) && defined(TX))
+#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32P4) || defined(CONFIG_IDF_TARGET_ESP32S2) || (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;
@@ -388,7 +390,7 @@ WLED_GLOBAL bool noWifiSleep _INIT(false);
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_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
+ #if defined(LOLIN_WIFI_FIX) && (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
WLED_GLOBAL uint8_t txPower _INIT(WIFI_POWER_8_5dBm);
#else
WLED_GLOBAL uint8_t txPower _INIT(WIFI_POWER_19_5dBm);
@@ -415,7 +417,7 @@ WLED_GLOBAL byte bootPreset _INIT(0); // save preset to load
WLED_GLOBAL bool useGlobalLedBuffer _INIT(false); // double buffering disabled on ESP8266
#else
WLED_GLOBAL bool useGlobalLedBuffer _INIT(true); // double buffering enabled on ESP32
- #if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32P4)
+ #if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32P4)
WLED_GLOBAL bool useParallelI2S _INIT(false); // parallel I2S for ESP32
#endif
#endif
@@ -469,7 +471,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_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32S2)
+ #if defined(CONFIG_IDF_TARGET_ESP32C5)
+ #error "DMX output is not supported on ESP32-C5 (esp_dmx library excluded)"
+ #elif defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32S2)
WLED_GLOBAL DMXESPSerial dmx;
#else //ESP32
WLED_GLOBAL SparkFunDMX dmx;
|