From 2b00b846dce1d1267dfdb2a3c2972a367cc0dd44 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Fri, 21 Mar 2025 23:38:34 +1100 Subject: Non-volatile memory data repository pattern (#24356) * First batch of eeconfig conversions. * Offset and length for datablocks. * `via`, `dynamic_keymap`. * Fix filename. * Commentary. * wilba leds * satisfaction75 * satisfaction75 * more keyboard whack-a-mole * satisfaction75 * omnikeyish * more whack-a-mole * `generic_features.mk` to automatically pick up nvm repositories * thievery * deferred variable resolve * whitespace * convert api to structs/unions * convert api to structs/unions * convert api to structs/unions * fixups * code-side docs * code size fix * rollback * nvm_xxxxx_erase * Updated location of eeconfig magic numbers so non-EEPROM nvm drivers can use them too. * Fixup build. * Fixup compilation error with encoders. * Build fixes. * Add `via_ci` keymap to onekey to exercise VIA bindings (and thus dynamic keymap et.al.), fixup compilation errors based on preprocessor+sizeof. * Build failure rectification. --- quantum/led_matrix/led_matrix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum/led_matrix/led_matrix.c') diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c index 58263c62e3..2e107a66e9 100644 --- a/quantum/led_matrix/led_matrix.c +++ b/quantum/led_matrix/led_matrix.c @@ -86,9 +86,9 @@ static last_hit_t last_hit_buffer; const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT; #endif -EECONFIG_DEBOUNCE_HELPER(led_matrix, EECONFIG_LED_MATRIX, led_matrix_eeconfig); +EECONFIG_DEBOUNCE_HELPER(led_matrix, led_matrix_eeconfig); -void eeconfig_update_led_matrix(void) { +void eeconfig_force_flush_led_matrix(void) { eeconfig_flush_led_matrix(true); } -- cgit v1.2.3 From 5c39722ab9c9c7b86f34d4ed4ca4620a47dab01b Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Sun, 20 Apr 2025 05:20:00 +1000 Subject: Allow for disabling EEPROM subsystem entirely. (#25173) --- builddefs/common_features.mk | 146 ++++++++++++++++++++------------------- data/schemas/keyboard.jsonschema | 2 +- quantum/dynamic_keymap.c | 2 - quantum/eeconfig.c | 5 -- quantum/led_matrix/led_matrix.c | 1 - quantum/rgb_matrix/rgb_matrix.c | 1 - quantum/unicode/unicode.c | 1 - quantum/via.c | 1 - 8 files changed, 75 insertions(+), 84 deletions(-) (limited to 'quantum/led_matrix/led_matrix.c') diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk index 802e01de43..f30a456fc3 100644 --- a/builddefs/common_features.mk +++ b/builddefs/common_features.mk @@ -171,80 +171,82 @@ endif VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c spi wear_leveling legacy_stm32_flash EEPROM_DRIVER ?= vendor -ifeq ($(filter $(EEPROM_DRIVER),$(VALID_EEPROM_DRIVER_TYPES)),) +ifneq ($(strip $(EEPROM_DRIVER)),none) + ifeq ($(filter $(EEPROM_DRIVER),$(VALID_EEPROM_DRIVER_TYPES)),) $(call CATASTROPHIC_ERROR,Invalid EEPROM_DRIVER,EEPROM_DRIVER="$(EEPROM_DRIVER)" is not a valid EEPROM driver) -else - OPT_DEFS += -DEEPROM_ENABLE - COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom - COMMON_VPATH += $(DRIVER_PATH)/eeprom - COMMON_VPATH += $(PLATFORM_COMMON_DIR) - ifeq ($(strip $(EEPROM_DRIVER)), custom) - # Custom EEPROM implementation -- only needs to implement init/erase/read_block/write_block - OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_CUSTOM - SRC += eeprom_driver.c - else ifeq ($(strip $(EEPROM_DRIVER)), wear_leveling) - # Wear-leveling EEPROM implementation - OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING - SRC += eeprom_driver.c eeprom_wear_leveling.c - else ifeq ($(strip $(EEPROM_DRIVER)), i2c) - # External I2C EEPROM implementation - OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C - I2C_DRIVER_REQUIRED = yes - SRC += eeprom_driver.c eeprom_i2c.c - else ifeq ($(strip $(EEPROM_DRIVER)), spi) - # External SPI EEPROM implementation - OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_SPI - SPI_DRIVER_REQUIRED = yes - SRC += eeprom_driver.c eeprom_spi.c - else ifeq ($(strip $(EEPROM_DRIVER)), legacy_stm32_flash) - # STM32 Emulated EEPROM, backed by MCU flash (soon to be deprecated) - OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_LEGACY_EMULATED_FLASH - COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash - COMMON_VPATH += $(DRIVER_PATH)/flash - SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c - else ifeq ($(strip $(EEPROM_DRIVER)), transient) - # Transient EEPROM implementation -- no data storage but provides runtime area for it - OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT - SRC += eeprom_driver.c eeprom_transient.c - else ifeq ($(strip $(EEPROM_DRIVER)), vendor) - # Vendor-implemented EEPROM - OPT_DEFS += -DEEPROM_VENDOR - ifeq ($(PLATFORM),AVR) - # Automatically provided by avr-libc, nothing required - else ifeq ($(PLATFORM),CHIBIOS) - ifneq ($(filter %_STM32F072xB %_STM32F042x6, $(MCU_SERIES)_$(MCU_LDSCRIPT)),) - # STM32 Emulated EEPROM, backed by MCU flash (soon to be deprecated) - OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_LEGACY_EMULATED_FLASH - COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash - COMMON_VPATH += $(DRIVER_PATH)/flash - SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c - else ifneq ($(filter $(MCU_SERIES),STM32F1xx STM32F3xx STM32F4xx STM32L4xx STM32G4xx WB32F3G71xx WB32FQ95xx AT32F415 GD32VF103),) - # Wear-leveling EEPROM implementation, backed by MCU flash - OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING - SRC += eeprom_driver.c eeprom_wear_leveling.c - WEAR_LEVELING_DRIVER ?= embedded_flash - else ifneq ($(filter $(MCU_SERIES),STM32L0xx STM32L1xx),) - # True EEPROM on STM32L0xx, L1xx - OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_L0_L1 - SRC += eeprom_driver.c eeprom_stm32_L0_L1.c - else ifneq ($(filter $(MCU_SERIES),RP2040),) - # Wear-leveling EEPROM implementation, backed by RP2040 flash - OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING - SRC += eeprom_driver.c eeprom_wear_leveling.c - WEAR_LEVELING_DRIVER ?= rp2040_flash - else ifneq ($(filter $(MCU_SERIES),KL2x K20x),) - # Teensy EEPROM implementations - OPT_DEFS += -DEEPROM_KINETIS_FLEXRAM - SRC += eeprom_kinetis_flexram.c - else - # Fall back to transient, i.e. non-persistent - OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT - SRC += eeprom_driver.c eeprom_transient.c + else + OPT_DEFS += -DEEPROM_ENABLE + COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom + COMMON_VPATH += $(DRIVER_PATH)/eeprom + COMMON_VPATH += $(PLATFORM_COMMON_DIR) + ifeq ($(strip $(EEPROM_DRIVER)), custom) + # Custom EEPROM implementation -- only needs to implement init/erase/read_block/write_block + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_CUSTOM + SRC += eeprom_driver.c + else ifeq ($(strip $(EEPROM_DRIVER)), wear_leveling) + # Wear-leveling EEPROM implementation + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING + SRC += eeprom_driver.c eeprom_wear_leveling.c + else ifeq ($(strip $(EEPROM_DRIVER)), i2c) + # External I2C EEPROM implementation + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C + I2C_DRIVER_REQUIRED = yes + SRC += eeprom_driver.c eeprom_i2c.c + else ifeq ($(strip $(EEPROM_DRIVER)), spi) + # External SPI EEPROM implementation + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_SPI + SPI_DRIVER_REQUIRED = yes + SRC += eeprom_driver.c eeprom_spi.c + else ifeq ($(strip $(EEPROM_DRIVER)), legacy_stm32_flash) + # STM32 Emulated EEPROM, backed by MCU flash (soon to be deprecated) + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_LEGACY_EMULATED_FLASH + COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash + COMMON_VPATH += $(DRIVER_PATH)/flash + SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c + else ifeq ($(strip $(EEPROM_DRIVER)), transient) + # Transient EEPROM implementation -- no data storage but provides runtime area for it + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT + SRC += eeprom_driver.c eeprom_transient.c + else ifeq ($(strip $(EEPROM_DRIVER)), vendor) + # Vendor-implemented EEPROM + OPT_DEFS += -DEEPROM_VENDOR + ifeq ($(PLATFORM),AVR) + # Automatically provided by avr-libc, nothing required + else ifeq ($(PLATFORM),CHIBIOS) + ifneq ($(filter %_STM32F072xB %_STM32F042x6, $(MCU_SERIES)_$(MCU_LDSCRIPT)),) + # STM32 Emulated EEPROM, backed by MCU flash (soon to be deprecated) + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_LEGACY_EMULATED_FLASH + COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash + COMMON_VPATH += $(DRIVER_PATH)/flash + SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c + else ifneq ($(filter $(MCU_SERIES),STM32F1xx STM32F3xx STM32F4xx STM32L4xx STM32G4xx WB32F3G71xx WB32FQ95xx AT32F415 GD32VF103),) + # Wear-leveling EEPROM implementation, backed by MCU flash + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING + SRC += eeprom_driver.c eeprom_wear_leveling.c + WEAR_LEVELING_DRIVER ?= embedded_flash + else ifneq ($(filter $(MCU_SERIES),STM32L0xx STM32L1xx),) + # True EEPROM on STM32L0xx, L1xx + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_L0_L1 + SRC += eeprom_driver.c eeprom_stm32_L0_L1.c + else ifneq ($(filter $(MCU_SERIES),RP2040),) + # Wear-leveling EEPROM implementation, backed by RP2040 flash + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING + SRC += eeprom_driver.c eeprom_wear_leveling.c + WEAR_LEVELING_DRIVER ?= rp2040_flash + else ifneq ($(filter $(MCU_SERIES),KL2x K20x),) + # Teensy EEPROM implementations + OPT_DEFS += -DEEPROM_KINETIS_FLEXRAM + SRC += eeprom_kinetis_flexram.c + else + # Fall back to transient, i.e. non-persistent + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT + SRC += eeprom_driver.c eeprom_transient.c + endif + else ifeq ($(PLATFORM),TEST) + # Test harness "EEPROM" + OPT_DEFS += -DEEPROM_TEST_HARNESS + SRC += eeprom.c endif - else ifeq ($(PLATFORM),TEST) - # Test harness "EEPROM" - OPT_DEFS += -DEEPROM_TEST_HARNESS - SRC += eeprom.c endif endif endif diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema index 2314c72bdb..4e8bae1084 100644 --- a/data/schemas/keyboard.jsonschema +++ b/data/schemas/keyboard.jsonschema @@ -319,7 +319,7 @@ "properties": { "driver": { "type": "string", - "enum": ["custom", "embedded_flash", "legacy", "rp2040_flash", "spi_flash"] + "enum": ["none", "custom", "embedded_flash", "legacy", "rp2040_flash", "spi_flash"] }, "backing_size": {"$ref": "qmk.definitions.v1#/unsigned_int"}, "logical_size": {"$ref": "qmk.definitions.v1#/unsigned_int"} diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c index 756b232f59..59027fb694 100644 --- a/quantum/dynamic_keymap.c +++ b/quantum/dynamic_keymap.c @@ -18,8 +18,6 @@ #include "dynamic_keymap.h" #include "keymap_introspection.h" #include "action.h" -#include "eeprom.h" -#include "progmem.h" #include "send_string.h" #include "keycodes.h" #include "nvm_dynamic_keymap.h" diff --git a/quantum/eeconfig.c b/quantum/eeconfig.c index 9aa60fc968..31bc9a6051 100644 --- a/quantum/eeconfig.c +++ b/quantum/eeconfig.c @@ -2,16 +2,11 @@ #include #include #include "debug.h" -#include "eeprom.h" #include "eeconfig.h" #include "action_layer.h" #include "nvm_eeconfig.h" #include "keycode_config.h" -#ifdef EEPROM_DRIVER -# include "eeprom_driver.h" -#endif // EEPROM_DRIVER - #ifdef BACKLIGHT_ENABLE # include "backlight.h" #endif // BACKLIGHT_ENABLE diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c index 2e107a66e9..f9d76e2776 100644 --- a/quantum/led_matrix/led_matrix.c +++ b/quantum/led_matrix/led_matrix.c @@ -19,7 +19,6 @@ #include "led_matrix.h" #include "progmem.h" -#include "eeprom.h" #include "eeconfig.h" #include "keyboard.h" #include "sync_timer.h" diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c index a18105c9b3..3fc9085f06 100644 --- a/quantum/rgb_matrix/rgb_matrix.c +++ b/quantum/rgb_matrix/rgb_matrix.c @@ -18,7 +18,6 @@ #include "rgb_matrix.h" #include "progmem.h" -#include "eeprom.h" #include "eeconfig.h" #include "keyboard.h" #include "sync_timer.h" diff --git a/quantum/unicode/unicode.c b/quantum/unicode/unicode.c index b0729335f0..dff1d43fb4 100644 --- a/quantum/unicode/unicode.c +++ b/quantum/unicode/unicode.c @@ -16,7 +16,6 @@ #include "unicode.h" -#include "eeprom.h" #include "eeconfig.h" #include "action.h" #include "action_util.h" diff --git a/quantum/via.c b/quantum/via.c index c746d9a608..3682b4ab2b 100644 --- a/quantum/via.c +++ b/quantum/via.c @@ -26,7 +26,6 @@ #include "raw_hid.h" #include "dynamic_keymap.h" -#include "eeprom.h" #include "eeconfig.h" #include "matrix.h" #include "timer.h" -- cgit v1.2.3 From 12caf0be4eab171ffeb041cc153f9addb68f404e Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Sun, 4 May 2025 17:21:47 -0700 Subject: Add additional hooks for Community modules (#25050) --- data/constants/module_hooks/1.1.0.hjson | 55 ++++++++++++++++++++++++ docs/features/community_modules.md | 33 ++++++++------ lib/python/qmk/cli/generate/community_modules.py | 10 +++++ quantum/action_layer.c | 19 ++++++++ quantum/action_layer.h | 3 ++ quantum/led_matrix/led_matrix.c | 10 +++++ quantum/pointing_device/pointing_device.c | 9 +++- quantum/pointing_device/pointing_device.h | 1 + quantum/rgb_matrix/rgb_matrix.c | 10 +++++ 9 files changed, 137 insertions(+), 13 deletions(-) create mode 100644 data/constants/module_hooks/1.1.0.hjson (limited to 'quantum/led_matrix/led_matrix.c') diff --git a/data/constants/module_hooks/1.1.0.hjson b/data/constants/module_hooks/1.1.0.hjson new file mode 100644 index 0000000000..b50dad6a66 --- /dev/null +++ b/data/constants/module_hooks/1.1.0.hjson @@ -0,0 +1,55 @@ +{ + pointing_device_init: { + ret_type: void + args: void + guard: defined(POINTING_DEVICE_ENABLE) + } + pointing_device_task: { + ret_type: report_mouse_t + args: report_mouse_t mouse_report + call_params: mouse_report + guard: defined(POINTING_DEVICE_ENABLE) + header: report.h + } + rgb_matrix_indicators: { + ret_type: bool + args: void + guard: defined(RGB_MATRIX_ENABLE) + header: rgb_matrix.h + } + rgb_matrix_indicators_advanced: { + ret_type: bool + args: uint8_t led_min, uint8_t led_max + call_params: led_min, led_max + guard: defined(RGB_MATRIX_ENABLE) + header: rgb_matrix.h + } + led_matrix_indicators: { + ret_type: bool + args: void + guard: defined(LED_MATRIX_ENABLE) + header: led_matrix.h + } + led_matrix_indicators_advanced: { + ret_type: bool + args: uint8_t led_min, uint8_t led_max + call_params: led_min, led_max + guard: defined(LED_MATRIX_ENABLE) + header: led_matrix.h + } + default_layer_state_set: { + ret_type: layer_state_t + args: layer_state_t state + call_params: state + guard: !defined(NO_ACTION_LAYER) + header: action_layer.h + } + layer_state_set: { + ret_type: layer_state_t + args: layer_state_t state + call_params: state + guard: !defined(NO_ACTION_LAYER) + header: action_layer.h + } + +} diff --git a/docs/features/community_modules.md b/docs/features/community_modules.md index 52526c9fe8..69fc47f617 100644 --- a/docs/features/community_modules.md +++ b/docs/features/community_modules.md @@ -127,18 +127,27 @@ Introspection is a relatively advanced topic within QMK, and existing patterns s Community Modules may provide specializations for the following APIs: -| Base API | API Format | Example (`hello_world` module) | API Version | -|----------------------------|-------------------------------------|----------------------------------------|-------------| -| `keyboard_pre_init` | `keyboard_pre_init_` | `keyboard_pre_init_hello_world` | `0.1.0` | -| `keyboard_post_init` | `keyboard_post_init_` | `keyboard_post_init_hello_world` | `0.1.0` | -| `pre_process_record` | `pre_process_record_` | `pre_process_record_hello_world` | `0.1.0` | -| `process_record` | `process_record_` | `process_record_hello_world` | `0.1.0` | -| `post_process_record` | `post_process_record_` | `post_process_record_hello_world` | `0.1.0` | -| `housekeeping_task` | `housekeeping_task_` | `housekeeping_task_hello_world` | `1.0.0` | -| `suspend_power_down` | `suspend_power_down_` | `suspend_power_down_hello_world` | `1.0.0` | -| `suspend_wakeup_init` | `suspend_wakeup_init_` | `suspend_wakeup_init_hello_world` | `1.0.0` | -| `shutdown` | `shutdown_` | `shutdown_hello_world` | `1.0.0` | -| `process_detected_host_os` | `process_detected_host_os_` | `process_detected_host_os_hello_world` | `1.0.0` | +| Base API | API Format | Example (`hello_world` module) | API Version | +|----------------------------------|-------------------------------------------|---------------------------------------------|-------------| +| `keyboard_pre_init` | `keyboard_pre_init_` | `keyboard_pre_init_hello_world` | `0.1.0` | +| `keyboard_post_init` | `keyboard_post_init_` | `keyboard_post_init_hello_world` | `0.1.0` | +| `pre_process_record` | `pre_process_record_` | `pre_process_record_hello_world` | `0.1.0` | +| `process_record` | `process_record_` | `process_record_hello_world` | `0.1.0` | +| `post_process_record` | `post_process_record_` | `post_process_record_hello_world` | `0.1.0` | +| `housekeeping_task` | `housekeeping_task_` | `housekeeping_task_hello_world` | `1.0.0` | +| `suspend_power_down` | `suspend_power_down_` | `suspend_power_down_hello_world` | `1.0.0` | +| `suspend_wakeup_init` | `suspend_wakeup_init_` | `suspend_wakeup_init_hello_world` | `1.0.0` | +| `shutdown` | `shutdown_` | `shutdown_hello_world` | `1.0.0` | +| `process_detected_host_os` | `process_detected_host_os_` | `process_detected_host_os_hello_world` | `1.0.0` | +| `default_layer_state_set` | `default_layer_state_set_` | `default_layer_state_set_hello_world` | `1.1.0` | +| `layer_state_set` | `layer_state_set_` | `layer_state_set_hello_world` | `1.1.0` | +| `led_matrix_indicators` | `led_matrix_indicators_` | `led_matrix_indicators_hello_word` | `1.1.0` | +| `led_matrix_indicators_advanced` | `led_matrix_indicators_advanced_` | `led_matrix_indicators_advanced_hello_word` | `1.1.0` | +| `rgb_matrix_indicators` | `rgb_matrix_indicators_` | `rgb_matrix_indicators_hello_word` | `1.1.0` | +| `rgb_matrix_indicators_advanced` | `rgb_matrix_indicators_advanced_` | `rgb_matrix_indicators_advanced_hello_word` | `1.1.0` | +| `pointing_device_init` | `pointing_device_init_` | `pointing_device_init_hello_word` | `1.1.0` | +| `pointing_device_task` | `pointing_device_task_` | `pointing_device_task_hello_word` | `1.1.0` | + ::: info An unspecified API is disregarded if a Community Module does not provide a specialization for it. diff --git a/lib/python/qmk/cli/generate/community_modules.py b/lib/python/qmk/cli/generate/community_modules.py index e12daccf1c..61e24077d3 100644 --- a/lib/python/qmk/cli/generate/community_modules.py +++ b/lib/python/qmk/cli/generate/community_modules.py @@ -76,6 +76,8 @@ def _render_api_implementations(api, module): lines.append(f'__attribute__((weak)) {api.ret_type} {api.name}_{module_name}_user({api.args}) {{') if api.ret_type == 'bool': lines.append(' return true;') + elif api.ret_type in ['layer_state_t', 'report_mouse_t']: + lines.append(f' return {api.call_params};') else: pass lines.append('}') @@ -86,6 +88,8 @@ def _render_api_implementations(api, module): if api.ret_type == 'bool': lines.append(f' if(!{api.name}_{module_name}_user({api.call_params})) {{ return false; }}') lines.append(' return true;') + elif api.ret_type in ['layer_state_t', 'report_mouse_t']: + lines.append(f' return {api.name}_{module_name}_user({api.call_params});') else: lines.append(f' {api.name}_{module_name}_user({api.call_params});') lines.append('}') @@ -96,6 +100,8 @@ def _render_api_implementations(api, module): if api.ret_type == 'bool': lines.append(f' if(!{api.name}_{module_name}_kb({api.call_params})) {{ return false; }}') lines.append(' return true;') + elif api.ret_type in ['layer_state_t', 'report_mouse_t']: + lines.append(f' return {api.name}_{module_name}_kb({api.call_params});') else: lines.append(f' {api.name}_{module_name}_kb({api.call_params});') lines.append('}') @@ -113,10 +119,14 @@ def _render_core_implementation(api, modules): module_name = Path(module).name if api.ret_type == 'bool': lines.append(f' && {api.name}_{module_name}({api.call_params})') + elif api.ret_type in ['layer_state_t', 'report_mouse_t']: + lines.append(f' {api.call_params} = {api.name}_{module_name}({api.call_params});') else: lines.append(f' {api.name}_{module_name}({api.call_params});') if api.ret_type == 'bool': lines.append(' ;') + elif api.ret_type in ['layer_state_t', 'report_mouse_t']: + lines.append(f' return {api.call_params};') lines.append('}') return lines diff --git a/quantum/action_layer.c b/quantum/action_layer.c index 7c09a5bd1e..5828dcb824 100644 --- a/quantum/action_layer.c +++ b/quantum/action_layer.c @@ -27,11 +27,20 @@ __attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t sta return default_layer_state_set_user(state); } +/** \brief Default Layer State Set At Module Level + * + * Run module code on default layer state change + */ +__attribute__((weak)) layer_state_t default_layer_state_set_modules(layer_state_t state) { + return state; +} + /** \brief Default Layer State Set * * Static function to set the default layer state, prints debug info and clears keys */ static void default_layer_state_set(layer_state_t state) { + state = default_layer_state_set_modules(state); state = default_layer_state_set_kb(state); ac_dprintf("default_layer_state: "); default_layer_debug(); @@ -107,11 +116,21 @@ __attribute__((weak)) layer_state_t layer_state_set_kb(layer_state_t state) { return layer_state_set_user(state); } +/** \brief Layer state set modules + * + * Runs module code on layer state change + */ + +__attribute__((weak)) layer_state_t layer_state_set_modules(layer_state_t state) { + return state; +} + /** \brief Layer state set * * Sets the layer to match the specified state (a bitmask) */ void layer_state_set(layer_state_t state) { + state = layer_state_set_modules(state); state = layer_state_set_kb(state); ac_dprintf("layer_state: "); layer_debug(); diff --git a/quantum/action_layer.h b/quantum/action_layer.h index a2410d49a5..067e33cdb5 100644 --- a/quantum/action_layer.h +++ b/quantum/action_layer.h @@ -78,6 +78,7 @@ extern layer_state_t default_layer_state; void default_layer_debug(void); void default_layer_set(layer_state_t state); +__attribute__((weak)) layer_state_t default_layer_state_set_modules(layer_state_t state); __attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t state); __attribute__((weak)) layer_state_t default_layer_state_set_user(layer_state_t state); @@ -114,6 +115,7 @@ void layer_and(layer_state_t state); void layer_xor(layer_state_t state); layer_state_t layer_state_set_user(layer_state_t state); layer_state_t layer_state_set_kb(layer_state_t state); +layer_state_t layer_state_set_modules(layer_state_t state); /** * @brief Applies the tri layer to global layer state. Not be used in layer_state_set_(kb|user) functions. @@ -149,6 +151,7 @@ layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_ # define layer_or(state) (void)state # define layer_and(state) (void)state # define layer_xor(state) (void)state +# define layer_state_set_modules(state) (void)state # define layer_state_set_kb(state) (void)state # define layer_state_set_user(state) (void)state # define update_tri_layer(layer1, layer2, layer3) diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c index f9d76e2776..00bc199ecf 100644 --- a/quantum/led_matrix/led_matrix.c +++ b/quantum/led_matrix/led_matrix.c @@ -358,7 +358,12 @@ void led_matrix_task(void) { } } +__attribute__((weak)) bool led_matrix_indicators_modules(void) { + return true; +} + void led_matrix_indicators(void) { + led_matrix_indicators_modules(); led_matrix_indicators_kb(); } @@ -370,6 +375,10 @@ __attribute__((weak)) bool led_matrix_indicators_user(void) { return true; } +__attribute__((weak)) bool led_matrix_indicators_advanced_modules(uint8_t led_min, uint8_t led_max) { + return true; +} + void led_matrix_indicators_advanced(effect_params_t *params) { /* special handling is needed for "params->iter", since it's already been incremented. * Could move the invocations to led_task_render, but then it's missing a few checks @@ -377,6 +386,7 @@ void led_matrix_indicators_advanced(effect_params_t *params) { * led_task_render, right before the iter++ line. */ LED_MATRIX_USE_LIMITS_ITER(min, max, params->iter - 1); + led_matrix_indicators_advanced_modules(min, max); led_matrix_indicators_advanced_kb(min, max); } diff --git a/quantum/pointing_device/pointing_device.c b/quantum/pointing_device/pointing_device.c index 5ee65c9c61..564c2d294c 100644 --- a/quantum/pointing_device/pointing_device.c +++ b/quantum/pointing_device/pointing_device.c @@ -109,6 +109,11 @@ const pointing_device_driver_t custom_pointing_device_driver = { const pointing_device_driver_t *pointing_device_driver = &POINTING_DEVICE_DRIVER(POINTING_DEVICE_DRIVER_NAME); +__attribute__((weak)) void pointing_device_init_modules(void) {} +__attribute__((weak)) report_mouse_t pointing_device_task_modules(report_mouse_t mouse_report) { + return mouse_report; +} + /** * @brief Keyboard level code pointing device initialisation * @@ -190,6 +195,7 @@ __attribute__((weak)) void pointing_device_init(void) { } #endif + pointing_device_init_modules(); pointing_device_init_kb(); pointing_device_init_user(); } @@ -319,8 +325,9 @@ __attribute__((weak)) bool pointing_device_task(void) { local_mouse_report = is_keyboard_left() ? pointing_device_task_combined_kb(local_mouse_report, shared_mouse_report) : pointing_device_task_combined_kb(shared_mouse_report, local_mouse_report); #else local_mouse_report = pointing_device_adjust_by_defines(local_mouse_report); - local_mouse_report = pointing_device_task_kb(local_mouse_report); #endif + local_mouse_report = pointing_device_task_modules(local_mouse_report); + local_mouse_report = pointing_device_task_kb(local_mouse_report); // automatic mouse layer function #ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE pointing_device_task_auto_mouse(local_mouse_report); diff --git a/quantum/pointing_device/pointing_device.h b/quantum/pointing_device/pointing_device.h index d8b583c87e..e7a0819ed9 100644 --- a/quantum/pointing_device/pointing_device.h +++ b/quantum/pointing_device/pointing_device.h @@ -17,6 +17,7 @@ along with this program. If not, see . #pragma once +#include #include #include "host.h" #include "report.h" diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c index 3fc9085f06..94852e3520 100644 --- a/quantum/rgb_matrix/rgb_matrix.c +++ b/quantum/rgb_matrix/rgb_matrix.c @@ -393,7 +393,12 @@ void rgb_matrix_task(void) { } } +__attribute__((weak)) bool rgb_matrix_indicators_modules(void) { + return true; +} + void rgb_matrix_indicators(void) { + rgb_matrix_indicators_modules(); rgb_matrix_indicators_kb(); } @@ -433,6 +438,10 @@ struct rgb_matrix_limits_t rgb_matrix_get_limits(uint8_t iter) { return limits; } +__attribute__((weak)) bool rgb_matrix_indicators_advanced_modules(uint8_t led_min, uint8_t led_max) { + return true; +} + void rgb_matrix_indicators_advanced(effect_params_t *params) { /* special handling is needed for "params->iter", since it's already been incremented. * Could move the invocations to rgb_task_render, but then it's missing a few checks @@ -440,6 +449,7 @@ void rgb_matrix_indicators_advanced(effect_params_t *params) { * rgb_task_render, right before the iter++ line. */ RGB_MATRIX_USE_LIMITS_ITER(min, max, params->iter - 1); + rgb_matrix_indicators_advanced_modules(min, max); rgb_matrix_indicators_advanced_kb(min, max); } -- cgit v1.2.3 From f4171412a676ae3cbd1cd50e859a7deb1a554e15 Mon Sep 17 00:00:00 2001 From: Pascal Getreuer <50221757+getreuer@users.noreply.github.com> Date: Sun, 11 May 2025 16:30:19 -0700 Subject: Enable community modules to define LED matrix and RGB matrix effects. (#25187) Co-authored-by: Joel Challis --- builddefs/build_keyboard.mk | 13 +++- data/constants/module_hooks/1.1.1.hjson | 3 + docs/features/community_modules.md | 8 +++ keyboards/handwired/onekey/info.json | 12 ++++ .../keymaps/cm_flow_led_matrix_effect/config.h | 16 +++++ .../keymaps/cm_flow_led_matrix_effect/keymap.c | 27 ++++++++ .../keymaps/cm_flow_led_matrix_effect/keymap.json | 3 + .../keymaps/cm_flow_rgb_matrix_effect/config.h | 16 +++++ .../keymaps/cm_flow_rgb_matrix_effect/keymap.c | 27 ++++++++ .../keymaps/cm_flow_rgb_matrix_effect/keymap.json | 3 + lib/python/qmk/cli/generate/community_modules.py | 75 +++++++++++----------- .../flow_led_matrix_effect/led_matrix_module.inc | 58 +++++++++++++++++ modules/qmk/flow_led_matrix_effect/qmk_module.json | 8 +++ modules/qmk/flow_rgb_matrix_effect/qmk_module.json | 8 +++ .../flow_rgb_matrix_effect/rgb_matrix_module.inc | 64 ++++++++++++++++++ quantum/led_matrix/led_matrix.c | 12 ++++ quantum/led_matrix/led_matrix.h | 6 ++ quantum/rgb_matrix/rgb_matrix.c | 12 ++++ quantum/rgb_matrix/rgb_matrix.h | 6 ++ 19 files changed, 339 insertions(+), 38 deletions(-) create mode 100644 data/constants/module_hooks/1.1.1.hjson create mode 100644 keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/config.h create mode 100644 keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.c create mode 100644 keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.json create mode 100644 keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/config.h create mode 100644 keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.c create mode 100644 keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.json create mode 100644 modules/qmk/flow_led_matrix_effect/led_matrix_module.inc create mode 100644 modules/qmk/flow_led_matrix_effect/qmk_module.json create mode 100644 modules/qmk/flow_rgb_matrix_effect/qmk_module.json create mode 100644 modules/qmk/flow_rgb_matrix_effect/rgb_matrix_module.inc (limited to 'quantum/led_matrix/led_matrix.c') diff --git a/builddefs/build_keyboard.mk b/builddefs/build_keyboard.mk index 514191b17d..c2c47c00fb 100644 --- a/builddefs/build_keyboard.mk +++ b/builddefs/build_keyboard.mk @@ -274,10 +274,19 @@ $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h: $(KEYMAP_JSON) $(D $(eval CMD=$(QMK_BIN) generate-community-modules-introspection-h -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h $(KEYMAP_JSON)) @$(BUILD_CMD) -SRC += $(INTERMEDIATE_OUTPUT)/src/community_modules.c +$(INTERMEDIATE_OUTPUT)/src/led_matrix_community_modules.inc: $(KEYMAP_JSON) $(DD_CONFIG_FILES) + @$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD) + $(eval CMD=$(QMK_BIN) generate-led-matrix-community-modules-inc -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/led_matrix_community_modules.inc $(KEYMAP_JSON)) + @$(BUILD_CMD) -generated-files: $(INTERMEDIATE_OUTPUT)/src/community_modules.h $(INTERMEDIATE_OUTPUT)/src/community_modules.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h +$(INTERMEDIATE_OUTPUT)/src/rgb_matrix_community_modules.inc: $(KEYMAP_JSON) $(DD_CONFIG_FILES) + @$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD) + $(eval CMD=$(QMK_BIN) generate-rgb-matrix-community-modules-inc -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/rgb_matrix_community_modules.inc $(KEYMAP_JSON)) + @$(BUILD_CMD) + +SRC += $(INTERMEDIATE_OUTPUT)/src/community_modules.c +generated-files: $(INTERMEDIATE_OUTPUT)/src/community_modules.h $(INTERMEDIATE_OUTPUT)/src/community_modules.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h $(INTERMEDIATE_OUTPUT)/src/led_matrix_community_modules.inc $(INTERMEDIATE_OUTPUT)/src/rgb_matrix_community_modules.inc include $(BUILDDEFS_PATH)/converters.mk diff --git a/data/constants/module_hooks/1.1.1.hjson b/data/constants/module_hooks/1.1.1.hjson new file mode 100644 index 0000000000..49f5d0d5d0 --- /dev/null +++ b/data/constants/module_hooks/1.1.1.hjson @@ -0,0 +1,3 @@ +{ + // This version exists to signify addition of LED/RGB effect support. +} diff --git a/docs/features/community_modules.md b/docs/features/community_modules.md index 8dede47bd4..eff07c939a 100644 --- a/docs/features/community_modules.md +++ b/docs/features/community_modules.md @@ -123,6 +123,14 @@ The source file may provide functions which allow access to information specifie Introspection is a relatively advanced topic within QMK, and existing patterns should be followed. If you need help please [open an issue](https://github.com/qmk/qmk_firmware/issues/new) or [chat with us on Discord](https://discord.gg/qmk). ::: +### `led_matrix_module.inc` + +This file defines LED matrix effects in the same form as used with `led_matrix_kb.inc` and `led_matrix_user.inc` (see [Custom LED Matrix Effects](led_matrix#custom-led-matrix-effects)). Effect mode names are prepended with `LED_MATRIX_COMMUNITY_MODULE_`. + +### `rgb_matrix_module.inc` + +This file defines RGB matrix effects in the same form as used with `rgb_matrix_kb.inc` and `rgb_matrix_user.inc` (see [Custom RGB Matrix Effects](rgb_matrix#custom-rgb-matrix-effects)). Effect mode names are prepended with `RGB_MATRIX_COMMUNITY_MODULE_`. + ### Compatible APIs Community Modules may provide specializations for the following APIs: diff --git a/keyboards/handwired/onekey/info.json b/keyboards/handwired/onekey/info.json index 7b6b7ddab8..d5f650f1bd 100644 --- a/keyboards/handwired/onekey/info.json +++ b/keyboards/handwired/onekey/info.json @@ -26,5 +26,17 @@ {"x": 0, "y": 0, "matrix": [0, 0]} ] } + }, + "led_matrix": { + "driver": "snled27351", + "layout": [ + {"matrix": [0, 0], "x": 0, "y": 0, "flags": 1} + ] + }, + "rgb_matrix": { + "driver": "snled27351", + "layout": [ + {"matrix": [0, 0], "x": 0, "y": 0, "flags": 1} + ] } } diff --git a/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/config.h b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/config.h new file mode 100644 index 0000000000..aed1e4ac6f --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/config.h @@ -0,0 +1,16 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#define SNLED27351_I2C_ADDRESS_1 SNLED27351_I2C_ADDRESS_GND diff --git a/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.c b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.c new file mode 100644 index 0000000000..0bd835ff25 --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.c @@ -0,0 +1,27 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// This keymap serves as a test for modules/qmk/flow_led_matrix_effect. + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {LAYOUT_ortho_1x1(LM_TOGG)}; + +const snled27351_led_t PROGMEM g_snled27351_leds[LED_MATRIX_LED_COUNT] = { + {0, CB6_CA1}, +}; + +void keyboard_post_init_user(void) { + led_matrix_mode_noeeprom(LED_MATRIX_COMMUNITY_MODULE_FLOW); +} diff --git a/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.json b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.json new file mode 100644 index 0000000000..0ff6bf5a4d --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.json @@ -0,0 +1,3 @@ +{ + "modules": ["qmk/flow_led_matrix_effect"] +} diff --git a/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/config.h b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/config.h new file mode 100644 index 0000000000..aed1e4ac6f --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/config.h @@ -0,0 +1,16 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#define SNLED27351_I2C_ADDRESS_1 SNLED27351_I2C_ADDRESS_GND diff --git a/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.c b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.c new file mode 100644 index 0000000000..72ef2d3f80 --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.c @@ -0,0 +1,27 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// This keymap serves as a test for modules/qmk/flow_rgb_matrix_effect. + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {LAYOUT_ortho_1x1(RM_TOGG)}; + +const snled27351_led_t PROGMEM g_snled27351_leds[LED_MATRIX_LED_COUNT] = { + {0, CB6_CA1}, +}; + +void keyboard_post_init_user(void) { + rgb_matrix_mode_noeeprom(RGB_MATRIX_COMMUNITY_MODULE_FLOW); +} diff --git a/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.json b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.json new file mode 100644 index 0000000000..56d2342867 --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.json @@ -0,0 +1,3 @@ +{ + "modules": ["qmk/flow_rgb_matrix_effect"] +} diff --git a/lib/python/qmk/cli/generate/community_modules.py b/lib/python/qmk/cli/generate/community_modules.py index 61e24077d3..1f37b760ca 100644 --- a/lib/python/qmk/cli/generate/community_modules.py +++ b/lib/python/qmk/cli/generate/community_modules.py @@ -278,33 +278,32 @@ def generate_community_modules_c(cli): dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) +def _generate_include_per_module(cli, include_file_name): + """Generates C code to include "/include_file_name" for each module.""" + if cli.args.output and cli.args.output.name == '-': + cli.args.output = None + + lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE] + + for module in get_modules(cli.args.keyboard, cli.args.filename): + full_path = f'{find_module_path(module)}/{include_file_name}' + lines.append('') + lines.append(f'#if __has_include("{full_path}")') + lines.append(f'#include "{full_path}"') + lines.append(f'#endif // __has_include("{full_path}")') + + dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) + + @cli.argument('-o', '--output', arg_only=True, type=qmk.path.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('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate community_modules.c for.') +@cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate community_modules_introspection.h for.') @cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file') @cli.subcommand('Creates a community_modules_introspection.h from a keymap.json file.') def generate_community_modules_introspection_h(cli): """Creates a community_modules_introspection.h from a keymap.json file """ - if cli.args.output and cli.args.output.name == '-': - cli.args.output = None - - lines = [ - GPL2_HEADER_C_LIKE, - GENERATED_HEADER_C_LIKE, - '', - ] - - modules = get_modules(cli.args.keyboard, cli.args.filename) - if len(modules) > 0: - for module in modules: - module_path = find_module_path(module) - lines.append(f'#if __has_include("{module_path}/introspection.h")') - lines.append(f'#include "{module_path}/introspection.h"') - lines.append(f'#endif // __has_include("{module_path}/introspection.h")') - lines.append('') - - dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) + _generate_include_per_module(cli, 'introspection.h') @cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to') @@ -315,22 +314,26 @@ def generate_community_modules_introspection_h(cli): def generate_community_modules_introspection_c(cli): """Creates a community_modules_introspection.c from a keymap.json file """ - if cli.args.output and cli.args.output.name == '-': - cli.args.output = None + _generate_include_per_module(cli, 'introspection.c') - lines = [ - GPL2_HEADER_C_LIKE, - GENERATED_HEADER_C_LIKE, - '', - ] - modules = get_modules(cli.args.keyboard, cli.args.filename) - if len(modules) > 0: - for module in modules: - module_path = find_module_path(module) - lines.append(f'#if __has_include("{module_path}/introspection.c")') - lines.append(f'#include "{module_path}/introspection.c"') - lines.append(f'#endif // __has_include("{module_path}/introspection.c")') - lines.append('') +@cli.argument('-o', '--output', arg_only=True, type=qmk.path.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('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate led_matrix_community_modules.inc for.') +@cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file') +@cli.subcommand('Creates an led_matrix_community_modules.inc from a keymap.json file.') +def generate_led_matrix_community_modules_inc(cli): + """Creates an led_matrix_community_modules.inc from a keymap.json file + """ + _generate_include_per_module(cli, 'led_matrix_module.inc') - dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) + +@cli.argument('-o', '--output', arg_only=True, type=qmk.path.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('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate rgb_matrix_community_modules.inc for.') +@cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file') +@cli.subcommand('Creates an rgb_matrix_community_modules.inc from a keymap.json file.') +def generate_rgb_matrix_community_modules_inc(cli): + """Creates an rgb_matrix_community_modules.inc from a keymap.json file + """ + _generate_include_per_module(cli, 'rgb_matrix_module.inc') diff --git a/modules/qmk/flow_led_matrix_effect/led_matrix_module.inc b/modules/qmk/flow_led_matrix_effect/led_matrix_module.inc new file mode 100644 index 0000000000..734e0f3494 --- /dev/null +++ b/modules/qmk/flow_led_matrix_effect/led_matrix_module.inc @@ -0,0 +1,58 @@ +// Copyright 2024-2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +LED_MATRIX_EFFECT(FLOW) + +#ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS + +// "Flow" animated effect. Draws moving wave patterns mimicking the appearance +// of flowing liquid. For interesting variety of patterns, space coordinates are +// slowly rotated and a function of several sine waves is evaluated. +static bool FLOW(effect_params_t* params) { + LED_MATRIX_USE_LIMITS(led_min, led_max); + + static uint16_t wrap_correction = 0; + static uint8_t last_high_byte = 0; + const uint8_t time_scale = 1 + led_matrix_eeconfig.speed / 8; + const uint8_t high_byte = (uint8_t)(g_led_timer >> 16); + if (last_high_byte != high_byte) { + last_high_byte = high_byte; + wrap_correction += ((uint16_t)time_scale) << 8; + } + const uint16_t time = scale16by8(g_led_timer, time_scale) + wrap_correction; + + // Compute rotation coefficients with 7 fractional bits. + const int8_t rot_c = cos8(time / 4) - 128; + const int8_t rot_s = sin8(time / 4) - 128; + const uint8_t omega = 32 + sin8(time) / 4; + + for (uint8_t i = led_min; i < led_max; ++i) { + LED_MATRIX_TEST_LED_FLAGS(); + const uint8_t x = g_led_config.point[i].x; + const uint8_t y = g_led_config.point[i].y; + + // Rotate (x, y) by the 2x2 rotation matrix described by rot_c, rot_s. + const uint8_t x1 = (uint8_t)((((int16_t)rot_c) * ((int16_t)x)) / 128) - (uint8_t)((((int16_t)rot_s) * ((int16_t)y)) / 128); + const uint8_t y1 = (uint8_t)((((int16_t)rot_s) * ((int16_t)x)) / 128) + (uint8_t)((((int16_t)rot_c) * ((int16_t)y)) / 128); + + uint8_t value = scale8(sin8(x1 - 2 * time), omega) + y1 + time / 4; + value = (value <= 127) ? value : (255 - value); + + led_matrix_set_value(i, scale8(led_matrix_eeconfig.val, value)); + } + + return led_matrix_check_finished_leds(led_max); +} + +#endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/modules/qmk/flow_led_matrix_effect/qmk_module.json b/modules/qmk/flow_led_matrix_effect/qmk_module.json new file mode 100644 index 0000000000..2d047cd0d0 --- /dev/null +++ b/modules/qmk/flow_led_matrix_effect/qmk_module.json @@ -0,0 +1,8 @@ +{ + "module_name": "Flow LED matrix effect", + "maintainer": "QMK Maintainers", + "license": "Apache-2.0", + "features": { + "led_matrix": true + } +} diff --git a/modules/qmk/flow_rgb_matrix_effect/qmk_module.json b/modules/qmk/flow_rgb_matrix_effect/qmk_module.json new file mode 100644 index 0000000000..3e42fe1ef4 --- /dev/null +++ b/modules/qmk/flow_rgb_matrix_effect/qmk_module.json @@ -0,0 +1,8 @@ +{ + "module_name": "Flow RGB matrix effect", + "maintainer": "QMK Maintainers", + "license": "Apache-2.0", + "features": { + "rgb_matrix": true + } +} diff --git a/modules/qmk/flow_rgb_matrix_effect/rgb_matrix_module.inc b/modules/qmk/flow_rgb_matrix_effect/rgb_matrix_module.inc new file mode 100644 index 0000000000..410838f7ec --- /dev/null +++ b/modules/qmk/flow_rgb_matrix_effect/rgb_matrix_module.inc @@ -0,0 +1,64 @@ +// Copyright 2024-2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +RGB_MATRIX_EFFECT(FLOW) + +#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS + +// "Flow" animated effect. Draws moving wave patterns mimicking the appearance +// of flowing liquid. For interesting variety of patterns, space coordinates are +// slowly rotated and a function of several sine waves is evaluated. +static bool FLOW(effect_params_t* params) { + RGB_MATRIX_USE_LIMITS(led_min, led_max); + + static uint16_t wrap_correction = 0; + static uint8_t last_high_byte = 0; + const uint8_t time_scale = 1 + rgb_matrix_config.speed / 8; + const uint8_t high_byte = (uint8_t)(g_rgb_timer >> 16); + if (last_high_byte != high_byte) { + last_high_byte = high_byte; + wrap_correction += ((uint16_t)time_scale) << 8; + } + const uint16_t time = scale16by8(g_rgb_timer, time_scale) + wrap_correction; + + // Compute rotation coefficients with 7 fractional bits. + const int8_t rot_c = cos8(time / 4) - 128; + const int8_t rot_s = sin8(time / 4) - 128; + const uint8_t omega = 32 + sin8(time) / 4; + + for (uint8_t i = led_min; i < led_max; ++i) { + RGB_MATRIX_TEST_LED_FLAGS(); + const uint8_t x = g_led_config.point[i].x; + const uint8_t y = g_led_config.point[i].y; + + // Rotate (x, y) by the 2x2 rotation matrix described by rot_c, rot_s. + const uint8_t x1 = (uint8_t)((((int16_t)rot_c) * ((int16_t)x)) / 128) - (uint8_t)((((int16_t)rot_s) * ((int16_t)y)) / 128); + const uint8_t y1 = (uint8_t)((((int16_t)rot_s) * ((int16_t)x)) / 128) + (uint8_t)((((int16_t)rot_c) * ((int16_t)y)) / 128); + + uint8_t value = scale8(sin8(x1 - 2 * time), omega) + y1 + time / 4; + value = (value <= 127) ? value : (255 - value); + + hsv_t hsv = rgb_matrix_config.hsv; + hsv.h -= value / 4; + hsv.s = scale8(hsv.s, (value < 74) ? 255 : (549 - 4 * value)); + hsv.v = scale8(hsv.v, (value < 95) ? (64 + 2 * value) : 255); + + rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv); + rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); + } + + return rgb_matrix_check_finished_leds(led_max); +} + +#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c index 00bc199ecf..7a0e8a5ebb 100644 --- a/quantum/led_matrix/led_matrix.c +++ b/quantum/led_matrix/led_matrix.c @@ -45,6 +45,9 @@ const led_point_t k_led_matrix_center = LED_MATRIX_CENTER; #define LED_MATRIX_CUSTOM_EFFECT_IMPLS #include "led_matrix_effects.inc" +#ifdef COMMUNITY_MODULES_ENABLE +# include "led_matrix_community_modules.inc" +#endif #ifdef LED_MATRIX_CUSTOM_KB # include "led_matrix_kb.inc" #endif @@ -282,6 +285,15 @@ static void led_task_render(uint8_t effect) { #include "led_matrix_effects.inc" #undef LED_MATRIX_EFFECT +#ifdef COMMUNITY_MODULES_ENABLE +# define LED_MATRIX_EFFECT(name, ...) \ + case LED_MATRIX_COMMUNITY_MODULE_##name: \ + rendering = name(&led_effect_params); \ + break; +# include "led_matrix_community_modules.inc" +# undef LED_MATRIX_EFFECT +#endif + #if defined(LED_MATRIX_CUSTOM_KB) || defined(LED_MATRIX_CUSTOM_USER) # define LED_MATRIX_EFFECT(name, ...) \ case LED_MATRIX_CUSTOM_##name: \ diff --git a/quantum/led_matrix/led_matrix.h b/quantum/led_matrix/led_matrix.h index 0006d487e9..0dfe33ffab 100644 --- a/quantum/led_matrix/led_matrix.h +++ b/quantum/led_matrix/led_matrix.h @@ -98,6 +98,12 @@ enum led_matrix_effects { #include "led_matrix_effects.inc" #undef LED_MATRIX_EFFECT +#ifdef COMMUNITY_MODULES_ENABLE +# define LED_MATRIX_EFFECT(name, ...) LED_MATRIX_COMMUNITY_MODULE_##name, +# include "led_matrix_community_modules.inc" +# undef LED_MATRIX_EFFECT +#endif + #if defined(LED_MATRIX_CUSTOM_KB) || defined(LED_MATRIX_CUSTOM_USER) # define LED_MATRIX_EFFECT(name, ...) LED_MATRIX_CUSTOM_##name, # ifdef LED_MATRIX_CUSTOM_KB diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c index 94852e3520..2679c48342 100644 --- a/quantum/rgb_matrix/rgb_matrix.c +++ b/quantum/rgb_matrix/rgb_matrix.c @@ -47,6 +47,9 @@ __attribute__((weak)) rgb_t rgb_matrix_hsv_to_rgb(hsv_t hsv) { #define RGB_MATRIX_CUSTOM_EFFECT_IMPLS #include "rgb_matrix_effects.inc" +#ifdef COMMUNITY_MODULES_ENABLE +# include "rgb_matrix_community_modules.inc" +#endif #ifdef RGB_MATRIX_CUSTOM_KB # include "rgb_matrix_kb.inc" #endif @@ -310,6 +313,15 @@ static void rgb_task_render(uint8_t effect) { #include "rgb_matrix_effects.inc" #undef RGB_MATRIX_EFFECT +#ifdef COMMUNITY_MODULES_ENABLE +# define RGB_MATRIX_EFFECT(name, ...) \ + case RGB_MATRIX_COMMUNITY_MODULE_##name: \ + rendering = name(&rgb_effect_params); \ + break; +# include "rgb_matrix_community_modules.inc" +# undef RGB_MATRIX_EFFECT +#endif + #if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER) # define RGB_MATRIX_EFFECT(name, ...) \ case RGB_MATRIX_CUSTOM_##name: \ diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h index e00e3927c7..c6b302631e 100644 --- a/quantum/rgb_matrix/rgb_matrix.h +++ b/quantum/rgb_matrix/rgb_matrix.h @@ -123,6 +123,12 @@ enum rgb_matrix_effects { #include "rgb_matrix_effects.inc" #undef RGB_MATRIX_EFFECT +#ifdef COMMUNITY_MODULES_ENABLE +# define RGB_MATRIX_EFFECT(name, ...) RGB_MATRIX_COMMUNITY_MODULE_##name, +# include "rgb_matrix_community_modules.inc" +# undef RGB_MATRIX_EFFECT +#endif + #if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER) # define RGB_MATRIX_EFFECT(name, ...) RGB_MATRIX_CUSTOM_##name, # ifdef RGB_MATRIX_CUSTOM_KB -- cgit v1.2.3