1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 12:42:30 +04:00

Scripts: OB recovery (#2964)

* Scripts: OB recovery
* Scripts: slightly different ob
* Scripts: remove excessive return
* Scripts: simplifying work with registers
* Make PVS happy

Co-authored-by: SG <who.just.the.doctor@gmail.com>
This commit is contained in:
あく
2023-08-10 18:45:17 +09:00
committed by MX
parent 09d5b3b1ed
commit dc2d12d468
6 changed files with 148 additions and 85 deletions

View File

@@ -44,11 +44,11 @@ class OpenOCDProgrammer(Programmer):
self.logger = logging.getLogger()
def reset(self, mode: Programmer.RunMode = Programmer.RunMode.Run) -> bool:
stm32 = STM32WB55()
stm32 = STM32WB55(self.openocd)
if mode == Programmer.RunMode.Run:
stm32.reset(self.openocd, stm32.RunMode.Run)
stm32.reset(stm32.RunMode.Run)
elif mode == Programmer.RunMode.Stop:
stm32.reset(self.openocd, stm32.RunMode.Init)
stm32.reset(stm32.RunMode.Init)
else:
raise Exception("Unknown mode")
@@ -96,11 +96,11 @@ class OpenOCDProgrammer(Programmer):
def option_bytes_validate(self, file_path: str) -> bool:
# Registers
stm32 = STM32WB55()
stm32 = STM32WB55(self.openocd)
# OpenOCD
self.openocd.start()
stm32.reset(self.openocd, stm32.RunMode.Init)
stm32.reset(stm32.RunMode.Init)
# Generate Option Bytes data
ob_data = OptionBytesData(file_path)
@@ -133,7 +133,7 @@ class OpenOCDProgrammer(Programmer):
self._ob_print_diff_table(ob_reference, ob_compare, self.logger.error)
# Stop OpenOCD
stm32.reset(self.openocd, stm32.RunMode.Run)
stm32.reset(stm32.RunMode.Run)
self.openocd.stop()
return return_code
@@ -143,11 +143,11 @@ class OpenOCDProgrammer(Programmer):
def option_bytes_set(self, file_path: str) -> bool:
# Registers
stm32 = STM32WB55()
stm32 = STM32WB55(self.openocd)
# OpenOCD
self.openocd.start()
stm32.reset(self.openocd, stm32.RunMode.Init)
stm32.reset(stm32.RunMode.Init)
# Generate Option Bytes data
ob_data = OptionBytesData(file_path)
@@ -159,11 +159,11 @@ class OpenOCDProgrammer(Programmer):
ob_dwords = int(ob_length / 8)
# Clear flash errors
stm32.clear_flash_errors(self.openocd)
stm32.clear_flash_errors()
# Unlock Flash and Option Bytes
stm32.flash_unlock(self.openocd)
stm32.option_bytes_unlock(self.openocd)
stm32.flash_unlock()
stm32.option_bytes_unlock()
ob_need_to_apply = False
@@ -194,16 +194,16 @@ class OpenOCDProgrammer(Programmer):
self.openocd.write_32(device_reg_addr, ob_value)
if ob_need_to_apply:
stm32.option_bytes_apply(self.openocd)
stm32.option_bytes_apply()
else:
self.logger.info("Option Bytes are already correct")
# Load Option Bytes
# That will reset and also lock the Option Bytes and the Flash
stm32.option_bytes_load(self.openocd)
stm32.option_bytes_load()
# Stop OpenOCD
stm32.reset(self.openocd, stm32.RunMode.Run)
stm32.reset(stm32.RunMode.Run)
self.openocd.stop()
return True
@@ -233,11 +233,10 @@ class OpenOCDProgrammer(Programmer):
self.logger.debug(f"Data: {data.hex().upper()}")
# Start OpenOCD
oocd = self.openocd
oocd.start()
self.openocd.start()
# Registers
stm32 = STM32WB55()
stm32 = STM32WB55(self.openocd)
try:
# Check that OTP is empty for the given address
@@ -245,7 +244,7 @@ class OpenOCDProgrammer(Programmer):
already_written = True
for i in range(0, data_size, 4):
file_word = int.from_bytes(data[i : i + 4], "little")
device_word = oocd.read_32(address + i)
device_word = self.openocd.read_32(address + i)
if device_word != 0xFFFFFFFF and device_word != file_word:
self.logger.error(
f"OTP memory at {address + i:08X} is not empty: {device_word:08X}"
@@ -260,7 +259,7 @@ class OpenOCDProgrammer(Programmer):
return OpenOCDProgrammerResult.Success
self.reset(self.RunMode.Stop)
stm32.clear_flash_errors(oocd)
stm32.clear_flash_errors()
# Write OTP memory by 8 bytes
for i in range(0, data_size, 8):
@@ -269,14 +268,14 @@ class OpenOCDProgrammer(Programmer):
self.logger.debug(
f"Writing {word_1:08X} {word_2:08X} to {address + i:08X}"
)
stm32.write_flash_64(oocd, address + i, word_1, word_2)
stm32.write_flash_64(address + i, word_1, word_2)
# Validate OTP memory
validation_result = True
for i in range(0, data_size, 4):
file_word = int.from_bytes(data[i : i + 4], "little")
device_word = oocd.read_32(address + i)
device_word = self.openocd.read_32(address + i)
if file_word != device_word:
self.logger.error(
f"Validation failed: {file_word:08X} != {device_word:08X} at {address + i:08X}"
@@ -284,11 +283,21 @@ class OpenOCDProgrammer(Programmer):
validation_result = False
finally:
# Stop OpenOCD
stm32.reset(oocd, stm32.RunMode.Run)
oocd.stop()
stm32.reset(stm32.RunMode.Run)
self.openocd.stop()
return (
OpenOCDProgrammerResult.Success
if validation_result
else OpenOCDProgrammerResult.ErrorValidation
)
def option_bytes_recover(self) -> bool:
try:
self.openocd.start()
stm32 = STM32WB55(self.openocd)
stm32.reset(stm32.RunMode.Halt)
stm32.option_bytes_recover()
return True
finally:
self.openocd.stop()