From 6393d6bc2dd66f84e9797d5135e211a02d5dc016 Mon Sep 17 00:00:00 2001 From: Peter Dragun Date: Fri, 16 Feb 2024 15:43:20 +0100 Subject: [PATCH] feat: print flash voltage in flash_id command Closes https://github.com/espressif/esptool/issues/224 --- docs/en/espefuse/set-flash-voltage-cmd.rst | 2 +- esptool/cmds.py | 1 + esptool/targets/esp32.py | 78 +++++++++++++++++----- esptool/targets/esp32c3.py | 3 + esptool/targets/esp32p4.py | 3 + esptool/targets/esp32s2.py | 9 +++ esptool/targets/esp32s3.py | 9 +++ esptool/targets/esp8266.py | 3 + 8 files changed, 92 insertions(+), 16 deletions(-) diff --git a/docs/en/espefuse/set-flash-voltage-cmd.rst b/docs/en/espefuse/set-flash-voltage-cmd.rst index 950cad4a1..6340858ca 100644 --- a/docs/en/espefuse/set-flash-voltage-cmd.rst +++ b/docs/en/espefuse/set-flash-voltage-cmd.rst @@ -15,7 +15,7 @@ Positional arguments: - ``voltage`` - Voltage selection ['1.8V', '3.3V', 'OFF']. -.. only:: esp32c2 or esp32c3 +.. only:: not esp32 and not esp32s2 and not esp32s3 .. note:: diff --git a/esptool/cmds.py b/esptool/cmds.py index beee92f79..52a09ef01 100644 --- a/esptool/cmds.py +++ b/esptool/cmds.py @@ -1108,6 +1108,7 @@ def flash_id(esp, args): flash_type_str = flash_type_dict.get(flash_type) if flash_type_str: print(f"Flash type set in eFuse: {flash_type_str}") + esp.get_flash_voltage() def read_flash(esp, args): diff --git a/esptool/targets/esp32.py b/esptool/targets/esp32.py index cd839da1a..2b2a2bbc4 100644 --- a/esptool/targets/esp32.py +++ b/esptool/targets/esp32.py @@ -5,6 +5,7 @@ import struct import time +from typing import Optional from ..loader import ESPLoader from ..util import FatalError, NotSupportedError @@ -49,6 +50,11 @@ class ESP32ROM(ESPLoader): EFUSE_RD_ABS_DONE_0_MASK = 1 << 4 EFUSE_RD_ABS_DONE_1_MASK = 1 << 5 + EFUSE_VDD_SPI_REG = EFUSE_RD_REG_BASE + 0x10 + VDD_SPI_XPD = 1 << 14 # XPD_SDIO_REG + VDD_SPI_TIEH = 1 << 15 # XPD_SDIO_TIEH + VDD_SPI_FORCE = 1 << 16 # XPD_SDIO_FORCE + DR_REG_SYSCON_BASE = 0x3FF66000 APB_CTL_DATE_ADDR = DR_REG_SYSCON_BASE + 0x7C APB_CTL_DATE_V = 0x1 @@ -64,6 +70,17 @@ class ESP32ROM(ESPLoader): TIMERS_RTC_CALI_VALUE = 0x01FFFFFF TIMERS_RTC_CALI_VALUE_S = 7 + GPIO_STRAP_REG = 0x3FF44038 + GPIO_STRAP_VDDSPI_MASK = 1 << 5 # GPIO_STRAP_VDDSDIO + + RTC_CNTL_SDIO_CONF_REG = 0x3FF48074 + RTC_CNTL_XPD_SDIO_REG = 1 << 31 + RTC_CNTL_DREFH_SDIO_M = 3 << 29 + RTC_CNTL_DREFM_SDIO_M = 3 << 27 + RTC_CNTL_DREFL_SDIO_M = 3 << 25 + RTC_CNTL_SDIO_FORCE = 1 << 22 + RTC_CNTL_SDIO_PD_EN = 1 << 21 + FLASH_SIZES = { "1MB": 0x00, "2MB": 0x10, @@ -315,32 +332,63 @@ def read_mac(self, mac_type="BASE_MAC"): def get_erase_size(self, offset, size): return size + def _get_efuse_flash_voltage(self) -> Optional[str]: + efuse = self.read_reg(self.EFUSE_VDD_SPI_REG) + # check efuse setting + if efuse & (self.VDD_SPI_FORCE | self.VDD_SPI_XPD | self.VDD_SPI_TIEH): + return "3.3V" + elif efuse & (self.VDD_SPI_FORCE | self.VDD_SPI_XPD): + return "1.8V" + elif efuse & self.VDD_SPI_FORCE: + return "OFF" + return None + + def _get_rtc_cntl_flash_voltage(self) -> Optional[str]: + reg = self.read_reg(self.RTC_CNTL_SDIO_CONF_REG) + # check if override is set in RTC_CNTL_SDIO_CONF_REG + if reg & self.RTC_CNTL_SDIO_FORCE: + if reg & self.RTC_CNTL_DREFH_SDIO_M: + return "1.9V" + elif reg & self.RTC_CNTL_XPD_SDIO_REG: + return "1.8V" + else: + return "OFF" + return None + + def get_flash_voltage(self): + """Get flash voltage setting and print it to the console.""" + voltage = self._get_rtc_cntl_flash_voltage() + source = "RTC_CNTL" + if not voltage: + voltage = self._get_efuse_flash_voltage() + source = "eFuse" + if not voltage: + strap_reg = self.read_reg(self.GPIO_STRAP_REG) + strap_reg &= self.GPIO_STRAP_VDDSPI_MASK + voltage = "1.8V" if strap_reg else "3.3V" + source = "a strapping pin" + print(f"Flash voltage set by {source} to {voltage}") + def override_vddsdio(self, new_voltage): new_voltage = new_voltage.upper() if new_voltage not in self.OVERRIDE_VDDSDIO_CHOICES: raise FatalError( - "The only accepted VDDSDIO overrides are '1.8V', '1.9V' and 'OFF'" + f"The only accepted VDDSDIO overrides are {', '.join(self.OVERRIDE_VDDSDIO_CHOICES)}" ) - RTC_CNTL_SDIO_CONF_REG = 0x3FF48074 - RTC_CNTL_XPD_SDIO_REG = 1 << 31 - RTC_CNTL_DREFH_SDIO_M = 3 << 29 - RTC_CNTL_DREFM_SDIO_M = 3 << 27 - RTC_CNTL_DREFL_SDIO_M = 3 << 25 - # RTC_CNTL_SDIO_TIEH = (1 << 23) - # not used here, setting TIEH=1 would set 3.3V output, + # RTC_CNTL_SDIO_TIEH is not used here, setting TIEH=1 would set 3.3V output, # not safe for esptool.py to do - RTC_CNTL_SDIO_FORCE = 1 << 22 - RTC_CNTL_SDIO_PD_EN = 1 << 21 - reg_val = RTC_CNTL_SDIO_FORCE # override efuse setting - reg_val |= RTC_CNTL_SDIO_PD_EN + reg_val = self.RTC_CNTL_SDIO_FORCE # override efuse setting + reg_val |= self.RTC_CNTL_SDIO_PD_EN if new_voltage != "OFF": - reg_val |= RTC_CNTL_XPD_SDIO_REG # enable internal LDO + reg_val |= self.RTC_CNTL_XPD_SDIO_REG # enable internal LDO if new_voltage == "1.9V": reg_val |= ( - RTC_CNTL_DREFH_SDIO_M | RTC_CNTL_DREFM_SDIO_M | RTC_CNTL_DREFL_SDIO_M + self.RTC_CNTL_DREFH_SDIO_M + | self.RTC_CNTL_DREFM_SDIO_M + | self.RTC_CNTL_DREFL_SDIO_M ) # boost voltage - self.write_reg(RTC_CNTL_SDIO_CONF_REG, reg_val) + self.write_reg(self.RTC_CNTL_SDIO_CONF_REG, reg_val) print("VDDSDIO regulator set to %s" % new_voltage) def read_flash_slow(self, offset, length, progress_fn): diff --git a/esptool/targets/esp32c3.py b/esptool/targets/esp32c3.py index e00e51786..0ef0905c9 100644 --- a/esptool/targets/esp32c3.py +++ b/esptool/targets/esp32c3.py @@ -152,6 +152,9 @@ def get_crystal_freq(self): # ESP32C3 XTAL is fixed to 40MHz return 40 + def get_flash_voltage(self): + pass # not supported on ESP32-C3 + def override_vddsdio(self, new_voltage): raise NotImplementedInROMError( "VDD_SDIO overrides are not supported for ESP32-C3" diff --git a/esptool/targets/esp32p4.py b/esptool/targets/esp32p4.py index 6a6ce3447..7b4a35fbe 100644 --- a/esptool/targets/esp32p4.py +++ b/esptool/targets/esp32p4.py @@ -112,6 +112,9 @@ def get_crystal_freq(self): # ESP32P4 XTAL is fixed to 40MHz return 40 + def get_flash_voltage(self): + pass # not supported on ESP32-P4 + def override_vddsdio(self, new_voltage): raise NotImplementedInROMError( "VDD_SDIO overrides are not supported for ESP32-P4" diff --git a/esptool/targets/esp32s2.py b/esptool/targets/esp32s2.py index 19f5532c6..5c7c6b7bb 100644 --- a/esptool/targets/esp32s2.py +++ b/esptool/targets/esp32s2.py @@ -81,6 +81,7 @@ class ESP32S2ROM(ESP32ROM): GPIO_STRAP_REG = 0x3F404038 GPIO_STRAP_SPI_BOOT_MASK = 0x8 # Not download mode + GPIO_STRAP_VDDSPI_MASK = 1 << 4 RTC_CNTL_OPTION1_REG = 0x3F408128 RTC_CNTL_FORCE_DOWNLOAD_BOOT_MASK = 0x1 # Is download mode forced over USB? @@ -99,6 +100,11 @@ class ESP32S2ROM(ESP32ROM): [0x50000000, 0x50002000, "RTC_DATA"], ] + EFUSE_VDD_SPI_REG = EFUSE_BASE + 0x34 + VDD_SPI_XPD = 1 << 4 + VDD_SPI_TIEH = 1 << 5 + VDD_SPI_FORCE = 1 << 6 + UF2_FAMILY_ID = 0xBFDD4EEE def get_pkg_version(self): @@ -183,6 +189,9 @@ def get_crystal_freq(self): # ESP32-S2 XTAL is fixed to 40MHz return 40 + def _get_rtc_cntl_flash_voltage(self): + return None # not supported on ESP32-S2 + def override_vddsdio(self, new_voltage): raise NotImplementedInROMError( "VDD_SDIO overrides are not supported for ESP32-S2" diff --git a/esptool/targets/esp32s3.py b/esptool/targets/esp32s3.py index f3d814455..7531f4ae0 100644 --- a/esptool/targets/esp32s3.py +++ b/esptool/targets/esp32s3.py @@ -95,6 +95,7 @@ class ESP32S3ROM(ESP32ROM): GPIO_STRAP_REG = 0x60004038 GPIO_STRAP_SPI_BOOT_MASK = 0x8 # Not download mode + GPIO_STRAP_VDDSPI_MASK = 1 << 4 RTC_CNTL_OPTION1_REG = 0x6000812C RTC_CNTL_FORCE_DOWNLOAD_BOOT_MASK = 0x1 # Is download mode forced over USB? @@ -115,6 +116,11 @@ class ESP32S3ROM(ESP32ROM): [0x50000000, 0x50002000, "RTC_DATA"], ] + EFUSE_VDD_SPI_REG = EFUSE_BASE + 0x34 + VDD_SPI_XPD = 1 << 4 + VDD_SPI_TIEH = 1 << 5 + VDD_SPI_FORCE = 1 << 6 + UF2_FAMILY_ID = 0xC47E5767 def get_pkg_version(self): @@ -251,6 +257,9 @@ def get_secure_boot_enabled(self): & self.EFUSE_SECURE_BOOT_EN_MASK ) + def _get_rtc_cntl_flash_voltage(self): + return None # not supported on ESP32-S3 + def override_vddsdio(self, new_voltage): raise NotImplementedInROMError( "VDD_SDIO overrides are not supported for ESP32-S3" diff --git a/esptool/targets/esp8266.py b/esptool/targets/esp8266.py index 58e465158..4bd3dc895 100644 --- a/esptool/targets/esp8266.py +++ b/esptool/targets/esp8266.py @@ -169,6 +169,9 @@ def get_erase_size(self, offset, size): else: return (num_sectors - head_sectors) * sector_size + def get_flash_voltage(self): + pass # not supported on ESP8266 + def override_vddsdio(self, new_voltage): raise NotSupportedError(self, "Overriding VDDSDIO")