Compare commits

...

9 Commits

Author SHA1 Message Date
QMK Bot
b7832d6527 Merge remote-tracking branch 'origin/develop' into xap 2023-03-23 01:49:07 +00:00
Nick Brassel
42aa83787f
Optionally keep intermediate file listings in order to do comparisons between builds. (#20237) 2023-03-23 12:48:25 +11:00
zvecr
42895141de Decouple lighting_map from XAP 2023-03-23 00:48:52 +00:00
zvecr
5eed80c66b Fix up after merge 2023-03-23 00:47:03 +00:00
QMK Bot
e92968d813 Merge remote-tracking branch 'origin/develop' into xap 2023-03-23 00:37:51 +00:00
Joel Challis
6540b31d71
Add some helpers to tidy up XAP (#20235) 2023-03-23 00:37:13 +00:00
zvecr
7edc0bcd43 Tidy up bool implementation 2023-03-22 21:21:02 +00:00
zvecr
5f7e520f8f Strip out XAP_GETTER for now 2023-03-22 21:21:02 +00:00
zvecr
64c5531be6 Refactor inline_generator to template 2023-03-22 21:21:02 +00:00
25 changed files with 1355 additions and 1521 deletions

View File

@ -441,6 +441,14 @@ $(eval $(call add_qmk_prefix_defs,MCU_FAMILY,MCU_FAMILY))
$(eval $(call add_qmk_prefix_defs,MCU_SERIES,MCU_SERIES))
$(eval $(call add_qmk_prefix_defs,BOARD,BOARD))
# Control whether intermediate file listings are generated
# e.g.:
# make handwired/onekey/blackpill_f411:default KEEP_INTERMEDIATES=yes
# cat .build/obj_handwired_onekey_blackpill_f411_default/quantum/quantum.i | sed -e 's@^#.*@@g' -e 's@^\s*//.*@@g' -e '/^\s*$/d' | clang-format
ifeq ($(strip $(KEEP_INTERMEDIATES)), yes)
OPT_DEFS += -save-temps=obj
endif
# TODO: remove this bodge?
PROJECT_DEFS := $(OPT_DEFS)
PROJECT_INC := $(VPATH) $(EXTRAINCDIRS) $(KEYBOARD_PATHS)

View File

@ -1,8 +1,25 @@
{{ constants.GPL2_HEADER_C_LIKE }}
{{ constants.GENERATED_HEADER_C_LIKE }}
{% macro route_conditions(route_stack) %}
{% set conditions = [] %}
{% for data in route_stack %}
{% if 'enable_if_preprocessor' in data %}
{{ conditions.append(data.enable_if_preprocessor) or '' }}
{% endif %}
{% endfor %}
{% if conditions %}
#if ({{ conditions | join(' && ') }})
{% endif %}
{{ caller() }}
{%- if conditions %}
#endif // ({{ conditions | join(' && ') }})
{% endif %}
{% endmacro %}
////////////////////////////////////////////////////////////////////////////////
// Full XAP {{ xap.version }} definitions
// Broadcast
{% for message_id,data in xap.broadcast_messages.messages | dictsort %}
{% if 'return_type' in data %}
@ -12,24 +29,116 @@ void {{ xap.broadcast_messages.define_prefix | lower }}_{{ data.define | to_snak
{% endif %}
{% endfor %}
////////////////////////////////////////////////////////////////////////////////
// Decl
{% macro export_route_declaration(container) %}
{% if 'routes' in container %}
{% for route, data in container.routes | dictsort %}
{% if 'return_execute' in data %}
bool xap_respond_{{ data.return_execute }}(xap_token_t token, const uint8_t *data, size_t data_len);
{% endif %}
{{ export_route_declaration(data) }}
{% endfor %}
{% endif %}
{% endmacro %}
{{ export_route_declaration(xap) }}
////////////////////////////////////////////////////////////////////////////////
// Data
{% macro export_route_data(prefix, container, route_stack) %}
{% set this_route_stack = route_stack.copy() %}
{{ this_route_stack.append(container) or '' }}
{% if 'routes' in container %}
{% for route, data in container.routes | dictsort %}
{% set this_prefix_uc = (prefix + '_' + data.define) | upper %}
{% set this_prefix_lc = this_prefix_uc | lower %}
{% if 'return_constant' in data %}
{% if data.return_type == 'struct' %}
{% call route_conditions(this_route_stack) %}
static const {{ this_prefix_lc }}_t {{ this_prefix_lc }}_data PROGMEM = {
{% for member in data.return_constant %}
{{ member }},
{% endfor %}
};
{% endcall %}
{% elif data.return_type == 'string' %}
{% call route_conditions(this_route_stack) %}
static const char {{ this_prefix_lc }}_str[] PROGMEM = {{ data.return_constant }};
{% endcall %}
{% else %}
{% call route_conditions(this_route_stack) %}
static const {{ data.return_type | type_to_c_before }} {{ this_prefix_lc }}_data PROGMEM = {{ data.return_constant }};
{% endcall %}
{% endif %}
{% endif %}
{{ export_route_data(this_prefix_lc, data, this_route_stack) }}
{% endfor %}
{% endif %}
{% endmacro %}
{{ export_route_data('XAP_ROUTE', xap, []) }}
////////////////////////////////////////////////////////////////////////////////
// Routes
{% macro append_routing_table(prefix, container, route_stack) %}
{% set this_route_stack = route_stack.copy() %}
{{ this_route_stack.append(container) }}
{% set stack_names = this_route_stack | map(attribute='name') | join(', ') %}
Stack names: {{ stack_names }}
{{ this_route_stack.append(container) or '' }}
{% if 'routes' in container %}
{% for route, data in container.routes | dictsort %}
{% set this_prefix_uc = (prefix + '_' + data.define) | upper %}
{% set this_prefix_lc = this_prefix_uc | lower %}
{{ append_routing_table(this_prefix_lc, data, this_route_stack) }}
Inner route prefix for {{ prefix }}: {{ this_prefix_lc }}
{% endfor %}
{% call route_conditions(this_route_stack) %}
static const xap_route_t {{ prefix | lower}}_table[] PROGMEM = {
{% for route, data in container.routes | dictsort %}
{% set inner_route_stack = this_route_stack.copy() %}
{{ inner_route_stack.append(data) or '' }}
{% if 'permissions' in data %}
{% set secure_status = 'ROUTE_PERMISSIONS_SECURE' %}
{% else %}
{% set secure_status = 'ROUTE_PERMISSIONS_INSECURE' %}
{% endif %}
{% call route_conditions(inner_route_stack) %}
[{{ prefix | upper }}_{{ data.define }}] = {
{% if 'routes' in data %}
.flags = {
.type = XAP_ROUTE,
.secure = {{ secure_status }},
},
.child_routes = {{ prefix | lower }}_{{ data.define | lower }}_table,
.child_routes_len = sizeof({{ prefix | lower }}_{{ data.define | lower }}_table)/sizeof(xap_route_t),
{% elif 'return_execute' in data %}
.flags = {
.type = XAP_EXECUTE,
.secure = {{ secure_status }},
},
.handler = xap_respond_{{ data.return_execute | lower }},
{% elif 'return_constant' in data and data.return_type == 'string' %}
.flags = {
.type = XAP_CONST_MEM,
.secure = {{ secure_status }},
},
.const_data = {{ prefix | lower }}_{{ data.define | lower }}_str,
.const_data_len = sizeof({{ prefix | lower }}_{{ data.define | lower }}_str) - 1,
{% elif 'return_constant' in data %}
.flags = {
.type = XAP_CONST_MEM,
.secure = {{ secure_status }},
},
.const_data = &{{ prefix | lower }}_{{ data.define | lower }}_data,
.const_data_len = sizeof({{ prefix | lower }}_{{ data.define | lower }}_data),
{% endif %}
},
{% endcall %}
{% endfor %}
};
{% endcall %}
{% endif %}
Prefix: {{ prefix }}
{% endmacro %}
{{ append_routing_table("xap_route", xap, []) }}
#if 0
{{ xap | tojson(indent=4) }}
#endif

View File

@ -38,6 +38,10 @@
}
type_docs: {
bool:
'''
Data type that contains values 0 and 1. Implementaed as an alias of `u8`.
'''
u64:
'''
An unsigned 64-bit integral, commonly seen as `uint64_t` from _stdint.h_.

View File

@ -58,6 +58,7 @@ subcommands = [
'qmk.cli.generate.keyboard_h',
'qmk.cli.generate.keycodes',
'qmk.cli.generate.keycodes_tests',
'qmk.cli.generate.lighting_map',
'qmk.cli.generate.rgb_breathe_table',
'qmk.cli.generate.rules_mk',
'qmk.cli.generate.version_h',
@ -83,7 +84,6 @@ subcommands = [
'qmk.cli.xap',
'qmk.cli.xap.generate_docs',
'qmk.cli.xap.generate_json',
'qmk.cli.xap.generate_lighting',
'qmk.cli.xap.generate_python',
'qmk.cli.xap.generate_qmk',
]

View File

@ -2,7 +2,7 @@ from milc import cli
from qmk.path import normpath
from qmk.commands import dump_lines
from qmk.xap.common import load_lighting_spec
from qmk.lighting import load_lighting_spec
from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE
PREFIX_MAP = {
@ -21,8 +21,21 @@ PREFIX_MAP = {
}
def _always_enabled(id):
"""Assumption that first effect is always enabled
"""
return id == '0x00'
def _wrap_ifdef(line, define):
return f'''
#ifdef {define}
{line}
#endif'''
def _append_lighting_map(lines, feature, spec):
"""TODO:
"""Translate effect to 'constant id'->'firmware id' lookup table
"""
groups = spec.get('groups', {})
ifdef_prefix = PREFIX_MAP[feature]['ifdef']
@ -33,17 +46,14 @@ def _append_lighting_map(lines, feature, spec):
define = obj['define']
offset = f' + {obj["offset"]}' if obj['offset'] else ''
line = f'''
#ifdef {ifdef_prefix}_{define}
{{ {id}, {def_prefix}_{define}{offset}}},
#endif'''
line = f'{{ {id}, {def_prefix}_{define}{offset}}},'
if not _always_enabled(id):
line = _wrap_ifdef(line, f'{ifdef_prefix}_{define}')
group = groups.get(obj.get('group', None), {}).get('define', None)
if group:
line = f'''
#ifdef {group}
{line}
#endif'''
line = _wrap_ifdef(line, group)
lines.append(line)
@ -52,7 +62,7 @@ def _append_lighting_map(lines, feature, spec):
# add helper funcs
lines.append(
f'''
uint8_t {feature}2xap(uint8_t val) {{
uint8_t {feature}_effect_to_id(uint8_t val) {{
for(uint8_t i = 0; i < ARRAY_SIZE({feature}_effect_map); i++) {{
if (pgm_read_byte(&{feature}_effect_map[i][1]) == val)
return pgm_read_byte(&{feature}_effect_map[i][0]);
@ -60,7 +70,7 @@ uint8_t {feature}2xap(uint8_t val) {{
return 0xFF;
}}
uint8_t xap2{feature}(uint8_t val) {{
uint8_t {feature}_id_to_effect(uint8_t val) {{
for(uint8_t i = 0; i < ARRAY_SIZE({feature}_effect_map); i++) {{
if (pgm_read_byte(&{feature}_effect_map[i][0]) == val)
return pgm_read_byte(&{feature}_effect_map[i][1]);
@ -70,8 +80,8 @@ uint8_t xap2{feature}(uint8_t val) {{
)
def _append_lighting_bitmask(lines, feature, spec):
"""TODO:
def _append_lighting_bit_field(lines, feature, spec):
"""Translate effect to bit of bit-field
"""
groups = spec.get('groups', {})
ifdef_prefix = PREFIX_MAP[feature]['ifdef']
@ -80,49 +90,37 @@ def _append_lighting_bitmask(lines, feature, spec):
for id, obj in spec.get('effects', {}).items():
define = obj['define']
line = f'''
#ifdef {ifdef_prefix}_{define}
| (1ULL << {id})
#endif'''
line = f' | (1ULL << {id})'
if not _always_enabled(id):
line = _wrap_ifdef(line, f'{ifdef_prefix}_{define}')
group = groups.get(obj.get('group', None), {}).get('define', None)
if group:
line = f'''
#ifdef {group}
{line}
#endif'''
line = _wrap_ifdef(line, group)
lines.append(line)
lines.append('};')
def _append_lighting_mapping(lines):
"""TODO:
def _append_lighting_mapping(lines, feature):
"""Generate lookup table and bit-field of effect
"""
# TODO: remove bodge for always enabled effects
lines.append('''
#define RGBLIGHT_EFFECT_STATIC_LIGHT
#define ENABLE_RGB_MATRIX_SOLID_COLOR
#define ENABLE_LED_MATRIX_SOLID
''')
spec = load_lighting_spec(feature)
for feature in PREFIX_MAP.keys():
spec = load_lighting_spec(feature)
lines.append(f'#ifdef {feature.upper()}_ENABLE')
_append_lighting_map(lines, feature, spec)
_append_lighting_bitmask(lines, feature, spec)
lines.append(f'#endif //{feature.upper()}_ENABLE')
_append_lighting_bit_field(lines, feature, spec)
_append_lighting_map(lines, feature, spec)
@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")
@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help='Quiet mode, only output error messages')
@cli.argument('-f', '--feature', required=True, help='Feature to generate map', choices=PREFIX_MAP.keys())
@cli.subcommand('Generates effect header.')
def xap_generate_lighting_map(cli):
def generate_lighting_map(cli):
# Preamble
lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#pragma once', '// clang-format off']
_append_lighting_mapping(lines)
_append_lighting_mapping(lines, cli.args.feature)
dump_lines(cli.args.output, lines, cli.args.quiet)

View File

@ -6,7 +6,6 @@ from qmk.path import normpath
from qmk.keyboard import keyboard_completer, keyboard_folder
from qmk.xap.common import render_xap_output, merge_xap_defs
from qmk.xap.gen_firmware.blob_generator import generate_blob
from qmk.xap.gen_firmware.inline_generator import generate_inline
@cli.argument('-o', '--output', type=normpath, help='File to write to')
@ -26,10 +25,8 @@ def xap_generate_qmk_inc(cli):
cli.subcommands['xap-generate-qmk-inc'].print_help()
return False
generate_inline(cli.args.output, cli.args.keyboard, cli.args.keymap)
defs = merge_xap_defs(cli.args.keyboard, cli.args.keymap)
with open(normpath(str(cli.args.output.resolve()) + '.generated.j2.c'), 'w', encoding='utf-8') as out_file:
with open(cli.args.output, 'w', encoding='utf-8') as out_file:
r = render_xap_output('firmware', 'xap_generated.inl.j2', defs, keyboard=cli.args.keyboard, keymap=cli.args.keymap)
while r.find('\n\n\n') != -1:
r = r.replace('\n\n\n', '\n\n')

View File

@ -0,0 +1,37 @@
import re
from pathlib import Path
from qmk.json_schema import json_load
def list_lighting_versions(feature):
"""Return available versions - sorted newest first
"""
ret = []
for file in Path('data/constants/lighting/').glob(f'{feature}_[0-9].[0-9].[0-9].hjson'):
ret.append(file.stem.split('_')[-1])
ret.sort(reverse=True)
return ret
def load_lighting_spec(feature, version='latest'):
"""Build lighting data from the requested spec file
"""
if version == 'latest':
version = list_lighting_versions(feature)[0]
spec = json_load(Path(f'data/constants/lighting/{feature}_{version}.hjson'))
# preprocess for gross rgblight "mode + n"
for obj in spec.get('effects', {}).values():
define = obj['key']
offset = 0
found = re.match('(.*)_(\\d+)$', define)
if found:
define = found.group(1)
offset = int(found.group(2)) - 1
obj['define'] = define
obj['offset'] = offset
return spec

View File

@ -1,7 +1,5 @@
"""This script handles the XAP protocol data files.
"""
import re
import os
import hjson
import jsonschema
from pathlib import Path
@ -10,6 +8,7 @@ from jinja2 import Environment, FileSystemLoader, select_autoescape
import qmk.constants
from qmk.git import git_get_version
from qmk.lighting import load_lighting_spec
from qmk.json_schema import json_load, validate, merge_ordered_dicts
from qmk.makefile import parse_rules_mk_file
from qmk.decorators import lru_cache
@ -21,41 +20,8 @@ USERSPACE_DIR = Path('users')
XAP_SPEC = 'xap.hjson'
def list_lighting_versions(feature):
"""Return available versions - sorted newest first
"""
ret = []
for file in Path('data/constants/').glob(f'{feature}_[0-9].[0-9].[0-9].json'):
ret.append(file.stem.split('_')[-1])
ret.sort(reverse=True)
return ret
def load_lighting_spec(feature, version='latest'):
"""Build lighting data from the requested spec file
"""
if version == 'latest':
version = list_lighting_versions(feature)[0]
spec = json_load(Path(f'data/constants/{feature}_{version}.json'))
# preprocess for gross rgblight "mode + n"
for obj in spec.get('effects', {}).values():
define = obj['key']
offset = 0
found = re.match('(.*)_(\\d+)$', define)
if found:
define = found.group(1)
offset = int(found.group(2)) - 1
obj['define'] = define
obj['offset'] = offset
return spec
def _get_jinja2_env(data_templates_xap_subdir: str):
templates_dir = os.path.join(qmk.constants.QMK_FIRMWARE, 'data', 'templates', 'xap', data_templates_xap_subdir)
templates_dir = qmk.constants.QMK_FIRMWARE / 'data/templates/xap' / data_templates_xap_subdir
j2 = Environment(loader=FileSystemLoader(templates_dir), autoescape=select_autoescape(), lstrip_blocks=True, trim_blocks=True)
return j2
@ -172,17 +138,3 @@ def merge_xap_defs(kb, km):
exit(1)
return defs
def route_conditions(route_stack):
"""Handles building the C preprocessor conditional based on the current route.
"""
conditions = []
for route in route_stack:
if 'enable_if_preprocessor' in route:
conditions.append(route['enable_if_preprocessor'])
if len(conditions) == 0:
return None
return "(" + ' && '.join([f'({c})' for c in conditions]) + ")"

View File

@ -1,298 +0,0 @@
"""This script generates the XAP protocol generated header to be compiled into QMK.
"""
from qmk.casing import to_snake
from qmk.commands import dump_lines
from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE
from qmk.xap.common import merge_xap_defs, route_conditions
def _get_c_type(xap_type):
if xap_type == 'bool':
return 'bool'
elif xap_type == 'u8':
return 'uint8_t'
elif xap_type == 'u16':
return 'uint16_t'
elif xap_type == 'u32':
return 'uint32_t'
elif xap_type == 'u64':
return 'uint64_t'
elif xap_type == 'struct':
return 'struct'
elif xap_type == 'string':
return 'const char *'
return 'unknown'
def _get_c_size(xap_type):
if xap_type == 'u8':
return 'sizeof(uint8_t)'
elif xap_type == 'u16':
return 'sizeof(uint16_t)'
elif xap_type == 'u32':
return 'sizeof(uint32_t)'
elif xap_type == 'u64':
return 8
elif xap_type == 'u8[32]':
return 32
return 0
def _get_route_type(container):
if 'routes' in container:
return 'XAP_ROUTE'
elif 'return_execute' in container:
return 'XAP_EXECUTE'
elif 'return_value' in container:
if container['return_type'] == 'u8':
return 'XAP_VALUE'
elif 'return_constant' in container:
if container['return_type'] == 'u8':
return 'XAP_CONST_MEM'
elif container['return_type'] == 'u16':
return 'XAP_CONST_MEM'
elif container['return_type'] == 'u32':
return 'XAP_CONST_MEM'
elif container['return_type'] == 'u64':
return 'XAP_CONST_MEM'
elif container['return_type'] == 'struct':
return 'XAP_CONST_MEM'
elif container['return_type'] == 'string':
return 'XAP_CONST_MEM'
elif 'return_getter' in container:
if container['return_type'] == 'u32':
return 'XAP_GETTER'
return 'UNSUPPORTED'
def _append_routing_table_declaration(lines, container, container_id, route_stack):
route_stack.append(container)
route_name = to_snake('_'.join([r['define'] for r in route_stack]))
condition = route_conditions(route_stack)
if condition:
lines.append(f'#if {condition}')
if 'routes' in container:
pass
elif 'return_execute' in container:
execute = container['return_execute']
lines.append(f'bool xap_respond_{execute}(xap_token_t token, const uint8_t *data, size_t data_len);')
# elif 'return_value' in container:
# value = container['return_value']
# return_type = container['return_type']
# lines.append('')
# lines.append(f'{_get_c_type(return_type)} {value} = 0;')
elif 'return_constant' in container:
if container['return_type'] == 'u8':
constant = container['return_constant']
lines.append('')
lines.append(f'static const uint8_t {route_name}_data PROGMEM = {constant};')
elif container['return_type'] == 'u16':
constant = container['return_constant']
lines.append('')
lines.append(f'static const uint16_t {route_name}_data PROGMEM = {constant};')
elif container['return_type'] == 'u32':
constant = container['return_constant']
lines.append('')
lines.append(f'static const uint32_t {route_name}_data PROGMEM = {constant};')
elif container['return_type'] == 'u64':
constant = container['return_constant']
lines.append('')
lines.append(f'static const uint64_t {route_name}_data PROGMEM = {constant};')
elif container['return_type'] == 'struct':
lines.append('')
lines.append(f'static const {route_name}_t {route_name}_data PROGMEM = {{')
for constant in container['return_constant']:
lines.append(f' {constant},')
lines.append('};')
elif container['return_type'] == 'string':
constant = container['return_constant']
lines.append('')
lines.append(f'static const char {route_name}_str[] PROGMEM = {constant};')
elif 'return_getter' in container:
if container['return_type'] == 'u32':
lines.append('')
lines.append(f'extern uint32_t {route_name}_getter(void);')
elif container['return_type'] == 'struct':
pass
if condition:
lines.append(f'#endif // {condition}')
lines.append('')
route_stack.pop()
def _append_routing_table_entry_flags(lines, container, container_id, route_stack):
pem_map = {
None: 'ROUTE_PERMISSIONS_INSECURE',
'secure': 'ROUTE_PERMISSIONS_SECURE',
}
is_secure = pem_map[container.get('permissions', None)]
lines.append(' .flags = {')
lines.append(f' .type = {_get_route_type(container)},')
lines.append(f' .secure = {is_secure},')
lines.append(' },')
def _append_routing_table_entry_route(lines, container, container_id, route_stack):
route_name = to_snake('_'.join([r['define'] for r in route_stack]))
lines.append(f' .child_routes = {route_name}_table,')
lines.append(f' .child_routes_len = sizeof({route_name}_table)/sizeof(xap_route_t),')
def _append_routing_table_entry_execute(lines, container, container_id, route_stack):
value = container['return_execute']
lines.append(f' .handler = xap_respond_{value},')
def _append_routing_table_entry_value(lines, container, container_id, route_stack):
value = container['return_value']
lines.append(f' .const_data = &{value},')
lines.append(f' .const_data_len = sizeof({value}),')
def _append_routing_table_entry_u32getter(lines, container, container_id, route_stack):
route_name = to_snake('_'.join([r['define'] for r in route_stack]))
lines.append(f' .u32getter = &{route_name}_getter,')
def _append_routing_table_entry_const_data(lines, container, container_id, route_stack):
route_name = to_snake('_'.join([r['define'] for r in route_stack]))
lines.append(f' .const_data = &{route_name}_data,')
lines.append(f' .const_data_len = sizeof({route_name}_data),')
def _append_routing_table_entry_string(lines, container, container_id, route_stack):
route_name = to_snake('_'.join([r['define'] for r in route_stack]))
lines.append(f' .const_data = {route_name}_str,')
lines.append(f' .const_data_len = sizeof({route_name}_str) - 1,')
def _append_routing_table_entry(lines, container, container_id, route_stack):
route_stack.append(container)
route_name = '_'.join([r['define'] for r in route_stack])
condition = route_conditions(route_stack)
if condition:
lines.append(f'#if {condition}')
lines.append(f' [{route_name}] = {{')
_append_routing_table_entry_flags(lines, container, container_id, route_stack)
if 'routes' in container:
_append_routing_table_entry_route(lines, container, container_id, route_stack)
elif 'return_execute' in container:
_append_routing_table_entry_execute(lines, container, container_id, route_stack)
elif 'return_value' in container:
_append_routing_table_entry_value(lines, container, container_id, route_stack)
elif 'return_constant' in container:
if container['return_type'] == 'u8':
_append_routing_table_entry_const_data(lines, container, container_id, route_stack)
elif container['return_type'] == 'u16':
_append_routing_table_entry_const_data(lines, container, container_id, route_stack)
elif container['return_type'] == 'u32':
_append_routing_table_entry_const_data(lines, container, container_id, route_stack)
elif container['return_type'] == 'u64':
_append_routing_table_entry_const_data(lines, container, container_id, route_stack)
elif container['return_type'] == 'struct':
_append_routing_table_entry_const_data(lines, container, container_id, route_stack)
elif container['return_type'] == 'string':
_append_routing_table_entry_string(lines, container, container_id, route_stack)
elif 'return_getter' in container:
if container['return_type'] == 'u32':
_append_routing_table_entry_u32getter(lines, container, container_id, route_stack)
lines.append(' },')
if condition:
lines.append(f'#endif // {condition}')
route_stack.pop()
def _append_routing_tables(lines, container, container_id=None, route_stack=None):
"""Handles building the list of the XAP routes, combining parent and child names together, as well as the route number.
"""
if route_stack is None:
route_stack = [container]
else:
route_stack.append(container)
route_name = to_snake('_'.join([r['define'] for r in route_stack]))
condition = route_conditions(route_stack)
if 'routes' in container:
for route_id in container['routes']:
route = container['routes'][route_id]
_append_routing_tables(lines, route, route_id, route_stack)
for route_id in container['routes']:
route = container['routes'][route_id]
_append_routing_table_declaration(lines, route, route_id, route_stack)
lines.append('')
if condition:
lines.append(f'#if {condition}')
lines.append(f'static const xap_route_t {route_name}_table[] PROGMEM = {{')
for route_id in container['routes']:
route = container['routes'][route_id]
_append_routing_table_entry(lines, route, route_id, route_stack)
lines.append('};')
if condition:
lines.append(f'#endif // {condition}')
lines.append('')
route_stack.pop()
def _append_broadcast_messages(lines, container):
"""TODO:
"""
broadcast_messages = container.get('broadcast_messages', {})
broadcast_prefix = broadcast_messages['define_prefix']
for key, value in broadcast_messages['messages'].items():
define = value.get('define')
name = to_snake(f'{broadcast_prefix}_{define}')
if 'return_type' in value:
ret_type = _get_c_type(value['return_type'])
lines.append(f'void {name}({ret_type} value) {{ xap_broadcast({key}, &value, sizeof(value)); }}')
else:
lines.append(f'void {name}(const void *data, size_t length){{ xap_broadcast({key}, data, length); }}')
def generate_inline(output_file, keyboard, keymap):
"""Generates the XAP protocol header file, generated during normal build.
"""
xap_defs = merge_xap_defs(keyboard, keymap)
# Preamble
lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '']
# Add all the generated code
_append_broadcast_messages(lines, xap_defs)
_append_routing_tables(lines, xap_defs)
dump_lines(output_file, lines)

View File

@ -27,6 +27,8 @@ def _xap_type_to_c_before(xt: str):
return 'uint32_t'
elif xt == 'u64':
return 'uint64_t'
elif xt == 'bool':
return 'uint8_t'
elif xt == 'string':
return 'const char*'
elif xt == 'token':

View File

@ -112,6 +112,10 @@ static bool audio_initialized = false;
static bool audio_driver_stopped = true;
audio_config_t audio_config;
void eeconfig_update_audio_current(void) {
eeconfig_update_audio(audio_config.raw);
}
void audio_init(void) {
if (audio_initialized) {
return;

View File

@ -63,6 +63,11 @@ typedef struct {
// public interface
/**
* @brief Save the current choices to the eeprom
*/
void eeconfig_update_audio_current(void);
/**
* @brief one-time initialization called by quantum/quantum.c
* @details usually done lazy, when some tones are to be played

View File

@ -0,0 +1,263 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
888 888 Y8P d88P" Y8P 888 Y8P
888 888 888 888
888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
888 888 888 888 X88 888 888 888 Y8b. 888 X88
888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
888 888
888 888
888 888
.d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
"Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
888
Y8b d88P
"Y88P"
*******************************************************************************/
#pragma once
// clang-format off
enum { ENABLED_LED_MATRIX_EFFECTS = 0
| (1ULL << 0x00)
#ifdef ENABLE_LED_MATRIX_ALPHAS_MODS
| (1ULL << 0x01)
#endif
#ifdef ENABLE_LED_MATRIX_BREATHING
| (1ULL << 0x02)
#endif
#ifdef ENABLE_LED_MATRIX_BAND
| (1ULL << 0x03)
#endif
#ifdef ENABLE_LED_MATRIX_BAND_PINWHEEL
| (1ULL << 0x04)
#endif
#ifdef ENABLE_LED_MATRIX_BAND_SPIRAL
| (1ULL << 0x05)
#endif
#ifdef ENABLE_LED_MATRIX_CYCLE_LEFT_RIGHT
| (1ULL << 0x06)
#endif
#ifdef ENABLE_LED_MATRIX_CYCLE_UP_DOWN
| (1ULL << 0x07)
#endif
#ifdef ENABLE_LED_MATRIX_CYCLE_OUT_IN
| (1ULL << 0x08)
#endif
#ifdef ENABLE_LED_MATRIX_DUAL_BEACON
| (1ULL << 0x09)
#endif
#ifdef ENABLE_LED_MATRIX_WAVE_LEFT_RIGHT
| (1ULL << 0x0A)
#endif
#ifdef ENABLE_LED_MATRIX_WAVE_UP_DOWN
| (1ULL << 0x0B)
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_SIMPLE
| (1ULL << 0x0C)
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_WIDE
| (1ULL << 0x0D)
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTIWIDE
| (1ULL << 0x0E)
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_CROSS
| (1ULL << 0x0F)
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTICROSS
| (1ULL << 0x10)
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_NEXUS
| (1ULL << 0x11)
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTINEXUS
| (1ULL << 0x12)
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_SPLASH
| (1ULL << 0x13)
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_MULTISPLASH
| (1ULL << 0x14)
#endif
#endif
};
static const uint8_t led_matrix_effect_map[][2] PROGMEM = {
{ 0x00, LED_MATRIX_SOLID},
#ifdef ENABLE_LED_MATRIX_ALPHAS_MODS
{ 0x01, LED_MATRIX_ALPHAS_MODS},
#endif
#ifdef ENABLE_LED_MATRIX_BREATHING
{ 0x02, LED_MATRIX_BREATHING},
#endif
#ifdef ENABLE_LED_MATRIX_BAND
{ 0x03, LED_MATRIX_BAND},
#endif
#ifdef ENABLE_LED_MATRIX_BAND_PINWHEEL
{ 0x04, LED_MATRIX_BAND_PINWHEEL},
#endif
#ifdef ENABLE_LED_MATRIX_BAND_SPIRAL
{ 0x05, LED_MATRIX_BAND_SPIRAL},
#endif
#ifdef ENABLE_LED_MATRIX_CYCLE_LEFT_RIGHT
{ 0x06, LED_MATRIX_CYCLE_LEFT_RIGHT},
#endif
#ifdef ENABLE_LED_MATRIX_CYCLE_UP_DOWN
{ 0x07, LED_MATRIX_CYCLE_UP_DOWN},
#endif
#ifdef ENABLE_LED_MATRIX_CYCLE_OUT_IN
{ 0x08, LED_MATRIX_CYCLE_OUT_IN},
#endif
#ifdef ENABLE_LED_MATRIX_DUAL_BEACON
{ 0x09, LED_MATRIX_DUAL_BEACON},
#endif
#ifdef ENABLE_LED_MATRIX_WAVE_LEFT_RIGHT
{ 0x0A, LED_MATRIX_WAVE_LEFT_RIGHT},
#endif
#ifdef ENABLE_LED_MATRIX_WAVE_UP_DOWN
{ 0x0B, LED_MATRIX_WAVE_UP_DOWN},
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_SIMPLE
{ 0x0C, LED_MATRIX_SOLID_REACTIVE_SIMPLE},
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_WIDE
{ 0x0D, LED_MATRIX_SOLID_REACTIVE_WIDE},
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTIWIDE
{ 0x0E, LED_MATRIX_SOLID_REACTIVE_MULTIWIDE},
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_CROSS
{ 0x0F, LED_MATRIX_SOLID_REACTIVE_CROSS},
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTICROSS
{ 0x10, LED_MATRIX_SOLID_REACTIVE_MULTICROSS},
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_NEXUS
{ 0x11, LED_MATRIX_SOLID_REACTIVE_NEXUS},
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTINEXUS
{ 0x12, LED_MATRIX_SOLID_REACTIVE_MULTINEXUS},
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_SPLASH
{ 0x13, LED_MATRIX_SOLID_SPLASH},
#endif
#endif
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_LED_MATRIX_SOLID_MULTISPLASH
{ 0x14, LED_MATRIX_SOLID_MULTISPLASH},
#endif
#endif
};
uint8_t led_matrix_effect_to_id(uint8_t val) {
for(uint8_t i = 0; i < ARRAY_SIZE(led_matrix_effect_map); i++) {
if (pgm_read_byte(&led_matrix_effect_map[i][1]) == val)
return pgm_read_byte(&led_matrix_effect_map[i][0]);
}
return 0xFF;
}
uint8_t led_matrix_id_to_effect(uint8_t val) {
for(uint8_t i = 0; i < ARRAY_SIZE(led_matrix_effect_map); i++) {
if (pgm_read_byte(&led_matrix_effect_map[i][0]) == val)
return pgm_read_byte(&led_matrix_effect_map[i][1]);
}
return 0xFF;
}

View File

@ -0,0 +1,477 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
888 888 Y8P d88P" Y8P 888 Y8P
888 888 888 888
888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
888 888 888 888 X88 888 888 888 Y8b. 888 X88
888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
888 888
888 888
888 888
.d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
"Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
888
Y8b d88P
"Y88P"
*******************************************************************************/
#pragma once
// clang-format off
enum { ENABLED_RGB_MATRIX_EFFECTS = 0
| (1ULL << 0x00)
#ifdef ENABLE_RGB_MATRIX_ALPHAS_MODS
| (1ULL << 0x01)
#endif
#ifdef ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
| (1ULL << 0x02)
#endif
#ifdef ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
| (1ULL << 0x03)
#endif
#ifdef ENABLE_RGB_MATRIX_BREATHING
| (1ULL << 0x04)
#endif
#ifdef ENABLE_RGB_MATRIX_BAND_SAT
| (1ULL << 0x05)
#endif
#ifdef ENABLE_RGB_MATRIX_BAND_VAL
| (1ULL << 0x06)
#endif
#ifdef ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
| (1ULL << 0x07)
#endif
#ifdef ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
| (1ULL << 0x08)
#endif
#ifdef ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
| (1ULL << 0x09)
#endif
#ifdef ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
| (1ULL << 0x0A)
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_ALL
| (1ULL << 0x0B)
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
| (1ULL << 0x0C)
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
| (1ULL << 0x0D)
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_OUT_IN
| (1ULL << 0x0E)
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
| (1ULL << 0x0F)
#endif
#ifdef ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
| (1ULL << 0x10)
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
| (1ULL << 0x11)
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_SPIRAL
| (1ULL << 0x12)
#endif
#ifdef ENABLE_RGB_MATRIX_DUAL_BEACON
| (1ULL << 0x13)
#endif
#ifdef ENABLE_RGB_MATRIX_RAINBOW_BEACON
| (1ULL << 0x14)
#endif
#ifdef ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
| (1ULL << 0x15)
#endif
#ifdef ENABLE_RGB_MATRIX_RAINDROPS
| (1ULL << 0x16)
#endif
#ifdef ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
| (1ULL << 0x17)
#endif
#ifdef ENABLE_RGB_MATRIX_HUE_BREATHING
| (1ULL << 0x18)
#endif
#ifdef ENABLE_RGB_MATRIX_HUE_PENDULUM
| (1ULL << 0x19)
#endif
#ifdef ENABLE_RGB_MATRIX_HUE_WAVE
| (1ULL << 0x1A)
#endif
#ifdef ENABLE_RGB_MATRIX_PIXEL_FRACTAL
| (1ULL << 0x1B)
#endif
#ifdef ENABLE_RGB_MATRIX_PIXEL_FLOW
| (1ULL << 0x1C)
#endif
#ifdef ENABLE_RGB_MATRIX_PIXEL_RAIN
| (1ULL << 0x1D)
#endif
#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS
#ifdef ENABLE_RGB_MATRIX_TYPING_HEATMAP
| (1ULL << 0x1E)
#endif
#endif
#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS
#ifdef ENABLE_RGB_MATRIX_DIGITAL_RAIN
| (1ULL << 0x1F)
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
| (1ULL << 0x20)
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE
| (1ULL << 0x21)
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
| (1ULL << 0x22)
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
| (1ULL << 0x23)
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
| (1ULL << 0x24)
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
| (1ULL << 0x25)
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
| (1ULL << 0x26)
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
| (1ULL << 0x27)
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SPLASH
| (1ULL << 0x28)
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_MULTISPLASH
| (1ULL << 0x29)
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_SPLASH
| (1ULL << 0x2A)
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
| (1ULL << 0x2B)
#endif
#endif
};
static const uint8_t rgb_matrix_effect_map[][2] PROGMEM = {
{ 0x00, RGB_MATRIX_SOLID_COLOR},
#ifdef ENABLE_RGB_MATRIX_ALPHAS_MODS
{ 0x01, RGB_MATRIX_ALPHAS_MODS},
#endif
#ifdef ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
{ 0x02, RGB_MATRIX_GRADIENT_UP_DOWN},
#endif
#ifdef ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
{ 0x03, RGB_MATRIX_GRADIENT_LEFT_RIGHT},
#endif
#ifdef ENABLE_RGB_MATRIX_BREATHING
{ 0x04, RGB_MATRIX_BREATHING},
#endif
#ifdef ENABLE_RGB_MATRIX_BAND_SAT
{ 0x05, RGB_MATRIX_BAND_SAT},
#endif
#ifdef ENABLE_RGB_MATRIX_BAND_VAL
{ 0x06, RGB_MATRIX_BAND_VAL},
#endif
#ifdef ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
{ 0x07, RGB_MATRIX_BAND_PINWHEEL_SAT},
#endif
#ifdef ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
{ 0x08, RGB_MATRIX_BAND_PINWHEEL_VAL},
#endif
#ifdef ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
{ 0x09, RGB_MATRIX_BAND_SPIRAL_SAT},
#endif
#ifdef ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
{ 0x0A, RGB_MATRIX_BAND_SPIRAL_VAL},
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_ALL
{ 0x0B, RGB_MATRIX_CYCLE_ALL},
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
{ 0x0C, RGB_MATRIX_CYCLE_LEFT_RIGHT},
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
{ 0x0D, RGB_MATRIX_CYCLE_UP_DOWN},
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_OUT_IN
{ 0x0E, RGB_MATRIX_CYCLE_OUT_IN},
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
{ 0x0F, RGB_MATRIX_CYCLE_OUT_IN_DUAL},
#endif
#ifdef ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
{ 0x10, RGB_MATRIX_RAINBOW_MOVING_CHEVRON},
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
{ 0x11, RGB_MATRIX_CYCLE_PINWHEEL},
#endif
#ifdef ENABLE_RGB_MATRIX_CYCLE_SPIRAL
{ 0x12, RGB_MATRIX_CYCLE_SPIRAL},
#endif
#ifdef ENABLE_RGB_MATRIX_DUAL_BEACON
{ 0x13, RGB_MATRIX_DUAL_BEACON},
#endif
#ifdef ENABLE_RGB_MATRIX_RAINBOW_BEACON
{ 0x14, RGB_MATRIX_RAINBOW_BEACON},
#endif
#ifdef ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
{ 0x15, RGB_MATRIX_RAINBOW_PINWHEELS},
#endif
#ifdef ENABLE_RGB_MATRIX_RAINDROPS
{ 0x16, RGB_MATRIX_RAINDROPS},
#endif
#ifdef ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
{ 0x17, RGB_MATRIX_JELLYBEAN_RAINDROPS},
#endif
#ifdef ENABLE_RGB_MATRIX_HUE_BREATHING
{ 0x18, RGB_MATRIX_HUE_BREATHING},
#endif
#ifdef ENABLE_RGB_MATRIX_HUE_PENDULUM
{ 0x19, RGB_MATRIX_HUE_PENDULUM},
#endif
#ifdef ENABLE_RGB_MATRIX_HUE_WAVE
{ 0x1A, RGB_MATRIX_HUE_WAVE},
#endif
#ifdef ENABLE_RGB_MATRIX_PIXEL_FRACTAL
{ 0x1B, RGB_MATRIX_PIXEL_FRACTAL},
#endif
#ifdef ENABLE_RGB_MATRIX_PIXEL_FLOW
{ 0x1C, RGB_MATRIX_PIXEL_FLOW},
#endif
#ifdef ENABLE_RGB_MATRIX_PIXEL_RAIN
{ 0x1D, RGB_MATRIX_PIXEL_RAIN},
#endif
#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS
#ifdef ENABLE_RGB_MATRIX_TYPING_HEATMAP
{ 0x1E, RGB_MATRIX_TYPING_HEATMAP},
#endif
#endif
#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS
#ifdef ENABLE_RGB_MATRIX_DIGITAL_RAIN
{ 0x1F, RGB_MATRIX_DIGITAL_RAIN},
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
{ 0x20, RGB_MATRIX_SOLID_REACTIVE_SIMPLE},
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE
{ 0x21, RGB_MATRIX_SOLID_REACTIVE},
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
{ 0x22, RGB_MATRIX_SOLID_REACTIVE_WIDE},
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
{ 0x23, RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE},
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
{ 0x24, RGB_MATRIX_SOLID_REACTIVE_CROSS},
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
{ 0x25, RGB_MATRIX_SOLID_REACTIVE_MULTICROSS},
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
{ 0x26, RGB_MATRIX_SOLID_REACTIVE_NEXUS},
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
{ 0x27, RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS},
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SPLASH
{ 0x28, RGB_MATRIX_SPLASH},
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_MULTISPLASH
{ 0x29, RGB_MATRIX_MULTISPLASH},
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_SPLASH
{ 0x2A, RGB_MATRIX_SOLID_SPLASH},
#endif
#endif
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifdef ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
{ 0x2B, RGB_MATRIX_SOLID_MULTISPLASH},
#endif
#endif
};
uint8_t rgb_matrix_effect_to_id(uint8_t val) {
for(uint8_t i = 0; i < ARRAY_SIZE(rgb_matrix_effect_map); i++) {
if (pgm_read_byte(&rgb_matrix_effect_map[i][1]) == val)
return pgm_read_byte(&rgb_matrix_effect_map[i][0]);
}
return 0xFF;
}
uint8_t rgb_matrix_id_to_effect(uint8_t val) {
for(uint8_t i = 0; i < ARRAY_SIZE(rgb_matrix_effect_map); i++) {
if (pgm_read_byte(&rgb_matrix_effect_map[i][0]) == val)
return pgm_read_byte(&rgb_matrix_effect_map[i][1]);
}
return 0xFF;
}

View File

@ -0,0 +1,377 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
888 888 Y8P d88P" Y8P 888 Y8P
888 888 888 888
888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
888 888 888 888 X88 888 888 888 Y8b. 888 X88
888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
888 888
888 888
888 888
.d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
"Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
888
Y8b d88P
"Y88P"
*******************************************************************************/
#pragma once
// clang-format off
enum { ENABLED_RGBLIGHT_EFFECTS = 0
| (1ULL << 0x00)
#ifdef RGBLIGHT_EFFECT_BREATHING
| (1ULL << 0x01)
#endif
#ifdef RGBLIGHT_EFFECT_BREATHING
| (1ULL << 0x02)
#endif
#ifdef RGBLIGHT_EFFECT_BREATHING
| (1ULL << 0x03)
#endif
#ifdef RGBLIGHT_EFFECT_BREATHING
| (1ULL << 0x04)
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
| (1ULL << 0x05)
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
| (1ULL << 0x06)
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
| (1ULL << 0x07)
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
| (1ULL << 0x08)
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
| (1ULL << 0x09)
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
| (1ULL << 0x0A)
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
| (1ULL << 0x0B)
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
| (1ULL << 0x0C)
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
| (1ULL << 0x0D)
#endif
#ifdef RGBLIGHT_EFFECT_SNAKE
| (1ULL << 0x0E)
#endif
#ifdef RGBLIGHT_EFFECT_SNAKE
| (1ULL << 0x0F)
#endif
#ifdef RGBLIGHT_EFFECT_SNAKE
| (1ULL << 0x10)
#endif
#ifdef RGBLIGHT_EFFECT_SNAKE
| (1ULL << 0x11)
#endif
#ifdef RGBLIGHT_EFFECT_SNAKE
| (1ULL << 0x12)
#endif
#ifdef RGBLIGHT_EFFECT_SNAKE
| (1ULL << 0x13)
#endif
#ifdef RGBLIGHT_EFFECT_KNIGHT
| (1ULL << 0x14)
#endif
#ifdef RGBLIGHT_EFFECT_KNIGHT
| (1ULL << 0x15)
#endif
#ifdef RGBLIGHT_EFFECT_KNIGHT
| (1ULL << 0x16)
#endif
#ifdef RGBLIGHT_EFFECT_CHRISTMAS
| (1ULL << 0x17)
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
| (1ULL << 0x18)
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
| (1ULL << 0x19)
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
| (1ULL << 0x1A)
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
| (1ULL << 0x1B)
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
| (1ULL << 0x1C)
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
| (1ULL << 0x1D)
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
| (1ULL << 0x1E)
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
| (1ULL << 0x1F)
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
| (1ULL << 0x20)
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
| (1ULL << 0x21)
#endif
#ifdef RGBLIGHT_EFFECT_RGB_TEST
| (1ULL << 0x22)
#endif
#ifdef RGBLIGHT_EFFECT_ALTERNATING
| (1ULL << 0x23)
#endif
#ifdef RGBLIGHT_EFFECT_TWINKLE
| (1ULL << 0x24)
#endif
#ifdef RGBLIGHT_EFFECT_TWINKLE
| (1ULL << 0x25)
#endif
#ifdef RGBLIGHT_EFFECT_TWINKLE
| (1ULL << 0x26)
#endif
#ifdef RGBLIGHT_EFFECT_TWINKLE
| (1ULL << 0x27)
#endif
#ifdef RGBLIGHT_EFFECT_TWINKLE
| (1ULL << 0x28)
#endif
#ifdef RGBLIGHT_EFFECT_TWINKLE
| (1ULL << 0x29)
#endif
};
static const uint8_t rgblight_effect_map[][2] PROGMEM = {
{ 0x00, RGBLIGHT_MODE_STATIC_LIGHT},
#ifdef RGBLIGHT_EFFECT_BREATHING
{ 0x01, RGBLIGHT_MODE_BREATHING},
#endif
#ifdef RGBLIGHT_EFFECT_BREATHING
{ 0x02, RGBLIGHT_MODE_BREATHING + 1},
#endif
#ifdef RGBLIGHT_EFFECT_BREATHING
{ 0x03, RGBLIGHT_MODE_BREATHING + 2},
#endif
#ifdef RGBLIGHT_EFFECT_BREATHING
{ 0x04, RGBLIGHT_MODE_BREATHING + 3},
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
{ 0x05, RGBLIGHT_MODE_RAINBOW_MOOD},
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
{ 0x06, RGBLIGHT_MODE_RAINBOW_MOOD + 1},
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
{ 0x07, RGBLIGHT_MODE_RAINBOW_MOOD + 2},
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
{ 0x08, RGBLIGHT_MODE_RAINBOW_SWIRL},
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
{ 0x09, RGBLIGHT_MODE_RAINBOW_SWIRL + 1},
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
{ 0x0A, RGBLIGHT_MODE_RAINBOW_SWIRL + 2},
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
{ 0x0B, RGBLIGHT_MODE_RAINBOW_SWIRL + 3},
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
{ 0x0C, RGBLIGHT_MODE_RAINBOW_SWIRL + 4},
#endif
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
{ 0x0D, RGBLIGHT_MODE_RAINBOW_SWIRL + 5},
#endif
#ifdef RGBLIGHT_EFFECT_SNAKE
{ 0x0E, RGBLIGHT_MODE_SNAKE},
#endif
#ifdef RGBLIGHT_EFFECT_SNAKE
{ 0x0F, RGBLIGHT_MODE_SNAKE + 1},
#endif
#ifdef RGBLIGHT_EFFECT_SNAKE
{ 0x10, RGBLIGHT_MODE_SNAKE + 2},
#endif
#ifdef RGBLIGHT_EFFECT_SNAKE
{ 0x11, RGBLIGHT_MODE_SNAKE + 3},
#endif
#ifdef RGBLIGHT_EFFECT_SNAKE
{ 0x12, RGBLIGHT_MODE_SNAKE + 4},
#endif
#ifdef RGBLIGHT_EFFECT_SNAKE
{ 0x13, RGBLIGHT_MODE_SNAKE + 5},
#endif
#ifdef RGBLIGHT_EFFECT_KNIGHT
{ 0x14, RGBLIGHT_MODE_KNIGHT},
#endif
#ifdef RGBLIGHT_EFFECT_KNIGHT
{ 0x15, RGBLIGHT_MODE_KNIGHT + 1},
#endif
#ifdef RGBLIGHT_EFFECT_KNIGHT
{ 0x16, RGBLIGHT_MODE_KNIGHT + 2},
#endif
#ifdef RGBLIGHT_EFFECT_CHRISTMAS
{ 0x17, RGBLIGHT_MODE_CHRISTMAS},
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
{ 0x18, RGBLIGHT_MODE_STATIC_GRADIENT},
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
{ 0x19, RGBLIGHT_MODE_STATIC_GRADIENT + 1},
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
{ 0x1A, RGBLIGHT_MODE_STATIC_GRADIENT + 2},
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
{ 0x1B, RGBLIGHT_MODE_STATIC_GRADIENT + 3},
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
{ 0x1C, RGBLIGHT_MODE_STATIC_GRADIENT + 4},
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
{ 0x1D, RGBLIGHT_MODE_STATIC_GRADIENT + 5},
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
{ 0x1E, RGBLIGHT_MODE_STATIC_GRADIENT + 6},
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
{ 0x1F, RGBLIGHT_MODE_STATIC_GRADIENT + 7},
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
{ 0x20, RGBLIGHT_MODE_STATIC_GRADIENT + 8},
#endif
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
{ 0x21, RGBLIGHT_MODE_STATIC_GRADIENT + 9},
#endif
#ifdef RGBLIGHT_EFFECT_RGB_TEST
{ 0x22, RGBLIGHT_MODE_RGB_TEST},
#endif
#ifdef RGBLIGHT_EFFECT_ALTERNATING
{ 0x23, RGBLIGHT_MODE_ALTERNATING},
#endif
#ifdef RGBLIGHT_EFFECT_TWINKLE
{ 0x24, RGBLIGHT_MODE_TWINKLE},
#endif
#ifdef RGBLIGHT_EFFECT_TWINKLE
{ 0x25, RGBLIGHT_MODE_TWINKLE + 1},
#endif
#ifdef RGBLIGHT_EFFECT_TWINKLE
{ 0x26, RGBLIGHT_MODE_TWINKLE + 2},
#endif
#ifdef RGBLIGHT_EFFECT_TWINKLE
{ 0x27, RGBLIGHT_MODE_TWINKLE + 3},
#endif
#ifdef RGBLIGHT_EFFECT_TWINKLE
{ 0x28, RGBLIGHT_MODE_TWINKLE + 4},
#endif
#ifdef RGBLIGHT_EFFECT_TWINKLE
{ 0x29, RGBLIGHT_MODE_TWINKLE + 5},
#endif
};
uint8_t rgblight_effect_to_id(uint8_t val) {
for(uint8_t i = 0; i < ARRAY_SIZE(rgblight_effect_map); i++) {
if (pgm_read_byte(&rgblight_effect_map[i][1]) == val)
return pgm_read_byte(&rgblight_effect_map[i][0]);
}
return 0xFF;
}
uint8_t rgblight_id_to_effect(uint8_t val) {
for(uint8_t i = 0; i < ARRAY_SIZE(rgblight_effect_map); i++) {
if (pgm_read_byte(&rgblight_effect_map[i][0]) == val)
return pgm_read_byte(&rgblight_effect_map[i][1]);
}
return 0xFF;
}

View File

@ -422,6 +422,10 @@ void rgblight_disable_noeeprom(void) {
rgblight_set();
}
void rgblight_enabled_noeeprom(bool state) {
state ? rgblight_enable_noeeprom() : rgblight_disable_noeeprom();
}
bool rgblight_is_enabled(void) {
return rgblight_config.enable;
}

View File

@ -321,6 +321,7 @@ void rgblight_enable(void);
void rgblight_enable_noeeprom(void);
void rgblight_disable(void);
void rgblight_disable_noeeprom(void);
void rgblight_enabled_noeeprom(bool state);
/* hue, sat, val change */
void rgblight_increase_hue(void);

View File

@ -32,7 +32,7 @@ bool xap_respond_set_audio_config(xap_token_t token, const void *data, size_t le
}
bool xap_respond_save_audio_config(xap_token_t token, const void *data, size_t length) {
eeconfig_update_audio(audio_config.raw);
eeconfig_update_audio_current();
return xap_respond_success(token);
}

View File

@ -57,18 +57,14 @@ bool xap_respond_save_backlight_config(xap_token_t token, const void *data, size
extern rgblight_config_t rgblight_config;
uint8_t rgblight2xap(uint8_t val);
uint8_t xap2rgblight(uint8_t val);
void rgblight_enabled_noeeprom(bool val) {
val ? rgblight_enable_noeeprom() : rgblight_disable_noeeprom();
}
uint8_t rgblight_effect_to_id(uint8_t val);
uint8_t rgblight_id_to_effect(uint8_t val);
bool xap_respond_get_rgblight_config(xap_token_t token, const void *data, size_t length) {
xap_route_lighting_rgblight_get_config_t ret;
ret.enable = rgblight_config.enable;
ret.mode = rgblight2xap(rgblight_config.mode);
ret.mode = rgblight_effect_to_id(rgblight_config.mode);
ret.hue = rgblight_config.hue;
ret.sat = rgblight_config.sat;
ret.val = rgblight_config.val;
@ -84,7 +80,7 @@ bool xap_respond_set_rgblight_config(xap_token_t token, const void *data, size_t
xap_route_lighting_rgblight_set_config_arg_t *arg = (xap_route_lighting_rgblight_set_config_arg_t *)data;
uint8_t mode = xap2rgblight(arg->mode);
uint8_t mode = rgblight_id_to_effect(arg->mode);
if (mode == INVALID_EFFECT) {
return false;
}
@ -109,8 +105,8 @@ bool xap_respond_save_rgblight_config(xap_token_t token, const void *data, size_
extern rgb_config_t rgb_matrix_config;
uint8_t rgb_matrix2xap(uint8_t val);
uint8_t xap2rgb_matrix(uint8_t val);
uint8_t rgb_matrix_effect_to_id(uint8_t val);
uint8_t rgb_matrix_id_to_effect(uint8_t val);
void rgb_matrix_enabled_noeeprom(bool val) {
val ? rgb_matrix_enable_noeeprom() : rgb_matrix_disable_noeeprom();
@ -120,7 +116,7 @@ bool xap_respond_get_rgb_matrix_config(xap_token_t token, const void *data, size
xap_route_lighting_rgb_matrix_get_config_t ret;
ret.enable = rgb_matrix_config.enable;
ret.mode = rgb_matrix2xap(rgb_matrix_config.mode);
ret.mode = rgb_matrix_effect_to_id(rgb_matrix_config.mode);
ret.hue = rgb_matrix_config.hsv.h;
ret.sat = rgb_matrix_config.hsv.s;
ret.val = rgb_matrix_config.hsv.v;
@ -137,7 +133,7 @@ bool xap_respond_set_rgb_matrix_config(xap_token_t token, const void *data, size
xap_route_lighting_rgb_matrix_set_config_arg_t *arg = (xap_route_lighting_rgb_matrix_set_config_arg_t *)data;
uint8_t mode = xap2rgb_matrix(arg->mode);
uint8_t mode = rgb_matrix_id_to_effect(arg->mode);
if (mode == INVALID_EFFECT) {
return false;
}

File diff suppressed because it is too large Load Diff

View File

@ -48,7 +48,6 @@ typedef enum xap_route_type_t {
XAP_ROUTE,
XAP_EXECUTE,
XAP_VALUE,
XAP_GETTER,
XAP_CONST_MEM,
TOTAL_XAP_ROUTE_TYPES
} xap_route_type_t;
@ -83,9 +82,6 @@ struct __attribute__((packed)) xap_route_t {
// XAP_EXECUTE
bool (*handler)(xap_token_t token, const uint8_t *data, size_t data_len);
// XAP_GETTER
uint32_t (*u32getter)(void);
// XAP_VALUE / XAP_CONST_MEM
struct {
const void * const_data;
@ -136,14 +132,6 @@ void xap_execute_route(xap_token_t token, const xap_route_t *routes, size_t max_
}
break;
case XAP_GETTER:
if (route.u32getter != NULL) {
const uint32_t ret = (route.u32getter)();
xap_respond_data(token, &ret, sizeof(ret));
return;
}
break;
case XAP_VALUE:
xap_respond_data(token, route.const_data, route.const_data_len);
return;

View File

@ -1,6 +1,9 @@
#!/bin/bash
set -e
qmk generate-lighting-map -f rgblight -o quantum/rgblight/lighting_map.h
qmk generate-lighting-map -f rgb_matrix -o quantum/rgb_matrix/lighting_map.h
qmk generate-lighting-map -f led_matrix -o quantum/led_matrix/lighting_map.h
qmk generate-rgb-breathe-table -o quantum/rgblight/rgblight_breathe_table.h
qmk generate-keycodes --version latest -o quantum/keycodes.h
qmk generate-keycodes-tests --version latest -o tests/test_common/keycode_table.cpp