2020-12-30 19:27:37 +01:00
""" Used by the make system to generate info_config.h from info.json.
"""
2021-01-31 21:46:00 +01:00
from pathlib import Path
from dotty_dict import dotty
2020-12-30 19:27:37 +01:00
from milc import cli
2022-03-21 11:57:41 +01:00
from qmk . info import info_json , keymap_json_config
from qmk . json_schema import json_load
2021-04-15 04:00:22 +02:00
from qmk . keyboard import keyboard_completer , keyboard_folder
2022-03-18 02:09:29 +01:00
from qmk . commands import dump_lines
2021-08-18 22:52:41 +02:00
from qmk . path import normpath
2022-03-18 02:09:29 +01:00
from qmk . constants import GPL2_HEADER_C_LIKE , GENERATED_HEADER_C_LIKE
2020-12-30 19:27:37 +01:00
2021-08-17 00:33:30 +02:00
def direct_pins ( direct_pins , postfix ) :
2020-12-30 19:27:37 +01:00
""" Return the config.h lines that set the direct pins.
"""
rows = [ ]
for row in direct_pins :
2021-01-08 09:00:15 +01:00
cols = ' , ' . join ( map ( str , [ col or ' NO_PIN ' for col in row ] ) )
2020-12-30 19:27:37 +01:00
rows . append ( ' { ' + cols + ' } ' )
2021-08-17 00:33:30 +02:00
return f """
#ifndef DIRECT_PINS{postfix}
# define DIRECT_PINS{postfix} {{ {", ".join(rows)} }}
#endif // DIRECT_PINS{postfix}
"""
2020-12-30 19:27:37 +01:00
2021-08-17 00:33:30 +02:00
def pin_array ( define , pins , postfix ) :
2021-01-31 21:46:00 +01:00
""" Return the config.h lines that set a pin array.
2020-12-30 19:27:37 +01:00
"""
2021-01-31 21:46:00 +01:00
pin_array = ' , ' . join ( map ( str , [ pin or ' NO_PIN ' for pin in pins ] ) )
2020-12-30 19:27:37 +01:00
2021-01-31 21:46:00 +01:00
return f """
2021-08-17 00:33:30 +02:00
#ifndef {define}_PINS{postfix}
# define {define}_PINS{postfix} {{ {pin_array} }}
#endif // {define}_PINS{postfix}
2021-01-31 21:46:00 +01:00
"""
2020-12-30 19:27:37 +01:00
2021-08-17 00:33:30 +02:00
def matrix_pins ( matrix_pins , postfix = ' ' ) :
2020-12-30 19:27:37 +01:00
""" Add the matrix config to the config.h.
"""
pins = [ ]
if ' direct ' in matrix_pins :
2021-08-17 00:33:30 +02:00
pins . append ( direct_pins ( matrix_pins [ ' direct ' ] , postfix ) )
2020-12-30 19:27:37 +01:00
if ' cols ' in matrix_pins :
2021-08-17 00:33:30 +02:00
pins . append ( pin_array ( ' MATRIX_COL ' , matrix_pins [ ' cols ' ] , postfix ) )
2020-12-30 19:27:37 +01:00
if ' rows ' in matrix_pins :
2021-08-17 00:33:30 +02:00
pins . append ( pin_array ( ' MATRIX_ROW ' , matrix_pins [ ' rows ' ] , postfix ) )
2020-12-30 19:27:37 +01:00
return ' \n ' . join ( pins )
2022-02-27 13:39:24 +01:00
def generate_matrix_size ( kb_info_json , config_h_lines ) :
""" Add the matrix size to the config.h.
"""
if ' matrix_pins ' in kb_info_json :
col_count = kb_info_json [ ' matrix_size ' ] [ ' cols ' ]
row_count = kb_info_json [ ' matrix_size ' ] [ ' rows ' ]
config_h_lines . append ( f """
#ifndef MATRIX_COLS
# define MATRIX_COLS {col_count}
#endif // MATRIX_COLS
#ifndef MATRIX_ROWS
# define MATRIX_ROWS {row_count}
#endif // MATRIX_ROWS
""" )
2021-08-17 00:33:30 +02:00
def generate_config_items ( kb_info_json , config_h_lines ) :
""" Iterate through the info_config map to generate basic config values.
2020-12-30 19:27:37 +01:00
"""
2021-03-24 17:26:38 +01:00
info_config_map = json_load ( Path ( ' data/mappings/info_config.json ' ) )
2020-12-30 19:27:37 +01:00
2021-01-31 21:46:00 +01:00
for config_key , info_dict in info_config_map . items ( ) :
info_key = info_dict [ ' info_key ' ]
2022-03-04 14:25:24 +01:00
key_type = info_dict . get ( ' value_type ' , ' raw ' )
2021-01-31 21:46:00 +01:00
to_config = info_dict . get ( ' to_config ' , True )
if not to_config :
continue
try :
config_value = kb_info_json [ info_key ]
except KeyError :
continue
if key_type . startswith ( ' array ' ) :
config_h_lines . append ( ' ' )
config_h_lines . append ( f ' #ifndef { config_key } ' )
config_h_lines . append ( f ' # define { config_key } {{ { " , " . join ( map ( str , config_value ) ) } }} ' )
config_h_lines . append ( f ' #endif // { config_key } ' )
elif key_type == ' bool ' :
if config_value :
config_h_lines . append ( ' ' )
config_h_lines . append ( f ' #ifndef { config_key } ' )
config_h_lines . append ( f ' # define { config_key } ' )
config_h_lines . append ( f ' #endif // { config_key } ' )
elif key_type == ' mapping ' :
for key , value in config_value . items ( ) :
config_h_lines . append ( ' ' )
config_h_lines . append ( f ' #ifndef { key } ' )
config_h_lines . append ( f ' # define { key } { value } ' )
config_h_lines . append ( f ' #endif // { key } ' )
2022-03-04 14:25:24 +01:00
elif key_type == ' str ' :
config_h_lines . append ( ' ' )
config_h_lines . append ( f ' #ifndef { config_key } ' )
config_h_lines . append ( f ' # define { config_key } " { config_value } " ' )
config_h_lines . append ( f ' #endif // { config_key } ' )
2022-01-16 22:44:34 +01:00
elif key_type == ' bcd_version ' :
( major , minor , revision ) = config_value . split ( ' . ' )
config_h_lines . append ( ' ' )
config_h_lines . append ( f ' #ifndef { config_key } ' )
config_h_lines . append ( f ' # define { config_key } 0x { major . zfill ( 2 ) } { minor } { revision } ' )
config_h_lines . append ( f ' #endif // { config_key } ' )
2021-01-31 21:46:00 +01:00
else :
config_h_lines . append ( ' ' )
config_h_lines . append ( f ' #ifndef { config_key } ' )
config_h_lines . append ( f ' # define { config_key } { config_value } ' )
config_h_lines . append ( f ' #endif // { config_key } ' )
2020-12-30 19:27:37 +01:00
2021-08-17 00:33:30 +02:00
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 ' ) :
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 ' :
config_h_lines . append ( ' # define MASTER_LEFT ' )
elif kb_info_json [ ' split ' ] [ ' primary ' ] == ' 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 ( ' ' )
config_h_lines . append ( ' #ifndef SPLIT_HAND_PIN ' )
config_h_lines . append ( ' # define SPLIT_HAND_PIN ' )
config_h_lines . append ( ' #endif // SPLIT_HAND_PIN ' )
elif kb_info_json [ ' split ' ] [ ' primary ' ] == ' matrix_grid ' :
config_h_lines . append ( ' ' )
config_h_lines . append ( ' #ifndef SPLIT_HAND_MATRIX_GRID ' )
config_h_lines . append ( ' # define SPLIT_HAND_MATRIX_GRID { %s } ' % ( ' , ' . join ( kb_info_json [ " split " ] [ " matrix_grid " ] , ) ) )
config_h_lines . append ( ' #endif // SPLIT_HAND_MATRIX_GRID ' )
elif kb_info_json [ ' split ' ] [ ' primary ' ] == ' eeprom ' :
config_h_lines . append ( ' ' )
config_h_lines . append ( ' #ifndef EE_HANDS ' )
config_h_lines . append ( ' # define EE_HANDS ' )
config_h_lines . append ( ' #endif // EE_HANDS ' )
if ' protocol ' in kb_info_json [ ' split ' ] . get ( ' transport ' , { } ) :
if kb_info_json [ ' split ' ] [ ' transport ' ] [ ' protocol ' ] == ' i2c ' :
config_h_lines . append ( ' ' )
config_h_lines . append ( ' #ifndef USE_I2C ' )
config_h_lines . append ( ' # define USE_I2C ' )
config_h_lines . append ( ' #endif // USE_I2C ' )
if ' right ' in kb_info_json [ ' split ' ] . get ( ' matrix_pins ' , { } ) :
config_h_lines . append ( matrix_pins ( kb_info_json [ ' split ' ] [ ' matrix_pins ' ] [ ' right ' ] , ' _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 " )
2021-08-18 22:52:41 +02:00
@cli.argument ( ' -kb ' , ' --keyboard ' , arg_only = True , type = keyboard_folder , completer = keyboard_completer , required = True , help = ' Keyboard to generate config.h for. ' )
@cli.argument ( ' -km ' , ' --keymap ' , arg_only = True , help = ' Keymap to generate config.h for. ' )
2021-08-17 00:33:30 +02:00
@cli.subcommand ( ' Used by the make system to generate info_config.h from info.json ' , hidden = True )
def generate_config_h ( cli ) :
""" Generates the info_config.h file.
"""
2021-08-18 22:52:41 +02:00
# Determine our keyboard/keymap
if cli . args . keymap :
2022-03-21 11:57:41 +01:00
kb_info_json = dotty ( keymap_json_config ( cli . args . keyboard , cli . args . keymap ) )
2021-08-18 22:52:41 +02:00
else :
kb_info_json = dotty ( info_json ( cli . args . keyboard ) )
2021-08-17 00:33:30 +02:00
# Build the info_config.h file.
2022-03-18 02:09:29 +01:00
config_h_lines = [ GPL2_HEADER_C_LIKE , GENERATED_HEADER_C_LIKE , ' #pragma once ' ]
2021-08-17 00:33:30 +02:00
generate_config_items ( kb_info_json , config_h_lines )
2022-02-27 13:39:24 +01:00
generate_matrix_size ( kb_info_json , config_h_lines )
2020-12-30 19:27:37 +01:00
if ' matrix_pins ' in kb_info_json :
config_h_lines . append ( matrix_pins ( kb_info_json [ ' matrix_pins ' ] ) )
2021-08-17 00:33:30 +02:00
if ' split ' in kb_info_json :
generate_split_config ( kb_info_json , config_h_lines )
2020-12-30 19:27:37 +01:00
# Show the results
2022-03-18 02:09:29 +01:00
dump_lines ( cli . args . output , config_h_lines , cli . args . quiet )