Scripts: add serial number support to cube programmer api, update usage. (#839)
This commit is contained in:
		
							parent
							
								
									68274b6c27
								
							
						
					
					
						commit
						01f08f99b1
					
				| @ -16,6 +16,7 @@ class Main(App): | |||||||
|         self.subparsers = self.parser.add_subparsers(help="sub-command help") |         self.subparsers = self.parser.add_subparsers(help="sub-command help") | ||||||
|         # Wipe |         # Wipe | ||||||
|         self.parser_wipe = self.subparsers.add_parser("wipe", help="Wipe MCU Flash") |         self.parser_wipe = self.subparsers.add_parser("wipe", help="Wipe MCU Flash") | ||||||
|  |         self._addArgsSWD(self.parser_wipe) | ||||||
|         self.parser_wipe.set_defaults(func=self.wipe) |         self.parser_wipe.set_defaults(func=self.wipe) | ||||||
|         # Core 1 boot |         # Core 1 boot | ||||||
|         self.parser_core1bootloader = self.subparsers.add_parser( |         self.parser_core1bootloader = self.subparsers.add_parser( | ||||||
| @ -78,10 +79,17 @@ class Main(App): | |||||||
|         parser.add_argument( |         parser.add_argument( | ||||||
|             "--port", type=str, help="Port to connect: swd or usb1", default="swd" |             "--port", type=str, help="Port to connect: swd or usb1", default="swd" | ||||||
|         ) |         ) | ||||||
|  |         parser.add_argument("--serial", type=str, help="ST-Link Serial Number") | ||||||
|  | 
 | ||||||
|  |     def _getCubeParams(self): | ||||||
|  |         return { | ||||||
|  |             "port": self.args.port, | ||||||
|  |             "serial": self.args.serial, | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|     def wipe(self): |     def wipe(self): | ||||||
|         self.logger.info(f"Wiping flash") |         self.logger.info(f"Wiping flash") | ||||||
|         cp = CubeProgrammer("swd") |         cp = CubeProgrammer(self._getCubeParams()) | ||||||
|         self.logger.info(f"Setting RDP to 0xBB") |         self.logger.info(f"Setting RDP to 0xBB") | ||||||
|         cp.setOptionBytes({"RDP": ("0xBB", "rw")}) |         cp.setOptionBytes({"RDP": ("0xBB", "rw")}) | ||||||
|         self.logger.info(f"Verifying RDP") |         self.logger.info(f"Verifying RDP") | ||||||
| @ -99,7 +107,7 @@ class Main(App): | |||||||
| 
 | 
 | ||||||
|     def core1bootloader(self): |     def core1bootloader(self): | ||||||
|         self.logger.info(f"Flashing bootloader") |         self.logger.info(f"Flashing bootloader") | ||||||
|         cp = CubeProgrammer(self.args.port) |         cp = CubeProgrammer(self._getCubeParams()) | ||||||
|         cp.flashBin("0x08000000", self.args.bootloader) |         cp.flashBin("0x08000000", self.args.bootloader) | ||||||
|         self.logger.info(f"Complete") |         self.logger.info(f"Complete") | ||||||
|         cp.resetTarget() |         cp.resetTarget() | ||||||
| @ -107,7 +115,7 @@ class Main(App): | |||||||
| 
 | 
 | ||||||
|     def core1firmware(self): |     def core1firmware(self): | ||||||
|         self.logger.info(f"Flashing firmware") |         self.logger.info(f"Flashing firmware") | ||||||
|         cp = CubeProgrammer(self.args.port) |         cp = CubeProgrammer(self._getCubeParams()) | ||||||
|         cp.flashBin("0x08008000", self.args.firmware) |         cp.flashBin("0x08008000", self.args.firmware) | ||||||
|         self.logger.info(f"Complete") |         self.logger.info(f"Complete") | ||||||
|         cp.resetTarget() |         cp.resetTarget() | ||||||
| @ -115,7 +123,7 @@ class Main(App): | |||||||
| 
 | 
 | ||||||
|     def core1(self): |     def core1(self): | ||||||
|         self.logger.info(f"Flashing bootloader") |         self.logger.info(f"Flashing bootloader") | ||||||
|         cp = CubeProgrammer(self.args.port) |         cp = CubeProgrammer(self._getCubeParams()) | ||||||
|         cp.flashBin("0x08000000", self.args.bootloader) |         cp.flashBin("0x08000000", self.args.bootloader) | ||||||
|         self.logger.info(f"Flashing firmware") |         self.logger.info(f"Flashing firmware") | ||||||
|         cp.flashBin("0x08008000", self.args.firmware) |         cp.flashBin("0x08008000", self.args.firmware) | ||||||
| @ -130,7 +138,7 @@ class Main(App): | |||||||
|             ) |             ) | ||||||
|             return 1 |             return 1 | ||||||
|         self.logger.info(f"Flashing Firmware Update Service") |         self.logger.info(f"Flashing Firmware Update Service") | ||||||
|         cp = CubeProgrammer(self.args.port) |         cp = CubeProgrammer(self._getCubeParams()) | ||||||
|         cp.flashCore2(self.args.fus_address, self.args.fus) |         cp.flashCore2(self.args.fus_address, self.args.fus) | ||||||
|         self.logger.info(f"Complete") |         self.logger.info(f"Complete") | ||||||
|         return 0 |         return 0 | ||||||
| @ -139,7 +147,7 @@ class Main(App): | |||||||
|         if int(self.args.radio_address, 16) > 0x080E0000: |         if int(self.args.radio_address, 16) > 0x080E0000: | ||||||
|             self.logger.error(f"I KNOW WHAT YOU DID LAST SUMMER") |             self.logger.error(f"I KNOW WHAT YOU DID LAST SUMMER") | ||||||
|             return 1 |             return 1 | ||||||
|         cp = CubeProgrammer(self.args.port) |         cp = CubeProgrammer(self._getCubeParams()) | ||||||
|         self.logger.info(f"Removing Current Radio Stack") |         self.logger.info(f"Removing Current Radio Stack") | ||||||
|         cp.deleteCore2RadioStack() |         cp.deleteCore2RadioStack() | ||||||
|         self.logger.info(f"Flashing Radio Stack") |         self.logger.info(f"Flashing Radio Stack") | ||||||
|  | |||||||
| @ -5,23 +5,35 @@ import subprocess | |||||||
| class CubeProgrammer: | class CubeProgrammer: | ||||||
|     """STM32 Cube Programmer cli wrapper""" |     """STM32 Cube Programmer cli wrapper""" | ||||||
| 
 | 
 | ||||||
|     def __init__(self, port, params=[]): |     def __init__(self, config={}): | ||||||
|         self.port = port |         assert isinstance(config, dict) | ||||||
|         self.params = params |         # Params base | ||||||
|  |         self.params = [] | ||||||
|  |         # Connect params | ||||||
|  |         connect = [] | ||||||
|  |         if "port" in config and config["port"]: | ||||||
|  |             connect.append(f"port={config['port']}") | ||||||
|  |         else: | ||||||
|  |             connect.append(f"port=swd") | ||||||
|  |         if "serial" in config and config["serial"]: | ||||||
|  |             connect.append(f"sn={config['serial']}") | ||||||
|  |         self.params.append("-c " + " ".join(connect)) | ||||||
|  |         # Other params | ||||||
|  |         if "params" in config: | ||||||
|  |             self.params += config["params"] | ||||||
|         # logging |         # logging | ||||||
|         self.logger = logging.getLogger() |         self.logger = logging.getLogger() | ||||||
| 
 | 
 | ||||||
|     def _execute(self, args): |     def _execute(self, args): | ||||||
|         try: |         try: | ||||||
|             output = subprocess.check_output( |             params = [ | ||||||
|                 [ |  | ||||||
|                 "STM32_Programmer_CLI", |                 "STM32_Programmer_CLI", | ||||||
|                 "-q", |                 "-q", | ||||||
|                     f"-c port={self.port}", |  | ||||||
|                 *self.params, |                 *self.params, | ||||||
|                 *args, |                 *args, | ||||||
|             ] |             ] | ||||||
|             ) |             self.logger.debug(f"_execute: {params}") | ||||||
|  |             output = subprocess.check_output(params) | ||||||
|         except subprocess.CalledProcessError as e: |         except subprocess.CalledProcessError as e: | ||||||
|             if e.output: |             if e.output: | ||||||
|                 print("Process output:\n", e.output.decode()) |                 print("Process output:\n", e.output.decode()) | ||||||
|  | |||||||
| @ -16,19 +16,27 @@ class Main(App): | |||||||
|         self.parser_check = self.subparsers.add_parser( |         self.parser_check = self.subparsers.add_parser( | ||||||
|             "check", help="Check Option Bytes" |             "check", help="Check Option Bytes" | ||||||
|         ) |         ) | ||||||
|         self.parser_check.add_argument( |         self._addArgsSWD(self.parser_check) | ||||||
|             "--port", type=str, help="Port to connect: swd or usb1", default="swd" |  | ||||||
|         ) |  | ||||||
|         self.parser_check.set_defaults(func=self.check) |         self.parser_check.set_defaults(func=self.check) | ||||||
|         # Set command |         # Set command | ||||||
|         self.parser_set = self.subparsers.add_parser("set", help="Set Option Bytes") |         self.parser_set = self.subparsers.add_parser("set", help="Set Option Bytes") | ||||||
|         self.parser_set.add_argument( |         self._addArgsSWD(self.parser_set) | ||||||
|             "--port", type=str, help="Port to connect: swd or usb1", default="swd" |  | ||||||
|         ) |  | ||||||
|         self.parser_set.set_defaults(func=self.set) |         self.parser_set.set_defaults(func=self.set) | ||||||
|         # OB |         # OB | ||||||
|         self.ob = {} |         self.ob = {} | ||||||
| 
 | 
 | ||||||
|  |     def _addArgsSWD(self, parser): | ||||||
|  |         parser.add_argument( | ||||||
|  |             "--port", type=str, help="Port to connect: swd or usb1", default="swd" | ||||||
|  |         ) | ||||||
|  |         parser.add_argument("--serial", type=str, help="ST-Link Serial Number") | ||||||
|  | 
 | ||||||
|  |     def _getCubeParams(self): | ||||||
|  |         return { | ||||||
|  |             "port": self.args.port, | ||||||
|  |             "serial": self.args.serial, | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|     def before(self): |     def before(self): | ||||||
|         self.logger.info(f"Loading Option Bytes data") |         self.logger.info(f"Loading Option Bytes data") | ||||||
|         file_path = os.path.join(os.path.dirname(sys.argv[0]), "ob.data") |         file_path = os.path.join(os.path.dirname(sys.argv[0]), "ob.data") | ||||||
| @ -39,7 +47,7 @@ class Main(App): | |||||||
| 
 | 
 | ||||||
|     def check(self): |     def check(self): | ||||||
|         self.logger.info(f"Checking Option Bytes") |         self.logger.info(f"Checking Option Bytes") | ||||||
|         cp = CubeProgrammer(self.args.port) |         cp = CubeProgrammer(self._getCubeParams()) | ||||||
|         if cp.checkOptionBytes(self.ob): |         if cp.checkOptionBytes(self.ob): | ||||||
|             self.logger.info(f"OB Check OK") |             self.logger.info(f"OB Check OK") | ||||||
|             return 0 |             return 0 | ||||||
| @ -49,7 +57,7 @@ class Main(App): | |||||||
| 
 | 
 | ||||||
|     def set(self): |     def set(self): | ||||||
|         self.logger.info(f"Setting Option Bytes") |         self.logger.info(f"Setting Option Bytes") | ||||||
|         cp = CubeProgrammer(self.args.port) |         cp = CubeProgrammer(self._getCubeParams()) | ||||||
|         if cp.setOptionBytes(self.ob): |         if cp.setOptionBytes(self.ob): | ||||||
|             self.logger.info(f"OB Set OK") |             self.logger.info(f"OB Set OK") | ||||||
|             return 0 |             return 0 | ||||||
|  | |||||||
| @ -44,59 +44,66 @@ class Main(App): | |||||||
|         self.parser_generate_all = self.subparsers.add_parser( |         self.parser_generate_all = self.subparsers.add_parser( | ||||||
|             "generate", help="Generate OTP binary" |             "generate", help="Generate OTP binary" | ||||||
|         ) |         ) | ||||||
|         self._add_first_args(self.parser_generate_all) |         self._addFirstArgs(self.parser_generate_all) | ||||||
|         self._add_second_args(self.parser_generate_all) |         self._addSecondArgs(self.parser_generate_all) | ||||||
|         self.parser_generate_all.add_argument("file", help="Output file") |         self.parser_generate_all.add_argument("file", help="Output file") | ||||||
|         self.parser_generate_all.set_defaults(func=self.generate_all) |         self.parser_generate_all.set_defaults(func=self.generate_all) | ||||||
|         # Flash First |         # Flash First | ||||||
|         self.parser_flash_first = self.subparsers.add_parser( |         self.parser_flash_first = self.subparsers.add_parser( | ||||||
|             "flash_first", help="Flash first block of OTP to device" |             "flash_first", help="Flash first block of OTP to device" | ||||||
|         ) |         ) | ||||||
|         self._add_swd_args(self.parser_flash_first) |         self._addArgsSWD(self.parser_flash_first) | ||||||
|         self._add_first_args(self.parser_flash_first) |         self._addFirstArgs(self.parser_flash_first) | ||||||
|         self.parser_flash_first.set_defaults(func=self.flash_first) |         self.parser_flash_first.set_defaults(func=self.flash_first) | ||||||
|         # Flash Second |         # Flash Second | ||||||
|         self.parser_flash_second = self.subparsers.add_parser( |         self.parser_flash_second = self.subparsers.add_parser( | ||||||
|             "flash_second", help="Flash second block of OTP to device" |             "flash_second", help="Flash second block of OTP to device" | ||||||
|         ) |         ) | ||||||
|         self._add_swd_args(self.parser_flash_second) |         self._addArgsSWD(self.parser_flash_second) | ||||||
|         self._add_second_args(self.parser_flash_second) |         self._addSecondArgs(self.parser_flash_second) | ||||||
|         self.parser_flash_second.set_defaults(func=self.flash_second) |         self.parser_flash_second.set_defaults(func=self.flash_second) | ||||||
|         # Flash All |         # Flash All | ||||||
|         self.parser_flash_all = self.subparsers.add_parser( |         self.parser_flash_all = self.subparsers.add_parser( | ||||||
|             "flash_all", help="Flash OTP to device" |             "flash_all", help="Flash OTP to device" | ||||||
|         ) |         ) | ||||||
|         self._add_swd_args(self.parser_flash_all) |         self._addArgsSWD(self.parser_flash_all) | ||||||
|         self._add_first_args(self.parser_flash_all) |         self._addFirstArgs(self.parser_flash_all) | ||||||
|         self._add_second_args(self.parser_flash_all) |         self._addSecondArgs(self.parser_flash_all) | ||||||
|         self.parser_flash_all.set_defaults(func=self.flash_all) |         self.parser_flash_all.set_defaults(func=self.flash_all) | ||||||
|         # logging |         # logging | ||||||
|         self.logger = logging.getLogger() |         self.logger = logging.getLogger() | ||||||
|         self.timestamp = datetime.datetime.now().timestamp() |         self.timestamp = datetime.datetime.now().timestamp() | ||||||
| 
 | 
 | ||||||
|     def _add_swd_args(self, parser): |     def _addArgsSWD(self, parser): | ||||||
|         parser.add_argument( |         parser.add_argument( | ||||||
|             "--port", type=str, help="Port to connect: swd or usb1", default="swd" |             "--port", type=str, help="Port to connect: swd or usb1", default="swd" | ||||||
|         ) |         ) | ||||||
|  |         parser.add_argument("--serial", type=str, help="ST-Link Serial Number") | ||||||
| 
 | 
 | ||||||
|     def _add_first_args(self, parser): |     def _getCubeParams(self): | ||||||
|  |         return { | ||||||
|  |             "port": self.args.port, | ||||||
|  |             "serial": self.args.serial, | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     def _addFirstArgs(self, parser): | ||||||
|         parser.add_argument("--version", type=int, help="Version", required=True) |         parser.add_argument("--version", type=int, help="Version", required=True) | ||||||
|         parser.add_argument("--firmware", type=int, help="Firmware", required=True) |         parser.add_argument("--firmware", type=int, help="Firmware", required=True) | ||||||
|         parser.add_argument("--body", type=int, help="Body", required=True) |         parser.add_argument("--body", type=int, help="Body", required=True) | ||||||
|         parser.add_argument("--connect", type=int, help="Connect", required=True) |         parser.add_argument("--connect", type=int, help="Connect", required=True) | ||||||
|         parser.add_argument("--display", type=str, help="Display", required=True) |         parser.add_argument("--display", type=str, help="Display", required=True) | ||||||
| 
 | 
 | ||||||
|     def _add_second_args(self, parser): |     def _addSecondArgs(self, parser): | ||||||
|         parser.add_argument("--color", type=str, help="Color", required=True) |         parser.add_argument("--color", type=str, help="Color", required=True) | ||||||
|         parser.add_argument("--region", type=str, help="Region", required=True) |         parser.add_argument("--region", type=str, help="Region", required=True) | ||||||
|         parser.add_argument("--name", type=str, help="Name", required=True) |         parser.add_argument("--name", type=str, help="Name", required=True) | ||||||
| 
 | 
 | ||||||
|     def _process_first_args(self): |     def _processFirstArgs(self): | ||||||
|         if self.args.display not in OTP_DISPLAYS: |         if self.args.display not in OTP_DISPLAYS: | ||||||
|             self.parser.error(f"Invalid display. Use one of {OTP_DISPLAYS.keys()}") |             self.parser.error(f"Invalid display. Use one of {OTP_DISPLAYS.keys()}") | ||||||
|         self.args.display = OTP_DISPLAYS[self.args.display] |         self.args.display = OTP_DISPLAYS[self.args.display] | ||||||
| 
 | 
 | ||||||
|     def _process_second_args(self): |     def _processSecondArgs(self): | ||||||
|         if self.args.color not in OTP_COLORS: |         if self.args.color not in OTP_COLORS: | ||||||
|             self.parser.error(f"Invalid color. Use one of {OTP_COLORS.keys()}") |             self.parser.error(f"Invalid color. Use one of {OTP_COLORS.keys()}") | ||||||
|         self.args.color = OTP_COLORS[self.args.color] |         self.args.color = OTP_COLORS[self.args.color] | ||||||
| @ -112,7 +119,7 @@ class Main(App): | |||||||
|                 "Name contains incorrect symbols. Only a-zA-Z0-9 allowed." |                 "Name contains incorrect symbols. Only a-zA-Z0-9 allowed." | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|     def _pack_first(self): |     def _packFirst(self): | ||||||
|         return struct.pack( |         return struct.pack( | ||||||
|             "<" "HBBL" "BBBBBBH", |             "<" "HBBL" "BBBBBBH", | ||||||
|             OTP_MAGIC, |             OTP_MAGIC, | ||||||
| @ -128,7 +135,7 @@ class Main(App): | |||||||
|             OTP_RESERVED, |             OTP_RESERVED, | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     def _pack_second(self): |     def _packSecond(self): | ||||||
|         return struct.pack( |         return struct.pack( | ||||||
|             "<" "BBHL" "8s", |             "<" "BBHL" "8s", | ||||||
|             self.args.color, |             self.args.color, | ||||||
| @ -140,10 +147,10 @@ class Main(App): | |||||||
| 
 | 
 | ||||||
|     def generate_all(self): |     def generate_all(self): | ||||||
|         self.logger.info(f"Generating OTP") |         self.logger.info(f"Generating OTP") | ||||||
|         self._process_first_args() |         self._processFirstArgs() | ||||||
|         self._process_second_args() |         self._processSecondArgs() | ||||||
|         open(f"{self.args.file}_first.bin", "wb").write(self._pack_first()) |         open(f"{self.args.file}_first.bin", "wb").write(self._packFirst()) | ||||||
|         open(f"{self.args.file}_second.bin", "wb").write(self._pack_second()) |         open(f"{self.args.file}_second.bin", "wb").write(self._packSecond()) | ||||||
|         self.logger.info( |         self.logger.info( | ||||||
|             f"Generated files: {self.args.file}_first.bin and {self.args.file}_second.bin" |             f"Generated files: {self.args.file}_first.bin and {self.args.file}_second.bin" | ||||||
|         ) |         ) | ||||||
| @ -153,17 +160,17 @@ class Main(App): | |||||||
|     def flash_first(self): |     def flash_first(self): | ||||||
|         self.logger.info(f"Flashing first block of OTP") |         self.logger.info(f"Flashing first block of OTP") | ||||||
| 
 | 
 | ||||||
|         self._process_first_args() |         self._processFirstArgs() | ||||||
| 
 | 
 | ||||||
|         filename = f"otp_unknown_first_{self.timestamp}.bin" |         filename = f"otp_unknown_first_{self.timestamp}.bin" | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|             self.logger.info(f"Packing binary data") |             self.logger.info(f"Packing binary data") | ||||||
|             file = open(filename, "wb") |             file = open(filename, "wb") | ||||||
|             file.write(self._pack_first()) |             file.write(self._packFirst()) | ||||||
|             file.close() |             file.close() | ||||||
|             self.logger.info(f"Flashing OTP") |             self.logger.info(f"Flashing OTP") | ||||||
|             cp = CubeProgrammer(self.args.port) |             cp = CubeProgrammer(self._getCubeParams()) | ||||||
|             cp.flashBin("0x1FFF7000", filename) |             cp.flashBin("0x1FFF7000", filename) | ||||||
|             cp.resetTarget() |             cp.resetTarget() | ||||||
|             self.logger.info(f"Flashed Successfully") |             self.logger.info(f"Flashed Successfully") | ||||||
| @ -177,17 +184,17 @@ class Main(App): | |||||||
|     def flash_second(self): |     def flash_second(self): | ||||||
|         self.logger.info(f"Flashing second block of OTP") |         self.logger.info(f"Flashing second block of OTP") | ||||||
| 
 | 
 | ||||||
|         self._process_second_args() |         self._processSecondArgs() | ||||||
| 
 | 
 | ||||||
|         filename = f"otp_{self.args.name}_second_{self.timestamp}.bin" |         filename = f"otp_{self.args.name}_second_{self.timestamp}.bin" | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|             self.logger.info(f"Packing binary data") |             self.logger.info(f"Packing binary data") | ||||||
|             file = open(filename, "wb") |             file = open(filename, "wb") | ||||||
|             file.write(self._pack_second()) |             file.write(self._packSecond()) | ||||||
|             file.close() |             file.close() | ||||||
|             self.logger.info(f"Flashing OTP") |             self.logger.info(f"Flashing OTP") | ||||||
|             cp = CubeProgrammer(self.args.port) |             cp = CubeProgrammer(self._getCubeParams()) | ||||||
|             cp.flashBin("0x1FFF7010", filename) |             cp.flashBin("0x1FFF7010", filename) | ||||||
|             cp.resetTarget() |             cp.resetTarget() | ||||||
|             self.logger.info(f"Flashed Successfully") |             self.logger.info(f"Flashed Successfully") | ||||||
| @ -201,19 +208,19 @@ class Main(App): | |||||||
|     def flash_all(self): |     def flash_all(self): | ||||||
|         self.logger.info(f"Flashing OTP") |         self.logger.info(f"Flashing OTP") | ||||||
| 
 | 
 | ||||||
|         self._process_first_args() |         self._processFirstArgs() | ||||||
|         self._process_second_args() |         self._processSecondArgs() | ||||||
| 
 | 
 | ||||||
|         filename = f"otp_{self.args.name}_whole_{self.timestamp}.bin" |         filename = f"otp_{self.args.name}_whole_{self.timestamp}.bin" | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|             self.logger.info(f"Packing binary data") |             self.logger.info(f"Packing binary data") | ||||||
|             file = open(filename, "wb") |             file = open(filename, "wb") | ||||||
|             file.write(self._pack_first()) |             file.write(self._packFirst()) | ||||||
|             file.write(self._pack_second()) |             file.write(self._packSecond()) | ||||||
|             file.close() |             file.close() | ||||||
|             self.logger.info(f"Flashing OTP") |             self.logger.info(f"Flashing OTP") | ||||||
|             cp = CubeProgrammer(self.args.port) |             cp = CubeProgrammer(self._getCubeParams()) | ||||||
|             cp.flashBin("0x1FFF7000", filename) |             cp.flashBin("0x1FFF7000", filename) | ||||||
|             cp.resetTarget() |             cp.resetTarget() | ||||||
|             self.logger.info(f"Flashed Successfully") |             self.logger.info(f"Flashed Successfully") | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく