Skip to content

Commit

Permalink
[Sysinfo] Add functions to compute runtime ABP and flash frequency
Browse files Browse the repository at this point in the history
  • Loading branch information
TD-er committed Aug 22, 2022
1 parent 474c2e1 commit 85738a7
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 66 deletions.
167 changes: 138 additions & 29 deletions src/src/Helpers/Hardware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#ifdef ESP32
# include <soc/soc.h>
# include <soc/efuse_reg.h>
# include <soc/spi_reg.h>
# include <soc/rtc.h>

# if ESP_IDF_VERSION_MAJOR > 3 // IDF 4+
# if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
Expand All @@ -40,9 +42,9 @@
# endif // if CONFIG_IDF_TARGET_ESP32
# else // ESP32 Before IDF 4.0
# include <rom/spi_flash.h>
# endif // if ESP_IDF_VERSION_MAJOR > 3
# endif // if ESP_IDF_VERSION_MAJOR > 3

#endif // ifdef ESP32
#endif // ifdef ESP32


#if FEATURE_SD
Expand Down Expand Up @@ -322,28 +324,29 @@ void I2CForceResetBus_swap_pins(uint8_t address) {
void I2CBegin(int8_t sda, int8_t scl, uint32_t clockFreq) {
#ifdef ESP32
uint32_t lastI2CClockSpeed = Wire.getClock();
#else
#else // ifdef ESP32
static uint32_t lastI2CClockSpeed = 0;
#endif
static int8_t last_sda = -1;
static int8_t last_scl = -1;
#endif // ifdef ESP32
static int8_t last_sda = -1;
static int8_t last_scl = -1;

if ((clockFreq == lastI2CClockSpeed) && (sda == last_sda) && (scl == last_scl)) {
// No need to change the clock speed.
return;
}
#ifdef ESP32

if ((sda != last_sda) || (scl != last_scl)) {
Wire.end();
}
#endif
#endif // ifdef ESP32
lastI2CClockSpeed = clockFreq;
last_scl = scl;
last_sda = sda;

#ifdef ESP32
Wire.begin(sda, scl, clockFreq); // Will only set the clock when not yet initialized.
Wire.setClock(clockFreq);
Wire.setClock(clockFreq);
#else // ifdef ESP32
Wire.begin(sda, scl);
Wire.setClock(clockFreq);
Expand Down Expand Up @@ -505,8 +508,10 @@ void initADC() {
# define DEFAULT_VREF 1100
# endif // ifndef DEFAULT_VREF
const adc_bits_width_t adc_bit_width = static_cast<adc_bits_width_t>(ADC_WIDTH_MAX - 1);

for (size_t atten = 0; atten < ADC_ATTEN_MAX; ++atten) {
adc1_calibration_type = esp_adc_cal_characterize(ADC_UNIT_1, static_cast<adc_atten_t>(atten), adc_bit_width, DEFAULT_VREF, &adc_chars[atten]);
adc1_calibration_type =
esp_adc_cal_characterize(ADC_UNIT_1, static_cast<adc_atten_t>(atten), adc_bit_width, DEFAULT_VREF, &adc_chars[atten]);
}
}

Expand Down Expand Up @@ -615,8 +620,111 @@ uint32_t getFlashRealSizeInBytes() {
return res;
}

#ifdef ESP32
uint32_t getAbpFrequency() {
# if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
return APB_CLK_FREQ;
# else // if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
rtc_cpu_freq_config_t conf;

// Get current CPU clock configuration
rtc_clk_cpu_freq_get_config(&conf);

/*
// Debug code
String log = F("getAbpFrequency: source = ");
log += conf.source;
log += F(" source_freq_mhz = ");
log += conf.source_freq_mhz;
log += F(" div = ");
log += conf.div;
log += F(" freq_mhz = ");
log += conf.freq_mhz;
addLog(LOG_LEVEL_INFO, log);
*/

if (conf.freq_mhz >= 80) {
return 80 * 1000000;
}
return (conf.source_freq_mhz * 1000000) / conf.div;
# endif // if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
}

#endif // ifdef ESP32


uint32_t getFlashChipSpeed() {
#ifdef ESP8266
return ESP.getFlashChipSpeed();
#else // ifdef ESP8266
const uint32_t spi_clock = REG_READ(SPI_CLOCK_REG(0));


if (spi_clock & BIT(31)) {
// spi_clk is equal to system clock
return getAbpFrequency();
}

/* SPI_CLKCNT_N : R/W ;bitpos:[17:12] ;default: 6'h3 ; */

// description: In the master mode it is the divider of spi_clk.
// So spi_clk frequencyis system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1)
const uint32_t spi_clkdiv_pre = (spi_clock >> 18) & 0x1FFF;
const uint32_t spi_clkcnt_n = (spi_clock >> 12) & 0x3F;

/*
// Debug code
const uint32_t spi_clkcnt_h = (spi_clock >> 6) & 0x3F;
const uint32_t spi_clkcnt_l = (spi_clock) & 0x3F;
String log = F("Flash freq: APB_CLK_FREQ = ");
log += getAbpFrequency();
log += F(" spi_clkdiv_pre = ");
log += spi_clkdiv_pre;
log += F(" spi_clkcnt_n = ");
log += spi_clkcnt_n;
log += F(" spi_clkcnt_h = ");
log += spi_clkcnt_h;
log += F(" spi_clkcnt_l = ");
log += spi_clkcnt_l;
addLog(LOG_LEVEL_INFO, log);
*/

return (getAbpFrequency() / (spi_clkdiv_pre + 1)) / (spi_clkcnt_n + 1);
#endif // ifdef ESP8266
}

const __FlashStringHelper* getFlashChipMode() {
#ifdef ESP8266

switch (ESP.getFlashChipMode()) {
case FM_QIO: return F("QIO");
case FM_QOUT: return F("QOUT");
case FM_DIO: return F("DIO");
case FM_DOUT: return F("DOUT");
}
return F("Unknown");
#else // ifdef ESP8266

// Source: https://github.com/letscontrolit/ESPEasy/pull/4200#issuecomment-1221607332
const uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));

/* 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");
#endif // ifdef ESP8266
}

bool puyaSupport() {
Expand Down Expand Up @@ -745,27 +853,27 @@ const __FlashStringHelper* getChipModel() {
switch (pkg_version) {
case EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ6:

if (single_core) { return F("ESP32-S0WDQ6"); } // Max 240MHz, Single core, QFN 6*6
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
else { return F("ESP32-D0WDQ6"); } // Max 240MHz, Dual core, QFN 6*6
case EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ5:

if (single_core) { return F("ESP32-S0WD"); } // Max 160MHz, Single core, QFN 5*5, ESP32-SOLO-1, ESP32-DevKitC
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-D0WDQ5-V3"); } // Max 240MHz, Dual core, QFN 5*5, ESP32-WROOM-32E, ESP32_WROVER-E, ESP32-DevKitC
else { return F("ESP32-D0WDQ5"); } // Max 240MHz, Dual core, QFN 5*5, ESP32-WROOM-32D, ESP32_WROVER-B, ESP32-DevKitC
else { return F("ESP32-D0WDQ5"); } // Max 240MHz, Dual core, QFN 5*5, ESP32-WROOM-32D, ESP32_WROVER-B, ESP32-DevKitC
case EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5:
return F("ESP32-D2WDQ5"); // Max 160MHz, Dual core, QFN 5*5, 2MB embedded flash
return F("ESP32-D2WDQ5"); // 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 EFUSE_RD_CHIP_VER_PKG_ESP32U4WDH:
return F("ESP32-U4WDH"); // Max 160MHz, Single core, QFN 5*5, 4MB embedded flash, ESP32-MINI-1,
// ESP32-DevKitM-1
// ESP32-DevKitM-1
case EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4:

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
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 EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302:
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
Expand Down Expand Up @@ -794,9 +902,9 @@ const __FlashStringHelper* getChipModel() {

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
// 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
// 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
Expand Down Expand Up @@ -890,7 +998,7 @@ const __FlashStringHelper* getChipModel() {
return F("ESP32");
#elif defined(ESP8266)
return isESP8285() ? F("ESP8285") : F("ESP8266");
#endif
#endif // ifdef ESP32
return F("Unknown");
}

Expand All @@ -903,13 +1011,13 @@ bool isESP8285() {
READ_PERI_REG(0x3ff0005c)
};

return (
(efuse_blocks[0] & (1 << 4))
|| (efuse_blocks[2] & (1 << 16))
);
#else
return
(efuse_blocks[0] & (1 << 4))
|| (efuse_blocks[2] & (1 << 16))
;
#else // ifdef ESP8266
return false;
#endif
#endif // ifdef ESP8266
}

uint8_t getChipRevision() {
Expand Down Expand Up @@ -1099,7 +1207,7 @@ void readBootCause() {
case TG1WDT_CPU_RESET: lastBootCause = BOOT_CAUSE_EXT_WD; break;
case SUPER_WDT_RESET: lastBootCause = BOOT_CAUSE_EXT_WD; break;
case GLITCH_RTC_RESET: lastBootCause = BOOT_CAUSE_POWER_UNSTABLE; break; // FIXME TD-er: Does this need a different reason?
case EFUSE_RESET: break; // FIXME TD-er: No idea what may cause this reset reason.
case EFUSE_RESET: break; // FIXME TD-er: No idea what may cause this reset reason.
# endif // ifdef ESP32S2
}
}
Expand Down Expand Up @@ -1483,7 +1591,7 @@ bool getGpioInfo(int gpio, int& pinnr, bool& input, bool& output, bool& warning)

# endif // if FEATURE_ETHERNET

# endif // ifdef ESP32S2
# endif // ifdef ESP32S2

if (UsePSRAM()) {
// PSRAM can use GPIO 16 and 17
Expand Down Expand Up @@ -1581,7 +1689,8 @@ bool getGpioInfo(int gpio, int& pinnr, bool& input, bool& output, bool& warning)
}
} else {
warning = true;
// On ESP8266 GPIO 9 & 10 are only usable if not connected to flash

// On ESP8266 GPIO 9 & 10 are only usable if not connected to flash
if (gpio == 9) {
// GPIO9 is internally used to control the flash memory.
input = false;
Expand Down
30 changes: 18 additions & 12 deletions src/src/Helpers/Hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@
// Needed to get ADC Vref
# include <esp_adc_cal.h>
# include <driver/adc.h>
#endif
#endif // ifdef ESP32

# ifdef ESP32
# if CONFIG_IDF_TARGET_ESP32
#define MAX_ADC_VALUE 4095
# else // if CONFIG_IDF_TARGET_ESP32
#define MAX_ADC_VALUE ((1 << SOC_ADC_MAX_BITWIDTH) - 1)
# endif // if CONFIG_IDF_TARGET_ESP32
# endif // ifdef ESP32
# ifdef ESP8266
#define MAX_ADC_VALUE 1023
# endif // ifdef ESP8266
#ifdef ESP32
# if CONFIG_IDF_TARGET_ESP32
# define MAX_ADC_VALUE 4095
# else // if CONFIG_IDF_TARGET_ESP32
# define MAX_ADC_VALUE ((1 << SOC_ADC_MAX_BITWIDTH) - 1)
# endif // if CONFIG_IDF_TARGET_ESP32
#endif // ifdef ESP32
#ifdef ESP8266
# define MAX_ADC_VALUE 1023
#endif // ifdef ESP8266


/********************************************************************************************\
Expand Down Expand Up @@ -75,7 +75,7 @@ int espeasy_analogRead(int pin);
#endif // ifdef ESP8266

#ifdef ESP32
void initADC();
void initADC();

bool hasADC_factory_calibration();
const __FlashStringHelper* getADC_factory_calibration_type();
Expand All @@ -99,6 +99,12 @@ uint32_t getFlashRealSizeInBytes();

uint32_t getFlashChipSpeed();

#ifdef ESP32
uint32_t getAbpFrequency();
#endif // ifdef ESP32

const __FlashStringHelper* getFlashChipMode();

bool puyaSupport();

uint8_t getFlashChipVendorId();
Expand Down
8 changes: 7 additions & 1 deletion src/src/Helpers/StringProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ const __FlashStringHelper * getLabel(LabelType::Enum label) {

case LabelType::ESP_CHIP_ID: return F("ESP Chip ID");
case LabelType::ESP_CHIP_FREQ: return F("ESP Chip Frequency");
#ifdef ESP32
case LabelType::ESP_CHIP_ABP_FREQ: return F("ESP ABP Frequency");
#endif
case LabelType::ESP_CHIP_MODEL: return F("ESP Chip Model");
case LabelType::ESP_CHIP_REVISION: return F("ESP Chip Revision");
case LabelType::ESP_CHIP_CORES: return F("ESP Chip Cores");
Expand Down Expand Up @@ -386,6 +389,9 @@ String getValue(LabelType::Enum label) {

case LabelType::ESP_CHIP_ID: return formatToHex(getChipId(), 6);
case LabelType::ESP_CHIP_FREQ: return String(ESP.getCpuFreqMHz());
#ifdef ESP32
case LabelType::ESP_CHIP_ABP_FREQ: return String(getApbFrequency() / 1000000);
#endif
case LabelType::ESP_CHIP_MODEL: return getChipModel();
case LabelType::ESP_CHIP_REVISION: return String(getChipRevision());
case LabelType::ESP_CHIP_CORES: return String(getChipCores());
Expand All @@ -402,7 +408,7 @@ String getValue(LabelType::Enum label) {
case LabelType::FLASH_CHIP_SPEED: return String(getFlashChipSpeed() / 1000000);
case LabelType::FLASH_IDE_SIZE: break;
case LabelType::FLASH_IDE_SPEED: break;
case LabelType::FLASH_IDE_MODE: break;
case LabelType::FLASH_IDE_MODE: return getFlashChipMode();
case LabelType::FLASH_WRITE_COUNT: break;
case LabelType::SKETCH_SIZE: break;
case LabelType::SKETCH_FREE: break;
Expand Down
3 changes: 3 additions & 0 deletions src/src/Helpers/StringProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ struct LabelType {

ESP_CHIP_ID,
ESP_CHIP_FREQ,
#ifdef ESP32
ESP_CHIP_ABP_FREQ,
#endif
ESP_CHIP_MODEL,
ESP_CHIP_REVISION,
ESP_CHIP_CORES,
Expand Down
Loading

0 comments on commit 85738a7

Please sign in to comment.