summaryrefslogtreecommitdiff
path: root/lib/python/qmk/cli/flash.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python/qmk/cli/flash.py')
-rw-r--r--lib/python/qmk/cli/flash.py120
1 files changed, 69 insertions, 51 deletions
diff --git a/lib/python/qmk/cli/flash.py b/lib/python/qmk/cli/flash.py
index ebe739c50e..c39f4b36d4 100644
--- a/lib/python/qmk/cli/flash.py
+++ b/lib/python/qmk/cli/flash.py
@@ -4,6 +4,7 @@ You can compile a keymap already in the repo or using a QMK Configurator export.
A bootloader must be specified.
"""
from subprocess import DEVNULL
+import sys
from argcomplete.completers import FilesCompleter
from milc import cli
@@ -12,6 +13,7 @@ import qmk.path
from qmk.decorators import automagic_keyboard, automagic_keymap
from qmk.commands import compile_configurator_json, create_make_command, parse_configurator_json
from qmk.keyboard import keyboard_completer, keyboard_folder
+from qmk.flashers import flasher
def print_bootloader_help():
@@ -38,9 +40,10 @@ def print_bootloader_help():
cli.echo('For more info, visit https://docs.qmk.fm/#/flashing')
-@cli.argument('filename', nargs='?', arg_only=True, type=qmk.path.FileType('r'), completer=FilesCompleter('.json'), help='The configurator export JSON to compile.')
+@cli.argument('filename', nargs='?', arg_only=True, type=qmk.path.FileType('r'), completer=FilesCompleter('.json'), help='A configurator export JSON to be compiled and flashed or a pre-compiled binary firmware file (bin/hex) to be flashed.')
@cli.argument('-b', '--bootloaders', action='store_true', help='List the available bootloaders.')
@cli.argument('-bl', '--bootloader', default='flash', help='The flash command, corresponding to qmk\'s make options of bootloaders.')
+@cli.argument('-m', '--mcu', help='The MCU name. Required for HalfKay, HID, USBAspLoader and ISP flashing.')
@cli.argument('-km', '--keymap', help='The keymap to build a firmware for. Use this if you dont have a configurator file. Ignored when a configurator file is supplied.')
@cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='The keyboard to build a firmware for. Use this if you dont have a configurator file. Ignored when a configurator file is supplied.')
@cli.argument('-n', '--dry-run', arg_only=True, action='store_true', help="Don't actually build, just show the make command to be run.")
@@ -53,6 +56,8 @@ def print_bootloader_help():
def flash(cli):
"""Compile and or flash QMK Firmware or keyboard/layout
+ If a binary firmware is supplied, try to flash that.
+
If a Configurator JSON export is supplied this command will create a new keymap. Keymap and Keyboard arguments
will be ignored.
@@ -60,56 +65,69 @@ def flash(cli):
If bootloader is omitted the make system will use the configured bootloader for that keyboard.
"""
- if cli.args.clean and not cli.args.filename and not cli.args.dry_run:
- if cli.config.flash.keyboard and cli.config.flash.keymap:
- command = create_make_command(cli.config.flash.keyboard, cli.config.flash.keymap, 'clean')
- cli.run(command, capture_output=False, stdin=DEVNULL)
-
- # Build the environment vars
- envs = {}
- for env in cli.args.env:
- if '=' in env:
- key, value = env.split('=', 1)
- envs[key] = value
- else:
- cli.log.warning('Invalid environment variable: %s', env)
-
- # Determine the compile command
- command = ''
-
- if cli.args.bootloaders:
- # Provide usage and list bootloaders
- cli.echo('usage: qmk flash [-h] [-b] [-n] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
- print_bootloader_help()
- return False
-
- if cli.args.filename:
- # Handle compiling a configurator JSON
- user_keymap = parse_configurator_json(cli.args.filename)
- keymap_path = qmk.path.keymap(user_keymap['keyboard'])
- command = compile_configurator_json(user_keymap, cli.args.bootloader, parallel=cli.config.flash.parallel, **envs)
-
- cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap'])
+ if cli.args.filename and cli.args.filename.suffix in ['.bin', '.hex']:
+ # Try to flash binary firmware
+ cli.echo('Flashing binary firmware...\nPlease reset your keyboard into bootloader mode now!\nPress Ctrl-C to exit.\n')
+ try:
+ err, msg = flasher(cli.args.mcu, cli.args.filename)
+ if err:
+ cli.log.error(msg)
+ return False
+ except KeyboardInterrupt:
+ cli.log.info('Ctrl-C was pressed, exiting...')
+ sys.exit(0)
else:
- if cli.config.flash.keyboard and cli.config.flash.keymap:
- # Generate the make command for a specific keyboard/keymap.
- command = create_make_command(cli.config.flash.keyboard, cli.config.flash.keymap, cli.args.bootloader, parallel=cli.config.flash.parallel, **envs)
-
- elif not cli.config.flash.keyboard:
- cli.log.error('Could not determine keyboard!')
- elif not cli.config.flash.keymap:
- cli.log.error('Could not determine keymap!')
-
- # Compile the firmware, if we're able to
- if command:
- cli.log.info('Compiling keymap with {fg_cyan}%s', ' '.join(command))
- if not cli.args.dry_run:
- cli.echo('\n')
- compile = cli.run(command, capture_output=False, stdin=DEVNULL)
- return compile.returncode
+ if cli.args.clean and not cli.args.filename and not cli.args.dry_run:
+ if cli.config.flash.keyboard and cli.config.flash.keymap:
+ command = create_make_command(cli.config.flash.keyboard, cli.config.flash.keymap, 'clean')
+ cli.run(command, capture_output=False, stdin=DEVNULL)
+
+ # Build the environment vars
+ envs = {}
+ for env in cli.args.env:
+ if '=' in env:
+ key, value = env.split('=', 1)
+ envs[key] = value
+ else:
+ cli.log.warning('Invalid environment variable: %s', env)
+
+ # Determine the compile command
+ command = ''
+
+ if cli.args.bootloaders:
+ # Provide usage and list bootloaders
+ cli.echo('usage: qmk flash [-h] [-b] [-n] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
+ print_bootloader_help()
+ return False
+
+ if cli.args.filename:
+ # Handle compiling a configurator JSON
+ user_keymap = parse_configurator_json(cli.args.filename)
+ keymap_path = qmk.path.keymap(user_keymap['keyboard'])
+ command = compile_configurator_json(user_keymap, cli.args.bootloader, parallel=cli.config.flash.parallel, **envs)
+
+ cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap'])
- else:
- cli.log.error('You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.')
- cli.echo('usage: qmk flash [-h] [-b] [-n] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
- return False
+ else:
+ if cli.config.flash.keyboard and cli.config.flash.keymap:
+ # Generate the make command for a specific keyboard/keymap.
+ command = create_make_command(cli.config.flash.keyboard, cli.config.flash.keymap, cli.args.bootloader, parallel=cli.config.flash.parallel, **envs)
+
+ elif not cli.config.flash.keyboard:
+ cli.log.error('Could not determine keyboard!')
+ elif not cli.config.flash.keymap:
+ cli.log.error('Could not determine keymap!')
+
+ # Compile the firmware, if we're able to
+ if command:
+ cli.log.info('Compiling keymap with {fg_cyan}%s', ' '.join(command))
+ if not cli.args.dry_run:
+ cli.echo('\n')
+ compile = cli.run(command, capture_output=False, stdin=DEVNULL)
+ return compile.returncode
+
+ else:
+ cli.log.error('You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.')
+ cli.echo('usage: qmk flash [-h] [-b] [-n] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]')
+ return False