diff --git a/scripts/flipper/utils/programmer_openocd.py b/scripts/flipper/utils/programmer_openocd.py index b3340610..3d217185 100644 --- a/scripts/flipper/utils/programmer_openocd.py +++ b/scripts/flipper/utils/programmer_openocd.py @@ -1,6 +1,7 @@ import logging import os import typing +from enum import Enum from flipper.utils.programmer import Programmer from flipper.utils.openocd import OpenOCD @@ -8,6 +9,14 @@ from flipper.utils.stm32wb55 import STM32WB55 from flipper.assets.obdata import OptionBytesData +class OpenOCDProgrammerResult(Enum): + Success = 0 + ErrorGeneric = 1 + ErrorAlignment = 2 + ErrorAlreadyWritten = 3 + ErrorValidation = 4 + + class OpenOCDProgrammer(Programmer): def __init__( self, @@ -199,18 +208,18 @@ class OpenOCDProgrammer(Programmer): return True - def otp_write(self, address: int, file_path: str) -> bool: + def otp_write(self, address: int, file_path: str) -> OpenOCDProgrammerResult: # Open file, check that it aligned to 8 bytes with open(file_path, "rb") as f: data = f.read() if len(data) % 8 != 0: self.logger.error(f"File {file_path} is not aligned to 8 bytes") - return False + return OpenOCDProgrammerResult.ErrorAlignment # Check that address is aligned to 8 bytes if address % 8 != 0: self.logger.error(f"Address {address} is not aligned to 8 bytes") - return False + return OpenOCDProgrammerResult.ErrorAlignment # Get size of data data_size = len(data) @@ -218,7 +227,7 @@ class OpenOCDProgrammer(Programmer): # Check that data size is aligned to 8 bytes if data_size % 8 != 0: self.logger.error(f"Data size {data_size} is not aligned to 8 bytes") - return False + return OpenOCDProgrammerResult.ErrorAlignment self.logger.debug(f"Writing {data_size} bytes to OTP at {address:08X}") self.logger.debug(f"Data: {data.hex().upper()}") @@ -241,14 +250,14 @@ class OpenOCDProgrammer(Programmer): self.logger.error( f"OTP memory at {address + i:08X} is not empty: {device_word:08X}" ) - raise Exception("OTP memory is not empty") + return OpenOCDProgrammerResult.ErrorAlreadyWritten if device_word != file_word: already_written = False if already_written: self.logger.info(f"OTP memory is already written with the given data") - return True + return OpenOCDProgrammerResult.Success self.reset(self.RunMode.Stop) stm32.clear_flash_errors(oocd) @@ -278,4 +287,8 @@ class OpenOCDProgrammer(Programmer): stm32.reset(oocd, stm32.RunMode.Run) oocd.stop() - return validation_result + return ( + OpenOCDProgrammerResult.Success + if validation_result + else OpenOCDProgrammerResult.ErrorValidation + ) diff --git a/scripts/otp.py b/scripts/otp.py index 3bfe30d2..cb76bdc8 100755 --- a/scripts/otp.py +++ b/scripts/otp.py @@ -34,8 +34,16 @@ OTP_DISPLAYS = { } from flipper.app import App -from flipper.cube import CubeProgrammer -from flipper.utils.programmer_openocd import OpenOCDProgrammer +from flipper.utils.programmer_openocd import OpenOCDProgrammer, OpenOCDProgrammerResult + + +class OTPException(Exception): + def __init__(self, message: str, result: OpenOCDProgrammerResult): + self.message = message + self.result = result + + def get_exit_code(self) -> int: + return int(self.result.value) class Main(App): @@ -183,13 +191,14 @@ class Main(App): self.args.serial, ) - if not openocd.otp_write(0x1FFF7000, filename): - raise Exception("Failed to flash OTP") + programmer_result = openocd.otp_write(0x1FFF7000, filename) + if programmer_result != OpenOCDProgrammerResult.Success: + raise OTPException("Failed to flash OTP", programmer_result) self.logger.info(f"Flashed Successfully") - except Exception as e: + except OTPException as e: self.logger.exception(e) - return 1 + return e.get_exit_code() finally: os.remove(filename) @@ -215,13 +224,14 @@ class Main(App): self.args.serial, ) - if not openocd.otp_write(0x1FFF7010, filename): - raise Exception("Failed to flash OTP") + programmer_result = openocd.otp_write(0x1FFF7010, filename) + if programmer_result != OpenOCDProgrammerResult.Success: + raise OTPException("Failed to flash OTP", programmer_result) self.logger.info(f"Flashed Successfully") - except Exception as e: + except OTPException as e: self.logger.exception(e) - return 1 + return e.get_exit_code() finally: os.remove(filename) @@ -249,13 +259,14 @@ class Main(App): self.args.serial, ) - if not openocd.otp_write(0x1FFF7000, filename): - raise Exception("Failed to flash OTP") + programmer_result = openocd.otp_write(0x1FFF7000, filename) + if programmer_result != OpenOCDProgrammerResult.Success: + raise OTPException("Failed to flash OTP", programmer_result) self.logger.info(f"Flashed Successfully") - except Exception as e: + except OTPException as e: self.logger.exception(e) - return 1 + return e.get_exit_code() finally: os.remove(filename)