From 3f4efa118d229c82cea42dadb4e7571e62467636 Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Sat, 3 Sep 2022 13:56:12 +0200 Subject: [PATCH] fix data-driven split handedness pin assignement --- data/schemas/keyboard.jsonschema | 36 ++++++- keyboards/tzarc/djinn/rev1/config.h | 1 - keyboards/tzarc/djinn/rev1/info.json | 5 + keyboards/tzarc/djinn/rev2/config.h | 1 - keyboards/tzarc/djinn/rev2/info.json | 5 + lib/python/qmk/cli/generate/config_h.py | 26 +++-- lib/python/qmk/info.py | 121 ++++++++++++++++++++---- 7 files changed, 160 insertions(+), 35 deletions(-) diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema index d608e8f79606..c4157517ffa2 100644 --- a/data/schemas/keyboard.jsonschema +++ b/data/schemas/keyboard.jsonschema @@ -576,7 +576,15 @@ } } }, + "main": { + "$comment": "deprecated - see handedness instead", + "deprecated": true, + "type": "string", + "enum": ["eeprom", "left", "matrix_grid", "pin", "right"] + }, "matrix_grid": { + "$comment": "deprecated - see handedness instead", + "deprecated": true, "type": "array", "items": {"$ref": "qmk.definitions.v1#/mcu_pin"} }, @@ -608,9 +616,31 @@ } } }, - "main": { - "type": "string", - "enum": ["eeprom", "left", "matrix_grid", "pin", "right"] + "handedness": { + "type": "object", + "additionalProperties": false, + "properties": { + "method": { + "type": "string", + "enum": ["pin", "matrix_grid", "eeprom", "usb"] + }, + "pin": { + "$comment": "only needed if method=pin, ignored otherwise", + "$ref": "qmk.definitions.v1#/mcu_pin" + }, + "matrix_grid": { + "$comment": "only needed if method=matrix_grid, ignored otherwise", + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": {"$ref": "qmk.definitions.v1#/mcu_pin"} + }, + "determined_side": { + "$comment": "defined which side is determined if the method evaluates positively: pin=High, matrix_grid=Low, eeprom=(ignored), usb=Host-detected", + "type": "string", + "enum": ["left", "right"] + } + } }, "soft_serial_pin": {"$ref": "qmk.definitions.v1#/mcu_pin"}, "soft_serial_speed": { diff --git a/keyboards/tzarc/djinn/rev1/config.h b/keyboards/tzarc/djinn/rev1/config.h index 5ced7003233c..4bbc0d174cad 100644 --- a/keyboards/tzarc/djinn/rev1/config.h +++ b/keyboards/tzarc/djinn/rev1/config.h @@ -3,7 +3,6 @@ #pragma once // Split configuration -#define SPLIT_HAND_PIN B11 #ifdef USE_PLUG_DETECT_PIN # define USB_VBUS_PIN B12 #endif diff --git a/keyboards/tzarc/djinn/rev1/info.json b/keyboards/tzarc/djinn/rev1/info.json index 65b9eb2eabfa..6d194cf40047 100644 --- a/keyboards/tzarc/djinn/rev1/info.json +++ b/keyboards/tzarc/djinn/rev1/info.json @@ -7,6 +7,11 @@ }, "split": { "soft_serial_pin": "B9", + "handedness": { + "method": "pin", + "pin": "B11", + "determined_side": "left" + }, "usb_detect": { "enabled": true } diff --git a/keyboards/tzarc/djinn/rev2/config.h b/keyboards/tzarc/djinn/rev2/config.h index 02224e4fc614..9ae00bf04c26 100644 --- a/keyboards/tzarc/djinn/rev2/config.h +++ b/keyboards/tzarc/djinn/rev2/config.h @@ -3,7 +3,6 @@ #pragma once // Split configuration -#define SPLIT_HAND_PIN B9 #define USB_VBUS_PIN B12 #define SERIAL_USART_DRIVER SD3 #define SERIAL_USART_PIN_SWAP diff --git a/keyboards/tzarc/djinn/rev2/info.json b/keyboards/tzarc/djinn/rev2/info.json index 22cafa74ae91..09b7e229b605 100644 --- a/keyboards/tzarc/djinn/rev2/info.json +++ b/keyboards/tzarc/djinn/rev2/info.json @@ -6,6 +6,11 @@ "max_brightness": 144 }, "split": { + "handedness": { + "method": "pin", + "pin": "B9", + "determined_side": "left" + }, "usb_detect": { "enabled": false } diff --git a/lib/python/qmk/cli/generate/config_h.py b/lib/python/qmk/cli/generate/config_h.py index 64d4db6ffe14..f4b82af779a4 100755 --- a/lib/python/qmk/cli/generate/config_h.py +++ b/lib/python/qmk/cli/generate/config_h.py @@ -130,23 +130,31 @@ def generate_encoder_config(encoder_json, config_h_lines, 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']: - if kb_info_json['split']['primary'] in ('left', 'right'): + if 'handedness' in kb_info_json['split'] and 'method' in kb_info_json['split']['handedness']: + if kb_info_json['split']['handedness']['method'] == 'usb': config_h_lines.append('') config_h_lines.append('#ifndef MASTER_LEFT') config_h_lines.append('# ifndef MASTER_RIGHT') - if kb_info_json['split']['primary'] == 'left': + if kb_info_json['split']['handedness'].get('determined_side', None) == 'left': config_h_lines.append('# define MASTER_LEFT') - elif kb_info_json['split']['primary'] == 'right': + elif kb_info_json['split']['handedness'].get('determined_side', None) == 'right': config_h_lines.append('# define MASTER_RIGHT') config_h_lines.append('# endif // MASTER_RIGHT') config_h_lines.append('#endif // MASTER_LEFT') - elif kb_info_json['split']['primary'] == 'pin': - config_h_lines.append(generate_define('SPLIT_HAND_PIN')) - elif kb_info_json['split']['primary'] == 'matrix_grid': - config_h_lines.append(generate_define('SPLIT_HAND_MATRIX_GRID', f'{{ {",".join(kb_info_json["split"]["matrix_grid"])} }}')) - elif kb_info_json['split']['primary'] == 'eeprom': + elif kb_info_json['split']['handedness']['method'] == 'pin': + config_h_lines.append(generate_define('SPLIT_HAND_PIN', kb_info_json["split"]["handedness"]["pin"])) + if kb_info_json['split']['handedness'].get('determined_side', None) == 'right': + # Handedness by Pin defaults to left if high, and right if low. + config_h_lines.append(generate_define('SPLIT_HAND_PIN_LOW_IS_LEFT')) + elif kb_info_json['split']['handedness']['method'] == 'matrix_grid': + config_h_lines.append(generate_define('SPLIT_HAND_MATRIX_GRID', f'{{ {",".join(kb_info_json["split"]["handedness"]["matrix_grid"])} }}')) + if kb_info_json['split']['handedness'].get('determined_side', None) == 'left': + # Handedness by Matrix Pin defaults to right if a diode is connected to this intersection, and right if not (intersection open). + config_h_lines.append(generate_define('SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT')) + elif kb_info_json['split']['handedness']['method'] == 'eeprom': config_h_lines.append(generate_define('EE_HANDS')) + else: + cli.log.debug("Unknown split.handedness.method configuration") if 'protocol' in kb_info_json['split'].get('transport', {}): if kb_info_json['split']['transport']['protocol'] == 'i2c': diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index dbd26153d84f..033ef4d32419 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -352,55 +352,134 @@ def _extract_secure_unlock(info_data, config_c): info_data['secure']['unlock_sequence'] = unlock_array -def _extract_split_main(info_data, config_c): - """Populate data about the split configuration - """ - # Figure out how the main half is determined +def _extract_split_handedness(info_data, config_c): + _extract_split_handedness_pin(info_data, config_c) + _extract_split_handedness_matrix_grid(info_data, config_c) + _extract_split_handedness_eeprom(info_data, config_c) + _extract_split_handedness_usb(info_data, config_c) + + +def _extract_split_handedness_pin(info_data, config_c): if config_c.get('SPLIT_HAND_PIN') is True: if 'split' not in info_data: info_data['split'] = {} + if 'handedness' not in info_data['split']: + info_data['split']['handedness'] = {} - if 'main' in info_data['split']: - _log_warning(info_data, 'Split main hand is specified in both config.h (SPLIT_HAND_PIN) and info.json (split.main) (Value: %s), the config.h value wins.' % info_data['split']['main']) + if info_data['split']['handedness'].get('method', '') == 'pin': + if 'pin' in info_data['split']['handedness']: + _log_warning(info_data, 'Split main hand is specified in both config.h (SPLIT_HAND_PIN) and info.json (split.handedness.method and split.handedness.pin) (Value: %s), the config.h value wins.' % info_data['split']['handedness']['pin']) + + info_data['split']['handedness'] = 'pin' + info_data['split']['handedness']['pin'] = _extract_pins(config_c['SPLIT_HAND_PIN'])[0] + + if config_c.get('SPLIT_HAND_PIN_LOW_IS_LEFT'): + if 'split' not in info_data: + info_data['split'] = {} + if 'handedness' not in info_data['split']: + info_data['split']['handedness'] = {} + + if info_data['split']['handedness'].get('method', '') == 'pin': + if info_data['split']['handedness'].get('determined_side', None) == 'left': + _log_warning( + info_data, 'Split main hand is specified in both config.h (SPLIT_HAND_PIN_LOW_IS_LEFT) and info.json (split.handedness.method and split.handedness.determined_side) (Value: %s), the config.h value wins.' % + info_data['split']['handedness']['determined_side'] + ) + + info_data['split']['handedness']['determined_side'] = 'right' + else: + if 'split' not in info_data: + info_data['split'] = {} + if 'handedness' not in info_data['split']: + info_data['split']['handedness'] = {} + info_data['split']['handedness']['determined_side'] = 'left' - info_data['split']['main'] = 'pin' +def _extract_split_handedness_matrix_grid(info_data, config_c): if config_c.get('SPLIT_HAND_MATRIX_GRID'): if 'split' not in info_data: info_data['split'] = {} + if 'handedness' not in info_data['split']: + info_data['split']['handedness'] = {} + + if info_data['split']['handedness'].get('method', '') == 'matrix_grid': + if 'matrix_grid' in info_data['split']['handedness']: + _log_warning( + info_data, + 'Split main hand is specified in both config.h (SPLIT_HAND_MATRIX_GRID) and info.json (split.handedness.method and split.handedness.matrix_grid) (Value: %s), the config.h value wins.' % info_data['split']['handedness']['matrix_grid'] + ) + + info_data['split']['handedness']['method'] = 'matrix_grid' + info_data['split']['handedness']['matrix_grid'] = _extract_pins(config_c['SPLIT_HAND_MATRIX_GRID']) - if 'main' in info_data['split']: - _log_warning(info_data, 'Split main hand is specified in both config.h (SPLIT_HAND_MATRIX_GRID) and info.json (split.main) (Value: %s), the config.h value wins.' % info_data['split']['main']) + if config_c.get('SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT'): + if 'split' not in info_data: + info_data['split'] = {} + if 'handedness' not in info_data['split']: + info_data['split']['handedness'] = {} - info_data['split']['main'] = 'matrix_grid' - info_data['split']['matrix_grid'] = _extract_pins(config_c['SPLIT_HAND_MATRIX_GRID']) + if info_data['split']['handedness'].get('method', '') == 'matrix_grid': + if info_data['split']['handedness'].get('determined_side', None) == 'right': + _log_warning( + info_data, 'Split main hand is specified in both config.h (SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT) and info.json (split.handedness.method and split.handedness.determined_side) (Value: %s), the config.h value wins.' % + info_data['split']['handedness']['determined_side'] + ) + info_data['split']['handedness']['determined_side'] = 'right' + else: + if 'split' not in info_data: + info_data['split'] = {} + if 'handedness' not in info_data['split']: + info_data['split']['handedness'] = {} + info_data['split']['handedness']['determined_side'] = 'left' + + +def _extract_split_handedness_eeprom(info_data, config_c): if config_c.get('EE_HANDS') is True: if 'split' not in info_data: info_data['split'] = {} + if 'handedness' not in info_data['split']: + info_data['split']['handedness'] = {} - if 'main' in info_data['split']: - _log_warning(info_data, 'Split main hand is specified in both config.h (EE_HANDS) and info.json (split.main) (Value: %s), the config.h value wins.' % info_data['split']['main']) + if info_data['split']['handedness'].get('method', '') == 'eeprom': + if 'pin' in info_data['split']['handedness']: + _log_warning(info_data, 'Split main hand is specified in both config.h (EE_HANDS) and info.json (split.handedness.method) (Value: %s), the config.h value wins.' % info_data['split']['handedness']['method']) - info_data['split']['main'] = 'eeprom' + info_data['split']['handedness']['method'] = 'eeprom' if config_c.get('MASTER_RIGHT') is True: if 'split' not in info_data: info_data['split'] = {} + if 'handedness' not in info_data['split']: + info_data['split']['handedness'] = {} + + if info_data['split']['handedness'].get('method', '') == 'usb': + if 'pin' in info_data['split']['handedness']: + _log_warning( + info_data, + 'Split main hand is specified in both config.h (MASTER_RIGHT) and info.json (split.handedness.method and split.handedness.determined_side) (Value: %s), the config.h value wins.' % info_data['split']['handedness']['determined_side'] + ) - if 'main' in info_data['split']: - _log_warning(info_data, 'Split main hand is specified in both config.h (MASTER_RIGHT) and info.json (split.main) (Value: %s), the config.h value wins.' % info_data['split']['main']) + info_data['split']['handedness']['method'] = 'usb' + info_data['split']['handedness']['determined_side'] = 'right' - info_data['split']['main'] = 'right' +def _extract_split_handedness_usb(info_data, config_c): if config_c.get('MASTER_LEFT') is True: if 'split' not in info_data: info_data['split'] = {} + if 'handedness' not in info_data['split']: + info_data['split']['handedness'] = {} - if 'main' in info_data['split']: - _log_warning(info_data, 'Split main hand is specified in both config.h (MASTER_LEFT) and info.json (split.main) (Value: %s), the config.h value wins.' % info_data['split']['main']) + if info_data['split']['handedness'].get('method', '') == 'usb': + if 'pin' in info_data['split']['handedness']: + _log_warning( + info_data, + 'Split main hand is specified in both config.h (MASTER_LEFT) and info.json (split.handedness.method and split.handedness.determined_side) (Value: %s), the config.h value wins.' % info_data['split']['handedness']['determined_side'] + ) - info_data['split']['main'] = 'left' + info_data['split']['handedness']['method'] = 'usb' + info_data['split']['handedness']['determined_side'] = 'left' def _extract_split_transport(info_data, config_c): @@ -583,7 +662,7 @@ def _extract_config_h(info_data, config_c): _extract_matrix_info(info_data, config_c) _extract_audio(info_data, config_c) _extract_secure_unlock(info_data, config_c) - _extract_split_main(info_data, config_c) + _extract_split_handedness(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)