#include "esp_heap_caps.h" #include "esp_chip_info.h" #include "esp_idf_version.h" #include "esp_arduino_version.h" #include "esp_rom_spiflash.h" #include "esp_flash.h" #include "esp_partition.h" #include "esp_app_format.h" #include "soc/efuse_reg.h" #include "soc/rtc.h" #include "soc/spi_reg.h" #if CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/spi_flash.h" #endif #include "esp_bit_defs.h" #include "Arduino.h" #include "esp32-hal-periman.h" #define chip_report_printf log_printf #define printMemCapsInfo(caps) _printMemCapsInfo(MALLOC_CAP_##caps, #caps) #define b2kb(b) ((float)b / 1024.0) #define b2mb(b) ((float)b / (1024.0 * 1024.0)) static void _printMemCapsInfo(uint32_t caps, const char *caps_str) { multi_heap_info_t info; size_t total = heap_caps_get_total_size(caps); heap_caps_get_info(&info, caps); chip_report_printf("%s Memory Info:\n", caps_str); chip_report_printf("------------------------------------------\n"); chip_report_printf(" Total Size : %8u B (%6.1f KB)\n", total, b2kb(total)); chip_report_printf(" Free Bytes : %8u B (%6.1f KB)\n", info.total_free_bytes, b2kb(info.total_free_bytes)); chip_report_printf(" Allocated Bytes : %8u B (%6.1f KB)\n", info.total_allocated_bytes, b2kb(info.total_allocated_bytes)); chip_report_printf(" Minimum Free Bytes: %8u B (%6.1f KB)\n", info.minimum_free_bytes, b2kb(info.minimum_free_bytes)); chip_report_printf(" Largest Free Block: %8u B (%6.1f KB)\n", info.largest_free_block, b2kb(info.largest_free_block)); } static void printPkgVersion(void) { chip_report_printf(" Package : "); #if CONFIG_IDF_TARGET_ESP32 uint32_t pkg_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_PACKAGE); switch (pkg_ver) { case EFUSE_RD_CHIP_VER_PKG_ESP32D0WDR2V3: chip_report_printf("D0WD-R2-V3"); break; case EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ6: chip_report_printf("D0WD-Q6"); break; case EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ5: chip_report_printf("D0WD-Q5"); break; case EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5: chip_report_printf("D2WD-Q5"); break; case EFUSE_RD_CHIP_VER_PKG_ESP32U4WDH: chip_report_printf("U4WD-H"); break; case EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4: chip_report_printf("PICO-D4"); break; case EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302: chip_report_printf("PICO-V3-02"); break; } #elif CONFIG_IDF_TARGET_ESP32S2 uint32_t pkg_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION); switch (pkg_ver) { case 1: chip_report_printf("FH16"); break; case 2: chip_report_printf("FH32"); break; default: chip_report_printf("%lu", pkg_ver); break; } #elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 uint32_t pkg_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION); chip_report_printf("%lu", pkg_ver); #elif CONFIG_IDF_TARGET_ESP32C2 uint32_t pkg_ver = REG_GET_FIELD(EFUSE_RD_BLK2_DATA1_REG, EFUSE_PKG_VERSION); chip_report_printf("%lu", pkg_ver); #elif CONFIG_IDF_TARGET_ESP32H2 uint32_t pkg_ver = REG_GET_FIELD(EFUSE_RD_MAC_SYS_4_REG, EFUSE_PKG_VERSION); chip_report_printf("%lu", pkg_ver); #elif CONFIG_IDF_TARGET_ESP32P4 uint32_t pkg_ver = REG_GET_FIELD(EFUSE_RD_MAC_SYS_2_REG, EFUSE_PKG_VERSION); chip_report_printf("%lu", pkg_ver); #else chip_report_printf("Unknown"); #endif chip_report_printf("\n"); } static void printChipInfo(void) { esp_chip_info_t info; esp_chip_info(&info); chip_report_printf("Chip Info:\n"); chip_report_printf("------------------------------------------\n"); chip_report_printf(" Model : "); switch (info.model) { case CHIP_ESP32: chip_report_printf("ESP32\n"); break; case CHIP_ESP32S2: chip_report_printf("ESP32-S2\n"); break; case CHIP_ESP32S3: chip_report_printf("ESP32-S3\n"); break; case CHIP_ESP32C2: chip_report_printf("ESP32-C2\n"); break; case CHIP_ESP32C3: chip_report_printf("ESP32-C3\n"); break; case CHIP_ESP32C6: chip_report_printf("ESP32-C6\n"); break; case CHIP_ESP32H2: chip_report_printf("ESP32-H2\n"); break; case CHIP_ESP32P4: chip_report_printf("ESP32-P4\n"); break; default: chip_report_printf("Unknown %d\n", info.model); break; } printPkgVersion(); chip_report_printf(" Revision : %.2f\n", (float)(info.revision) / 100.0); chip_report_printf(" Cores : %d\n", info.cores); rtc_cpu_freq_config_t conf; rtc_clk_cpu_freq_get_config(&conf); chip_report_printf(" CPU Frequency : %lu MHz\n", conf.freq_mhz); chip_report_printf(" XTAL Frequency : %d MHz\n", rtc_clk_xtal_freq_get()); chip_report_printf(" Features Bitfield : %#010x\n", info.features); chip_report_printf(" Embedded Flash : %s\n", (info.features & CHIP_FEATURE_EMB_FLASH) ? "Yes" : "No"); chip_report_printf(" Embedded PSRAM : %s\n", (info.features & CHIP_FEATURE_EMB_PSRAM) ? "Yes" : "No"); chip_report_printf(" 2.4GHz WiFi : %s\n", (info.features & CHIP_FEATURE_WIFI_BGN) ? "Yes" : "No"); chip_report_printf(" Classic BT : %s\n", (info.features & CHIP_FEATURE_BT) ? "Yes" : "No"); chip_report_printf(" BT Low Energy : %s\n", (info.features & CHIP_FEATURE_BLE) ? "Yes" : "No"); chip_report_printf(" IEEE 802.15.4 : %s\n", (info.features & CHIP_FEATURE_IEEE802154) ? "Yes" : "No"); } static void printFlashInfo(void) { #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 #define ESP_FLASH_IMAGE_BASE 0x1000 #elif CONFIG_IDF_TARGET_ESP32P4 #define ESP_FLASH_IMAGE_BASE 0x2000 #else #define ESP_FLASH_IMAGE_BASE 0x0000 #endif // REG_SPI_BASE is not defined for S3/C3 ?? #if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 #ifdef REG_SPI_BASE #undef REG_SPI_BASE #endif // REG_SPI_BASE #define REG_SPI_BASE(i) (DR_REG_SPI1_BASE + (((i) > 1) ? (((i) * 0x1000) + 0x20000) : (((~(i)) & 1) * 0x1000))) #endif // TARGET chip_report_printf("Flash Info:\n"); chip_report_printf("------------------------------------------\n"); uint32_t hw_size = 1 << (g_rom_flashchip.device_id & 0xFF); chip_report_printf(" Chip Size : %8lu B (%.0f MB)\n", hw_size, b2mb(hw_size)); chip_report_printf(" Block Size : %8lu B (%6.1f KB)\n", g_rom_flashchip.block_size, b2kb(g_rom_flashchip.block_size)); chip_report_printf(" Sector Size : %8lu B (%6.1f KB)\n", g_rom_flashchip.sector_size, b2kb(g_rom_flashchip.sector_size)); chip_report_printf(" Page Size : %8lu B (%6.1f KB)\n", g_rom_flashchip.page_size, b2kb(g_rom_flashchip.page_size)); esp_image_header_t fhdr; esp_flash_read(esp_flash_default_chip, (void *)&fhdr, ESP_FLASH_IMAGE_BASE, sizeof(esp_image_header_t)); if (fhdr.magic == ESP_IMAGE_HEADER_MAGIC) { uint32_t f_freq = 0; switch (fhdr.spi_speed) { #if CONFIG_IDF_TARGET_ESP32H2 case 0x0: f_freq = 32; break; case 0x2: f_freq = 16; break; case 0xf: f_freq = 64; break; #else case 0x0: f_freq = 40; break; case 0x1: f_freq = 26; break; case 0x2: f_freq = 20; break; case 0xf: f_freq = 80; break; #endif default: f_freq = fhdr.spi_speed; break; } chip_report_printf(" Bus Speed : %lu MHz\n", f_freq); } chip_report_printf(" Bus Mode : "); #if CONFIG_ESPTOOLPY_OCT_FLASH chip_report_printf("OPI\n"); #elif CONFIG_ESPTOOLPY_FLASHMODE_QIO chip_report_printf("QIO\n"); #elif CONFIG_ESPTOOLPY_FLASHMODE_QOUT chip_report_printf("QOUT\n"); #elif CONFIG_ESPTOOLPY_FLASHMODE_DIO chip_report_printf("DIO\n"); #elif CONFIG_ESPTOOLPY_FLASHMODE_DOUT chip_report_printf("DOUT\n"); #endif } static void printPartitionsInfo(void) { chip_report_printf("Partitions Info:\n"); chip_report_printf("------------------------------------------\n"); esp_partition_iterator_t iterator = esp_partition_find(ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, NULL); if (iterator != NULL) { esp_partition_iterator_t it = iterator; while (it != NULL) { const esp_partition_t *partition = esp_partition_get(it); if (partition) { chip_report_printf(" %17s : addr: 0x%08X, size: %7.1f KB", partition->label, partition->address, b2kb(partition->size)); if (partition->type == ESP_PARTITION_TYPE_APP) { chip_report_printf(", type: APP"); if (partition->subtype == 0) { chip_report_printf(", subtype: FACTORY"); } else if (partition->subtype >= 0x10 && partition->subtype < 0x20) { chip_report_printf(", subtype: OTA_%lu", partition->subtype - 0x10); } else if (partition->subtype == 0x20) { chip_report_printf(", subtype: TEST"); } else { chip_report_printf(", subtype: 0x%02X", partition->subtype); } } else { chip_report_printf(", type: DATA"); chip_report_printf(", subtype: "); switch (partition->subtype) { case ESP_PARTITION_SUBTYPE_DATA_OTA: chip_report_printf("OTA"); break; case ESP_PARTITION_SUBTYPE_DATA_PHY: chip_report_printf("PHY"); break; case ESP_PARTITION_SUBTYPE_DATA_NVS: chip_report_printf("NVS"); break; case ESP_PARTITION_SUBTYPE_DATA_COREDUMP: chip_report_printf("COREDUMP"); break; case ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS: chip_report_printf("NVS_KEYS"); break; case ESP_PARTITION_SUBTYPE_DATA_EFUSE_EM: chip_report_printf("EFUSE_EM"); break; case ESP_PARTITION_SUBTYPE_DATA_UNDEFINED: chip_report_printf("UNDEFINED"); break; case ESP_PARTITION_SUBTYPE_DATA_ESPHTTPD: chip_report_printf("ESPHTTPD"); break; case ESP_PARTITION_SUBTYPE_DATA_FAT: chip_report_printf("FAT"); break; case ESP_PARTITION_SUBTYPE_DATA_SPIFFS: chip_report_printf("SPIFFS"); break; case ESP_PARTITION_SUBTYPE_DATA_LITTLEFS: chip_report_printf("LITTLEFS"); break; default: chip_report_printf("0x%02X", partition->subtype); break; } } chip_report_printf("\n"); } it = esp_partition_next(it); } //esp_partition_iterator_release(iterator); } } static void printSoftwareInfo(void) { chip_report_printf("Software Info:\n"); chip_report_printf("------------------------------------------\n"); chip_report_printf(" Compile Date/Time : %s %s\n", __DATE__, __TIME__); #ifdef ARDUINO_HOST_OS chip_report_printf(" Compile Host OS : %s\n", ARDUINO_HOST_OS); #endif chip_report_printf(" ESP-IDF Version : %s\n", esp_get_idf_version()); chip_report_printf(" Arduino Version : %s\n", ESP_ARDUINO_VERSION_STR); } static void printBoardInfo(void) { chip_report_printf("Board Info:\n"); chip_report_printf("------------------------------------------\n"); chip_report_printf(" Arduino Board : %s\n", ARDUINO_BOARD); chip_report_printf(" Arduino Variant : %s\n", ARDUINO_VARIANT); #ifdef ARDUINO_FQBN chip_report_printf(" Arduino FQBN : %s\n", ARDUINO_FQBN); #else #ifdef CORE_DEBUG_LEVEL chip_report_printf(" Core Debug Level : %d\n", CORE_DEBUG_LEVEL); #endif #ifdef ARDUINO_RUNNING_CORE chip_report_printf(" Arduino Runs Core : %d\n", ARDUINO_RUNNING_CORE); chip_report_printf(" Arduino Events on : %d\n", ARDUINO_EVENT_RUNNING_CORE); #endif #ifdef ARDUINO_USB_MODE chip_report_printf(" Arduino USB Mode : %d\n", ARDUINO_USB_MODE); #endif #ifdef ARDUINO_USB_CDC_ON_BOOT chip_report_printf(" CDC On Boot : %d\n", ARDUINO_USB_CDC_ON_BOOT); #endif #endif /* ARDUINO_FQBN */ } static void printPerimanInfo(void) { chip_report_printf("GPIO Info:\n"); chip_report_printf("------------------------------------------\n"); #if defined(BOARD_HAS_PIN_REMAP) chip_report_printf(" DPIN|GPIO : BUS_TYPE[bus/unit][chan]\n"); #else chip_report_printf(" GPIO : BUS_TYPE[bus/unit][chan]\n"); #endif chip_report_printf(" -------------------------------------- \n"); for (uint8_t i = 0; i < SOC_GPIO_PIN_COUNT; i++) { if (!perimanPinIsValid(i)) { continue; //invalid pin } peripheral_bus_type_t type = perimanGetPinBusType(i); if (type == ESP32_BUS_TYPE_INIT) { continue; //unused pin } #if defined(BOARD_HAS_PIN_REMAP) int dpin = gpioNumberToDigitalPin(i); if (dpin < 0) { continue; //pin is not exported } else { chip_report_printf(" D%-3d|%4u : ", dpin, i); } #else chip_report_printf(" %4u : ", i); #endif const char *extra_type = perimanGetPinBusExtraType(i); if (extra_type) { chip_report_printf("%s", extra_type); } else { chip_report_printf("%s", perimanGetTypeName(type)); } int8_t bus_number = perimanGetPinBusNum(i); if (bus_number != -1) { chip_report_printf("[%u]", bus_number); } int8_t bus_channel = perimanGetPinBusChannel(i); if (bus_channel != -1) { chip_report_printf("[%u]", bus_channel); } chip_report_printf("\n"); } } void printBeforeSetupInfo(void) { #if ARDUINO_USB_CDC_ON_BOOT Serial.begin(0); Serial.setDebugOutput(true); uint8_t t = 0; while (!Serial && (t++ < 200)) { delay(10); //wait up to 2 seconds for the IDE to connect } #endif chip_report_printf("=========== Before Setup Start ===========\n"); printChipInfo(); chip_report_printf("------------------------------------------\n"); printMemCapsInfo(INTERNAL); chip_report_printf("------------------------------------------\n"); if (psramFound()) { printMemCapsInfo(SPIRAM); chip_report_printf(" Bus Mode : "); #if CONFIG_SPIRAM_MODE_OCT chip_report_printf("OPI\n"); #else chip_report_printf("QSPI\n"); #endif chip_report_printf("------------------------------------------\n"); } printFlashInfo(); chip_report_printf("------------------------------------------\n"); printPartitionsInfo(); chip_report_printf("------------------------------------------\n"); printSoftwareInfo(); chip_report_printf("------------------------------------------\n"); printBoardInfo(); chip_report_printf("============ Before Setup End ============\n"); delay(100); //allow the print to finish } void printAfterSetupInfo(void) { chip_report_printf("=========== After Setup Start ============\n"); printMemCapsInfo(INTERNAL); chip_report_printf("------------------------------------------\n"); if (psramFound()) { printMemCapsInfo(SPIRAM); chip_report_printf("------------------------------------------\n"); } printPerimanInfo(); chip_report_printf("============ After Setup End =============\n"); delay(20); //allow the print to finish }