stash more lighting

This commit is contained in:
zvecr 2022-09-28 23:47:12 +01:00
parent 1dbb4c0f96
commit f81328068e
11 changed files with 708 additions and 8 deletions

View File

@ -0,0 +1,80 @@
{
"groups": {
"reactive": {}
},
"effects": {
"0x01": {
"key": "SOLID"
},
"0x02": {
"key": "ALPHAS_MODS"
},
"0x03": {
"key": "BREATHING"
},
"0x04": {
"key": "BAND"
},
"0x05": {
"key": "BAND_PINWHEEL"
},
"0x06": {
"key": "BAND_SPIRAL"
},
"0x07": {
"key": "CYCLE_LEFT_RIGHT"
},
"0x08": {
"key": "CYCLE_UP_DOWN"
},
"0x09": {
"key": "CYCLE_OUT_IN"
},
"0x0A": {
"key": "DUAL_BEACON"
},
"0x0B": {
"key": "WAVE_LEFT_RIGHT"
},
"0x0C": {
"key": "WAVE_UP_DOWN"
},
"0x0D": {
"key": "SOLID_REACTIVE_SIMPLE",
"group": "reactive"
},
"0x0E": {
"key": "SOLID_REACTIVE_WIDE",
"group": "reactive"
},
"0x0F": {
"key": "SOLID_REACTIVE_MULTIWIDE",
"group": "reactive"
},
"0x10": {
"key": "SOLID_REACTIVE_CROSS",
"group": "reactive"
},
"0x11": {
"key": "SOLID_REACTIVE_MULTICROSS",
"group": "reactive"
},
"0x12": {
"key": "SOLID_REACTIVE_NEXUS",
"group": "reactive"
},
"0x13": {
"key": "SOLID_REACTIVE_MULTINEXUS",
"group": "reactive"
},
"0x14": {
"key": "SOLID_SPLASH",
"group": "reactive"
},
"0x15": {
"key": "SOLID_MULTISPLASH",
"group": "reactive"
}
}
}

View File

@ -0,0 +1,156 @@
{
"groups": {
"framebuffer": {},
"reactive": {}
},
"effects": {
"0x01": {
"key": "SOLID_COLOR"
},
"0x02": {
"key": "ALPHAS_MODS"
},
"0x03": {
"key": "GRADIENT_UP_DOWN"
},
"0x04": {
"key": "GRADIENT_LEFT_RIGHT"
},
"0x05": {
"key": "BREATHING"
},
"0x06": {
"key": "BAND_SAT"
},
"0x07": {
"key": "BAND_VAL"
},
"0x08": {
"key": "BAND_PINWHEEL_SAT"
},
"0x09": {
"key": "BAND_PINWHEEL_VAL"
},
"0x0A": {
"key": "BAND_SPIRAL_SAT"
},
"0x0B": {
"key": "BAND_SPIRAL_VAL"
},
"0x0C": {
"key": "CYCLE_ALL"
},
"0x0D": {
"key": "CYCLE_LEFT_RIGHT"
},
"0x0E": {
"key": "CYCLE_UP_DOWN"
},
"0x0F": {
"key": "CYCLE_OUT_IN"
},
"0x10": {
"key": "CYCLE_OUT_IN_DUAL"
},
"0x11": {
"key": "RAINBOW_MOVING_CHEVRON"
},
"0x12": {
"key": "CYCLE_PINWHEEL"
},
"0x13": {
"key": "CYCLE_SPIRAL"
},
"0x14": {
"key": "DUAL_BEACON"
},
"0x15": {
"key": "RAINBOW_BEACON"
},
"0x16": {
"key": "RAINBOW_PINWHEELS"
},
"0x17": {
"key": "RAINDROPS"
},
"0x18": {
"key": "JELLYBEAN_RAINDROPS"
},
"0x19": {
"key": "HUE_BREATHING"
},
"0x1A": {
"key": "HUE_PENDULUM"
},
"0x1B": {
"key": "HUE_WAVE"
},
"0x1C": {
"key": "PIXEL_FRACTAL"
},
"0x1D": {
"key": "PIXEL_FLOW"
},
"0x1E": {
"key": "PIXEL_RAIN"
},
"0x1F": {
"key": "TYPING_HEATMAP",
"group": "framebuffer"
},
"0x20": {
"key": "DIGITAL_RAIN",
"group": "framebuffer"
},
"0x21": {
"key": "SOLID_REACTIVE_SIMPLE",
"group": "reactive"
},
"0x22": {
"key": "RGB_MATRIX_SOLID_REACTIVE",
"group": "reactive"
},
"0x23": {
"key": "RGB_MATRIX_SOLID_REACTIVE_WIDE",
"group": "reactive"
},
"0x24": {
"key": "SOLID_REACTIVE_MULTIWIDE",
"group": "reactive"
},
"0x25": {
"key": "SOLID_REACTIVE_CROSS",
"group": "reactive"
},
"0x26": {
"key": "SOLID_REACTIVE_MULTICROSS",
"group": "reactive"
},
"0x27": {
"key": "SOLID_REACTIVE_NEXUS",
"group": "reactive"
},
"0x28": {
"key": "SOLID_REACTIVE_MULTINEXUS",
"group": "reactive"
},
"0x29": {
"key": "SPLASH",
"group": "reactive"
},
"0x2A": {
"key": "MULTISPLASH",
"group": "reactive"
},
"0x2B": {
"key": "SOLID_SPLASH",
"group": "reactive"
},
"0x2C": {
"key": "SOLID_MULTISPLASH",
"group": "reactive"
}
}
}

View File

@ -0,0 +1,130 @@
{
"effects": {
"0x01": {
"key": "STATIC_LIGHT"
},
"0x02": {
"key": "BREATHING"
},
"0x03": {
"key": "BREATHING_2"
},
"0x04": {
"key": "BREATHING_3"
},
"0x05": {
"key": "BREATHING_4"
},
"0x06": {
"key": "RAINBOW_MOOD"
},
"0x07": {
"key": "RAINBOW_MOOD_2"
},
"0x08": {
"key": "RAINBOW_MOOD_3"
},
"0x09": {
"key": "RAINBOW_SWIRL"
},
"0x0A": {
"key": "RAINBOW_SWIRL_2"
},
"0x0B": {
"key": "RAINBOW_SWIRL_3"
},
"0x0C": {
"key": "RAINBOW_SWIRL_4"
},
"0x0D": {
"key": "RAINBOW_SWIRL_5"
},
"0x0E": {
"key": "RAINBOW_SWIRL_6"
},
"0x0F": {
"key": "SNAKE"
},
"0x10": {
"key": "SNAKE_2"
},
"0x11": {
"key": "SNAKE_3"
},
"0x12": {
"key": "SNAKE_4"
},
"0x13": {
"key": "SNAKE_5"
},
"0x14": {
"key": "SNAKE_6"
},
"0x15": {
"key": "KNIGHT"
},
"0x16": {
"key": "KNIGHT_2"
},
"0x17": {
"key": "KNIGHT_3"
},
"0x18": {
"key": "CHRISTMAS"
},
"0x19": {
"key": "STATIC_GRADIENT"
},
"0x1A": {
"key": "STATIC_GRADIENT_2"
},
"0x1B": {
"key": "STATIC_GRADIENT_3"
},
"0x1C": {
"key": "STATIC_GRADIENT_4"
},
"0x1D": {
"key": "STATIC_GRADIENT_5"
},
"0x1E": {
"key": "STATIC_GRADIENT_6"
},
"0x1F": {
"key": "STATIC_GRADIENT_7"
},
"0x20": {
"key": "STATIC_GRADIENT_8"
},
"0x21": {
"key": "STATIC_GRADIENT_9"
},
"0x22": {
"key": "STATIC_GRADIENT_10"
},
"0x23": {
"key": "TEST"
},
"0x24": {
"key": "ALTERNATING"
},
"0x25": {
"key": "TWINKLE"
},
"0x26": {
"key": "TWINKLE_2"
},
"0x27": {
"key": "TWINKLE_3"
},
"0x28": {
"key": "TWINKLE_4"
},
"0x29": {
"key": "TWINKLE_5"
},
"0x2A": {
"key": "TWINKLE_6"
}
}
}

View File

@ -22,7 +22,9 @@ class {{ name }}(namedtuple('{{ name }}', '{{ members }}')):
{% set type_definitions = [
{'name':'XAPRequest', 'members': 'token length data', 'fmt':'<HB61s'},
{'name':'XAPResponse', 'members': 'token flags length data', 'fmt':'<HBB60s'},
{'name':'XAPConfigRgblight', 'members': 'enable mode hue sat val speed', 'fmt':'<BBBBBB'}
{'name':'XAPConfigBacklight', 'members': 'enable mode val', 'fmt':'<BBB'},
{'name':'XAPConfigRgblight', 'members': 'enable mode hue sat val speed', 'fmt':'<BBBBBB'},
{'name':'XAPConfigRgbMatrix', 'members': 'enable mode hue sat val speed flags', 'fmt':'<BBBBBBB'}
] %}
{% for item in type_definitions -%}{{ gen_struct(item.name, item.members, item.fmt) }}{% endfor -%}

View File

@ -1,10 +1,73 @@
{
version: 0.3.0
uses: {
rgblight: 0.0.1
rgb_matrix: 0.0.1
led_matrix: 0.0.1
}
routes: {
0x06: {
routes: {
0x02: {
type: router
name: backlight
define: BACKLIGHT
description:
'''
This subsystem allows for control over the backlight subsystem.
'''
enable_if_preprocessor: defined(BACKLIGHT_ENABLE)
routes: {
0x01: {
type: command
name: Capabilities Query
define: CAPABILITIES_QUERY
description:
'''
backlight subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.
'''
return_type: u32
return_purpose: capabilities
return_constant: XAP_ROUTE_LIGHTING_BACKLIGHT_CAPABILITIES
}
0x02: {
type: command
name: Get Enabled Effects
define: GET_ENABLED_EFFECTS
description: Each bit should be considered as a "usable" effect id
return_type: u8
return_constant: ENABLED_BACKLIGHT_EFFECTS
}
0x03: {
type: command
name: Get Config
define: GET_CONFIG
description: Query the current config.
return_type: struct
return_struct_length: 3
return_struct_members: [
{
type: u8
name: enable
},
{
type: u8
name: mode
},
{
type: u8
name: val
},
]
return_execute: get_backlight_config
}
}
}
0x03: {
type: router
name: rgblight
@ -72,6 +135,78 @@
}
}
}
0x04: {
type: router
name: rgbmatrix
define: RGB_MATRIX
description:
'''
This subsystem allows for control over the rgb matrix subsystem.
'''
enable_if_preprocessor: defined(RGB_MATRIX_ENABLE)
routes: {
0x01: {
type: command
name: Capabilities Query
define: CAPABILITIES_QUERY
description:
'''
rgb matrix subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.
'''
return_type: u32
return_purpose: capabilities
return_constant: XAP_ROUTE_LIGHTING_RGB_MATRIX_CAPABILITIES
}
0x02: {
type: command
name: Get Enabled Effects
define: GET_ENABLED_EFFECTS
description: Each bit should be considered as a "usable" effect id
return_type: u64
return_constant: ENABLED_RGB_MATRIX_EFFECTS
}
0x03: {
type: command
name: Get Config
define: GET_CONFIG
description: Query the current config.
return_type: struct
return_struct_length: 7
return_struct_members: [
{
type: u8
name: enable
},
{
type: u8
name: mode
},
{
type: u8
name: hue
},
{
type: u8
name: sat
},
{
type: u8
name: val
},
{
type: u8
name: speed
},
{
type: u8
name: flags
},
]
return_execute: get_rgb_matrix_config
}
}
}
}
}
}

View File

@ -152,6 +152,15 @@ This subsystem allows for control over the lighting subsystem.
| -- | -- | -- | -- | -- |
| Capabilities Query | `0x06 0x01` | |__Response:__ `u32`| Lighting subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.|
#### backlight - `0x06 0x02`
This subsystem allows for control over the backlight subsystem.
| Name | Route | Tags | Payloads | Description |
| -- | -- | -- | -- | -- |
| Capabilities Query | `0x06 0x02 0x01` | |__Response:__ `u32`| backlight subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.|
| Get Enabled Effects | `0x06 0x02 0x02` | |__Response:__ `u8`| Each bit should be considered as a "usable" effect id|
| Get Config | `0x06 0x02 0x03` | |__Response:__<br>&nbsp;&nbsp;&nbsp;&nbsp;* enable: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* mode: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* val: `u8`| Query the current config.|
#### rgblight - `0x06 0x03`
This subsystem allows for control over the rgblight subsystem.
@ -161,6 +170,15 @@ This subsystem allows for control over the rgblight subsystem.
| Get Enabled Effects | `0x06 0x03 0x02` | |__Response:__ `u64`| Each bit should be considered as a "usable" effect id|
| Get Config | `0x06 0x03 0x03` | |__Response:__<br>&nbsp;&nbsp;&nbsp;&nbsp;* enable: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* mode: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* hue: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* sat: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* val: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* speed: `u8`| Query the current config.|
#### rgbmatrix - `0x06 0x04`
This subsystem allows for control over the rgb matrix subsystem.
| Name | Route | Tags | Payloads | Description |
| -- | -- | -- | -- | -- |
| Capabilities Query | `0x06 0x04 0x01` | |__Response:__ `u32`| rgb matrix subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.|
| Get Enabled Effects | `0x06 0x04 0x02` | |__Response:__ `u64`| Each bit should be considered as a "usable" effect id|
| Get Config | `0x06 0x04 0x03` | |__Response:__<br>&nbsp;&nbsp;&nbsp;&nbsp;* enable: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* mode: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* hue: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* sat: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* val: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* speed: `u8`<br>&nbsp;&nbsp;&nbsp;&nbsp;* flags: `u8`| Query the current config.|
## Broadcast messages

View File

@ -7,7 +7,7 @@ from milc import cli
from qmk.keyboard import render_layout
from qmk.xap.common import get_xap_keycodes
from xap_client import XAPClient, XAPEventType, XAPSecureStatus, XAPConfigRgblight
from xap_client import XAPClient, XAPEventType, XAPSecureStatus, XAPConfigRgblight, XAPConfigBacklight, XAPConfigRgbMatrix, XAPRoutes
KEYCODE_MAP = get_xap_keycodes('latest')
@ -188,12 +188,31 @@ class XAPShell(cmd.Cmd):
return False
def do_dump(self, line):
ret = self.device.transaction(b'\x06\x03\x03')
ret = XAPConfigRgblight.from_bytes(ret)
print(ret)
caps = self.device.int_transaction(XAPRoutes.LIGHTING_CAPABILITIES_QUERY)
ret = self.device.int_transaction(b'\x06\x03\x02')
print(f'XAPEffectRgblight(enabled={bin(ret)})')
if caps & (1 << XAPRoutes.LIGHTING_BACKLIGHT[-1]):
ret = self.device.transaction(XAPRoutes.LIGHTING_BACKLIGHT_GET_CONFIG)
ret = XAPConfigBacklight.from_bytes(ret)
print(ret)
ret = self.device.int_transaction(XAPRoutes.LIGHTING_BACKLIGHT_GET_ENABLED_EFFECTS)
print(f'XAPEffectBacklight(enabled={bin(ret)})')
if caps & (1 << XAPRoutes.LIGHTING_RGBLIGHT[-1]):
ret = self.device.transaction(XAPRoutes.LIGHTING_RGBLIGHT_GET_CONFIG)
ret = XAPConfigRgblight.from_bytes(ret)
print(ret)
ret = self.device.int_transaction(XAPRoutes.LIGHTING_RGBLIGHT_GET_ENABLED_EFFECTS)
print(f'XAPEffectRgblight(enabled={bin(ret)})')
if caps & (1 << XAPRoutes.LIGHTING_RGB_MATRIX[-1]):
ret = self.device.transaction(XAPRoutes.LIGHTING_RGB_MATRIX_GET_CONFIG)
ret = XAPConfigRgbMatrix.from_bytes(ret)
print(ret)
ret = self.device.int_transaction(XAPRoutes.LIGHTING_RGB_MATRIX_GET_ENABLED_EFFECTS)
print(f'XAPEffectRgbMatrix(enabled={bin(ret)})')
@cli.argument('-v', '--verbose', arg_only=True, action='store_true', help='Turns on verbose output.')

View File

@ -61,7 +61,15 @@ class XAPRoutes():
REMAPPING_SET_ENCODER_KEYCODE = b'\x05\x04'
# LIGHTING
LIGHTING_CAPABILITIES_QUERY = b'\x06\x01'
LIGHTING_BACKLIGHT = b'\x06\x02'
LIGHTING_BACKLIGHT_CAPABILITIES_QUERY = b'\x06\x02\x01'
LIGHTING_BACKLIGHT_GET_ENABLED_EFFECTS = b'\x06\x02\x02'
LIGHTING_BACKLIGHT_GET_CONFIG = b'\x06\x02\x03'
LIGHTING_RGBLIGHT = b'\x06\x03'
LIGHTING_RGBLIGHT_CAPABILITIES_QUERY = b'\x06\x03\x01'
LIGHTING_RGBLIGHT_GET_ENABLED_EFFECTS = b'\x06\x03\x02'
LIGHTING_RGBLIGHT_GET_CONFIG = b'\x06\x03\x03'
LIGHTING_RGB_MATRIX = b'\x06\x04'
LIGHTING_RGB_MATRIX_CAPABILITIES_QUERY = b'\x06\x04\x01'
LIGHTING_RGB_MATRIX_GET_ENABLED_EFFECTS = b'\x06\x04\x02'
LIGHTING_RGB_MATRIX_GET_CONFIG = b'\x06\x04\x03'

View File

@ -59,6 +59,20 @@ class XAPResponse(namedtuple('XAPResponse', 'token flags length data')):
return self.fmt.pack(*list(self))
class XAPConfigBacklight(namedtuple('XAPConfigBacklight', 'enable mode val')):
fmt = Struct('<BBB')
def __new__(cls, *args):
return super().__new__(cls, *args)
@classmethod
def from_bytes(cls, data):
return cls._make(cls.fmt.unpack(data))
def to_bytes(self):
return self.fmt.pack(*list(self))
class XAPConfigRgblight(namedtuple('XAPConfigRgblight', 'enable mode hue sat val speed')):
fmt = Struct('<BBBBBB')
@ -73,6 +87,20 @@ class XAPConfigRgblight(namedtuple('XAPConfigRgblight', 'enable mode hue sat val
return self.fmt.pack(*list(self))
class XAPConfigRgbMatrix(namedtuple('XAPConfigRgbMatrix', 'enable mode hue sat val speed flags')):
fmt = Struct('<BBBBBBB')
def __new__(cls, *args):
return super().__new__(cls, *args)
@classmethod
def from_bytes(cls, data):
return cls._make(cls.fmt.unpack(data))
def to_bytes(self):
return self.fmt.pack(*list(self))
# Spec structs
# TODO: gen outbound object for board_identifiers
# TODO: gen inbound object for get_keymap_keycode
@ -80,6 +108,8 @@ class XAPConfigRgblight(namedtuple('XAPConfigRgblight', 'enable mode hue sat val
# TODO: gen inbound object for set_keymap_keycode
# TODO: gen inbound object for set_encoder_keycode
# TODO: gen outbound object for get_config
# TODO: gen outbound object for get_config
# TODO: gen outbound object for get_config
class XAPSecureStatus(IntEnum):

View File

@ -31,6 +31,11 @@ bool get_config_blob_chunk(uint16_t offset, uint8_t *data, uint8_t data_len) {
// TODO: return actual values
#define ENABLED_RGBLIGHT_EFFECTS 0xFFFFFFFF
#define ENABLED_RGB_MATRIX_EFFECTS 0xFFFFFFFF
#ifdef BACKLIGHT_BREATHING
# define ENABLED_BACKLIGHT_EFFECTS 0b00000001
#else
# define ENABLED_BACKLIGHT_EFFECTS 0b00000000
#endif
#define QSTR2(z) #z
#define QSTR(z) QSTR2(z)

View File

@ -182,14 +182,88 @@ bool xap_respond_dynamic_encoder_set_keycode(xap_token_t token, const void *data
}
#endif
#if ((defined(BACKLIGHT_ENABLE)))
# include "backlight.h"
extern backlight_config_t backlight_config;
bool xap_respond_get_backlight_config(xap_token_t token, const void *data, size_t length) {
xap_route_lighting_backlight_get_config_t ret;
ret.enable = backlight_config.enable;
ret.mode = backlight_config.breathing;
ret.val = backlight_config.level;
return xap_respond_data(token, &ret, sizeof(ret));
}
#endif
#if ((defined(RGBLIGHT_ENABLE)))
# include "rgblight.h"
extern rgblight_config_t rgblight_config;
// static uint8_t effect_map[][2] = {
// {1, RGBLIGHT_MODE_STATIC_LIGHT},
// # ifdef RGBLIGHT_EFFECT_BREATHING
// {2, RGBLIGHT_MODE_BREATHING},
// {3, RGBLIGHT_MODE_BREATHING + 1},
// {4, RGBLIGHT_MODE_BREATHING + 2},
// {5, RGBLIGHT_MODE_BREATHING + 3},
// # endif
// /*...*/
// };
// static uint8_t xap2rgb(uint8_t val) {
// for(uint8_t i = 0; i < ARRAY_SIZE(effect_map); i++){
// if (effect_map[i][0] == val) {
// return effect_map[i][1];
// }
// }
// return 0;
// }
// static uint8_t rgb2xap(uint8_t val) {
// for(uint8_t i = 0; i < ARRAY_SIZE(effect_map); i++){
// if (effect_map[i][1] == val) {
// return effect_map[i][0];
// }
// }
// return 0;
// }
static uint8_t effect_map[43] = {
0, //
RGBLIGHT_MODE_STATIC_LIGHT, //
# ifdef RGBLIGHT_EFFECT_BREATHING
RGBLIGHT_MODE_BREATHING,
RGBLIGHT_MODE_BREATHING + 1,
RGBLIGHT_MODE_BREATHING + 2,
RGBLIGHT_MODE_BREATHING + 3,
# endif
0,
/*...*/
};
// static uint8_t xap2rgb(uint8_t val) {
// return effect_map[val];
// }
static uint8_t rgb2xap(uint8_t val) {
for (uint8_t i = 0; i < ARRAY_SIZE(effect_map); i++) {
if (effect_map[i] == val) {
return i;
}
}
return 0;
}
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 = rgblight_config.mode;
ret.mode = rgb2xap(rgblight_config.mode);
ret.hue = rgblight_config.hue;
ret.sat = rgblight_config.sat;
ret.val = rgblight_config.val;
@ -198,3 +272,46 @@ bool xap_respond_get_rgblight_config(xap_token_t token, const void *data, size_t
return xap_respond_data(token, &ret, sizeof(ret));
}
#endif
#if ((defined(RGB_MATRIX_ENABLE)))
# include "rgb_matrix.h"
extern rgb_config_t rgb_matrix_config;
static uint8_t effect_map[43] = {
0, //
RGB_MATRIX_SOLID_COLOR, //
# ifdef ENABLE_RGB_MATRIX_ALPHAS_MODS
RGB_MATRIX_ALPHAS_MODS,
# endif
0,
/*...*/
};
// static uint8_t xap2rgb(uint8_t val) {
// return effect_map[val];
// }
static uint8_t rgb2xap(uint8_t val) {
for (uint8_t i = 0; i < ARRAY_SIZE(effect_map); i++) {
if (effect_map[i] == val) {
return i;
}
}
return 0;
}
bool xap_respond_get_rgb_matrix_config(xap_token_t token, const void *data, size_t length) {
xap_route_lighting_rgb_matrix_get_config_t ret;
ret.enable = rgb_matrix_config.enable;
ret.mode = rgb2xap(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;
ret.speed = rgb_matrix_config.speed;
ret.flags = rgb_matrix_config.flags;
return xap_respond_data(token, &ret, sizeof(ret));
}
#endif