mirror of
https://github.com/espressif/esptool.git
synced 2025-10-18 00:32:43 +08:00
feat(espefuse): Adds incompatible eFuse settings check for S3
This commit is contained in:

committed by
Radim Karniš

parent
1059ec7faf
commit
c2448436fc
@@ -10,6 +10,10 @@ Positional arguments:
|
||||
- ``eFuse name``
|
||||
- ``value``
|
||||
|
||||
Optional arguments:
|
||||
|
||||
* ``--force``. Suppress an error to burn eFuses. The tool checks for incompatible eFuse states to prevent them from burning and potentially **bricking the chip**. Use this flag only if you are sure. This will suppress the eFuse incompatibility error.
|
||||
|
||||
It can be list of eFuse names and values (like EFUSE_NAME1 1 EFUSE_NAME2 7 EFUSE_NAME3 10 etc.).
|
||||
|
||||
New values can be a numeric value in decimal or hex (with "0x" prefix). eFuse bits can only be burned from 0 to 1, attempting to set any back to 0 will have no effect. Most eFuses have a limited bit width (many are only 1-bit flags). Longer eFuses (MAC addresses, keys) can be set with this command, but it's better to use a specific command (``burn_custom_mac``, ``burn_key``) for a specific field.
|
||||
|
@@ -649,6 +649,10 @@ class EspEfusesBase(object):
|
||||
"""Returns (error count, failure boolean flag)"""
|
||||
return self.blocks[block_num].num_errors, self.blocks[block_num].fail
|
||||
|
||||
def is_efuses_incompatible_for_burn(self):
|
||||
# Overwrite this function for a specific target if you want to check if a certain eFuse(s) can be burned.
|
||||
return False
|
||||
|
||||
|
||||
class EfuseFieldBase(EfuseProtectBase):
|
||||
def __init__(self, parent, param):
|
||||
|
@@ -74,6 +74,11 @@ def add_common_commands(subparsers, efuses):
|
||||
+ [name for e in efuses.efuses for name in e.alt_names if name != ""],
|
||||
efuses=efuses,
|
||||
)
|
||||
burn.add_argument(
|
||||
"--force",
|
||||
help="Suppress an error to burn eFuses",
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
read_protect_efuse = subparsers.add_parser(
|
||||
"read_protect_efuse",
|
||||
@@ -480,6 +485,14 @@ def burn_efuse(esp, efuses, args):
|
||||
)
|
||||
print(" espefuse/esptool will not work.")
|
||||
|
||||
if efuses.is_efuses_incompatible_for_burn():
|
||||
if args.force:
|
||||
print("Ignore incompatible eFuse settings.")
|
||||
else:
|
||||
raise esptool.FatalError(
|
||||
"Incompatible eFuse settings detected, abort. (use --force flag to skip it)."
|
||||
)
|
||||
|
||||
if not efuses.burn_all(check_batch_mode=True):
|
||||
return
|
||||
|
||||
|
@@ -296,6 +296,28 @@ class EspEfuses(base_fields.EspEfusesBase):
|
||||
output = "Flash voltage (VDD_SPI) set to 3.3V by efuse."
|
||||
return output
|
||||
|
||||
def is_efuses_incompatible_for_burn(self):
|
||||
# getting chip version: self._esp.get_chip_revision()
|
||||
if (
|
||||
(
|
||||
self["DIS_USB_JTAG"].get()
|
||||
and self["DIS_USB_SERIAL_JTAG"].get(from_read=False)
|
||||
)
|
||||
or (
|
||||
self["DIS_USB_JTAG"].get(from_read=False)
|
||||
and self["DIS_USB_SERIAL_JTAG"].get()
|
||||
)
|
||||
or (
|
||||
self["DIS_USB_JTAG"].get(from_read=False)
|
||||
and self["DIS_USB_SERIAL_JTAG"].get(from_read=False)
|
||||
)
|
||||
):
|
||||
print(
|
||||
"DIS_USB_JTAG and DIS_USB_SERIAL_JTAG cannot be set together due to a bug in the ROM bootloader!"
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class EfuseField(base_fields.EfuseFieldBase):
|
||||
@staticmethod
|
||||
|
@@ -296,6 +296,28 @@ class EspEfuses(base_fields.EspEfusesBase):
|
||||
output = "Flash voltage (VDD_SPI) set to 3.3V by efuse."
|
||||
return output
|
||||
|
||||
def is_efuses_incompatible_for_burn(self):
|
||||
# getting chip version: self._esp.get_chip_revision()
|
||||
if (
|
||||
(
|
||||
self["DIS_USB_JTAG"].get(from_read=True)
|
||||
and self["DIS_USB_SERIAL_JTAG"].get(from_read=False)
|
||||
)
|
||||
or (
|
||||
self["DIS_USB_JTAG"].get(from_read=False)
|
||||
and self["DIS_USB_SERIAL_JTAG"].get(from_read=True)
|
||||
)
|
||||
or (
|
||||
self["DIS_USB_JTAG"].get(from_read=False)
|
||||
and self["DIS_USB_SERIAL_JTAG"].get(from_read=False)
|
||||
)
|
||||
):
|
||||
print(
|
||||
"DIS_USB_JTAG and DIS_USB_SERIAL_JTAG cannot be set together due to a bug in the ROM bootloader"
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class EfuseField(base_fields.EfuseFieldBase):
|
||||
@staticmethod
|
||||
|
@@ -801,6 +801,24 @@ class TestBurnEfuseCommands(EfuseTestCase):
|
||||
ADC2_TP_HIGH 45"
|
||||
)
|
||||
|
||||
@pytest.mark.skipif(
|
||||
arg_chip != "esp32s3",
|
||||
reason="Currently S3 only has this efuse incompatibility check",
|
||||
)
|
||||
def test_burn_efuse_incompatibility_check(self):
|
||||
self.espefuse_py(
|
||||
"burn_efuse DIS_USB_JTAG 1 DIS_USB_SERIAL_JTAG 1",
|
||||
check_msg="Incompatible eFuse settings detected, abort",
|
||||
ret_code=2,
|
||||
)
|
||||
self.espefuse_py("burn_efuse DIS_USB_JTAG 1")
|
||||
self.espefuse_py(
|
||||
"burn_efuse DIS_USB_SERIAL_JTAG 1",
|
||||
check_msg="Incompatible eFuse settings detected, abort",
|
||||
ret_code=2,
|
||||
)
|
||||
self.espefuse_py("burn_efuse DIS_USB_SERIAL_JTAG 1 --force")
|
||||
|
||||
|
||||
class TestBurnKeyCommands(EfuseTestCase):
|
||||
@pytest.mark.skipif(arg_chip != "esp32", reason="ESP32-only")
|
||||
|
Reference in New Issue
Block a user