From f506da0544931210535abe865d1c0fff1dea95f5 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Tue, 28 Jun 2022 22:04:29 +0800 Subject: [PATCH] esptool: Adds major and minor chip revisions --- esptool/cmds.py | 8 +++++- esptool/targets/esp32.py | 47 +++++++++++++++++++-------------- esptool/targets/esp32c2.py | 23 ++++++++-------- esptool/targets/esp32c3.py | 30 +++++++++++---------- esptool/targets/esp32c6beta.py | 6 ++--- esptool/targets/esp32h2beta1.py | 30 +++++++++++---------- esptool/targets/esp32h2beta2.py | 6 ++--- esptool/targets/esp32s2.py | 39 ++++++++++++++------------- esptool/targets/esp32s3.py | 20 +++++++++++++- esptool/targets/esp32s3beta2.py | 4 ++- 10 files changed, 126 insertions(+), 87 deletions(-) diff --git a/esptool/cmds.py b/esptool/cmds.py index d6ac74d8e0..6fc8a5bf49 100644 --- a/esptool/cmds.py +++ b/esptool/cmds.py @@ -339,7 +339,13 @@ def write_flash(esp, args): f"{argfile.name} is not an {esp.CHIP_NAME} image. " "Use --force to flash anyway." ) - rev = esp.get_chip_revision() + # In IDF, image.min_rev is set based on Kconfig option. + # For C3 chip, image.min_rev is the Minor revision + # while for the rest chips it is the Major revision. + if esp.CHIP_NAME == "ESP32-C3": + rev = esp.get_minor_chip_version() + else: + rev = esp.get_major_chip_version() if rev < image.min_rev: raise FatalError( f"{argfile.name} requires chip revision " diff --git a/esptool/targets/esp32.py b/esptool/targets/esp32.py index b2f634fe08..ea7deb5ad2 100644 --- a/esptool/targets/esp32.py +++ b/esptool/targets/esp32.py @@ -48,6 +48,9 @@ class ESP32ROM(ESPLoader): EFUSE_RD_ABS_DONE_1_MASK = 1 << 5 DR_REG_SYSCON_BASE = 0x3FF66000 + APB_CTL_DATE_ADDR = DR_REG_SYSCON_BASE + 0x7C + APB_CTL_DATE_V = 0x1 + APB_CTL_DATE_S = 31 SPI_W0_OFFS = 0x80 @@ -165,7 +168,7 @@ def get_secure_boot_enabled(self): efuses = self.read_reg(self.EFUSE_RD_ABS_DONE_REG) rev = self.get_chip_revision() return efuses & self.EFUSE_RD_ABS_DONE_0_MASK or ( - rev >= 3 and efuses & self.EFUSE_RD_ABS_DONE_1_MASK + rev >= 300 and efuses & self.EFUSE_RD_ABS_DONE_1_MASK ) def get_pkg_version(self): @@ -175,27 +178,31 @@ def get_pkg_version(self): return pkg_version def get_chip_revision(self): - word3 = self.read_efuse(3) - word5 = self.read_efuse(5) - apb_ctl_date = self.read_reg(self.DR_REG_SYSCON_BASE + 0x7C) - - rev_bit0 = (word3 >> 15) & 0x1 - rev_bit1 = (word5 >> 20) & 0x1 - rev_bit2 = (apb_ctl_date >> 31) & 0x1 - if rev_bit0: - if rev_bit1: - if rev_bit2: - return 3 - else: - return 2 - else: - return 1 - return 0 + return self.get_major_chip_version() * 100 + self.get_minor_chip_version() + + def get_minor_chip_version(self): + return (self.read_efuse(5) >> 24) & 0x3 + + def get_major_chip_version(self): + rev_bit0 = (self.read_efuse(3) >> 15) & 0x1 + rev_bit1 = (self.read_efuse(5) >> 20) & 0x1 + apb_ctl_date = self.read_reg(self.APB_CTL_DATE_ADDR) + rev_bit2 = (apb_ctl_date >> self.APB_CTL_DATE_S) & self.APB_CTL_DATE_V + combine_value = (rev_bit2 << 2) | (rev_bit1 << 1) | rev_bit0 + + revision = { + 0: 0, + 1: 1, + 3: 2, + 7: 3, + }.get(combine_value, 0) + return revision def get_chip_description(self): pkg_version = self.get_pkg_version() - chip_revision = self.get_chip_revision() - rev3 = chip_revision == 3 + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + rev3 = major_rev == 3 single_core = self.read_efuse(3) & (1 << 0) # CHIP_VER DIS_APP_CPU chip_name = { @@ -212,7 +219,7 @@ def get_chip_description(self): if chip_name.startswith("ESP32-D0WD") and rev3: chip_name += "-V3" - return "%s (revision %d)" % (chip_name, chip_revision) + return f"{chip_name} (revision v{major_rev}.{minor_rev})" def get_chip_features(self): features = ["WiFi"] diff --git a/esptool/targets/esp32c2.py b/esptool/targets/esp32c2.py index e22aa1b311..c3b7a6a403 100644 --- a/esptool/targets/esp32c2.py +++ b/esptool/targets/esp32c2.py @@ -23,6 +23,7 @@ class ESP32C2ROM(ESP32C3ROM): CHIP_DETECT_MAGIC_VALUE = [0x6F51306F, 0x7C41A06F] EFUSE_BASE = 0x60008800 + EFUSE_BLOCK2_ADDR = EFUSE_BASE + 0x040 MAC_EFUSE_REG = EFUSE_BASE + 0x040 EFUSE_SECURE_BOOT_EN_REG = EFUSE_BASE + 0x30 @@ -62,26 +63,24 @@ class ESP32C2ROM(ESP32C3ROM): def get_pkg_version(self): num_word = 1 - block2_addr = self.EFUSE_BASE + 0x040 - word1 = self.read_reg(block2_addr + (4 * num_word)) - pkg_version = (word1 >> 22) & 0x07 - return pkg_version + return (self.read_reg(self.EFUSE_BLOCK2_ADDR + (4 * num_word)) >> 22) & 0x07 def get_chip_description(self): chip_name = { 0: "ESP32-C2", 1: "ESP32-C2", }.get(self.get_pkg_version(), "unknown ESP32-C2") - chip_revision = self.get_chip_revision() + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return f"{chip_name} (revision v{major_rev}.{minor_rev})" - return "%s (revision %d)" % (chip_name, chip_revision) + def get_minor_chip_version(self): + num_word = 1 + return (self.read_reg(self.EFUSE_BLOCK2_ADDR + (4 * num_word)) >> 16) & 0xF - def get_chip_revision(self): - res = self.check_command("get security info", self.ESP_GET_SECURITY_INFO, b"") - # Checks only the first two bytes of api_version to be 2/4 status - # bytes invariant (needed for --before no_reset, as the last two bytes can - # get discarded) - return int.from_bytes(res[16:17], "little") + def get_major_chip_version(self): + num_word = 1 + return (self.read_reg(self.EFUSE_BLOCK2_ADDR + (4 * num_word)) >> 20) & 0x3 def get_crystal_freq(self): # The crystal detection algorithm of ESP32/ESP8266 works for ESP32-C2 as well. diff --git a/esptool/targets/esp32c3.py b/esptool/targets/esp32c3.py index e79f5bba4c..33092c2549 100644 --- a/esptool/targets/esp32c3.py +++ b/esptool/targets/esp32c3.py @@ -38,6 +38,7 @@ class ESP32C3ROM(ESP32ROM): UART_CLKDIV_REG = 0x60000014 EFUSE_BASE = 0x60008800 + EFUSE_BLOCK1_ADDR = EFUSE_BASE + 0x044 MAC_EFUSE_REG = EFUSE_BASE + 0x044 EFUSE_RD_REG_BASE = EFUSE_BASE + 0x030 # BLOCK0 read base address @@ -86,25 +87,26 @@ class ESP32C3ROM(ESP32ROM): 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) & 0x07 - return pkg_version - - def get_chip_revision(self): - # reads WAFER_VERSION field from EFUSE_RD_MAC_SPI_SYS_3_REG - block1_addr = self.EFUSE_BASE + 0x044 - num_word = 3 - pos = 18 - return (self.read_reg(block1_addr + (4 * num_word)) & (0x7 << pos)) >> pos + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x07 + + def get_minor_chip_version(self): + hi_num_word = 5 + hi = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * hi_num_word)) >> 23) & 0x01 + low_num_word = 3 + low = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * low_num_word)) >> 18) & 0x07 + return (hi << 3) + low + + def get_major_chip_version(self): + num_word = 5 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 24) & 0x03 def get_chip_description(self): chip_name = { 0: "ESP32-C3", }.get(self.get_pkg_version(), "unknown ESP32-C3") - chip_revision = self.get_chip_revision() - - return "%s (revision %d)" % (chip_name, chip_revision) + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return f"{chip_name} (revision v{major_rev}.{minor_rev})" def get_chip_features(self): return ["WiFi", "BLE"] diff --git a/esptool/targets/esp32c6beta.py b/esptool/targets/esp32c6beta.py index 52132e6432..d30e7b010b 100644 --- a/esptool/targets/esp32c6beta.py +++ b/esptool/targets/esp32c6beta.py @@ -18,6 +18,6 @@ def get_chip_description(self): chip_name = { 0: "ESP32-C6", }.get(self.get_pkg_version(), "unknown ESP32-C6") - chip_revision = self.get_chip_revision() - - return "%s (revision %d)" % (chip_name, chip_revision) + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return f"{chip_name} (revision v{major_rev}.{minor_rev})" diff --git a/esptool/targets/esp32h2beta1.py b/esptool/targets/esp32h2beta1.py index 9d3c68dc39..529ba4c0a4 100644 --- a/esptool/targets/esp32h2beta1.py +++ b/esptool/targets/esp32h2beta1.py @@ -33,6 +33,7 @@ class ESP32H2BETA1ROM(ESP32ROM): UART_DATE_REG_ADDR = 0x60000000 + 0x7C EFUSE_BASE = 0x6001A000 + EFUSE_BLOCK1_ADDR = EFUSE_BASE + 0x044 MAC_EFUSE_REG = EFUSE_BASE + 0x044 EFUSE_RD_REG_BASE = EFUSE_BASE + 0x030 # BLOCK0 read base address @@ -70,25 +71,26 @@ class ESP32H2BETA1ROM(ESP32ROM): 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 - - def get_chip_revision(self): - # reads WAFER_VERSION field from EFUSE_RD_MAC_SPI_SYS_3_REG - block1_addr = self.EFUSE_BASE + 0x044 - num_word = 3 - pos = 18 - return (self.read_reg(block1_addr + (4 * num_word)) & (0x7 << pos)) >> pos + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x0F + + def get_minor_chip_version(self): + hi_num_word = 5 + hi = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * hi_num_word)) >> 23) & 0x01 + low_num_word = 3 + low = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * low_num_word)) >> 18) & 0x07 + return (hi << 3) + low + + def get_major_chip_version(self): + num_word = 5 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 24) & 0x03 def get_chip_description(self): chip_name = { 0: "ESP32-H2", }.get(self.get_pkg_version(), "unknown ESP32-H2") - chip_revision = self.get_chip_revision() - - return "%s (revision %d)" % (chip_name, chip_revision) + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return f"{chip_name} (revision v{major_rev}.{minor_rev})" def get_chip_features(self): return ["BLE/802.15.4"] diff --git a/esptool/targets/esp32h2beta2.py b/esptool/targets/esp32h2beta2.py index 8102eb5b2c..97a66a019e 100644 --- a/esptool/targets/esp32h2beta2.py +++ b/esptool/targets/esp32h2beta2.py @@ -16,9 +16,9 @@ def get_chip_description(self): chip_name = { 1: "ESP32-H2(beta2)", }.get(self.get_pkg_version(), "unknown ESP32-H2") - chip_revision = self.get_chip_revision() - - return "{} (revision {})".format(chip_name, chip_revision) + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return f"{chip_name} (revision v{major_rev}.{minor_rev})" class ESP32H2BETA2StubLoader(ESP32H2BETA2ROM): diff --git a/esptool/targets/esp32s2.py b/esptool/targets/esp32s2.py index e02f08c5d7..5bfefa6cf0 100644 --- a/esptool/targets/esp32s2.py +++ b/esptool/targets/esp32s2.py @@ -43,6 +43,8 @@ class ESP32S2ROM(ESP32ROM): # todo: use espefuse APIs to get this info EFUSE_BASE = 0x3F41A000 EFUSE_RD_REG_BASE = EFUSE_BASE + 0x030 # BLOCK0 read base address + EFUSE_BLOCK1_ADDR = EFUSE_BASE + 0x044 + EFUSE_BLOCK2_ADDR = EFUSE_BASE + 0x05C EFUSE_PURPOSE_KEY0_REG = EFUSE_BASE + 0x34 EFUSE_PURPOSE_KEY0_SHIFT = 24 @@ -97,31 +99,31 @@ class ESP32S2ROM(ESP32ROM): def get_pkg_version(self): num_word = 4 - block1_addr = self.EFUSE_BASE + 0x044 - word3 = self.read_reg(block1_addr + (4 * num_word)) - pkg_version = (word3 >> 0) & 0x0F - return pkg_version + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 0) & 0x0F + + def get_minor_chip_version(self): + hi_num_word = 3 + hi = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * hi_num_word)) >> 20) & 0x01 + low_num_word = 4 + low = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * low_num_word)) >> 4) & 0x07 + return (hi << 3) + low + + def get_major_chip_version(self): + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 18) & 0x03 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 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x0F 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 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 28) & 0x0F def get_block2_version(self): + # BLK_VERSION_MINOR num_word = 4 - block2_addr = self.EFUSE_BASE + 0x05C - word4 = self.read_reg(block2_addr + (4 * num_word)) - block2_version = (word4 >> 4) & 0x07 - return block2_version + return (self.read_reg(self.EFUSE_BLOCK2_ADDR + (4 * num_word)) >> 4) & 0x07 def get_chip_description(self): chip_name = { @@ -134,8 +136,9 @@ def get_chip_description(self): self.get_flash_version() + self.get_psram_version() * 100, "unknown ESP32-S2", ) - - return "%s" % (chip_name) + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return f"{chip_name} (revision v{major_rev}.{minor_rev})" def get_chip_features(self): features = ["WiFi"] diff --git a/esptool/targets/esp32s3.py b/esptool/targets/esp32s3.py index 22f6961e6b..1168427b23 100644 --- a/esptool/targets/esp32s3.py +++ b/esptool/targets/esp32s3.py @@ -43,6 +43,7 @@ class ESP32S3ROM(ESP32ROM): # todo: use espefuse APIs to get this info EFUSE_BASE = 0x60007000 # BLOCK0 read base address + EFUSE_BLOCK1_ADDR = EFUSE_BASE + 0x44 MAC_EFUSE_REG = EFUSE_BASE + 0x044 EFUSE_RD_REG_BASE = EFUSE_BASE + 0x030 # BLOCK0 read base address @@ -100,8 +101,25 @@ class ESP32S3ROM(ESP32ROM): [0x50000000, 0x50002000, "RTC_DATA"], ] + def get_pkg_version(self): + num_word = 3 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x07 + + def get_minor_chip_version(self): + hi_num_word = 5 + hi = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * hi_num_word)) >> 23) & 0x01 + low_num_word = 3 + low = (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * low_num_word)) >> 18) & 0x07 + return (hi << 3) + low + + def get_major_chip_version(self): + num_word = 5 + return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 24) & 0x03 + def get_chip_description(self): - return "ESP32-S3" + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return f"{self.CHIP_NAME} (revision v{major_rev}.{minor_rev})" def get_chip_features(self): return ["WiFi", "BLE"] diff --git a/esptool/targets/esp32s3beta2.py b/esptool/targets/esp32s3beta2.py index da53a6eefc..87c60dcce1 100644 --- a/esptool/targets/esp32s3beta2.py +++ b/esptool/targets/esp32s3beta2.py @@ -15,7 +15,9 @@ class ESP32S3BETA2ROM(ESP32S3ROM): EFUSE_BASE = 0x6001A000 # BLOCK0 read base address def get_chip_description(self): - return "ESP32-S3(beta2)" + major_rev = self.get_major_chip_version() + minor_rev = self.get_minor_chip_version() + return f"{self.CHIP_NAME} (revision v{major_rev}.{minor_rev})" class ESP32S3BETA2StubLoader(ESP32S3BETA2ROM):