blob: f738bcf6a0f746f0a1ec60f790016257305ae5af [file] [log] [blame]
# 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()