2019-10-05 08:38:34 +02:00
""" Compile and flash QMK Firmware
You can compile a keymap already in the repo or using a QMK Configurator export .
A bootloader must be specified .
"""
2021-04-15 04:00:22 +02:00
from argcomplete . completers import FilesCompleter
2023-11-15 06:24:54 +01:00
from pathlib import Path
2022-10-20 15:35:27 +02:00
2019-11-20 23:54:18 +01:00
from milc import cli
2020-03-13 23:47:04 +01:00
import qmk . path
from qmk . decorators import automagic_keyboard , automagic_keymap
2023-11-15 06:24:54 +01:00
from qmk . commands import build_environment
2021-04-15 04:00:22 +02:00
from qmk . keyboard import keyboard_completer , keyboard_folder
2023-01-19 01:24:13 +01:00
from qmk . keymap import keymap_completer , locate_keymap
2022-08-20 07:39:19 +02:00
from qmk . flashers import flasher
2023-11-15 06:24:54 +01:00
from qmk . build_targets import KeyboardKeymapBuildTarget , JsonKeymapBuildTarget
2023-01-19 01:24:13 +01:00
2023-01-01 05:51:29 +01:00
def _list_bootloaders ( ) :
2019-10-05 08:38:34 +02:00
""" Prints the available bootloaders listed in docs.qmk.fm.
"""
2023-01-01 05:51:29 +01:00
cli . print_help ( )
2019-10-05 08:38:34 +02:00
cli . log . info ( ' Here are the available bootloaders: ' )
2021-10-15 23:07:33 +02:00
cli . echo ( ' \t avrdude ' )
cli . echo ( ' \t bootloadhid ' )
2019-10-05 08:38:34 +02:00
cli . echo ( ' \t dfu ' )
2021-10-15 23:07:33 +02:00
cli . echo ( ' \t dfu-util ' )
cli . echo ( ' \t mdloader ' )
cli . echo ( ' \t st-flash ' )
cli . echo ( ' \t st-link-cli ' )
cli . log . info ( ' Enhanced variants for split keyboards: ' )
cli . echo ( ' \t avrdude-split-left ' )
cli . echo ( ' \t avrdude-split-right ' )
2019-10-05 08:38:34 +02:00
cli . echo ( ' \t dfu-ee ' )
cli . echo ( ' \t dfu-split-left ' )
cli . echo ( ' \t dfu-split-right ' )
cli . echo ( ' \t dfu-util-split-left ' )
cli . echo ( ' \t dfu-util-split-right ' )
2022-05-31 00:04:50 +02:00
cli . echo ( ' \t uf2-split-left ' )
cli . echo ( ' \t uf2-split-right ' )
2019-10-05 08:38:34 +02:00
cli . echo ( ' For more info, visit https://docs.qmk.fm/#/flashing ' )
2023-01-01 05:51:29 +01:00
return False
def _flash_binary ( filename , mcu ) :
""" Try to flash binary firmware
"""
cli . echo ( ' Flashing binary firmware... \n Please reset your keyboard into bootloader mode now! \n Press Ctrl-C to exit. \n ' )
try :
err , msg = flasher ( mcu , filename )
if err :
cli . log . error ( msg )
return False
except KeyboardInterrupt :
cli . log . info ( ' Ctrl-C was pressed, exiting... ' )
return True
2019-10-05 08:38:34 +02:00
2019-11-16 08:10:19 +01:00
2022-08-20 07:39:19 +02:00
@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. ' )
2020-03-13 23:47:04 +01:00
@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. ' )
2022-08-20 07:39:19 +02:00
@cli.argument ( ' -m ' , ' --mcu ' , help = ' The MCU name. Required for HalfKay, HID, USBAspLoader and ISP flashing. ' )
2023-01-01 05:51:29 +01:00
@cli.argument ( ' -kb ' , ' --keyboard ' , type = keyboard_folder , completer = keyboard_completer , help = ' The keyboard to build a firmware for. Ignored when a configurator export is supplied. ' )
@cli.argument ( ' -km ' , ' --keymap ' , completer = keymap_completer , help = ' The keymap to build a firmware for. Ignored when a configurator export is supplied. ' )
2020-03-13 23:47:04 +01:00
@cli.argument ( ' -n ' , ' --dry-run ' , arg_only = True , action = ' store_true ' , help = " Don ' t actually build, just show the make command to be run. " )
2021-08-18 00:46:59 +02:00
@cli.argument ( ' -j ' , ' --parallel ' , type = int , default = 1 , help = " Set the number of parallel make jobs; 0 means unlimited. " )
2021-01-17 00:13:04 +01:00
@cli.argument ( ' -e ' , ' --env ' , arg_only = True , action = ' append ' , default = [ ] , help = " Set a variable to be passed to make. May be passed multiple times. " )
@cli.argument ( ' -c ' , ' --clean ' , arg_only = True , action = ' store_true ' , help = " Remove object files before compiling. " )
2019-10-05 08:38:34 +02:00
@cli.subcommand ( ' QMK Flash. ' )
2020-03-13 23:47:04 +01:00
@automagic_keyboard
@automagic_keymap
2019-10-05 08:38:34 +02:00
def flash ( cli ) :
""" Compile and or flash QMK Firmware or keyboard/layout
2022-08-20 07:39:19 +02:00
If a binary firmware is supplied , try to flash that .
2023-01-01 05:51:29 +01:00
If a Configurator export is supplied this command will create a new keymap , overwriting an existing keymap if one exists .
2019-10-05 08:38:34 +02:00
2023-01-01 05:51:29 +01:00
If a keyboard and keymap are provided this command will build a firmware based on that .
2019-10-05 08:38:34 +02:00
2020-03-13 23:47:04 +01:00
If bootloader is omitted the make system will use the configured bootloader for that keyboard .
2019-10-05 08:38:34 +02:00
"""
2023-11-15 06:24:54 +01:00
if cli . args . filename and isinstance ( cli . args . filename , Path ) and cli . args . filename . suffix in [ ' .bin ' , ' .hex ' , ' .uf2 ' ] :
2023-01-01 05:51:29 +01:00
return _flash_binary ( cli . args . filename , cli . args . mcu )
2022-10-20 15:35:27 +02:00
if cli . args . bootloaders :
2023-01-01 05:51:29 +01:00
return _list_bootloaders ( )
2022-10-20 15:35:27 +02:00
# Build the environment vars
envs = build_environment ( cli . args . env )
2023-11-15 06:24:54 +01:00
# Handler for the build target
target = None
2022-10-20 15:35:27 +02:00
if cli . args . filename :
2023-11-15 06:24:54 +01:00
# if we were given a filename, assume we have a json build target
target = JsonKeymapBuildTarget ( cli . args . filename )
2022-10-20 15:35:27 +02:00
elif cli . config . flash . keyboard and cli . config . flash . keymap :
2023-11-15 06:24:54 +01:00
# if we got a keyboard and keymap, attempt to find it
if not locate_keymap ( cli . config . flash . keyboard , cli . config . flash . keymap ) :
2023-01-19 01:24:13 +01:00
cli . log . error ( ' Invalid keymap argument. ' )
cli . print_help ( )
return False
2023-11-15 06:24:54 +01:00
# If we got here, then we have a valid keyboard and keymap for a build target
target = KeyboardKeymapBuildTarget ( cli . config . flash . keyboard , cli . config . flash . keymap )
2022-10-20 15:35:27 +02:00
2023-11-15 06:24:54 +01:00
if not target :
2022-10-20 15:35:27 +02:00
cli . log . error ( ' You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap. ' )
cli . print_help ( )
return False
2023-11-15 06:24:54 +01:00
target . configure ( parallel = cli . config . flash . parallel , clean = cli . args . clean )
target . compile ( cli . args . bootloader , dry_run = cli . args . dry_run , * * envs )