From 7196b177aa61c44d009690c41e88aeee77083afa Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Mon, 10 Oct 2022 20:20:46 +0200 Subject: [PATCH] ESP32 chip info tool for WLED_DEBUG This is a nice little chip info tool that I've created some time ago. When building with `-D WLED_DEBUG`, it reports some interesting information about your ESP32 on serial monitor. ```` ==================================== Chip info for ESP32-D0WDQ5 SDK: v4.4.1-472-gc9140caf8c ------------------------------------ XTAL FREQ: 40 MHz APB FREQ: 80.0 MHz CPU FREQ: 240 MHz ESP32 DEVICE: ESP32-D0WD-V3 rev.3, 2 core(s), 240MHz. Chip feature flags: 0b110010 * 0b0000010 Chip has 2.4GHz WiFi * 0b0001000 Chip has Bluetooth LE * 0b0010000 Chip has Bluetooth Classic FLASH CHIP FREQ (magic): 80.0 MHz FLASH SIZE (magic byte): 4.00 MB FLASH MODE (magic byte): 2 ; 0=QIO, 1=QOUT, 2=DIO, 3=DOUT or other FLASH CHIP ID: 0x16405E FLASH CHIP FREQ: 80.0 MHz FLASH REAL SIZE: 4.00 MB FLASH REAL MODE: DIO ------------------------------------ RAM HEAP SIZE: 261.79 KB FREE RAM: 232.57 KB MAX RAM alloc: 107.99 KB ESP32 PSRAM: found. * SPI RAM Chip availeable: 64MBits = 8MBytes total PSRAM: 4094 KB FREE PSRAM: 4093.89 KB MAX PSRAM alloc:4031.99 KB used PSRAM: 0 Bytes * PSRAM free after malloc / ps_malloc : 2833.85 KB * Can allocate big memory with ps_malloc() * Can allocate big memory with malloc() CPU #0 - last reset reason = 1 POWERON_RESET => Vbat power on reset CPU #1 - last reset reason = 14 EXT_CPU_RESET => APP CPU reset by PRO CPU ==================================== ```` --- tools/ESP32-Chip_info.hpp | 558 ++++++++++++++++++++++++++++++++++++++ wled00/wled.cpp | 19 +- 2 files changed, 573 insertions(+), 4 deletions(-) create mode 100644 tools/ESP32-Chip_info.hpp diff --git a/tools/ESP32-Chip_info.hpp b/tools/ESP32-Chip_info.hpp new file mode 100644 index 00000000..04fd3f68 --- /dev/null +++ b/tools/ESP32-Chip_info.hpp @@ -0,0 +1,558 @@ +#pragma once + +/* A tool that print some ESP32 hardware information + * to serial monitor. + * main function: showRealSpeed(); + */ + + +/* code below is based on https://github.com/Jason2866/ESP32_Show_Info + * that was created by Jason2866, subject to the GNU General Public License v3.0 + * detailed license conditions: https://github.com/Jason2866/ESP32_Show_Info/blob/main/LICENSE + */ +#include +#include "soc/spi_reg.h" +#include + +#if CONFIG_IDF_TARGET_ESP32 +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) + #include "esp32/rom/spi_flash.h" + #include "esp32/spiram.h" + #include "spiram_psram.h" +#else + #include "esp_spi_flash.h" + #include "rom/spi_flash.h" + #include "esp_spiram.h" + //#include "spiram_psram.h" +#endif +#elif CONFIG_IDF_TARGET_ESP32S2 // ESP32-S2 + #include "esp32s2/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S3 // ESP32-S3 + #include "esp32s3/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32C3 // ESP32-C3 + #include "esp32c3/rom/spi_flash.h" +#endif + +#include +#include + +#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 + #ifndef REG_SPI_BASE + #define REG_SPI_BASE(i) (DR_REG_SPI1_BASE + (((i)>1) ? (((i)* 0x1000) + 0x20000) : (((~(i)) & 1)* 0x1000 ))) + #endif // REG_SPI_BASE +#endif // TARGET + +uint32_t my_ESP_getFlashChipId(void) +{ + uint32_t id = g_rom_flashchip.device_id; + id = ((id & 0xff) << 16) | ((id >> 16) & 0xff) | (id & 0xff00); + return id; +} + +uint32_t my_ESP_getFlashChipRealSize(void) +{ + uint32_t id = (my_ESP_getFlashChipId() >> 16) & 0xFF; + return 2 << (id - 1); +} + +String my_ESP_getFlashChipMode(void) { +#if CONFIG_IDF_TARGET_ESP32S2 +const uint32_t spi_ctrl = REG_READ(PERIPHS_SPI_FLASH_CTRL); +#else +const uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0)); +#endif +/* Not all of the following constants are already defined in older versions of spi_reg.h, so do it manually for now*/ +if (spi_ctrl & BIT(24)) { //SPI_FREAD_QIO + return F("QIO"); +} else if (spi_ctrl & BIT(20)) { //SPI_FREAD_QUAD + return F("QOUT"); +} else if (spi_ctrl & BIT(23)) { //SPI_FREAD_DIO + return F("DIO"); +} else if (spi_ctrl & BIT(14)) { // SPI_FREAD_DUAL + return F("DOUT"); +} else if (spi_ctrl & BIT(13)) { //SPI_FASTRD_MODE + return F("Fast"); +} else { + return F("Slow"); +} +return F("DOUT"); +} + + +//******** Flash Chip Speed is NOT correctl !!!! ***** +uint32_t my_ESP_getFlashChipSpeed(void) +{ + const uint32_t spi_clock = REG_READ(SPI_CLOCK_REG(0)); + if (spi_clock & BIT(31)) { + // spi_clk is equal to system clock + return getApbFrequency(); + } + return spiClockDivToFrequency(spi_clock); +} + +String my_GetDeviceHardware(void) { + // https://www.espressif.com/en/products/socs + +/* +Source: esp-idf esp_system.h and esptool + +typedef enum { + CHIP_ESP32 = 1, //!< ESP32 + CHIP_ESP32S2 = 2, //!< ESP32-S2 + CHIP_ESP32S3 = 9, //!< ESP32-S3 + CHIP_ESP32C3 = 5, //!< ESP32-C3 + CHIP_ESP32H2 = 6, //!< ESP32-H2 + CHIP_ESP32C2 = 12, //!< ESP32-C2 +} esp_chip_model_t; + +// Chip feature flags, used in esp_chip_info_t +#define CHIP_FEATURE_EMB_FLASH BIT(0) //!< Chip has embedded flash memory +#define CHIP_FEATURE_WIFI_BGN BIT(1) //!< Chip has 2.4GHz WiFi +#define CHIP_FEATURE_BLE BIT(4) //!< Chip has Bluetooth LE +#define CHIP_FEATURE_BT BIT(5) //!< Chip has Bluetooth Classic +#define CHIP_FEATURE_IEEE802154 BIT(6) //!< Chip has IEEE 802.15.4 +#define CHIP_FEATURE_EMB_PSRAM BIT(7) //!< Chip has embedded psram + + +// The structure represents information about the chip +typedef struct { + esp_chip_model_t model; //!< chip model, one of esp_chip_model_t + uint32_t features; //!< bit mask of CHIP_FEATURE_x feature flags + uint8_t cores; //!< number of CPU cores + uint8_t revision; //!< chip revision number +} esp_chip_info_t; + +*/ + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + + uint32_t chip_model = chip_info.model; + uint32_t chip_revision = chip_info.revision; +// uint32_t chip_revision = ESP.getChipRevision(); + bool rev3 = (3 == chip_revision); +// bool single_core = (1 == ESP.getChipCores()); + bool single_core = (1 == chip_info.cores); + + if (chip_model < 2) { // ESP32 +#ifdef CONFIG_IDF_TARGET_ESP32 +/* esptool: + def get_pkg_version(self): + word3 = self.read_efuse(3) + pkg_version = (word3 >> 9) & 0x07 + pkg_version += ((word3 >> 2) & 0x1) << 3 + return pkg_version +*/ + uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG); + uint32_t pkg_version = chip_ver & 0x7; + +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("HDW: ESP32 Model %d, Revision %d, Core %d, Package %d"), chip_info.model, chip_revision, chip_info.cores, chip_ver); + + switch (pkg_version) { + case 0: + if (single_core) { return F("ESP32-S0WDQ6"); } // Max 240MHz, Single core, QFN 6*6 + else if (rev3) { return F("ESP32-D0WDQ6-V3"); } // Max 240MHz, Dual core, QFN 6*6 + else { return F("ESP32-D0WDQ6"); } // Max 240MHz, Dual core, QFN 6*6 + case 1: + if (single_core) { return F("ESP32-S0WD"); } // Max 160MHz, Single core, QFN 5*5, ESP32-SOLO-1, ESP32-DevKitC + else if (rev3) { return F("ESP32-D0WD-V3"); } // Max 240MHz, Dual core, QFN 5*5, ESP32-WROOM-32E, ESP32_WROVER-E, ESP32-DevKitC + else { return F("ESP32-D0WD"); } // Max 240MHz, Dual core, QFN 5*5, ESP32-WROOM-32D, ESP32_WROVER-B, ESP32-DevKitC + case 2: return F("ESP32-D2WD"); // Max 160MHz, Dual core, QFN 5*5, 2MB embedded flash + case 3: + if (single_core) { return F("ESP32-S0WD-OEM"); } // Max 160MHz, Single core, QFN 5*5, Xiaomi Yeelight + else { return F("ESP32-D0WD-OEM"); } // Max 240MHz, Dual core, QFN 5*5 + case 4: return F("ESP32-U4WDH"); // Max 160MHz, Single core, QFN 5*5, 4MB embedded flash, ESP32-MINI-1, ESP32-DevKitM-1 + case 5: + if (rev3) { return F("ESP32-PICO-V3"); } // Max 240MHz, Dual core, LGA 7*7, ESP32-PICO-V3-ZERO, ESP32-PICO-V3-ZERO-DevKit + else { return F("ESP32-PICO-D4"); } // Max 240MHz, Dual core, LGA 7*7, 4MB embedded flash, ESP32-PICO-KIT + case 6: return F("ESP32-PICO-V3-02"); // Max 240MHz, Dual core, LGA 7*7, 8MB embedded flash, 2MB embedded PSRAM, ESP32-PICO-MINI-02, ESP32-PICO-DevKitM-2 + case 7: return F("ESP32-D0WDR2-V3"); // Max 240MHz, Dual core, QFN 5*5, ESP32-WROOM-32E, ESP32_WROVER-E, ESP32-DevKitC + } +#endif // CONFIG_IDF_TARGET_ESP32 + return F("ESP32"); + } + else if (2 == chip_model) { // ESP32-S2 +#ifdef CONFIG_IDF_TARGET_ESP32S2 +/* esptool: + def get_flash_version(self): + num_word = 3 + block1_addr = self.EFUSE_BASE + 0x044 + word3 = self.read_reg(block1_addr + (4 * num_word)) + pkg_version = (word3 >> 21) & 0x0F + return pkg_version + + def get_psram_version(self): + num_word = 3 + block1_addr = self.EFUSE_BASE + 0x044 + word3 = self.read_reg(block1_addr + (4 * num_word)) + pkg_version = (word3 >> 28) & 0x0F + return pkg_version +*/ + uint32_t chip_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_FLASH_VERSION); + uint32_t psram_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PSRAM_VERSION); + uint32_t pkg_version = (chip_ver & 0xF) + ((psram_ver & 0xF) * 100); + +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("HDW: ESP32 Model %d, Revision %d, Core %d, Package %d"), chip_info.model, chip_revision, chip_info.cores, chip_ver); + + switch (pkg_version) { + case 0: return F("ESP32-S2"); // Max 240MHz, Single core, QFN 7*7, ESP32-S2-WROOM, ESP32-S2-WROVER, ESP32-S2-Saola-1, ESP32-S2-Kaluga-1 + case 1: return F("ESP32-S2FH2"); // Max 240MHz, Single core, QFN 7*7, 2MB embedded flash, ESP32-S2-MINI-1, ESP32-S2-DevKitM-1 + case 2: return F("ESP32-S2FH4"); // Max 240MHz, Single core, QFN 7*7, 4MB embedded flash + case 3: return F("ESP32-S2FN4R2"); // Max 240MHz, Single core, QFN 7*7, 4MB embedded flash, 2MB embedded PSRAM, , ESP32-S2-MINI-1U, ESP32-S2-DevKitM-1U + case 100: return F("ESP32-S2R2"); + case 102: return F("ESP32-S2FNR2"); // Max 240MHz, Single core, QFN 7*7, 4MB embedded flash, 2MB embedded PSRAM, , Lolin S2 mini + } +#endif // CONFIG_IDF_TARGET_ESP32S2 + return F("ESP32-S2"); + } + else if (9 == chip_model) { // ESP32-S3 +#ifdef CONFIG_IDF_TARGET_ESP32S3 + // no variants for now +#endif // CONFIG_IDF_TARGET_ESP32S3 + return F("ESP32-S3"); // Max 240MHz, Dual core, QFN 7*7, ESP32-S3-WROOM-1, ESP32-S3-DevKitC-1 + } + else if (5 == chip_model) { // ESP32-C3 +#ifdef CONFIG_IDF_TARGET_ESP32C3 +/* esptool: + def get_pkg_version(self): + num_word = 3 + block1_addr = self.EFUSE_BASE + 0x044 + word3 = self.read_reg(block1_addr + (4 * num_word)) + pkg_version = (word3 >> 21) & 0x0F + return pkg_version +*/ + uint32_t chip_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION); + uint32_t pkg_version = chip_ver & 0x7; +// uint32_t pkg_version = esp_efuse_get_pkg_ver(); + +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("HDW: ESP32 Model %d, Revision %d, Core %d, Package %d"), chip_info.model, chip_revision, chip_info.cores, chip_ver); + + switch (pkg_version) { + case 0: return F("ESP32-C3"); // Max 160MHz, Single core, QFN 5*5, ESP32-C3-WROOM-02, ESP32-C3-DevKitC-02 + case 1: return F("ESP32-C3FH4"); // Max 160MHz, Single core, QFN 5*5, 4MB embedded flash, ESP32-C3-MINI-1, ESP32-C3-DevKitM-1 + } +#endif // CONFIG_IDF_TARGET_ESP32C3 + return F("ESP32-C3"); + } + else if (6 == chip_model) { // ESP32-S3(beta3) + return F("ESP32-S3"); + } + else if (7 == chip_model) { // ESP32-C6(beta) +#ifdef CONFIG_IDF_TARGET_ESP32C6 +/* esptool: + def get_pkg_version(self): + num_word = 3 + block1_addr = self.EFUSE_BASE + 0x044 + word3 = self.read_reg(block1_addr + (4 * num_word)) + pkg_version = (word3 >> 21) & 0x0F + return pkg_version +*/ + uint32_t chip_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION); + uint32_t pkg_version = chip_ver & 0x7; +// uint32_t pkg_version = esp_efuse_get_pkg_ver(); + +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("HDW: ESP32 Model %d, Revision %d, Core %d, Package %d"), chip_info.model, chip_revision, chip_info.cores, chip_ver); + + switch (pkg_version) { + case 0: return F("ESP32-C6"); + } +#endif // CONFIG_IDF_TARGET_ESP32C6 + return F("ESP32-C6"); + } + else if (10 == chip_model) { // ESP32-H2 +#ifdef CONFIG_IDF_TARGET_ESP32H2 +/* esptool: + def get_pkg_version(self): + num_word = 3 + block1_addr = self.EFUSE_BASE + 0x044 + word3 = self.read_reg(block1_addr + (4 * num_word)) + pkg_version = (word3 >> 21) & 0x0F + return pkg_version +*/ + uint32_t chip_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION); + uint32_t pkg_version = chip_ver & 0x7; +// uint32_t pkg_version = esp_efuse_get_pkg_ver(); + +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("HDW: ESP32 Model %d, Revision %d, Core %d, Package %d"), chip_info.model, chip_revision, chip_info.cores, chip_ver); + + switch (pkg_version) { + case 0: return F("ESP32-H2"); + } +#endif // CONFIG_IDF_TARGET_ESP32H2 + return F("ESP32-H2"); + } + return F("ESP32"); +} + +String my_GetDeviceHardwareRevision(void) { + // ESP32-S2 + // ESP32-D0WDQ6 rev.1 + // ESP32-C3 rev.2 + // ESP32-C3 rev.3 + String result = my_GetDeviceHardware(); // ESP32-C3 + + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + char revision[10] = { 0 }; + if (chip_info.revision) { + snprintf_P(revision, sizeof(revision), PSTR(" rev.%d"), chip_info.revision); + } + result += revision; // ESP32-C3 rev.3 + + return result; +} + +static void my_show_chip_info(void) { + #ifndef CHIP_FEATURE_IEEE802154 + #define CHIP_FEATURE_IEEE802154 BIT(6) //!< Chip has IEEE 802.15.4 + #endif + #ifndef CHIP_FEATURE_EMB_PSRAM + #define CHIP_FEATURE_EMB_PSRAM BIT(7) //!< Chip has embedded psram + #endif + + esp_chip_info_t my_info; + //Serial.println(""); + esp_chip_info(&my_info); +#if 0 + Serial.println("ESP Chip Info:"); + switch ((int)my_info.model) { + case (int)CHIP_ESP32: Serial.print("ESP32 "); break; + case 2: Serial.print("ESP32-S2 "); break; + case 9: Serial.print("ESP32-S3 "); break; + case 5: Serial.print("ESP32-C3 "); break; + case 6: Serial.print("ESP32-H2 "); break; + case 12: Serial.print("ESP32-C2 "); break; + default: Serial.print("(unknown) 0x"); Serial.print((int)my_info.model, HEX); Serial.print(" "); break; + } + Serial.print(" Rev "); + Serial.print(my_info.revision); + Serial.print(", "); + Serial.print(my_info.cores); + Serial.println(" cores."); + Serial.flush(); +#endif + + Serial.print("Chip feature flags: 0b"); + Serial.println(my_info.features, BIN); + if (my_info.features & CHIP_FEATURE_EMB_FLASH) Serial.println(" * 0b0000001 Chip has embedded FLASH memory"); + if (my_info.features & CHIP_FEATURE_WIFI_BGN) Serial.println(" * 0b0000010 Chip has 2.4GHz WiFi"); + if (my_info.features & CHIP_FEATURE_BLE) Serial.println(" * 0b0001000 Chip has Bluetooth LE"); + if (my_info.features & CHIP_FEATURE_BT) Serial.println(" * 0b0010000 Chip has Bluetooth Classic"); + if (my_info.features & CHIP_FEATURE_IEEE802154) Serial.println(" * 0b0100000 Chip has IEEE 802.15.4"); + if (my_info.features & CHIP_FEATURE_EMB_PSRAM) Serial.println(" * 0b1000000 Chip has embedded PSRAM"); + Serial.println(); +} + + +// see https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/ResetReason/ResetReason.ino +/* Print last reset reason of ESP32 +* ================================= +* Use either of the methods print_reset_reason +* or verbose_print_reset_reason to display the +* cause for the last reset of this device. +* +* Public Domain License. +* Author: +* Evandro Luis Copercini - 2017 +*/ +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) +#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 +#include +#elif CONFIG_IDF_TARGET_ESP32S2 +#include +#elif CONFIG_IDF_TARGET_ESP32C3 +#include +#elif CONFIG_IDF_TARGET_ESP32S3 +#include +#else +#error Target CONFIG_IDF_TARGET is not supported +#endif +#else // ESP32 Before IDF 4.0 +#include +#endif + +void my_print_reset_reason(int reason) +{ + Serial.print(reason); + switch (reason) + { + case 0 : Serial.print (" NA"); break; + case 1 : Serial.print (" POWERON_RESET");break; /**<1, Vbat power on reset*/ + case 3 : Serial.print (" SW_RESET");break; /**<3, Software reset digital core*/ + case 4 : Serial.print (" OWDT_RESET");break; /**<4, Legacy watch dog reset digital core*/ + case 5 : Serial.print (" DEEPSLEEP_RESET");break; /**<5, Deep Sleep reset digital core*/ + case 6 : Serial.print (" SDIO_RESET");break; /**<6, Reset by SLC module, reset digital core*/ + case 7 : Serial.print (" TG0WDT_SYS_RESET");break; /**<7, Timer Group0 Watch dog reset digital core*/ + case 8 : Serial.print (" TG1WDT_SYS_RESET");break; /**<8, Timer Group1 Watch dog reset digital core*/ + case 9 : Serial.print (" RTCWDT_SYS_RESET");break; /**<9, RTC Watch dog Reset digital core*/ + case 10 : Serial.print(" INTRUSION_RESET");break; /**<10, Instrusion tested to reset CPU*/ + case 11 : Serial.print(" TGWDT_CPU_RESET");break; /**<11, Time Group reset CPU*/ + case 12 : Serial.print(" SW_CPU_RESET");break; /**<12, Software reset CPU*/ + case 13 : Serial.print(" RTCWDT_CPU_RESET");break; /**<13, RTC Watch dog Reset CPU*/ + case 14 : Serial.print(" EXT_CPU_RESET");break; /**<14, for APP CPU, reseted by PRO CPU*/ + case 15 : Serial.print(" RTCWDT_BROWN_OUT_RESET");break; /**<15, Reset when the vdd voltage is not stable*/ + case 16 : Serial.print(" RTCWDT_RTC_RESET");break; /**<16, RTC Watch dog reset digital core and rtc module*/ + case 17 : Serial.print (" TG1WDT_CPU_RESET");break; /**<17, Time Group1 reset CPU*/ + case 18 : Serial.print (" SUPER_WDT_RESET");break; /**<18, super watchdog reset digital core and rtc module*/ + case 19 : Serial.print (" GLITCH_RTC_RESET");break; /**<19, glitch reset digital core and rtc module*/ + case 20 : Serial.print (" EFUSE_RESET");break; /**<20, efuse reset digital core*/ + case 21 : Serial.print (" USB_UART_CHIP_RESET");break; /**<21, usb uart reset digital core */ + case 22 : Serial.print (" USB_JTAG_CHIP_RESET");break; /**<22, usb jtag reset digital core */ + case 23 : Serial.print (" POWER_GLITCH_RESET");break; /**<23, power glitch reset digital core and rtc module*/ + default : Serial.print (" NO_MEAN"); + } +} +void my_verbose_print_reset_reason(int reason) +{ + switch (reason) + { + case 0 : Serial.print ("none"); break; + case 1 : Serial.print ("Vbat power on reset");break; + case 3 : Serial.print ("Software reset digital core");break; + case 4 : Serial.print ("Legacy watch dog reset digital core");break; + case 5 : Serial.print ("Deep Sleep reset digital core");break; + case 6 : Serial.print ("Reset by SLC module, reset digital core");break; + case 7 : Serial.print ("Timer Group0 Watch dog reset digital core");break; + case 8 : Serial.print ("Timer Group1 Watch dog reset digital core");break; + case 9 : Serial.print ("RTC Watch dog Reset digital core");break; + case 10 : Serial.print ("Instrusion tested to reset CPU");break; + case 11 : Serial.print ("Time Group reset CPU");break; + case 12 : Serial.print ("Software reset CPU");break; + case 13 : Serial.print ("RTC Watch dog Reset CPU");break; + case 14 : Serial.print ("APP CPU reset by PRO CPU");break; + case 15 : Serial.print ("Reset when the vdd voltage is not stable");break; + case 16 : Serial.print ("RTC Watch dog reset digital core and rtc module");break; + default : Serial.print ("other "); Serial.print(reason); + } +} + + +/* + * parts below were created by softhack007, licended under GPL v3.0 + */ + +void show_psram_info_part1(void) +{ +#if defined(BOARD_HAS_PSRAM) || defined(WLED_USE_PSRAM) + //if (esp_spiram_is_initialized() == false) esp_spiram_init(); + Serial.println(psramFound() ? "ESP32 PSRAM: found.": "ESP32 PSRAM: not found!"); + if (!psramFound()) return; + psramInit(); + + // the next part only works on "classic" ESP32 + #if !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) + #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) + esp_spiram_size_t my_psram_size; + if (esp_spiram_is_initialized() == false) esp_spiram_init(); + my_psram_size = esp_spiram_get_chip_size(); + switch (my_psram_size) { + case ESP_SPIRAM_SIZE_16MBITS: Serial.println("* SPI RAM Chip availeable: 16MBits = 2MBytes"); break; + case ESP_SPIRAM_SIZE_32MBITS: Serial.println("* SPI RAM Chip availeable: 32MBits = 4MBytes"); break; + case ESP_SPIRAM_SIZE_64MBITS: Serial.println("* SPI RAM Chip availeable: 64MBits = 8MBytes"); break; + case ESP_SPIRAM_SIZE_INVALID: Serial.println("* SPI RAM size is invalid"); break; + default: Serial.print("* ?SPI RAM size is unknown (0x"); Serial.print(my_psram_size, HEX); Serial.println(")"); break; + } + #endif + #endif +#endif +} + +void show_psram_info_part2(void) +{ +#if defined(BOARD_HAS_PSRAM) || defined(WLED_USE_PSRAM) + if (!psramFound()) return; + + // usually the next part won't work ... + #ifdef PSRAM_MODE + switch (PSRAM_MODE) { + case PSRAM_VADDR_MODE_NORMAL: Serial.println("* PSRAM mode = PSRAM_VADDR_MODE_NORMAL"); break; + case PSRAM_VADDR_MODE_LOWHIGH: Serial.println("* PSRAM mode = SRAM_VADDR_MODE_LOWHIGH"); break; + case PSRAM_VADDR_MODE_EVENODD: Serial.println("* PSRAM mode = PSRAM_VADDR_MODE_EVENODD"); break; + } + #endif + #ifdef PSRAM_SPEED + switch (PSRAM_SPEED) { + case PSRAM_CACHE_F40M_S40M: Serial.println("* PSRAM speed = PSRAM_CACHE_F40M_S40M -> speed=40 esptool_flash=40 (by config)"); break; + case PSRAM_CACHE_F80M_S40M: Serial.println("* PSRAM speed = PSRAM_CACHE_F80M_S40M -> speed=40 esptool_flash=80 (by config)"); break; + case PSRAM_CACHE_F80M_S80M: Serial.println("* PSRAM speed = PSRAM_CACHE_F80M_S80M -> speed=80 esptool_flash=80 (by config)"); break; + } + #endif + + // try to allocate PSRAM (one 640KB chunk so we can be sure it will not fit into DRAM) + void * buff2 = ps_malloc(640 * 1024); + uint8_t * buf = (uint8_t*)malloc(620 * 1024); + Serial.print("* PSRAM free after malloc / ps_malloc : "); Serial.print(ESP.getFreePsram() / 1024.0, 2); Serial.println(" KB (1.2MB allocated)"); + if (buff2 == NULL) + Serial.println("* can't allocate big memory with ps_malloc()"); + else { + Serial.println("* Can allocate big memory with ps_malloc()"); + free(buff2); + } + if (buf == NULL) + Serial.println("* can't allocate big memory with malloc()"); + else { + free(buf); + Serial.println("* Can allocate big memory with malloc()"); + } + +#endif +} + +void showRealSpeed() { + //Serial.begin(115200); + Serial.flush(); + Serial.println(F("\n====================================")); + Serial.print( F("Chip info for ")); Serial.println(ESP.getChipModel()); + Serial.print( F("SDK: ")); Serial.println(ESP.getSdkVersion()); + Serial.println(F("------------------------------------\n")); + + Serial.print(" XTAL FREQ: "); Serial.print(getXtalFrequencyMhz()); Serial.println(" MHz"); + Serial.print(" APB FREQ: "); Serial.print(getApbFrequency() / 1000000.0, 1); Serial.println(" MHz"); + Serial.print(" CPU FREQ: "); Serial.print(getCpuFrequencyMhz()); Serial.println(" MHz\n"); + + Serial.print("ESP32 DEVICE: "); Serial.print(my_GetDeviceHardwareRevision()); + Serial.print(F(", ")); Serial.print(ESP.getChipCores()); Serial.print(F(" core(s)")); + Serial.print(F(", ")); Serial.print(ESP.getCpuFreqMHz()); Serial.println(F("MHz.\n")); + my_show_chip_info(); + + Serial.print("FLASH CHIP FREQ (magic): "); Serial.print(ESP.getFlashChipSpeed()/1000000.0, 1); Serial.println(" MHz"); + Serial.print("FLASH SIZE (magic byte): "); Serial.print(ESP.getFlashChipSize() / (1024.0 * 1024), 2); Serial.println(" MB"); + Serial.print("FLASH MODE (magic byte): "); Serial.print(ESP.getFlashChipMode()); Serial.println(" ; 0=QIO, 1=QOUT, 2=DIO, 3=DOUT or other\n"); + + Serial.print("FLASH CHIP ID: 0x"); Serial.println(my_ESP_getFlashChipId(), HEX); + Serial.print("FLASH CHIP FREQ: "); Serial.print(my_ESP_getFlashChipSpeed() / 1000000.0, 1); Serial.println(" MHz"); + Serial.print("FLASH REAL SIZE: "); Serial.print(my_ESP_getFlashChipRealSize() / (1024.0 * 1024), 2); Serial.println(" MB"); + Serial.print("FLASH REAL MODE: "); Serial.println(my_ESP_getFlashChipMode()); + + Serial.println(F("\n------------------------------------")); + Serial.print( "RAM HEAP SIZE: "); Serial.print(ESP.getHeapSize() / 1024.0, 2); Serial.println(" KB"); + Serial.print( " FREE RAM: "); Serial.print(ESP.getFreeHeap() / 1024.0, 2); Serial.println(" KB"); + Serial.print( " MAX RAM alloc: "); Serial.print(ESP.getMaxAllocHeap() / 1024.0, 2); Serial.println(" KB"); + +#if defined(BOARD_HAS_PSRAM) || defined(WLED_USE_PSRAM) + Serial.println(); + show_psram_info_part1(); + if (psramFound()) { + Serial.print(" total PSRAM: "); Serial.print(ESP.getPsramSize() / 1024.0, 0); Serial.println(" KB"); + Serial.print(" FREE PSRAM: "); Serial.print(ESP.getFreePsram() / 1024.0, 2); Serial.println(" KB"); + Serial.print(" MAX PSRAM alloc:"); Serial.print(ESP.getMaxAllocPsram() / 1024.0, 2); Serial.println(" KB"); + Serial.print(" used PSRAM: "); Serial.print(ESP.getPsramSize() - ESP.getFreePsram()); Serial.println(" Bytes"); + Serial.println(); + show_psram_info_part2(); + } +#endif + + Serial.println(); + Serial.print("CPU #0 - last reset reason = "); + my_print_reset_reason(rtc_get_reset_reason(0)); Serial.print("\t => "); + my_verbose_print_reset_reason(rtc_get_reset_reason(0)); + Serial.println(); + if (ESP.getChipCores() > 1) { + Serial.print("CPU #1 - last reset reason = "); + my_print_reset_reason(rtc_get_reset_reason(1));Serial.print("\t => "); + my_verbose_print_reset_reason(rtc_get_reset_reason(1)); + Serial.println(); + } + + Serial.println(F("====================================\n")); + Serial.flush(); +} diff --git a/wled00/wled.cpp b/wled00/wled.cpp index c9f590fb..97390281 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -8,6 +8,10 @@ #include "soc/rtc_cntl_reg.h" #endif +#if defined(WLED_DEBUG) && defined(ARDUINO_ARCH_ESP32) +#include "../tools/ESP32-Chip_info.hpp" +#endif + /* * Main WLED class implementation. Mostly initialization and connection logic */ @@ -188,10 +192,13 @@ void WLED::loop() DEBUG_PRINT(F("Free heap: ")); DEBUG_PRINTLN(ESP.getFreeHeap()); #if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM) if (psramFound()) { - DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB"); - DEBUG_PRINT(F("Free PSRAM: ")); DEBUG_PRINT(ESP.getFreePsram()/1024); DEBUG_PRINTLN("kB"); - } else - DEBUG_PRINTLN(F("No PSRAM")); + //DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB"); + DEBUG_PRINT(F("Free PSRAM: ")); DEBUG_PRINT(ESP.getFreePsram()/1024); DEBUG_PRINTLN("kB"); + DEBUG_PRINT(F("PSRAM in use:")); DEBUG_PRINT(ESP.getPsramSize() - ESP.getFreePsram()); DEBUG_PRINTLN(F(" Bytes")); + + } else { + //DEBUG_PRINTLN(F("No PSRAM")); + } #endif DEBUG_PRINT(F("Wifi state: ")); DEBUG_PRINTLN(WiFi.status()); @@ -274,6 +281,10 @@ void WLED::setup() #ifdef ARDUINO_ARCH_ESP32 DEBUG_PRINT(F("esp32 ")); DEBUG_PRINTLN(ESP.getSdkVersion()); + + #if defined(WLED_DEBUG) && defined(ARDUINO_ARCH_ESP32) + showRealSpeed(); + #endif #else DEBUG_PRINT(F("esp8266 ")); DEBUG_PRINTLN(ESP.getCoreVersion());