Skip to content

Commit

Permalink
fix data-driven split handedness pin assignement
Browse files Browse the repository at this point in the history
  • Loading branch information
Kriechi committed Apr 17, 2023
1 parent f554c66 commit 3f4efa1
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 35 deletions.
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

0 comments on commit 3f4efa1

Please sign in to comment.