diff options
Diffstat (limited to 'lib/python')
| -rw-r--r-- | lib/python/qmk/cli/doctor/macos.py | 2 | ||||
| -rw-r--r-- | lib/python/qmk/cli/flash.py | 2 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/generate/config_h.py | 29 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/generate/info_json.py | 8 | ||||
| -rw-r--r-- | lib/python/qmk/constants.py | 2 | ||||
| -rw-r--r-- | lib/python/qmk/git.py | 4 | ||||
| -rw-r--r-- | lib/python/qmk/info.py | 58 | ||||
| -rw-r--r-- | lib/python/qmk/json_schema.py | 6 | 
8 files changed, 98 insertions, 13 deletions
| diff --git a/lib/python/qmk/cli/doctor/macos.py b/lib/python/qmk/cli/doctor/macos.py index 00fb272858..5d088c9492 100644 --- a/lib/python/qmk/cli/doctor/macos.py +++ b/lib/python/qmk/cli/doctor/macos.py @@ -8,6 +8,6 @@ from .check import CheckStatus  def os_test_macos():      """Run the Mac specific tests.      """ -    cli.log.info("Detected {fg_cyan}macOS %s{fg_reset}.", platform.mac_ver()[0]) +    cli.log.info("Detected {fg_cyan}macOS %s (%s){fg_reset}.", platform.mac_ver()[0], 'Apple Silicon' if platform.processor() == 'arm' else 'Intel')      return CheckStatus.OK diff --git a/lib/python/qmk/cli/flash.py b/lib/python/qmk/cli/flash.py index 216896b974..ebe739c50e 100644 --- a/lib/python/qmk/cli/flash.py +++ b/lib/python/qmk/cli/flash.py @@ -33,6 +33,8 @@ def print_bootloader_help():      cli.echo('\tdfu-split-right')      cli.echo('\tdfu-util-split-left')      cli.echo('\tdfu-util-split-right') +    cli.echo('\tuf2-split-left') +    cli.echo('\tuf2-split-right')      cli.echo('For more info, visit https://docs.qmk.fm/#/flashing') diff --git a/lib/python/qmk/cli/generate/config_h.py b/lib/python/qmk/cli/generate/config_h.py index 893892c479..9d50368aba 100755 --- a/lib/python/qmk/cli/generate/config_h.py +++ b/lib/python/qmk/cli/generate/config_h.py @@ -134,6 +134,29 @@ def generate_config_items(kb_info_json, config_h_lines):              config_h_lines.append(f'#endif // {config_key}') +def generate_encoder_config(encoder_json, config_h_lines, postfix=''): +    """Generate the config.h lines for encoders.""" +    a_pads = [] +    b_pads = [] +    resolutions = [] +    for encoder in encoder_json.get("rotary", []): +        a_pads.append(encoder["pin_a"]) +        b_pads.append(encoder["pin_b"]) +        resolutions.append(str(encoder.get("resolution", 4))) + +    config_h_lines.append(f'#ifndef ENCODERS_PAD_A{postfix}') +    config_h_lines.append(f'#   define ENCODERS_PAD_A{postfix} {{ { ", ".join(a_pads) } }}') +    config_h_lines.append(f'#endif // ENCODERS_PAD_A{postfix}') + +    config_h_lines.append(f'#ifndef ENCODERS_PAD_B{postfix}') +    config_h_lines.append(f'#   define ENCODERS_PAD_B{postfix} {{ { ", ".join(b_pads) } }}') +    config_h_lines.append(f'#endif // ENCODERS_PAD_B{postfix}') + +    config_h_lines.append(f'#ifndef ENCODER_RESOLUTIONS{postfix}') +    config_h_lines.append(f'#   define ENCODER_RESOLUTIONS{postfix} {{ { ", ".join(resolutions) } }}') +    config_h_lines.append(f'#endif // ENCODER_RESOLUTIONS{postfix}') + +  def generate_split_config(kb_info_json, config_h_lines):      """Generate the config.h lines for split boards."""      if 'primary' in kb_info_json['split']: @@ -173,6 +196,9 @@ def generate_split_config(kb_info_json, config_h_lines):      if 'right' in kb_info_json['split'].get('matrix_pins', {}):          config_h_lines.append(matrix_pins(kb_info_json['split']['matrix_pins']['right'], '_RIGHT')) +    if 'right' in kb_info_json['split'].get('encoder', {}): +        generate_encoder_config(kb_info_json['split']['encoder']['right'], config_h_lines, '_RIGHT') +  @cli.argument('-o', '--output', arg_only=True, type=normpath, help='File to write to')  @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") @@ -198,6 +224,9 @@ def generate_config_h(cli):      if 'matrix_pins' in kb_info_json:          config_h_lines.append(matrix_pins(kb_info_json['matrix_pins'])) +    if 'encoder' in kb_info_json: +        generate_encoder_config(kb_info_json['encoder'], config_h_lines) +      if 'split' in kb_info_json:          generate_split_config(kb_info_json, config_h_lines) diff --git a/lib/python/qmk/cli/generate/info_json.py b/lib/python/qmk/cli/generate/info_json.py index 284d1a8510..0dc80f10cc 100755 --- a/lib/python/qmk/cli/generate/info_json.py +++ b/lib/python/qmk/cli/generate/info_json.py @@ -5,7 +5,7 @@ Compile an info.json for a particular keyboard and pretty-print it.  import json  from argcomplete.completers import FilesCompleter -from jsonschema import Draft7Validator, RefResolver, validators +from jsonschema import Draft202012Validator, RefResolver, validators  from milc import cli  from pathlib import Path @@ -18,7 +18,7 @@ from qmk.path import is_keyboard, normpath  def pruning_validator(validator_class): -    """Extends Draft7Validator to remove properties that aren't specified in the schema. +    """Extends Draft202012Validator to remove properties that aren't specified in the schema.      """      validate_properties = validator_class.VALIDATORS["properties"] @@ -37,10 +37,10 @@ def strip_info_json(kb_info_json):      """Remove the API-only properties from the info.json.      """      schema_store = compile_schema_store() -    pruning_draft_7_validator = pruning_validator(Draft7Validator) +    pruning_draft_validator = pruning_validator(Draft202012Validator)      schema = schema_store['qmk.keyboard.v1']      resolver = RefResolver.from_schema(schema_store['qmk.keyboard.v1'], store=schema_store) -    validator = pruning_draft_7_validator(schema, resolver=resolver).validate +    validator = pruning_draft_validator(schema, resolver=resolver).validate      return validator(kb_info_json) diff --git a/lib/python/qmk/constants.py b/lib/python/qmk/constants.py index a54d9058bc..be85a1dbff 100644 --- a/lib/python/qmk/constants.py +++ b/lib/python/qmk/constants.py @@ -14,7 +14,7 @@ QMK_FIRMWARE_UPSTREAM = 'qmk/qmk_firmware'  MAX_KEYBOARD_SUBFOLDERS = 5  # Supported processor types -CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK66FX1M0', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F405', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L442', 'STM32L443', 'GD32VF103', 'WB32F3G71', 'WB32FQ95' +CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK66FX1M0', 'RP2040', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F405', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L442', 'STM32L443', 'GD32VF103', 'WB32F3G71', 'WB32FQ95'  LUFA_PROCESSORS = 'at90usb162', 'atmega16u2', 'atmega32u2', 'atmega16u4', 'atmega32u4', 'at90usb646', 'at90usb647', 'at90usb1286', 'at90usb1287', None  VUSB_PROCESSORS = 'atmega32a', 'atmega328p', 'atmega328', 'attiny85' diff --git a/lib/python/qmk/git.py b/lib/python/qmk/git.py index f493628492..960184a0a2 100644 --- a/lib/python/qmk/git.py +++ b/lib/python/qmk/git.py @@ -111,9 +111,9 @@ def git_check_deviation(active_branch):  def git_get_ignored_files(check_dir='.'): -    """Return a list of files that would be captured by the current .gitingore +    """Return a list of files that would be captured by the current .gitignore      """ -    invalid = cli.run(['git', 'ls-files', '-c', '-o', '-i', '--exclude-standard', check_dir]) +    invalid = cli.run(['git', 'ls-files', '-c', '-o', '-i', '--exclude-from=.gitignore', check_dir])      if invalid.returncode != 0:          return []      return invalid.stdout.strip().splitlines() diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 23761d71b7..d308de9db8 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -218,6 +218,62 @@ def _extract_audio(info_data, config_c):          info_data['audio'] = {'pins': audio_pins} +def _extract_encoders_values(config_c, postfix=''): +    """Common encoder extraction logic +    """ +    a_pad = config_c.get(f'ENCODERS_PAD_A{postfix}', '').replace(' ', '')[1:-1] +    b_pad = config_c.get(f'ENCODERS_PAD_B{postfix}', '').replace(' ', '')[1:-1] +    resolutions = config_c.get(f'ENCODER_RESOLUTIONS{postfix}', '').replace(' ', '')[1:-1] + +    default_resolution = config_c.get('ENCODER_RESOLUTION', '4') + +    if a_pad and b_pad: +        a_pad = list(filter(None, a_pad.split(','))) +        b_pad = list(filter(None, b_pad.split(','))) +        resolutions = list(filter(None, resolutions.split(','))) +        resolutions += [default_resolution] * (len(a_pad) - len(resolutions)) + +        encoders = [] +        for index in range(len(a_pad)): +            encoders.append({'pin_a': a_pad[index], 'pin_b': b_pad[index], "resolution": int(resolutions[index])}) + +        return encoders + + +def _extract_encoders(info_data, config_c): +    """Populate data about encoder pins +    """ +    encoders = _extract_encoders_values(config_c) +    if encoders: +        if 'encoder' not in info_data: +            info_data['encoder'] = {} + +        if 'rotary' in info_data['encoder']: +            _log_warning(info_data, 'Encoder config is specified in both config.h and info.json (encoder.rotary) (Value: %s), the config.h value wins.' % info_data['encoder']['rotary']) + +        info_data['encoder']['rotary'] = encoders + + +def _extract_split_encoders(info_data, config_c): +    """Populate data about split encoder pins +    """ +    encoders = _extract_encoders_values(config_c, '_RIGHT') +    if encoders: +        if 'split' not in info_data: +            info_data['split'] = {} + +        if 'encoder' not in info_data['split']: +            info_data['split']['encoder'] = {} + +        if 'right' not in info_data['split']['encoder']: +            info_data['split']['encoder']['right'] = {} + +        if 'rotary' in info_data['split']['encoder']['right']: +            _log_warning(info_data, 'Encoder config is specified in both config.h and info.json (encoder.rotary) (Value: %s), the config.h value wins.' % info_data['split']['encoder']['right']['rotary']) + +        info_data['split']['encoder']['right']['rotary'] = encoders + +  def _extract_secure_unlock(info_data, config_c):      """Populate data about the secure unlock sequence      """ @@ -506,6 +562,8 @@ def _extract_config_h(info_data, config_c):      _extract_split_main(info_data, config_c)      _extract_split_transport(info_data, config_c)      _extract_split_right_pins(info_data, config_c) +    _extract_encoders(info_data, config_c) +    _extract_split_encoders(info_data, config_c)      _extract_device_version(info_data)      return info_data diff --git a/lib/python/qmk/json_schema.py b/lib/python/qmk/json_schema.py index 682346113e..01175146b5 100644 --- a/lib/python/qmk/json_schema.py +++ b/lib/python/qmk/json_schema.py @@ -68,11 +68,7 @@ def create_validator(schema):      schema_store = compile_schema_store()      resolver = jsonschema.RefResolver.from_schema(schema_store[schema], store=schema_store) -    # TODO: Remove this after the jsonschema>=4 requirement had time to reach users -    try: -        return jsonschema.Draft202012Validator(schema_store[schema], resolver=resolver).validate -    except AttributeError: -        return jsonschema.Draft7Validator(schema_store[schema], resolver=resolver).validate +    return jsonschema.Draft202012Validator(schema_store[schema], resolver=resolver).validate  def validate(data, schema): | 
