| # Copyright 2023 The Pigweed Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| # use this file except in compliance with the License. You may obtain a copy of |
| # the License at |
| # |
| # https://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations under |
| # the License. |
| """Flash Gonk via DFU.""" |
| |
| import argparse |
| from pathlib import Path |
| import shutil |
| import signal |
| import subprocess |
| import sys |
| |
| import pw_cli.color |
| |
| from gonk_tools.firmware_files import bundled_bin_path |
| |
| _COLOR = pw_cli.color.colors() |
| |
| |
| def _parse_args(): |
| parser = argparse.ArgumentParser(description=__doc__) |
| |
| parser.add_argument( |
| '--bin-file', |
| help='Binary to flash', |
| type=Path, |
| ) |
| return parser.parse_args() |
| |
| |
| def pyfu_flash(bin_file: Path) -> int: |
| pyfu_util_binary = shutil.which('pyfu-usb') |
| if not pyfu_util_binary or not Path(pyfu_util_binary).is_file(): |
| raise FileNotFoundError('Unable to find "pyfu-usb"') |
| |
| pyfu_flash_args = [ |
| pyfu_util_binary, |
| '--verbose', |
| '--device', |
| '0483:df11', |
| '--address', |
| '0x08000000', |
| '--download', |
| str(bin_file), |
| ] |
| |
| print( |
| _COLOR.cyan('Running ==>'), |
| ' '.join(pyfu_flash_args), |
| ) |
| |
| # Ignore Ctrl-C to allow pyfu-usb to handle normally. |
| signal.signal(signal.SIGINT, signal.SIG_IGN) |
| return subprocess.run(pyfu_flash_args, check=False).returncode |
| |
| |
| def dfu_flash(bin_file: Path) -> int: |
| dfu_util_binary = shutil.which('dfu-util') |
| if not dfu_util_binary or not Path(dfu_util_binary).is_file(): |
| raise FileNotFoundError('Unable to find "dfu-util"') |
| |
| dfu_flash_args = [ |
| dfu_util_binary, |
| '--device', |
| '0483:df11', |
| '--dfuse-address', |
| '0x08000000:leave', |
| '--alt', |
| '0', |
| '--download', |
| str(bin_file), |
| ] |
| |
| print( |
| _COLOR.cyan('Running ==>'), |
| ' '.join(dfu_flash_args), |
| ) |
| |
| # Ignore Ctrl-C to allow pyfu-usb to handle normally. |
| signal.signal(signal.SIGINT, signal.SIG_IGN) |
| return subprocess.run(dfu_flash_args, check=False).returncode |
| |
| |
| def main( |
| bin_file: Path | None = None, |
| ) -> int: |
| """Flash Gonk via pyfu-usb.""" |
| |
| if not bin_file: |
| bin_file = bundled_bin_path() |
| |
| if not bin_file or not bin_file.is_file(): |
| raise FileNotFoundError( |
| f'Unable to find the binary file to flash: "{bin_file}"' |
| ) |
| |
| pyfu_flash_returncode = pyfu_flash(bin_file) |
| if pyfu_flash_returncode == 0: |
| return 0 |
| |
| print( |
| _COLOR.red('ERROR:'), |
| 'Unable to flash with pyfu-util; Falling back to "dfu-util"', |
| ) |
| return dfu_flash(bin_file) |
| |
| |
| def flash() -> None: |
| sys.exit(main(**vars(_parse_args()))) |
| |
| |
| if __name__ == '__main__': |
| flash() |