Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix data-driven split handedness pin assignement #18254

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions data/schemas/keyboard.jsonschema
Original file line number Diff line number Diff line change
Expand Up @@ -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"}
},
Expand Down Expand Up @@ -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": {
Expand Down
1 change: 0 additions & 1 deletion keyboards/tzarc/djinn/rev1/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#pragma once

// Split configuration
#define SPLIT_HAND_PIN B11
#ifdef USE_PLUG_DETECT_PIN
# define USB_VBUS_PIN B12
#endif
Expand Down
5 changes: 5 additions & 0 deletions keyboards/tzarc/djinn/rev1/info.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
},
"split": {
"soft_serial_pin": "B9",
"handedness": {
"method": "pin",
"pin": "B11",
"determined_side": "left"
},
"usb_detect": {
"enabled": true
}
Expand Down
1 change: 0 additions & 1 deletion keyboards/tzarc/djinn/rev2/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions keyboards/tzarc/djinn/rev2/info.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
"max_brightness": 144
},
"split": {
"handedness": {
"method": "pin",
"pin": "B9",
"determined_side": "left"
},
"usb_detect": {
"enabled": false
}
Expand Down
26 changes: 17 additions & 9 deletions lib/python/qmk/cli/generate/config_h.py
Original file line number Diff line number Diff line change
Expand Up @@ -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':
Expand Down
121 changes: 100 additions & 21 deletions lib/python/qmk/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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)
Expand Down