Merge in keymap level to XAP info.json payload

This commit is contained in:
zvecr 2022-03-20 01:25:04 +00:00
parent 29f349b90b
commit b365cbce15
3 changed files with 91 additions and 44 deletions

View File

@ -1,19 +1,13 @@
"""This script generates the XAP protocol generated sources to be compiled into QMK firmware.
"""
import json
import gzip
from milc import cli
from qmk.path import normpath
from qmk.info import info_json
from qmk.commands import get_chunks, dump_lines
from qmk.keyboard import keyboard_completer, keyboard_folder
from qmk.xap.gen_firmware.info_generator import generate_info
from qmk.xap.gen_firmware.inline_generator import generate_inline
from qmk.xap.gen_firmware.header_generator import generate_header
from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE
@cli.argument('-o', '--output', type=normpath, help='File to write to')
@cli.subcommand('Generates the XAP protocol include.', hidden=False if cli.config.user.developer else True)
@ -44,36 +38,14 @@ def xap_generate_qmk_h(cli):
def xap_generate_info_h(cli):
"""Generates the XAP info.json payload header file, generated during normal build.
"""
# Determine our keyboard
# Determine our keyboard/keymap
if not cli.args.keyboard:
cli.log.error('Missing parameter: --keyboard')
cli.subcommands['xap-generate-info-h'].print_help()
return False
if not cli.args.keymap:
cli.log.error('Missing parameter: --keymap')
cli.subcommands['xap-generate-info-h'].print_help()
return False
# TODO: merge in keymap level content
# Build the info.json file
kb_info_json = info_json(cli.args.keyboard)
# Minify
str_data = json.dumps(kb_info_json, separators=(',', ':'))
# Compress
compressed = gzip.compress(str_data.encode("utf-8"), compresslevel=9)
# split into lines to match xxd output
hex_array = ["0x{:02X}".format(b) for b in compressed]
data_len = len(hex_array)
data = ""
for chunk in get_chunks(hex_array, 12):
data += f' {", ".join(chunk)},\n'
lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#pragma once', '']
# Gen output file
lines.append('unsigned char info_json_gz[] = {')
lines.append(data)
lines.append('};')
lines.append(f'unsigned int info_json_gz_len = {data_len};')
dump_lines(cli.args.output, lines)
generate_info(cli.args.output, cli.args.keyboard, cli.args.keymap)

View File

@ -8,10 +8,10 @@ from dotty_dict import dotty
from milc import cli
from qmk.constants import CHIBIOS_PROCESSORS, LUFA_PROCESSORS, VUSB_PROCESSORS
from qmk.c_parse import find_layouts
from qmk.c_parse import find_layouts, parse_config_h_file
from qmk.json_schema import deep_update, json_load, validate
from qmk.keyboard import config_h, rules_mk
from qmk.keymap import list_keymaps
from qmk.keymap import list_keymaps, locate_keymap
from qmk.makefile import parse_rules_mk_file
from qmk.math import compute
@ -68,8 +68,8 @@ def info_json(keyboard):
# Merge in the data from info.json, config.h, and rules.mk
info_data = merge_info_jsons(keyboard, info_data)
info_data = _extract_rules_mk(info_data)
info_data = _extract_config_h(info_data)
info_data = _extract_rules_mk(info_data, rules_mk(str(keyboard)))
info_data = _extract_config_h(info_data, config_h(str(keyboard)))
# Ensure that we have matrix row and column counts
info_data = _matrix_size(info_data)
@ -257,6 +257,10 @@ def _extract_split_main(info_data, config_c):
def _extract_split_transport(info_data, config_c):
# TODO: Ignore?
if 'split' not in info_data:
return
# Figure out the transport method
if config_c.get('USE_I2C') is True:
if 'split' not in info_data:
@ -400,11 +404,9 @@ def _extract_device_version(info_data):
info_data['usb']['device_version'] = f'{major}.{minor}.{revision}'
def _extract_config_h(info_data):
def _extract_config_h(info_data, config_c):
"""Pull some keyboard information from existing config.h files
"""
config_c = config_h(info_data['keyboard_folder'])
# Pull in data from the json map
dotty_info = dotty(info_data)
info_config_map = json_load(Path('data/mappings/info_config.json'))
@ -472,10 +474,9 @@ def _extract_config_h(info_data):
return info_data
def _extract_rules_mk(info_data):
def _extract_rules_mk(info_data, rules):
"""Pull some keyboard information from existing rules.mk files
"""
rules = rules_mk(info_data['keyboard_folder'])
info_data['processor'] = rules.get('MCU', info_data.get('processor', 'atmega32u4'))
if info_data['processor'] in CHIBIOS_PROCESSORS:
@ -766,3 +767,37 @@ def find_info_json(keyboard):
# Return a list of the info.json files that actually exist
return [info_json for info_json in info_jsons if info_json.exists()]
def parse_keymap_json_file(file):
"""load a valid keymap.json
"""
if not file.exists():
return {}
km_info_json = json_load(file)
validate(km_info_json, 'qmk.keymap.v1')
return km_info_json
def keymap_json(keyboard, keymap):
"""Generate the info.json data for a specific keymap.
"""
keymap_folder = locate_keymap(keyboard, keymap).parent
# Files to scan
keymap_config = keymap_folder / 'config.h'
keymap_rules = keymap_folder / 'rules.mk'
keymap_file = keymap_folder / 'keymap.json'
# Build the info.json file
kb_info_json = info_json(keyboard)
# Merge in the data from keymap.json
km_info_json = parse_keymap_json_file(keymap_file).get('config', {})
deep_update(kb_info_json, km_info_json)
# Merge in the data from config.h, and rules.mk
_extract_rules_mk(kb_info_json, parse_rules_mk_file(keymap_rules))
_extract_config_h(kb_info_json, parse_config_h_file(keymap_config))
return kb_info_json

View File

@ -0,0 +1,40 @@
"""This script generates the XAP info.json payload header to be compiled into QMK.
"""
import json
import gzip
from qmk.info import keymap_json
from qmk.commands import get_chunks, dump_lines
from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE
def generate_info(output_file, keyboard, keymap):
# Build the info.json file
km_info_json = keymap_json(keyboard, keymap)
# TODO: Munge to XAP requirements
# Minify
str_data = json.dumps(km_info_json, separators=(',', ':'))
# Compress
compressed = gzip.compress(str_data.encode("utf-8"), compresslevel=9)
# split into lines to match xxd output
hex_array = ["0x{:02X}".format(b) for b in compressed]
data_len = len(hex_array)
data = ""
for chunk in get_chunks(hex_array, 12):
data += f' {", ".join(chunk)},\n'
lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#pragma once', '']
# Gen output file
lines.append('unsigned char info_json_gz[] = {')
lines.append(data)
lines.append('};')
lines.append(f'unsigned int info_json_gz_len = {data_len};')
dump_lines(output_file, lines)