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