1# Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) 2# 3# SPDX-License-Identifier: Apache-2.0 4 5'''Runner for the Official Bouffalo Lab open source command-line flash tool (bflb-mcu-tool)''' 6 7from runners.core import MissingProgram, RunnerCaps, ZephyrBinaryRunner 8 9DEFAULT_PORT = '/dev/ttyUSB0' 10DEFAULT_SPEED = '115200' 11DEFAULT_CHIP = 'bl602' 12DEFAULT_EXECUTABLE = "bflb-mcu-tool-uart" 13 14 15class BlFlashCommandBinaryRunner(ZephyrBinaryRunner): 16 '''Runner front-end for bflb-mcu-tool.''' 17 18 def __init__( 19 self, cfg, port=DEFAULT_PORT, baudrate=DEFAULT_SPEED, chipname=DEFAULT_CHIP, erase=False 20 ): 21 super().__init__(cfg) 22 self.port = port 23 self.baudrate = baudrate 24 self.chipname = chipname 25 self.erase = bool(erase) 26 27 @classmethod 28 def name(cls): 29 return 'bflb_mcu_tool' 30 31 @classmethod 32 def capabilities(cls): 33 return RunnerCaps(commands={'flash'}, erase=True, dev_id=True) 34 35 @classmethod 36 def do_add_parser(cls, parser): 37 parser.set_defaults(dev_id=DEFAULT_PORT) 38 parser.add_argument( 39 '-b', 40 '--baudrate', 41 default=DEFAULT_SPEED, 42 help=f"serial port speed to use, default is {str(DEFAULT_SPEED)}", 43 ) 44 parser.add_argument( 45 '-ch', 46 '--chipname', 47 default=DEFAULT_CHIP, 48 help=f"chip model, default is {str(DEFAULT_CHIP)}", 49 choices=['bl602', 'bl606p', 'bl616', 'bl702', 'bl702l', 'bl808'], 50 ) 51 52 @classmethod 53 def do_create(cls, cfg, args): 54 return BlFlashCommandBinaryRunner( 55 cfg, port=args.dev_id, baudrate=args.baudrate, chipname=args.chipname, erase=args.erase 56 ) 57 58 def do_run(self, command, **kwargs): 59 try: 60 self.require(DEFAULT_EXECUTABLE) 61 except MissingProgram as err: 62 self.logger.error( 63 "You may use `pip install bflb-mcu-tool-uart` to install bflb-mcu-tool-uart" 64 ) 65 raise err 66 self.ensure_output('bin') 67 cmd_flash = [ 68 DEFAULT_EXECUTABLE, 69 '--port', 70 self.port, 71 '--baudrate', 72 self.baudrate, 73 '--chipname', 74 self.chipname, 75 '--firmware', 76 self.cfg.bin_file, 77 ] 78 if self.erase is True: 79 cmd_flash.append("--erase") 80 self.check_call(cmd_flash) 81