Skip to content

Commit

Permalink
esptool: Adds major and minor chip revisions
Browse files Browse the repository at this point in the history
  • Loading branch information
KonstantinKondrashov authored and radimkarnis committed Sep 13, 2022
1 parent a194e8d commit f506da0
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 87 deletions.
8 changes: 7 additions & 1 deletion esptool/cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
Expand Down
47 changes: 27 additions & 20 deletions esptool/targets/esp32.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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):
Expand All @@ -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 = {
Expand All @@ -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"]
Expand Down
23 changes: 11 additions & 12 deletions esptool/targets/esp32c2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
30 changes: 16 additions & 14 deletions esptool/targets/esp32c3.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"]
Expand Down
6 changes: 3 additions & 3 deletions esptool/targets/esp32c6beta.py
Original file line number Diff line number Diff line change
Expand Up @@ -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})"
30 changes: 16 additions & 14 deletions esptool/targets/esp32h2beta1.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"]
Expand Down
6 changes: 3 additions & 3 deletions esptool/targets/esp32h2beta2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
39 changes: 21 additions & 18 deletions esptool/targets/esp32s2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 = {
Expand All @@ -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"]
Expand Down
20 changes: 19 additions & 1 deletion esptool/targets/esp32s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"]
Expand Down
4 changes: 3 additions & 1 deletion esptool/targets/esp32s3beta2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down

0 comments on commit f506da0

Please sign in to comment.