From 78b3b8915e6a14e193e4ad1bcbeaa52d5a6ab49f Mon Sep 17 00:00:00 2001 From: Maximilian Engl Date: Sun, 26 Nov 2023 14:29:15 +0000 Subject: [PATCH] Feature: pointer movement/scrolling #2027 --- .devcontainer/Dockerfile | 2 +- .github/workflows/build.yml | 2 +- .../hardware-metadata-validation.yml | 2 +- .github/workflows/test.yml | 2 +- .vscode/c_cpp_properties.json | 84 +++--- app/CMakeLists.txt | 10 +- app/Kconfig | 14 +- app/Kconfig.behaviors | 8 +- app/boards/arm/dz60rgb/dz60rgb_rev1_defconfig | 3 - app/boards/arm/ferris/ferris_rev02_defconfig | 2 +- app/boards/arm/mikoto/CMakeLists.txt | 5 +- app/boards/arm/mikoto/Kconfig.defconfig | 3 - app/boards/arm/mikoto/pinmux.c | 3 +- app/boards/arm/nrfmicro/CMakeLists.txt | 5 +- app/boards/arm/nrfmicro/Kconfig.defconfig | 3 - app/boards/arm/planck/planck_rev6_defconfig | 3 - app/boards/arm/puchi_ble/CMakeLists.txt | 5 +- app/boards/arm/puchi_ble/Kconfig.defconfig | 3 - app/boards/shields/corne/Kconfig.defconfig | 5 +- app/boards/shields/corne/corne.dtsi | 1 + .../shields/elephant42/Kconfig.defconfig | 5 +- app/boards/shields/elephant42/elephant42.dtsi | 1 + app/boards/shields/jorne/Kconfig.defconfig | 5 +- app/boards/shields/jorne/jorne.dtsi | 1 + .../shields/knob_goblin/Kconfig.defconfig | 5 +- .../shields/knob_goblin/knob_goblin.overlay | 1 + app/boards/shields/kyria/Kconfig.defconfig | 5 +- app/boards/shields/kyria/kyria_common.dtsi | 1 + app/boards/shields/leeloo/Kconfig.defconfig | 5 +- app/boards/shields/leeloo/leeloo_common.dtsi | 1 + .../shields/leeloo_micro/Kconfig.defconfig | 5 +- .../shields/leeloo_micro/leeloo_micro.dtsi | 1 + app/boards/shields/lily58/Kconfig.defconfig | 5 +- app/boards/shields/lily58/lily58.dtsi | 1 + app/boards/shields/lotus58/Kconfig.defconfig | 5 +- app/boards/shields/lotus58/lotus58.dtsi | 1 + app/boards/shields/microdox/Kconfig.defconfig | 5 +- .../shields/microdox/microdox_common.dtsi | 1 + app/boards/shields/murphpad/Kconfig.defconfig | 5 +- app/boards/shields/murphpad/murphpad.overlay | 1 + app/boards/shields/nibble/Kconfig.defconfig | 5 +- app/boards/shields/nibble/nibble.overlay | 1 + .../shields/nice_view/Kconfig.defconfig | 5 +- app/boards/shields/nice_view/widgets/status.c | 4 +- app/boards/shields/snap/Kconfig.defconfig | 5 +- app/boards/shields/snap/snap.dtsi | 1 + app/boards/shields/sofle/Kconfig.defconfig | 5 +- app/boards/shields/sofle/sofle.dtsi | 1 + .../splitkb_aurora_corne/Kconfig.defconfig | 5 +- .../splitkb_aurora_corne.dtsi | 1 + .../splitkb_aurora_helix/Kconfig.defconfig | 3 - .../splitkb_aurora_helix.dtsi | 1 + .../splitkb_aurora_lily58/Kconfig.defconfig | 5 +- .../splitkb_aurora_lily58.dtsi | 1 + .../splitkb_aurora_sofle/Kconfig.defconfig | 3 - .../splitkb_aurora_sofle.dtsi | 1 + .../splitkb_aurora_sweep/Kconfig.defconfig | 5 +- .../splitkb_aurora_sweep.dtsi | 1 + app/boards/shields/tidbit/Kconfig.defconfig | 5 +- app/boards/shields/tidbit/tidbit.dtsi | 1 + .../shields/waterfowl/Kconfig.defconfig | 5 +- app/boards/shields/waterfowl/waterfowl.dtsi | 1 + app/boards/shields/zodiark/Kconfig.defconfig | 5 +- app/boards/shields/zodiark/zodiark.dtsi | 1 + app/dts/behaviors.dtsi | 3 + app/dts/behaviors/mouse_move.dtsi | 15 + app/dts/behaviors/mouse_scroll.dtsi | 15 + .../zmk,behavior-input-two-axis.yaml | 21 ++ .../behaviors/zmk,behavior-mouse-move.yaml | 21 ++ app/dts/bindings/zmk,input-configs.yaml | 24 ++ app/include/dt-bindings/zmk/mouse.h | 28 +- app/include/zmk/endpoints.h | 2 +- app/include/zmk/hid.h | 18 +- app/include/zmk/mouse.h | 4 +- app/include/zmk/mouse/input_config.h | 21 ++ app/module/drivers/kscan/Kconfig | 8 + app/module/drivers/kscan/kscan_composite.c | 2 +- app/module/drivers/kscan/kscan_gpio_demux.c | 4 +- app/module/drivers/kscan/kscan_gpio_direct.c | 8 +- app/module/drivers/kscan/kscan_gpio_matrix.c | 2 +- app/module/drivers/kscan/kscan_mock.c | 4 +- .../drivers/sensor/max17048/CMakeLists.txt | 4 +- app/module/drivers/sensor/max17048/Kconfig | 4 +- app/prj.conf | 1 + app/src/activity.c | 6 +- app/src/backlight.c | 2 +- app/src/battery.c | 2 +- app/src/behaviors/behavior_backlight.c | 2 +- app/src/behaviors/behavior_bt.c | 2 +- app/src/behaviors/behavior_caps_word.c | 2 +- app/src/behaviors/behavior_ext_power.c | 2 +- app/src/behaviors/behavior_hold_tap.c | 5 +- app/src/behaviors/behavior_input_two_axis.c | 272 ++++++++++++++++++ app/src/behaviors/behavior_key_press.c | 2 +- app/src/behaviors/behavior_key_repeat.c | 2 +- app/src/behaviors/behavior_key_toggle.c | 2 +- app/src/behaviors/behavior_macro.c | 2 +- app/src/behaviors/behavior_mod_morph.c | 2 +- app/src/behaviors/behavior_momentary_layer.c | 2 +- app/src/behaviors/behavior_mouse_key_press.c | 27 +- app/src/behaviors/behavior_mouse_move.c | 269 +++++++++++++++++ app/src/behaviors/behavior_none.c | 2 +- app/src/behaviors/behavior_outputs.c | 2 +- app/src/behaviors/behavior_reset.c | 2 +- app/src/behaviors/behavior_rgb_underglow.c | 2 +- app/src/behaviors/behavior_sensor_rotate.c | 2 +- .../behaviors/behavior_sensor_rotate_var.c | 2 +- app/src/behaviors/behavior_sticky_key.c | 5 +- app/src/behaviors/behavior_tap_dance.c | 6 +- app/src/behaviors/behavior_to_layer.c | 2 +- app/src/behaviors/behavior_toggle_layer.c | 2 +- app/src/behaviors/behavior_transparent.c | 2 +- app/src/ble.c | 6 +- app/src/combo.c | 2 +- app/src/display/Kconfig | 8 +- app/src/endpoints.c | 2 +- app/src/hid.c | 37 ++- app/src/hog.c | 31 +- app/src/main.c | 13 +- app/src/mouse.c | 43 --- app/src/mouse/Kconfig | 40 +++ app/src/mouse/hid_input_listener.c | 110 +++++++ app/src/mouse/input_config.c | 42 +++ app/src/mouse/main.c | 30 ++ app/src/rgb_underglow.c | 2 +- app/src/sensors.c | 2 +- app/src/split/bluetooth/central.c | 2 +- app/src/split/bluetooth/peripheral.c | 4 +- app/src/split/bluetooth/service.c | 2 +- app/src/usb.c | 2 +- app/src/usb_hid.c | 2 +- app/src/wpm.c | 2 +- .../move_diagonal_scaling/events.patterns | 1 + .../keycode_events.snapshot | 22 ++ .../native_posix_64.keymap | 38 +++ .../move_diagonal_xy_invert/events.patterns | 1 + .../keycode_events.snapshot | 22 ++ .../native_posix_64.keymap | 38 +++ .../move_diagonal_xy_swap/events.patterns | 1 + .../keycode_events.snapshot | 22 ++ .../native_posix_64.keymap | 37 +++ .../mouse-move/move_diagonal/events.patterns | 1 + .../move_diagonal/keycode_events.snapshot | 22 ++ .../move_diagonal/native_posix_64.keymap | 28 ++ .../mouse-move/move_x/events.patterns | 1 + .../mouse-move/move_x/keycode_events.snapshot | 24 ++ .../mouse-move/move_x/native_posix_64.keymap | 28 ++ .../mouse-move/move_y/events.patterns | 1 + .../mouse-move/move_y/keycode_events.snapshot | 24 ++ .../mouse-move/move_y/native_posix_64.keymap | 28 ++ app/west.yml | 7 +- docs/docs/intro.md | 2 +- 152 files changed, 1543 insertions(+), 324 deletions(-) create mode 100644 app/dts/behaviors/mouse_move.dtsi create mode 100644 app/dts/behaviors/mouse_scroll.dtsi create mode 100644 app/dts/bindings/behaviors/zmk,behavior-input-two-axis.yaml create mode 100644 app/dts/bindings/behaviors/zmk,behavior-mouse-move.yaml create mode 100644 app/dts/bindings/zmk,input-configs.yaml create mode 100644 app/include/zmk/mouse/input_config.h create mode 100644 app/src/behaviors/behavior_input_two_axis.c create mode 100644 app/src/behaviors/behavior_mouse_move.c delete mode 100644 app/src/mouse.c create mode 100644 app/src/mouse/Kconfig create mode 100644 app/src/mouse/hid_input_listener.c create mode 100644 app/src/mouse/input_config.c create mode 100644 app/src/mouse/main.c create mode 100644 app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/events.patterns create mode 100644 app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/keycode_events.snapshot create mode 100644 app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/native_posix_64.keymap create mode 100644 app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/events.patterns create mode 100644 app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/keycode_events.snapshot create mode 100644 app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/native_posix_64.keymap create mode 100644 app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/events.patterns create mode 100644 app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/keycode_events.snapshot create mode 100644 app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/native_posix_64.keymap create mode 100644 app/tests/mouse-keys/mouse-move/move_diagonal/events.patterns create mode 100644 app/tests/mouse-keys/mouse-move/move_diagonal/keycode_events.snapshot create mode 100644 app/tests/mouse-keys/mouse-move/move_diagonal/native_posix_64.keymap create mode 100644 app/tests/mouse-keys/mouse-move/move_x/events.patterns create mode 100644 app/tests/mouse-keys/mouse-move/move_x/keycode_events.snapshot create mode 100644 app/tests/mouse-keys/mouse-move/move_x/native_posix_64.keymap create mode 100644 app/tests/mouse-keys/mouse-move/move_y/events.patterns create mode 100644 app/tests/mouse-keys/mouse-move/move_y/keycode_events.snapshot create mode 100644 app/tests/mouse-keys/mouse-move/move_y/native_posix_64.keymap diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 5b69e18043d5..4ac253f12546 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/zmkfirmware/zmk-dev-arm:3.2 +FROM docker.io/zmkfirmware/zmk-dev-arm:3.5-branch COPY .bashrc tmp RUN mv /tmp/.bashrc ~/.bashrc diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 82b156e106c4..a0475627aece 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ jobs: if: ${{ always() }} runs-on: ubuntu-latest container: - image: docker.io/zmkfirmware/zmk-build-arm:3.2 + image: docker.io/zmkfirmware/zmk-build-arm:3.5-branch needs: compile-matrix strategy: matrix: diff --git a/.github/workflows/hardware-metadata-validation.yml b/.github/workflows/hardware-metadata-validation.yml index 100928368e31..98ffb9620386 100644 --- a/.github/workflows/hardware-metadata-validation.yml +++ b/.github/workflows/hardware-metadata-validation.yml @@ -18,7 +18,7 @@ jobs: validate-metadata: runs-on: ubuntu-latest container: - image: docker.io/zmkfirmware/zmk-dev-arm:3.2 + image: docker.io/zmkfirmware/zmk-dev-arm:3.5-branch steps: - uses: actions/checkout@v3 - name: Install dependencies diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e8a9d2209e46..6c9054f5ffcd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,7 @@ jobs: test: ${{ fromJSON(needs.collect-tests.outputs.test-dirs) }} runs-on: ubuntu-latest container: - image: docker.io/zmkfirmware/zmk-build-arm:3.2 + image: docker.io/zmkfirmware/zmk-build-arm:3.5-branch steps: - name: Checkout uses: actions/checkout@v3 diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 9ee605cebd07..55358efca206 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -1,48 +1,38 @@ { - "configurations": [ - { - "name": "LEFT", - "includePath": [ - "/workspaces/zmk/**" - ], - "defines": [], - "compilerPath": "/opt/zephyr-sdk-0.15.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc", - "cStandard": "c17", - "cppStandard": "c++98", - "intelliSenseMode": "linux-gcc-arm", - "compileCommands": "/workspaces/zmk/app/build/left/compile_commands.json", - "compilerPathInCppPropertiesJson": "/opt/zephyr-sdk-0.15.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc", - "compileCommandsInCppPropertiesJson": "${workspaceFolder}/app/build/left/compile_commands.json", - "mergeConfigurations": false, - "browse": { - "path": [ - "/workspaces/zmk/**", - "${workspaceFolder}" - ], - "limitSymbolsToIncludedHeaders": true - } - }, - { - "name": "RIGHT", - "includePath": [ - "/workspaces/zmk/**" - ], - "defines": [], - "compilerPath": "/opt/zephyr-sdk-0.15.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc", - "cStandard": "c17", - "cppStandard": "c++98", - "intelliSenseMode": "linux-gcc-arm", - "compilerPathInCppPropertiesJson": "/opt/zephyr-sdk-0.15.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc", - "mergeConfigurations": false, - "browse": { - "path": [ - "/workspaces/zmk/**", - "/workspaces/zmk" - ], - "limitSymbolsToIncludedHeaders": true - }, - "compileCommands": "/workspaces/zmk/app/build/right/compile_commands.json" - } - ], - "version": 4 -} \ No newline at end of file + "configurations": [ + { + "name": "LEFT", + "includePath": ["/workspaces/zmk/**"], + "defines": [], + "compilerPath": "/opt/zephyr-sdk-0.16.3/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc", + "cStandard": "c17", + "cppStandard": "c++98", + "intelliSenseMode": "linux-gcc-arm", + "compileCommands": "/workspaces/zmk/app/build/left/compile_commands.json", + "compilerPathInCppPropertiesJson": "/opt/zephyr-sdk-0.16.3/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc", + "compileCommandsInCppPropertiesJson": "${workspaceFolder}/app/build/left/compile_commands.json", + "mergeConfigurations": false, + "browse": { + "path": ["/workspaces/zmk/**", "${workspaceFolder}"], + "limitSymbolsToIncludedHeaders": true + } + }, + { + "name": "RIGHT", + "includePath": ["/workspaces/zmk/**"], + "defines": [], + "compilerPath": "/opt/zephyr-sdk-0.16.3/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc", + "cStandard": "c17", + "cppStandard": "c++98", + "intelliSenseMode": "linux-gcc-arm", + "compilerPathInCppPropertiesJson": "/opt/zephyr-sdk-0.16.3/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc", + "mergeConfigurations": false, + "browse": { + "path": ["/workspaces/zmk/**", "/workspaces/zmk"], + "limitSymbolsToIncludedHeaders": true + }, + "compileCommands": "/workspaces/zmk/app/build/right/compile_commands.json" + } + ], + "version": 4 +} diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 0891364b4377..f4a78c50c140 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -17,6 +17,9 @@ project(zmk) zephyr_linker_sources(RODATA include/linker/zmk-events.ld) +zephyr_syscall_header(${APPLICATION_SOURCE_DIR}/include/drivers/behavior.h) +zephyr_syscall_header(${APPLICATION_SOURCE_DIR}/include/drivers/ext_power.h) + # Add your source file to the "app" target. This must come after # find_package(Zephyr) which defines the target. target_include_directories(app PRIVATE include) @@ -24,6 +27,8 @@ target_sources(app PRIVATE src/stdlib.c) target_sources(app PRIVATE src/activity.c) target_sources(app PRIVATE src/kscan.c) target_sources(app PRIVATE src/matrix_transform.c) +target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/mouse/main.c) +target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/mouse/input_config.c) target_sources(app PRIVATE src/sensors.c) target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/wpm.c) target_sources(app PRIVATE src/event_manager.c) @@ -31,14 +36,14 @@ target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/ext_power_generic.c) target_sources(app PRIVATE src/events/activity_state_changed.c) target_sources(app PRIVATE src/events/position_state_changed.c) target_sources(app PRIVATE src/events/sensor_event.c) -target_sources(app PRIVATE src/events/mouse_button_state_changed.c) target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/events/wpm_state_changed.c) target_sources_ifdef(CONFIG_USB_DEVICE_STACK app PRIVATE src/events/usb_conn_state_changed.c) target_sources(app PRIVATE src/behaviors/behavior_reset.c) target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/behaviors/behavior_ext_power.c) if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL) target_sources(app PRIVATE src/hid.c) - target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/mouse.c) + target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/mouse/main.c) + target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/mouse/hid_input_listener.c) target_sources(app PRIVATE src/behaviors/behavior_key_press.c) target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_KEY_TOGGLE app PRIVATE src/behaviors/behavior_key_toggle.c) target_sources(app PRIVATE src/behaviors/behavior_hold_tap.c) @@ -57,6 +62,7 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL) target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SENSOR_ROTATE_VAR app PRIVATE src/behaviors/behavior_sensor_rotate_var.c) target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SENSOR_ROTATE_COMMON app PRIVATE src/behaviors/behavior_sensor_rotate_common.c) target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_MOUSE_KEY_PRESS app PRIVATE src/behaviors/behavior_mouse_key_press.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_INPUT_TWO_AXIS app PRIVATE src/behaviors/behavior_input_two_axis.c) target_sources(app PRIVATE src/combo.c) target_sources(app PRIVATE src/behaviors/behavior_tap_dance.c) target_sources(app PRIVATE src/behavior_queue.c) diff --git a/app/Kconfig b/app/Kconfig index f92f0ae3b86d..9fbe29000f56 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -131,11 +131,6 @@ if ZMK_BLE config BT_TINYCRYPT_ECC default y if BT_HCI && !BT_CTLR -choice BT_LL_SW_LLCP_IMPL - default BT_LL_SW_LLCP_LEGACY - -endchoice - config SYSTEM_WORKQUEUE_STACK_SIZE default 4096 if SOC_RP2040 default 2048 @@ -321,9 +316,7 @@ endmenu menu "Mouse Options" -config ZMK_MOUSE - bool "Enable ZMK mouse emulation" - default n +rsource "src/mouse/Kconfig" #Mouse Options endmenu @@ -342,13 +335,12 @@ config ZMK_IDLE_TIMEOUT config ZMK_SLEEP bool "Enable deep sleep support" + depends on HAS_POWEROFF + select POWEROFF imply USB if ZMK_SLEEP -config PM_DEVICE - default y - config ZMK_IDLE_SLEEP_TIMEOUT int "Milliseconds of inactivity before entering deep sleep" default 900000 diff --git a/app/Kconfig.behaviors b/app/Kconfig.behaviors index 11bc8c5900f1..537b53d8a723 100644 --- a/app/Kconfig.behaviors +++ b/app/Kconfig.behaviors @@ -12,6 +12,12 @@ config ZMK_BEHAVIOR_MOUSE_KEY_PRESS depends on DT_HAS_ZMK_BEHAVIOR_MOUSE_KEY_PRESS_ENABLED imply ZMK_MOUSE +config ZMK_BEHAVIOR_INPUT_TWO_AXIS + bool + default y + depends on DT_HAS_ZMK_BEHAVIOR_INPUT_TWO_AXIS_ENABLED + imply ZMK_MOUSE + config ZMK_BEHAVIOR_SENSOR_ROTATE_COMMON bool default n @@ -31,4 +37,4 @@ config ZMK_BEHAVIOR_SENSOR_ROTATE_VAR config ZMK_BEHAVIOR_MACRO bool default y - depends on DT_HAS_ZMK_BEHAVIOR_MACRO_ENABLED || DT_HAS_ZMK_BEHAVIOR_MACRO_ONE_PARAM_ENABLED || DT_HAS_ZMK_BEHAVIOR_MACRO_TWO_PARAM_ENABLED \ No newline at end of file + depends on DT_HAS_ZMK_BEHAVIOR_MACRO_ENABLED || DT_HAS_ZMK_BEHAVIOR_MACRO_ONE_PARAM_ENABLED || DT_HAS_ZMK_BEHAVIOR_MACRO_TWO_PARAM_ENABLED diff --git a/app/boards/arm/dz60rgb/dz60rgb_rev1_defconfig b/app/boards/arm/dz60rgb/dz60rgb_rev1_defconfig index 53bc0e110345..6b6c8a48de6d 100644 --- a/app/boards/arm/dz60rgb/dz60rgb_rev1_defconfig +++ b/app/boards/arm/dz60rgb/dz60rgb_rev1_defconfig @@ -5,9 +5,6 @@ CONFIG_SOC_STM32F303XC=y # 72MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 -# enable pinmux -CONFIG_PINMUX=y - # enable GPIO CONFIG_GPIO=y diff --git a/app/boards/arm/ferris/ferris_rev02_defconfig b/app/boards/arm/ferris/ferris_rev02_defconfig index 267035c9fb11..bd03c3050d7c 100644 --- a/app/boards/arm/ferris/ferris_rev02_defconfig +++ b/app/boards/arm/ferris/ferris_rev02_defconfig @@ -6,7 +6,7 @@ CONFIG_SOC_STM32F072XB=y # 48MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=48000000 -# enable PINMUX +# enable PINCTRL CONFIG_PINCTRL=y # enable GPIO diff --git a/app/boards/arm/mikoto/CMakeLists.txt b/app/boards/arm/mikoto/CMakeLists.txt index 12cf9b1cf1a1..05214a680e9b 100644 --- a/app/boards/arm/mikoto/CMakeLists.txt +++ b/app/boards/arm/mikoto/CMakeLists.txt @@ -1,6 +1,3 @@ - -if(CONFIG_PINMUX) zephyr_library() zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() \ No newline at end of file +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) \ No newline at end of file diff --git a/app/boards/arm/mikoto/Kconfig.defconfig b/app/boards/arm/mikoto/Kconfig.defconfig index 8117cc87329b..5702c6de347d 100644 --- a/app/boards/arm/mikoto/Kconfig.defconfig +++ b/app/boards/arm/mikoto/Kconfig.defconfig @@ -21,9 +21,6 @@ endif # USB config BT_CTLR default BT -config PINMUX - default y - choice BOARD_MIKOTO_CHARGER_CURRENT default BOARD_MIKOTO_CHARGER_CURRENT_100MA endchoice diff --git a/app/boards/arm/mikoto/pinmux.c b/app/boards/arm/mikoto/pinmux.c index 524aa17e5bf9..c34c2dc85b1c 100644 --- a/app/boards/arm/mikoto/pinmux.c +++ b/app/boards/arm/mikoto/pinmux.c @@ -11,8 +11,7 @@ #include #include -static int pinmux_mikoto_init(const struct device *port) { - ARG_UNUSED(port); +static int pinmux_mikoto_init(void) { #if CONFIG_BOARD_MIKOTO_520 const struct device *p0 = DEVICE_DT_GET(DT_NODELABEL(gpio0)); diff --git a/app/boards/arm/nrfmicro/CMakeLists.txt b/app/boards/arm/nrfmicro/CMakeLists.txt index 12cf9b1cf1a1..05214a680e9b 100644 --- a/app/boards/arm/nrfmicro/CMakeLists.txt +++ b/app/boards/arm/nrfmicro/CMakeLists.txt @@ -1,6 +1,3 @@ - -if(CONFIG_PINMUX) zephyr_library() zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() \ No newline at end of file +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) \ No newline at end of file diff --git a/app/boards/arm/nrfmicro/Kconfig.defconfig b/app/boards/arm/nrfmicro/Kconfig.defconfig index 659e9c5c173e..38daacde3fde 100644 --- a/app/boards/arm/nrfmicro/Kconfig.defconfig +++ b/app/boards/arm/nrfmicro/Kconfig.defconfig @@ -18,9 +18,6 @@ endif # USB_DEVICE_STACK config BT_CTLR default BT -config PINMUX - default y - if BOARD_NRFMICRO_13 || BOARD_NRFMICRO_13_52833 config BOARD_NRFMICRO_CHARGER diff --git a/app/boards/arm/planck/planck_rev6_defconfig b/app/boards/arm/planck/planck_rev6_defconfig index 74050f3d9c10..ce08f41dff8b 100644 --- a/app/boards/arm/planck/planck_rev6_defconfig +++ b/app/boards/arm/planck/planck_rev6_defconfig @@ -5,9 +5,6 @@ CONFIG_SOC_STM32F303XC=y # 72MHz system clock CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=72000000 - -# enable pinmux -CONFIG_PINMUX=y CONFIG_PINCTRL=y # enable GPIO diff --git a/app/boards/arm/puchi_ble/CMakeLists.txt b/app/boards/arm/puchi_ble/CMakeLists.txt index 12cf9b1cf1a1..05214a680e9b 100644 --- a/app/boards/arm/puchi_ble/CMakeLists.txt +++ b/app/boards/arm/puchi_ble/CMakeLists.txt @@ -1,6 +1,3 @@ - -if(CONFIG_PINMUX) zephyr_library() zephyr_library_sources(pinmux.c) -zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) -endif() \ No newline at end of file +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) \ No newline at end of file diff --git a/app/boards/arm/puchi_ble/Kconfig.defconfig b/app/boards/arm/puchi_ble/Kconfig.defconfig index 3533104b2a52..0ba7eefd0435 100644 --- a/app/boards/arm/puchi_ble/Kconfig.defconfig +++ b/app/boards/arm/puchi_ble/Kconfig.defconfig @@ -16,7 +16,4 @@ endif # USB_DEVICE_STACK config BT_CTLR default BT -config PINMUX - default y - endif # BOARD_PUCHI_BLE_v1 diff --git a/app/boards/shields/corne/Kconfig.defconfig b/app/boards/shields/corne/Kconfig.defconfig index 07dd07e9c0f9..27d50df35707 100644 --- a/app/boards/shields/corne/Kconfig.defconfig +++ b/app/boards/shields/corne/Kconfig.defconfig @@ -21,9 +21,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -31,7 +28,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/corne/corne.dtsi b/app/boards/shields/corne/corne.dtsi index 0e9eddf967f0..ad5885b3aba6 100644 --- a/app/boards/shields/corne/corne.dtsi +++ b/app/boards/shields/corne/corne.dtsi @@ -78,6 +78,7 @@ RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9) RC(2,10 segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/elephant42/Kconfig.defconfig b/app/boards/shields/elephant42/Kconfig.defconfig index 70a312c10d55..dc10e980d94c 100644 --- a/app/boards/shields/elephant42/Kconfig.defconfig +++ b/app/boards/shields/elephant42/Kconfig.defconfig @@ -24,9 +24,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -34,7 +31,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/elephant42/elephant42.dtsi b/app/boards/shields/elephant42/elephant42.dtsi index b0e9a32ebc4a..b5e257162cef 100644 --- a/app/boards/shields/elephant42/elephant42.dtsi +++ b/app/boards/shields/elephant42/elephant42.dtsi @@ -55,6 +55,7 @@ RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(1,6) RC(1,7) segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; \ No newline at end of file diff --git a/app/boards/shields/jorne/Kconfig.defconfig b/app/boards/shields/jorne/Kconfig.defconfig index 04beb792c4df..ba332226f298 100644 --- a/app/boards/shields/jorne/Kconfig.defconfig +++ b/app/boards/shields/jorne/Kconfig.defconfig @@ -22,9 +22,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -32,7 +29,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/jorne/jorne.dtsi b/app/boards/shields/jorne/jorne.dtsi index 1d12b85c90f4..d5760a27aecd 100644 --- a/app/boards/shields/jorne/jorne.dtsi +++ b/app/boards/shields/jorne/jorne.dtsi @@ -94,6 +94,7 @@ RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9) RC(2,10 segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/knob_goblin/Kconfig.defconfig b/app/boards/shields/knob_goblin/Kconfig.defconfig index d8d468edb948..3f08e28724f2 100644 --- a/app/boards/shields/knob_goblin/Kconfig.defconfig +++ b/app/boards/shields/knob_goblin/Kconfig.defconfig @@ -14,9 +14,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -24,7 +21,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/knob_goblin/knob_goblin.overlay b/app/boards/shields/knob_goblin/knob_goblin.overlay index 03051ce58208..ad9fb15f52ae 100644 --- a/app/boards/shields/knob_goblin/knob_goblin.overlay +++ b/app/boards/shields/knob_goblin/knob_goblin.overlay @@ -76,6 +76,7 @@ segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/kyria/Kconfig.defconfig b/app/boards/shields/kyria/Kconfig.defconfig index 2d162736b49f..36e029638c0f 100644 --- a/app/boards/shields/kyria/Kconfig.defconfig +++ b/app/boards/shields/kyria/Kconfig.defconfig @@ -22,9 +22,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -32,7 +29,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/kyria/kyria_common.dtsi b/app/boards/shields/kyria/kyria_common.dtsi index 1056794d5848..5095000360de 100644 --- a/app/boards/shields/kyria/kyria_common.dtsi +++ b/app/boards/shields/kyria/kyria_common.dtsi @@ -57,5 +57,6 @@ display-offset = <0>; multiplex-ratio = <63>; prechargep = <0x22>; + inversion-on; }; }; diff --git a/app/boards/shields/leeloo/Kconfig.defconfig b/app/boards/shields/leeloo/Kconfig.defconfig index 046bd49a3dd2..a3d95f63a39d 100644 --- a/app/boards/shields/leeloo/Kconfig.defconfig +++ b/app/boards/shields/leeloo/Kconfig.defconfig @@ -34,9 +34,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -44,7 +41,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/leeloo/leeloo_common.dtsi b/app/boards/shields/leeloo/leeloo_common.dtsi index ef775cfbe61c..e04617bfca5e 100644 --- a/app/boards/shields/leeloo/leeloo_common.dtsi +++ b/app/boards/shields/leeloo/leeloo_common.dtsi @@ -87,6 +87,7 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(4,5) RC(4,6) RC(3,6) RC(3,7) segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/leeloo_micro/Kconfig.defconfig b/app/boards/shields/leeloo_micro/Kconfig.defconfig index 26256120a76a..8af3214d1c87 100644 --- a/app/boards/shields/leeloo_micro/Kconfig.defconfig +++ b/app/boards/shields/leeloo_micro/Kconfig.defconfig @@ -24,9 +24,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -34,7 +31,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/leeloo_micro/leeloo_micro.dtsi b/app/boards/shields/leeloo_micro/leeloo_micro.dtsi index ab68a6153f11..9712ac0c997e 100644 --- a/app/boards/shields/leeloo_micro/leeloo_micro.dtsi +++ b/app/boards/shields/leeloo_micro/leeloo_micro.dtsi @@ -85,6 +85,7 @@ RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(3,4) RC(3,5) RC(2,5) RC(2,6) RC(2,7) segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; \ No newline at end of file diff --git a/app/boards/shields/lily58/Kconfig.defconfig b/app/boards/shields/lily58/Kconfig.defconfig index e77a9c2208df..169a6ad7270b 100644 --- a/app/boards/shields/lily58/Kconfig.defconfig +++ b/app/boards/shields/lily58/Kconfig.defconfig @@ -22,9 +22,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -32,7 +29,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/lily58/lily58.dtsi b/app/boards/shields/lily58/lily58.dtsi index eb427a581ba1..234b65d4a081 100644 --- a/app/boards/shields/lily58/lily58.dtsi +++ b/app/boards/shields/lily58/lily58.dtsi @@ -77,6 +77,7 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(4,5) RC(4,6) RC(3,6) RC(3,7) segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/lotus58/Kconfig.defconfig b/app/boards/shields/lotus58/Kconfig.defconfig index 62695c2020a5..984095c7afed 100644 --- a/app/boards/shields/lotus58/Kconfig.defconfig +++ b/app/boards/shields/lotus58/Kconfig.defconfig @@ -24,9 +24,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -34,7 +31,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/lotus58/lotus58.dtsi b/app/boards/shields/lotus58/lotus58.dtsi index 8b1c66f98df9..9e1f5e2c9377 100644 --- a/app/boards/shields/lotus58/lotus58.dtsi +++ b/app/boards/shields/lotus58/lotus58.dtsi @@ -86,6 +86,7 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(4,5) RC(4,6) RC(3,6) RC(3,7 segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/microdox/Kconfig.defconfig b/app/boards/shields/microdox/Kconfig.defconfig index e355c6411ee3..3737b83fd3d9 100644 --- a/app/boards/shields/microdox/Kconfig.defconfig +++ b/app/boards/shields/microdox/Kconfig.defconfig @@ -24,9 +24,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -34,7 +31,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/microdox/microdox_common.dtsi b/app/boards/shields/microdox/microdox_common.dtsi index 0460e012287f..ba522a18bfd4 100644 --- a/app/boards/shields/microdox/microdox_common.dtsi +++ b/app/boards/shields/microdox/microdox_common.dtsi @@ -46,6 +46,7 @@ RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9) display-offset = <0>; multiplex-ratio = <31>; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/murphpad/Kconfig.defconfig b/app/boards/shields/murphpad/Kconfig.defconfig index 80e65351dad7..9d80a13936b6 100644 --- a/app/boards/shields/murphpad/Kconfig.defconfig +++ b/app/boards/shields/murphpad/Kconfig.defconfig @@ -14,9 +14,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -24,7 +21,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/murphpad/murphpad.overlay b/app/boards/shields/murphpad/murphpad.overlay index f175c55e1c03..47825411a288 100644 --- a/app/boards/shields/murphpad/murphpad.overlay +++ b/app/boards/shields/murphpad/murphpad.overlay @@ -70,6 +70,7 @@ segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/nibble/Kconfig.defconfig b/app/boards/shields/nibble/Kconfig.defconfig index 19bddec77b87..3915ff0fb87a 100644 --- a/app/boards/shields/nibble/Kconfig.defconfig +++ b/app/boards/shields/nibble/Kconfig.defconfig @@ -14,9 +14,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -24,7 +21,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/nibble/nibble.overlay b/app/boards/shields/nibble/nibble.overlay index 43be6c766fcc..9078d16bbffa 100644 --- a/app/boards/shields/nibble/nibble.overlay +++ b/app/boards/shields/nibble/nibble.overlay @@ -70,6 +70,7 @@ RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,6) RC(4,9) display-offset = <0>; multiplex-ratio = <31>; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/nice_view/Kconfig.defconfig b/app/boards/shields/nice_view/Kconfig.defconfig index 53edc1ccc7f2..c31cec89f0f6 100644 --- a/app/boards/shields/nice_view/Kconfig.defconfig +++ b/app/boards/shields/nice_view/Kconfig.defconfig @@ -6,7 +6,7 @@ if SHIELD_NICE_VIEW config LV_Z_VDB_SIZE default 100 -config LV_Z_DPI +config LV_DPI_DEF default 161 config LV_Z_BITS_PER_PIXEL @@ -24,6 +24,9 @@ choice ZMK_DISPLAY_STATUS_SCREEN default ZMK_DISPLAY_STATUS_SCREEN_CUSTOM endchoice +config LV_Z_MEM_POOL_SIZE + default 4096 if ZMK_DISPLAY_STATUS_SCREEN_CUSTOM + config ZMK_DISPLAY_STATUS_SCREEN_CUSTOM imply NICE_VIEW_WIDGET_STATUS diff --git a/app/boards/shields/nice_view/widgets/status.c b/app/boards/shields/nice_view/widgets/status.c index 453fd6500393..419b5174a8f9 100644 --- a/app/boards/shields/nice_view/widgets/status.c +++ b/app/boards/shields/nice_view/widgets/status.c @@ -149,7 +149,7 @@ static void draw_middle(lv_obj_t *widget, lv_color_t cbuf[], const struct status for (int i = 0; i < 5; i++) { bool selected = i == state->active_profile_index; - lv_canvas_draw_arc(canvas, circle_offsets[i][0], circle_offsets[i][1], 13, 0, 359, + lv_canvas_draw_arc(canvas, circle_offsets[i][0], circle_offsets[i][1], 13, 0, 360, &arc_dsc); if (selected) { @@ -180,7 +180,7 @@ static void draw_bottom(lv_obj_t *widget, lv_color_t cbuf[], const struct status // Draw layer if (state->layer_label == NULL) { - char text[9] = {}; + char text[10] = {}; sprintf(text, "LAYER %i", state->layer_index); diff --git a/app/boards/shields/snap/Kconfig.defconfig b/app/boards/shields/snap/Kconfig.defconfig index e21111e969a7..0338df484896 100644 --- a/app/boards/shields/snap/Kconfig.defconfig +++ b/app/boards/shields/snap/Kconfig.defconfig @@ -24,9 +24,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -34,7 +31,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/snap/snap.dtsi b/app/boards/shields/snap/snap.dtsi index 7523f35b06c9..48d64dbef3f0 100644 --- a/app/boards/shields/snap/snap.dtsi +++ b/app/boards/shields/snap/snap.dtsi @@ -81,6 +81,7 @@ RC(5,7) RC(5,6) RC(5,5) RC(5,4) RC(5,2) RC(5,0) RC(5,15) display-offset = <0>; multiplex-ratio = <31>; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/sofle/Kconfig.defconfig b/app/boards/shields/sofle/Kconfig.defconfig index 4e7bf88488ee..4eb3d743b86f 100644 --- a/app/boards/shields/sofle/Kconfig.defconfig +++ b/app/boards/shields/sofle/Kconfig.defconfig @@ -24,9 +24,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -34,7 +31,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/sofle/sofle.dtsi b/app/boards/shields/sofle/sofle.dtsi index 4917ca321edf..94920757c6b1 100644 --- a/app/boards/shields/sofle/sofle.dtsi +++ b/app/boards/shields/sofle/sofle.dtsi @@ -86,6 +86,7 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(4,5) RC(4,6) RC(3,6) RC(3,7) segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/splitkb_aurora_corne/Kconfig.defconfig b/app/boards/shields/splitkb_aurora_corne/Kconfig.defconfig index a28792c7bb1b..d3ac6c77e26a 100644 --- a/app/boards/shields/splitkb_aurora_corne/Kconfig.defconfig +++ b/app/boards/shields/splitkb_aurora_corne/Kconfig.defconfig @@ -30,9 +30,6 @@ config SSD1306 config I2C default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -40,7 +37,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne.dtsi b/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne.dtsi index 3eefdc6aeed0..5e1536f062cb 100644 --- a/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne.dtsi +++ b/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne.dtsi @@ -88,6 +88,7 @@ RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9) RC(2,10 segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/splitkb_aurora_helix/Kconfig.defconfig b/app/boards/shields/splitkb_aurora_helix/Kconfig.defconfig index 6d7a55691e2a..df32b83b237d 100644 --- a/app/boards/shields/splitkb_aurora_helix/Kconfig.defconfig +++ b/app/boards/shields/splitkb_aurora_helix/Kconfig.defconfig @@ -28,9 +28,6 @@ config SSD1306 config I2C default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL diff --git a/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix.dtsi b/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix.dtsi index e580e87daba7..751087c0a5d9 100644 --- a/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix.dtsi +++ b/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix.dtsi @@ -74,6 +74,7 @@ segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/splitkb_aurora_lily58/Kconfig.defconfig b/app/boards/shields/splitkb_aurora_lily58/Kconfig.defconfig index e54e2b4332ff..861db44f0b1c 100644 --- a/app/boards/shields/splitkb_aurora_lily58/Kconfig.defconfig +++ b/app/boards/shields/splitkb_aurora_lily58/Kconfig.defconfig @@ -30,9 +30,6 @@ config SSD1306 config I2C default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -40,7 +37,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58.dtsi b/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58.dtsi index 06b3ef3955c3..96ded7d5dc9e 100644 --- a/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58.dtsi +++ b/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58.dtsi @@ -74,6 +74,7 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(4,1) RC(4,10) RC(3,6) RC(3,7) segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/splitkb_aurora_sofle/Kconfig.defconfig b/app/boards/shields/splitkb_aurora_sofle/Kconfig.defconfig index b53c4c8dc16e..172548e87d7e 100644 --- a/app/boards/shields/splitkb_aurora_sofle/Kconfig.defconfig +++ b/app/boards/shields/splitkb_aurora_sofle/Kconfig.defconfig @@ -28,9 +28,6 @@ config SSD1306 config I2C default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL diff --git a/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle.dtsi b/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle.dtsi index 798cd84e5f3a..10c434b8c3da 100644 --- a/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle.dtsi +++ b/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle.dtsi @@ -74,6 +74,7 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(4,5) RC(4,6) RC(3,6) RC(3,7) segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/splitkb_aurora_sweep/Kconfig.defconfig b/app/boards/shields/splitkb_aurora_sweep/Kconfig.defconfig index 83cb1bf687c8..6a0e37286c94 100644 --- a/app/boards/shields/splitkb_aurora_sweep/Kconfig.defconfig +++ b/app/boards/shields/splitkb_aurora_sweep/Kconfig.defconfig @@ -30,9 +30,6 @@ config SSD1306 config I2C default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -40,7 +37,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep.dtsi b/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep.dtsi index c5483af5476c..fdd8a2dc9472 100644 --- a/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep.dtsi +++ b/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep.dtsi @@ -76,6 +76,7 @@ segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/tidbit/Kconfig.defconfig b/app/boards/shields/tidbit/Kconfig.defconfig index 393fbef1bf29..70bb1d74d30e 100644 --- a/app/boards/shields/tidbit/Kconfig.defconfig +++ b/app/boards/shields/tidbit/Kconfig.defconfig @@ -15,9 +15,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -25,7 +22,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/tidbit/tidbit.dtsi b/app/boards/shields/tidbit/tidbit.dtsi index c7af200137d3..6717a3af22c7 100644 --- a/app/boards/shields/tidbit/tidbit.dtsi +++ b/app/boards/shields/tidbit/tidbit.dtsi @@ -112,6 +112,7 @@ segment-remap; com-invdir; com-sequential; + inversion-on; prechargep = <0x22>; }; }; diff --git a/app/boards/shields/waterfowl/Kconfig.defconfig b/app/boards/shields/waterfowl/Kconfig.defconfig index dbee82b87d76..1efc359609ca 100644 --- a/app/boards/shields/waterfowl/Kconfig.defconfig +++ b/app/boards/shields/waterfowl/Kconfig.defconfig @@ -22,9 +22,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -32,7 +29,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/waterfowl/waterfowl.dtsi b/app/boards/shields/waterfowl/waterfowl.dtsi index 3d9140941b4d..6ef961b834d2 100644 --- a/app/boards/shields/waterfowl/waterfowl.dtsi +++ b/app/boards/shields/waterfowl/waterfowl.dtsi @@ -106,5 +106,6 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) display-offset = <0>; multiplex-ratio = <63>; prechargep = <0x22>; + inversion-on; }; }; diff --git a/app/boards/shields/zodiark/Kconfig.defconfig b/app/boards/shields/zodiark/Kconfig.defconfig index e7538c418152..07ed7dbe706e 100644 --- a/app/boards/shields/zodiark/Kconfig.defconfig +++ b/app/boards/shields/zodiark/Kconfig.defconfig @@ -24,9 +24,6 @@ config I2C config SSD1306 default y -config SSD1306_REVERSE_MODE - default y - endif # ZMK_DISPLAY if LVGL @@ -34,7 +31,7 @@ if LVGL config LV_Z_VDB_SIZE default 64 -config LV_Z_DPI +config LV_DPI_DEF default 148 config LV_Z_BITS_PER_PIXEL diff --git a/app/boards/shields/zodiark/zodiark.dtsi b/app/boards/shields/zodiark/zodiark.dtsi index 66ebb7b47f9a..640f9b7b853c 100644 --- a/app/boards/shields/zodiark/zodiark.dtsi +++ b/app/boards/shields/zodiark/zodiark.dtsi @@ -84,5 +84,6 @@ RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,4) RC(4,5) RC(4,6) RC(4,7) R display-offset = <0>; multiplex-ratio = <31>; prechargep = <0x22>; + inversion-on; }; }; diff --git a/app/dts/behaviors.dtsi b/app/dts/behaviors.dtsi index 23f2fee28068..8a8d023d7b98 100644 --- a/app/dts/behaviors.dtsi +++ b/app/dts/behaviors.dtsi @@ -20,3 +20,6 @@ #include #include #include +#include +#include +#include diff --git a/app/dts/behaviors/mouse_move.dtsi b/app/dts/behaviors/mouse_move.dtsi new file mode 100644 index 000000000000..d18eae939fab --- /dev/null +++ b/app/dts/behaviors/mouse_move.dtsi @@ -0,0 +1,15 @@ +#include + +/ { + behaviors { + /omit-if-no-ref/ mmv: behavior_mouse_move { + compatible = "zmk,behavior-input-two-axis"; + label = "MOUSE_MOVE"; + #binding-cells = <1>; + x-input-code = ; + y-input-code = ; + time-to-max-speed-ms = <300>; + acceleration-exponent = <1>; + }; + }; +}; diff --git a/app/dts/behaviors/mouse_scroll.dtsi b/app/dts/behaviors/mouse_scroll.dtsi new file mode 100644 index 000000000000..e08a9e9fd194 --- /dev/null +++ b/app/dts/behaviors/mouse_scroll.dtsi @@ -0,0 +1,15 @@ +#include + +/ { + behaviors { + /omit-if-no-ref/ msc: behavior_mouse_scroll { + compatible = "zmk,behavior-input-two-axis"; + label = "MOUSE_SCROLL"; + #binding-cells = <1>; + x-input-code = ; + y-input-code = ; + time-to-max-speed-ms = <300>; + acceleration-exponent = <0>; + }; + }; +}; diff --git a/app/dts/bindings/behaviors/zmk,behavior-input-two-axis.yaml b/app/dts/bindings/behaviors/zmk,behavior-input-two-axis.yaml new file mode 100644 index 000000000000..820ee7035b8a --- /dev/null +++ b/app/dts/bindings/behaviors/zmk,behavior-input-two-axis.yaml @@ -0,0 +1,21 @@ +description: Two axis input behavior + +compatible: "zmk,behavior-input-two-axis" + +include: one_param.yaml + +properties: + x-input-code: + type: int + required: true + y-input-code: + type: int + required: true + delay-ms: + type: int + time-to-max-speed-ms: + type: int + required: true + acceleration-exponent: + type: int + default: 1 diff --git a/app/dts/bindings/behaviors/zmk,behavior-mouse-move.yaml b/app/dts/bindings/behaviors/zmk,behavior-mouse-move.yaml new file mode 100644 index 000000000000..ae18d9e4112f --- /dev/null +++ b/app/dts/bindings/behaviors/zmk,behavior-mouse-move.yaml @@ -0,0 +1,21 @@ +description: Mouse move + +compatible: "zmk,behavior-mouse-move" + +include: one_param.yaml + +properties: + x-code: + type: int + required: true + y-code: + type: int + required: true + delay-ms: + type: int + time-to-max-speed-ms: + type: int + required: true + acceleration-exponent: + type: int + default: 1 diff --git a/app/dts/bindings/zmk,input-configs.yaml b/app/dts/bindings/zmk,input-configs.yaml new file mode 100644 index 000000000000..83bd4a1939df --- /dev/null +++ b/app/dts/bindings/zmk,input-configs.yaml @@ -0,0 +1,24 @@ +description: | + Allows post-processing of input events based on the configuration + +compatible: "zmk,input-configs" + +child-binding: + description: "A configuration for a given input device" + + properties: + device: + type: phandle + required: true + xy-swap: + type: boolean + x-invert: + type: boolean + y-invert: + type: boolean + scale-multiplier: + type: int + default: 1 + scale-divisor: + type: int + default: 1 diff --git a/app/include/dt-bindings/zmk/mouse.h b/app/include/dt-bindings/zmk/mouse.h index 582518aff7e6..ea34e1243f16 100644 --- a/app/include/dt-bindings/zmk/mouse.h +++ b/app/include/dt-bindings/zmk/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 The ZMK Contributors + * Copyright (c) 2023 The ZMK Contributors * * SPDX-License-Identifier: MIT */ @@ -22,3 +22,29 @@ #define MB4 BIT(3) #define MB5 BIT(4) + +#ifndef ZMK_MOUSE_DEFAULT_MOVE_VAL +#define ZMK_MOUSE_DEFAULT_MOVE_VAL 600 +#endif + +#ifndef ZMK_MOUSE_DEFAULT_SCRL_VAL +#define ZMK_MOUSE_DEFAULT_SCRL_VAL 10 +#endif + +/* Mouse move behavior */ +#define MOVE_Y(vert) ((vert)&0xFFFF) +#define MOVE_Y_DECODE(encoded) (int16_t)((encoded)&0x0000FFFF) +#define MOVE_X(hor) (((hor)&0xFFFF) << 16) +#define MOVE_X_DECODE(encoded) (int16_t)(((encoded)&0xFFFF0000) >> 16) + +#define MOVE(hor, vert) (MOVE_X(hor) + MOVE_Y(vert)) + +#define MOVE_UP MOVE_Y(-ZMK_MOUSE_DEFAULT_MOVE_VAL) +#define MOVE_DOWN MOVE_Y(ZMK_MOUSE_DEFAULT_MOVE_VAL) +#define MOVE_LEFT MOVE_X(-ZMK_MOUSE_DEFAULT_MOVE_VAL) +#define MOVE_RIGHT MOVE_X(ZMK_MOUSE_DEFAULT_MOVE_VAL) + +#define SCRL_UP MOVE_Y(ZMK_MOUSE_DEFAULT_SCRL_VAL) +#define SCRL_DOWN MOVE_Y(-ZMK_MOUSE_DEFAULT_SCRL_VAL) +#define SCRL_LEFT MOVE_X(-ZMK_MOUSE_DEFAULT_SCRL_VAL) +#define SCRL_RIGHT MOVE_X(ZMK_MOUSE_DEFAULT_SCRL_VAL) diff --git a/app/include/zmk/endpoints.h b/app/include/zmk/endpoints.h index 70240183e366..b4eac1f38c43 100644 --- a/app/include/zmk/endpoints.h +++ b/app/include/zmk/endpoints.h @@ -72,4 +72,4 @@ int zmk_endpoints_send_report(uint16_t usage_page); #if IS_ENABLED(CONFIG_ZMK_MOUSE) int zmk_endpoints_send_mouse_report(); -#endif // IS_ENABLE(CONFIG_ZMK_MOUSE) +#endif // IS_ENABLED(CONFIG_ZMK_MOUSE) diff --git a/app/include/zmk/hid.h b/app/include/zmk/hid.h index aeaa69d8d080..2c7264c05be2 100644 --- a/app/include/zmk/hid.h +++ b/app/include/zmk/hid.h @@ -53,6 +53,10 @@ #define ZMK_HID_REPORT_ID_CONSUMER 0x02 #define ZMK_HID_REPORT_ID_MOUSE 0x03 +// Needed until Zephyr offers a 2 byte usage macro +#define HID_USAGE16(idx) \ + HID_ITEM(HID_ITEM_TAG_USAGE, HID_ITEM_TYPE_LOCAL, 2), (idx & 0xFF), (idx >> 8 & 0xFF) + static const uint8_t zmk_hid_report_desc[] = { HID_USAGE_PAGE(HID_USAGE_GEN_DESKTOP), HID_USAGE(HID_USAGE_GD_KEYBOARD), @@ -150,6 +154,13 @@ static const uint8_t zmk_hid_report_desc[] = { HID_REPORT_SIZE(0x08), HID_REPORT_COUNT(0x03), HID_INPUT(ZMK_HID_MAIN_VAL_DATA | ZMK_HID_MAIN_VAL_VAR | ZMK_HID_MAIN_VAL_REL), + HID_USAGE_PAGE(HID_USAGE_CONSUMER), + HID_USAGE16(HID_USAGE_CONSUMER_AC_PAN), + HID_LOGICAL_MIN8(-0x7F), + HID_LOGICAL_MAX8(0x7F), + HID_REPORT_SIZE(0x08), + HID_REPORT_COUNT(0x01), + HID_INPUT(ZMK_HID_MAIN_VAL_DATA | ZMK_HID_MAIN_VAL_VAR | ZMK_HID_MAIN_VAL_REL), HID_END_COLLECTION, HID_END_COLLECTION, #endif // IS_ENABLED(CONFIG_ZMK_MOUSE) @@ -207,7 +218,8 @@ struct zmk_hid_mouse_report_body { zmk_mouse_button_flags_t buttons; int8_t d_x; int8_t d_y; - int8_t d_wheel; + int8_t d_scroll_y; + int8_t d_scroll_x; } __packed; struct zmk_hid_mouse_report { @@ -248,6 +260,10 @@ int zmk_hid_mouse_button_press(zmk_mouse_button_t button); int zmk_hid_mouse_button_release(zmk_mouse_button_t button); int zmk_hid_mouse_buttons_press(zmk_mouse_button_flags_t buttons); int zmk_hid_mouse_buttons_release(zmk_mouse_button_flags_t buttons); +void zmk_hid_mouse_movement_set(int16_t x, int16_t y); +void zmk_hid_mouse_scroll_set(int8_t x, int8_t y); +void zmk_hid_mouse_movement_update(int16_t x, int16_t y); +void zmk_hid_mouse_scroll_update(int8_t x, int8_t y); void zmk_hid_mouse_clear(); #endif // IS_ENABLED(CONFIG_ZMK_MOUSE) diff --git a/app/include/zmk/mouse.h b/app/include/zmk/mouse.h index d873f15689a7..28dab60d1433 100644 --- a/app/include/zmk/mouse.h +++ b/app/include/zmk/mouse.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 The ZMK Contributors + * Copyright (c) 2023 The ZMK Contributors * * SPDX-License-Identifier: MIT */ @@ -10,3 +10,5 @@ typedef uint8_t zmk_mouse_button_flags_t; typedef uint16_t zmk_mouse_button_t; + +int zmk_mouse_init(void); diff --git a/app/include/zmk/mouse/input_config.h b/app/include/zmk/mouse/input_config.h new file mode 100644 index 000000000000..0a37b346cafe --- /dev/null +++ b/app/include/zmk/mouse/input_config.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include + +struct zmk_input_config { + const struct device *dev; + bool xy_swap; + bool x_invert; + bool y_invert; + uint16_t scale_multiplier; + uint16_t scale_divisor; +}; + +const struct zmk_input_config *zmk_input_config_get_for_device(const struct device *dev); \ No newline at end of file diff --git a/app/module/drivers/kscan/Kconfig b/app/module/drivers/kscan/Kconfig index 6f60b3f919f1..8a76588ff814 100644 --- a/app/module/drivers/kscan/Kconfig +++ b/app/module/drivers/kscan/Kconfig @@ -13,6 +13,14 @@ config ZMK_KSCAN_COMPOSITE_DRIVER bool default $(dt_compat_enabled,$(DT_COMPAT_ZMK_KSCAN_COMPOSITE)) +if ZMK_KSCAN_COMPOSITE_DRIVER + +config ZMK_KSCAN_COMPOSITE_INIT_PRIORITY + int "Init Priority for the composite kscan driver" + default 95 + +endif + config ZMK_KSCAN_GPIO_DRIVER bool select GPIO diff --git a/app/module/drivers/kscan/kscan_composite.c b/app/module/drivers/kscan/kscan_composite.c index 97311ef8e52a..2a3643245c50 100644 --- a/app/module/drivers/kscan/kscan_composite.c +++ b/app/module/drivers/kscan/kscan_composite.c @@ -109,4 +109,4 @@ static const struct kscan_composite_config kscan_composite_config = {}; static struct kscan_composite_data kscan_composite_data; DEVICE_DT_INST_DEFINE(0, kscan_composite_init, NULL, &kscan_composite_data, &kscan_composite_config, - POST_KERNEL, CONFIG_KSCAN_INIT_PRIORITY, &mock_driver_api); + POST_KERNEL, CONFIG_ZMK_KSCAN_COMPOSITE_INIT_PRIORITY, &mock_driver_api); diff --git a/app/module/drivers/kscan/kscan_gpio_demux.c b/app/module/drivers/kscan/kscan_gpio_demux.c index 2cbe116d9f24..10433c5a1d0c 100644 --- a/app/module/drivers/kscan/kscan_gpio_demux.c +++ b/app/module/drivers/kscan/kscan_gpio_demux.c @@ -9,6 +9,7 @@ #include #include #include +#include #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -105,7 +106,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); } \ \ static void kscan_gpio_work_handler_##n(struct k_work *work) { \ - struct kscan_gpio_data_##n *data = CONTAINER_OF(work, struct kscan_gpio_data_##n, work); \ + struct k_work_delayable *d_work = k_work_delayable_from_work(work); \ + struct kscan_gpio_data_##n *data = CONTAINER_OF(d_work, struct kscan_gpio_data_##n, work); \ kscan_gpio_read_##n(data->dev); \ } \ \ diff --git a/app/module/drivers/kscan/kscan_gpio_direct.c b/app/module/drivers/kscan/kscan_gpio_direct.c index 5b227784dadc..b5e77f633016 100644 --- a/app/module/drivers/kscan/kscan_gpio_direct.c +++ b/app/module/drivers/kscan/kscan_gpio_direct.c @@ -192,10 +192,10 @@ static int kscan_direct_read(const struct device *dev) { for (int i = 0; i < data->inputs.len; i++) { const struct kscan_gpio *gpio = &data->inputs.gpios[i]; - struct zmk_debounce_state *state = &data->pin_state[gpio->index]; + struct zmk_debounce_state *deb_state = &data->pin_state[gpio->index]; - if (zmk_debounce_get_changed(state)) { - const bool pressed = zmk_debounce_is_pressed(state); + if (zmk_debounce_get_changed(deb_state)) { + const bool pressed = zmk_debounce_is_pressed(deb_state); LOG_DBG("Sending event at 0,%i state %s", gpio->index, pressed ? "on" : "off"); data->callback(dev, 0, gpio->index, pressed); @@ -204,7 +204,7 @@ static int kscan_direct_read(const struct device *dev) { } } - continue_scan = continue_scan || zmk_debounce_is_active(state); + continue_scan = continue_scan || zmk_debounce_is_active(deb_state); } if (continue_scan) { diff --git a/app/module/drivers/kscan/kscan_gpio_matrix.c b/app/module/drivers/kscan/kscan_gpio_matrix.c index 0d8a3190659a..6e91bf95fb0e 100644 --- a/app/module/drivers/kscan/kscan_gpio_matrix.c +++ b/app/module/drivers/kscan/kscan_gpio_matrix.c @@ -290,7 +290,7 @@ static int kscan_matrix_read(const struct device *dev) { } static void kscan_matrix_work_handler(struct k_work *work) { - struct k_work_delayable *dwork = CONTAINER_OF(work, struct k_work_delayable, work); + struct k_work_delayable *dwork = k_work_delayable_from_work(work); struct kscan_matrix_data *data = CONTAINER_OF(dwork, struct kscan_matrix_data, work); kscan_matrix_read(data->dev); } diff --git a/app/module/drivers/kscan/kscan_mock.c b/app/module/drivers/kscan/kscan_mock.c index 604e164cbc52..1ffb937e8c4c 100644 --- a/app/module/drivers/kscan/kscan_mock.c +++ b/app/module/drivers/kscan/kscan_mock.c @@ -9,6 +9,7 @@ #include #include #include +#include #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -61,7 +62,8 @@ static int kscan_mock_configure(const struct device *dev, kscan_callback_t callb } \ } \ static void kscan_mock_work_handler_##n(struct k_work *work) { \ - struct kscan_mock_data *data = CONTAINER_OF(work, struct kscan_mock_data, work); \ + struct k_work_delayable *d_work = k_work_delayable_from_work(work); \ + struct kscan_mock_data *data = CONTAINER_OF(d_work, struct kscan_mock_data, work); \ const struct kscan_mock_config_##n *cfg = data->dev->config; \ uint32_t ev = cfg->events[data->event_index]; \ LOG_DBG("ev %u row %d column %d state %d\n", ev, ZMK_MOCK_ROW(ev), ZMK_MOCK_COL(ev), \ diff --git a/app/module/drivers/sensor/max17048/CMakeLists.txt b/app/module/drivers/sensor/max17048/CMakeLists.txt index e895fa11fb8c..43b7af4d097b 100644 --- a/app/module/drivers/sensor/max17048/CMakeLists.txt +++ b/app/module/drivers/sensor/max17048/CMakeLists.txt @@ -5,5 +5,5 @@ zephyr_include_directories(.) zephyr_library() -zephyr_library_sources_ifdef(CONFIG_MAX17048 max17048.c) -zephyr_library_sources_ifndef(CONFIG_MAX17048 ${ZEPHYR_BASE}/misc/empty_file.c) +zephyr_library_sources_ifdef(CONFIG_ZMK_MAX17048 max17048.c) +zephyr_library_sources_ifndef(CONFIG_ZMK_MAX17048 ${ZEPHYR_BASE}/misc/empty_file.c) diff --git a/app/module/drivers/sensor/max17048/Kconfig b/app/module/drivers/sensor/max17048/Kconfig index 8a7ec16e85d2..9537e269b7f8 100644 --- a/app/module/drivers/sensor/max17048/Kconfig +++ b/app/module/drivers/sensor/max17048/Kconfig @@ -3,7 +3,7 @@ DT_COMPAT_MAXIM_MAX17048 := maxim,max17048 -menuconfig MAX17048 +menuconfig ZMK_MAX17048 bool "MAX17048/9 I2C-based Fuel Gauge" default $(dt_compat_enabled,$(DT_COMPAT_MAXIM_MAX17048)) depends on I2C @@ -12,7 +12,7 @@ menuconfig MAX17048 Enable driver for MAX17048/9 I2C-based Fuel Gauge. Supports measuring battery voltage and state-of-charge. -if MAX17048 +if ZMK_MAX17048 config SENSOR_MAX17048_INIT_PRIORITY int "Init priority" diff --git a/app/prj.conf b/app/prj.conf index e69de29bb2d1..cd2bc13ffd24 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -0,0 +1 @@ +CONFIG_APPLICATION_DEFINED_SYSCALL=y \ No newline at end of file diff --git a/app/src/activity.c b/app/src/activity.c index 41fe2e15dc41..7894cb7116ff 100644 --- a/app/src/activity.c +++ b/app/src/activity.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include @@ -70,7 +70,7 @@ void activity_work_handler(struct k_work *work) { if (inactive_time > MAX_SLEEP_MS && !is_usb_power_present()) { // Put devices in suspend power mode before sleeping set_state(ZMK_ACTIVITY_SLEEP); - pm_state_force(0U, &(struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0}); + sys_poweroff(); } else #endif /* IS_ENABLED(CONFIG_ZMK_SLEEP) */ if (inactive_time > MAX_IDLE_MS) { @@ -84,7 +84,7 @@ void activity_expiry_function() { k_work_submit(&activity_work); } K_TIMER_DEFINE(activity_timer, activity_expiry_function, NULL); -int activity_init() { +int activity_init(void) { activity_last_uptime = k_uptime_get(); k_timer_start(&activity_timer, K_SECONDS(1), K_SECONDS(1)); diff --git a/app/src/backlight.c b/app/src/backlight.c index f633ddb728b6..7f87737df723 100644 --- a/app/src/backlight.c +++ b/app/src/backlight.c @@ -78,7 +78,7 @@ static void backlight_save_work_handler(struct k_work *work) { static struct k_work_delayable backlight_save_work; #endif -static int zmk_backlight_init(const struct device *_arg) { +static int zmk_backlight_init(void) { if (!device_is_ready(backlight_dev)) { LOG_ERR("Backlight device \"%s\" is not ready", backlight_dev->name); return -ENODEV; diff --git a/app/src/battery.c b/app/src/battery.c index c6466272082e..a2609d7e2867 100644 --- a/app/src/battery.c +++ b/app/src/battery.c @@ -84,7 +84,7 @@ static void zmk_battery_timer(struct k_timer *timer) { K_TIMER_DEFINE(battery_timer, zmk_battery_timer, NULL); -static int zmk_battery_init(const struct device *_arg) { +static int zmk_battery_init(void) { #if !DT_HAS_CHOSEN(zmk_battery) battery = device_get_binding("BATTERY"); diff --git a/app/src/behaviors/behavior_backlight.c b/app/src/behaviors/behavior_backlight.c index fe2155b7fd0d..27d8de93aa64 100644 --- a/app/src/behaviors/behavior_backlight.c +++ b/app/src/behaviors/behavior_backlight.c @@ -91,7 +91,7 @@ static const struct behavior_driver_api behavior_backlight_driver_api = { .locality = BEHAVIOR_LOCALITY_GLOBAL, }; -DEVICE_DT_INST_DEFINE(0, behavior_backlight_init, NULL, NULL, NULL, APPLICATION, +DEVICE_DT_INST_DEFINE(0, behavior_backlight_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_backlight_driver_api); #endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ diff --git a/app/src/behaviors/behavior_bt.c b/app/src/behaviors/behavior_bt.c index bf98532ce931..69724691cefa 100644 --- a/app/src/behaviors/behavior_bt.c +++ b/app/src/behaviors/behavior_bt.c @@ -52,7 +52,7 @@ static const struct behavior_driver_api behavior_bt_driver_api = { .binding_released = on_keymap_binding_released, }; -DEVICE_DT_INST_DEFINE(0, behavior_bt_init, NULL, NULL, NULL, APPLICATION, +DEVICE_DT_INST_DEFINE(0, behavior_bt_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_bt_driver_api); #endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ diff --git a/app/src/behaviors/behavior_caps_word.c b/app/src/behaviors/behavior_caps_word.c index 4c9fd71186de..7fc34984bbfb 100644 --- a/app/src/behaviors/behavior_caps_word.c +++ b/app/src/behaviors/behavior_caps_word.c @@ -182,7 +182,7 @@ static int behavior_caps_word_init(const struct device *dev) { .continuations_count = DT_INST_PROP_LEN(n, continue_list), \ }; \ DEVICE_DT_INST_DEFINE(n, behavior_caps_word_init, NULL, &behavior_caps_word_data_##n, \ - &behavior_caps_word_config_##n, APPLICATION, \ + &behavior_caps_word_config_##n, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_caps_word_driver_api); DT_INST_FOREACH_STATUS_OKAY(KP_INST) diff --git a/app/src/behaviors/behavior_ext_power.c b/app/src/behaviors/behavior_ext_power.c index 690ac97175e9..ebc75ac609cc 100644 --- a/app/src/behaviors/behavior_ext_power.c +++ b/app/src/behaviors/behavior_ext_power.c @@ -74,7 +74,7 @@ static const struct behavior_driver_api behavior_ext_power_driver_api = { .locality = BEHAVIOR_LOCALITY_GLOBAL, }; -DEVICE_DT_INST_DEFINE(0, behavior_ext_power_init, NULL, NULL, NULL, APPLICATION, +DEVICE_DT_INST_DEFINE(0, behavior_ext_power_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY, &behavior_ext_power_driver_api); #endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index d4aa0dce0363..5f70de4ac6b6 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -678,7 +678,8 @@ ZMK_SUBSCRIPTION(behavior_hold_tap, zmk_position_state_changed); ZMK_SUBSCRIPTION(behavior_hold_tap, zmk_keycode_state_changed); void behavior_hold_tap_timer_work_handler(struct k_work *item) { - struct active_hold_tap *hold_tap = CONTAINER_OF(item, struct active_hold_tap, work); + struct k_work_delayable *d_work = k_work_delayable_from_work(item); + struct active_hold_tap *hold_tap = CONTAINER_OF(d_work, struct active_hold_tap, work); if (hold_tap->work_is_cancelled) { clear_hold_tap(hold_tap); @@ -716,7 +717,7 @@ static int behavior_hold_tap_init(const struct device *dev) { .hold_trigger_key_positions_len = DT_INST_PROP_LEN(n, hold_trigger_key_positions), \ }; \ DEVICE_DT_INST_DEFINE(n, behavior_hold_tap_init, NULL, NULL, &behavior_hold_tap_config_##n, \ - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ &behavior_hold_tap_driver_api); DT_INST_FOREACH_STATUS_OKAY(KP_INST) diff --git a/app/src/behaviors/behavior_input_two_axis.c b/app/src/behaviors/behavior_input_two_axis.c new file mode 100644 index 000000000000..305112e5f39b --- /dev/null +++ b/app/src/behaviors/behavior_input_two_axis.c @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_input_two_axis + +#include +#include +#include +#include +#include // CLAMP + +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +struct vector2d { + float x; + float y; +}; + +struct movement_state_1d { + float remainder; + int16_t speed; + uint64_t start_time; +}; + +struct movement_state_2d { + struct movement_state_1d x; + struct movement_state_1d y; +}; + +struct behavior_input_two_axis_data { + struct k_work_delayable tick_work; + const struct device *dev; + + struct movement_state_2d state; +}; + +struct behavior_input_two_axis_config { + int16_t x_code; + int16_t y_code; + int delay_ms; + int time_to_max_speed_ms; + // acceleration exponent 0: uniform speed + // acceleration exponent 1: uniform acceleration + // acceleration exponent 2: uniform jerk + int acceleration_exponent; +}; + +#if CONFIG_MINIMAL_LIBC +static float powf(float base, float exponent) { + // poor man's power implementation rounds the exponent down to the nearest integer. + float power = 1.0f; + for (; exponent >= 1.0f; exponent--) { + power = power * base; + } + return power; +} +#else +#include +#endif + +static int64_t ms_since_start(int64_t start, int64_t now, int64_t delay) { + if (start == 0) { + return 0; + } + int64_t move_duration = now - (start + delay); + // start can be in the future if there's a delay + if (move_duration < 0) { + move_duration = 0; + } + return move_duration; +} + +static float speed(const struct behavior_input_two_axis_config *config, float max_speed, + int64_t duration_ms) { + // Calculate the speed based on MouseKeysAccel + // See https://en.wikipedia.org/wiki/Mouse_keys + if (duration_ms == 0) { + return 0; + } + + if (duration_ms > config->time_to_max_speed_ms || config->time_to_max_speed_ms == 0 || + config->acceleration_exponent == 0) { + return max_speed; + } + float time_fraction = (float)duration_ms / config->time_to_max_speed_ms; + return max_speed * powf(time_fraction, config->acceleration_exponent); +} + +static void track_remainder(float *move, float *remainder) { + float new_move = *move + *remainder; + *remainder = new_move - (int)new_move; + *move = (int)new_move; +} + +static float update_movement_1d(const struct behavior_input_two_axis_config *config, + struct movement_state_1d *state, int64_t now) { + float move = 0; + if (state->speed == 0) { + state->remainder = 0; + return move; + } + + int64_t move_duration = ms_since_start(state->start_time, now, config->delay_ms); + move = + (move_duration > 0) + ? (speed(config, state->speed, move_duration) * CONFIG_ZMK_MOUSE_TICK_DURATION / 1000) + : 0; + + track_remainder(&(move), &(state->remainder)); + + return move; +} +static struct vector2d update_movement_2d(const struct behavior_input_two_axis_config *config, + struct movement_state_2d *state, int64_t now) { + struct vector2d move = {0}; + + move = (struct vector2d){ + .x = update_movement_1d(config, &state->x, now), + .y = update_movement_1d(config, &state->y, now), + }; + + return move; +} + +static bool is_non_zero_1d_movement(int16_t speed) { return speed != 0; } + +static bool is_non_zero_2d_movement(struct movement_state_2d *state) { + return is_non_zero_1d_movement(state->x.speed) || is_non_zero_1d_movement(state->y.speed); +} + +static bool should_be_working(struct behavior_input_two_axis_data *data) { + return is_non_zero_2d_movement(&data->state); +} + +static void tick_work_cb(struct k_work *work) { + struct k_work_delayable *d_work = k_work_delayable_from_work(work); + struct behavior_input_two_axis_data *data = + CONTAINER_OF(d_work, struct behavior_input_two_axis_data, tick_work); + const struct device *dev = data->dev; + const struct behavior_input_two_axis_config *cfg = dev->config; + + uint32_t timestamp = k_uptime_get(); + + LOG_INF("tick start times: %lld %lld %lld", data->state.x.start_time, data->state.y.start_time, + timestamp); + + struct vector2d move = update_movement_2d(cfg, &data->state, timestamp); + + int ret = 0; + bool have_x = is_non_zero_1d_movement(move.x); + bool have_y = is_non_zero_1d_movement(move.y); + if (have_x) { + ret = input_report_rel(dev, cfg->x_code, (int16_t)CLAMP(move.x, INT16_MIN, INT16_MAX), + !have_y, K_NO_WAIT); + } + if (have_y) { + ret = input_report_rel(dev, cfg->y_code, (int16_t)CLAMP(move.y, INT16_MIN, INT16_MAX), true, + K_NO_WAIT); + } + + if (should_be_working(data)) { + k_work_schedule(&data->tick_work, K_MSEC(CONFIG_ZMK_MOUSE_TICK_DURATION)); + } +} + +static void set_start_times_for_activity_1d(struct movement_state_1d *state) { + if (state->speed != 0 && state->start_time == 0) { + state->start_time = k_uptime_get(); + } else if (state->speed == 0) { + state->start_time = 0; + } +} +static void set_start_times_for_activity(struct movement_state_2d *state) { + set_start_times_for_activity_1d(&state->x); + set_start_times_for_activity_1d(&state->y); +} + +static void update_work_scheduling(const struct device *dev) { + struct behavior_input_two_axis_data *data = dev->data; + + set_start_times_for_activity(&data->state); + + if (should_be_working(data)) { + k_work_schedule(&data->tick_work, K_MSEC(CONFIG_ZMK_MOUSE_TICK_DURATION)); + } else { + k_work_cancel_delayable(&data->tick_work); + } +} + +int zmk_input_synth_pointer_adjust_speed(const struct device *dev, int16_t dx, int16_t dy) { + struct behavior_input_two_axis_data *data = dev->data; + + LOG_DBG("Adjusting: %d %d", dx, dy); + data->state.x.speed += dx; + data->state.y.speed += dy; + + LOG_DBG("After: %d %d", data->state.x.speed, data->state.y.speed); + + update_work_scheduling(dev); + + return 0; +} + +// static void process_key_state(const struct device *dev, int32_t val, bool pressed) { +// for (int i = 0; i < ZMK_HID_MOUSE_NUM_BUTTONS; i++) { +// if (val & BIT(i)) { +// WRITE_BIT(val, i, 0); +// input_report_key(dev, INPUT_BTN_0 + i, pressed ? 1 : 0, val == 0, K_FOREVER); +// } +// } +// } + +static int behavior_input_two_axis_init(const struct device *dev) { + struct behavior_input_two_axis_data *data = dev->data; + + data->dev = dev; + k_work_init_delayable(&data->tick_work, tick_work_cb); + + return 0; +}; + +static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + + const struct device *behavior_dev = device_get_binding(binding->behavior_dev); + + LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); + + int16_t x = MOVE_X_DECODE(binding->param1); + int16_t y = MOVE_Y_DECODE(binding->param1); + + zmk_input_synth_pointer_adjust_speed(behavior_dev, x, y); + return 0; +} + +static int on_keymap_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + const struct device *behavior_dev = device_get_binding(binding->behavior_dev); + + LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); + + int16_t x = MOVE_X_DECODE(binding->param1); + int16_t y = MOVE_Y_DECODE(binding->param1); + + zmk_input_synth_pointer_adjust_speed(behavior_dev, -x, -y); + return 0; +} + +static const struct behavior_driver_api behavior_input_two_axis_driver_api = { + .binding_pressed = on_keymap_binding_pressed, .binding_released = on_keymap_binding_released}; + +#define KP_INST(n) \ + static struct behavior_input_two_axis_data behavior_input_two_axis_data_##n = {}; \ + static struct behavior_input_two_axis_config behavior_input_two_axis_config_##n = { \ + .x_code = DT_INST_PROP(n, x_input_code), \ + .y_code = DT_INST_PROP(n, y_input_code), \ + .delay_ms = DT_INST_PROP_OR(n, delay_ms, 0), \ + .time_to_max_speed_ms = DT_INST_PROP(n, time_to_max_speed_ms), \ + .acceleration_exponent = DT_INST_PROP_OR(n, acceleration_exponent, 1), \ + }; \ + DEVICE_DT_INST_DEFINE(n, behavior_input_two_axis_init, NULL, \ + &behavior_input_two_axis_data_##n, &behavior_input_two_axis_config_##n, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + &behavior_input_two_axis_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(KP_INST) diff --git a/app/src/behaviors/behavior_key_press.c b/app/src/behaviors/behavior_key_press.c index 2765db9f3ca4..9c4ffd329d7a 100644 --- a/app/src/behaviors/behavior_key_press.c +++ b/app/src/behaviors/behavior_key_press.c @@ -36,7 +36,7 @@ static const struct behavior_driver_api behavior_key_press_driver_api = { .binding_pressed = on_keymap_binding_pressed, .binding_released = on_keymap_binding_released}; #define KP_INST(n) \ - DEVICE_DT_INST_DEFINE(n, behavior_key_press_init, NULL, NULL, NULL, APPLICATION, \ + DEVICE_DT_INST_DEFINE(n, behavior_key_press_init, NULL, NULL, NULL, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_key_press_driver_api); DT_INST_FOREACH_STATUS_OKAY(KP_INST) diff --git a/app/src/behaviors/behavior_key_repeat.c b/app/src/behaviors/behavior_key_repeat.c index 033f498b8751..26b84be1fbdf 100644 --- a/app/src/behaviors/behavior_key_repeat.c +++ b/app/src/behaviors/behavior_key_repeat.c @@ -117,7 +117,7 @@ static int behavior_key_repeat_init(const struct device *dev) { .usage_pages_count = DT_INST_PROP_LEN(n, usage_pages), \ }; \ DEVICE_DT_INST_DEFINE(n, behavior_key_repeat_init, NULL, &behavior_key_repeat_data_##n, \ - &behavior_key_repeat_config_##n, APPLICATION, \ + &behavior_key_repeat_config_##n, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_key_repeat_driver_api); DT_INST_FOREACH_STATUS_OKAY(KR_INST) diff --git a/app/src/behaviors/behavior_key_toggle.c b/app/src/behaviors/behavior_key_toggle.c index cbbdd0d91aca..4288ed6ddca7 100644 --- a/app/src/behaviors/behavior_key_toggle.c +++ b/app/src/behaviors/behavior_key_toggle.c @@ -38,7 +38,7 @@ static const struct behavior_driver_api behavior_key_toggle_driver_api = { }; #define KT_INST(n) \ - DEVICE_DT_INST_DEFINE(n, behavior_key_toggle_init, NULL, NULL, NULL, APPLICATION, \ + DEVICE_DT_INST_DEFINE(n, behavior_key_toggle_init, NULL, NULL, NULL, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_key_toggle_driver_api); DT_INST_FOREACH_STATUS_OKAY(KT_INST) diff --git a/app/src/behaviors/behavior_macro.c b/app/src/behaviors/behavior_macro.c index c47284531a7a..9201e9dba9ab 100644 --- a/app/src/behaviors/behavior_macro.c +++ b/app/src/behaviors/behavior_macro.c @@ -225,7 +225,7 @@ static const struct behavior_driver_api behavior_macro_driver_api = { .count = DT_PROP_LEN(inst, bindings), \ .bindings = TRANSFORMED_BEHAVIORS(inst)}; \ DEVICE_DT_DEFINE(inst, behavior_macro_init, NULL, &behavior_macro_state_##inst, \ - &behavior_macro_config_##inst, APPLICATION, \ + &behavior_macro_config_##inst, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_macro_driver_api); DT_FOREACH_STATUS_OKAY(zmk_behavior_macro, MACRO_INST) diff --git a/app/src/behaviors/behavior_mod_morph.c b/app/src/behaviors/behavior_mod_morph.c index d540abd93af6..0843fce1fecc 100644 --- a/app/src/behaviors/behavior_mod_morph.c +++ b/app/src/behaviors/behavior_mod_morph.c @@ -98,7 +98,7 @@ static int behavior_mod_morph_init(const struct device *dev) { return 0; } }; \ static struct behavior_mod_morph_data behavior_mod_morph_data_##n = {}; \ DEVICE_DT_INST_DEFINE(n, behavior_mod_morph_init, NULL, &behavior_mod_morph_data_##n, \ - &behavior_mod_morph_config_##n, APPLICATION, \ + &behavior_mod_morph_config_##n, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_mod_morph_driver_api); DT_INST_FOREACH_STATUS_OKAY(KP_INST) diff --git a/app/src/behaviors/behavior_momentary_layer.c b/app/src/behaviors/behavior_momentary_layer.c index c2bd0ffcb984..ff05af01e668 100644 --- a/app/src/behaviors/behavior_momentary_layer.c +++ b/app/src/behaviors/behavior_momentary_layer.c @@ -40,4 +40,4 @@ static const struct behavior_mo_config behavior_mo_config = {}; static struct behavior_mo_data behavior_mo_data; DEVICE_DT_INST_DEFINE(0, behavior_mo_init, NULL, &behavior_mo_data, &behavior_mo_config, - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_mo_driver_api); + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_mo_driver_api); diff --git a/app/src/behaviors/behavior_mouse_key_press.c b/app/src/behaviors/behavior_mouse_key_press.c index 6718155768cd..f2a691ffed0b 100644 --- a/app/src/behaviors/behavior_mouse_key_press.c +++ b/app/src/behaviors/behavior_mouse_key_press.c @@ -11,8 +11,9 @@ #include #include -#include -#include +#include +#include +#include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -20,26 +21,38 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); static int behavior_mouse_key_press_init(const struct device *dev) { return 0; }; +static void process_key_state(const struct device *dev, int32_t val, bool pressed) { + for (int i = 0; i < ZMK_HID_MOUSE_NUM_BUTTONS; i++) { + if (val & BIT(i)) { + WRITE_BIT(val, i, 0); + input_report_key(dev, INPUT_BTN_0 + i, pressed ? 1 : 0, val == 0, K_FOREVER); + } + } +} + static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); - return ZMK_EVENT_RAISE( - zmk_mouse_button_state_changed_from_encoded(binding->param1, true, event.timestamp)); + process_key_state(device_get_binding(binding->behavior_dev), binding->param1, true); + + return 0; } static int on_keymap_binding_released(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); - return ZMK_EVENT_RAISE( - zmk_mouse_button_state_changed_from_encoded(binding->param1, false, event.timestamp)); + + process_key_state(device_get_binding(binding->behavior_dev), binding->param1, false); + + return 0; } static const struct behavior_driver_api behavior_mouse_key_press_driver_api = { .binding_pressed = on_keymap_binding_pressed, .binding_released = on_keymap_binding_released}; #define MKP_INST(n) \ - DEVICE_DT_INST_DEFINE(n, behavior_mouse_key_press_init, NULL, NULL, NULL, APPLICATION, \ + DEVICE_DT_INST_DEFINE(n, behavior_mouse_key_press_init, NULL, NULL, NULL, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ &behavior_mouse_key_press_driver_api); diff --git a/app/src/behaviors/behavior_mouse_move.c b/app/src/behaviors/behavior_mouse_move.c new file mode 100644 index 000000000000..f077fe5dc126 --- /dev/null +++ b/app/src/behaviors/behavior_mouse_move.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_mouse_move + +#include +#include +#include +#include +#include // CLAMP + +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +struct vector2d { + float x; + float y; +}; + +struct movement_state_1d { + float remainder; + int16_t speed; + uint64_t start_time; +}; + +struct movement_state_2d { + struct movement_state_1d x; + struct movement_state_1d y; +}; + +struct behavior_mouse_move_data { + struct k_work_delayable tick_work; + const struct device *dev; + + struct movement_state_2d state; +}; + +struct behavior_mouse_move_config { + int16_t x_code; + int16_t y_code; + int delay_ms; + int time_to_max_speed_ms; + // acceleration exponent 0: uniform speed + // acceleration exponent 1: uniform acceleration + // acceleration exponent 2: uniform jerk + int acceleration_exponent; +}; + +#if CONFIG_MINIMAL_LIBC +static float powf(float base, float exponent) { + // poor man's power implementation rounds the exponent down to the nearest integer. + float power = 1.0f; + for (; exponent >= 1.0f; exponent--) { + power = power * base; + } + return power; +} +#else +#include +#endif + +static int64_t ms_since_start(int64_t start, int64_t now, int64_t delay) { + if (start == 0) { + return 0; + } + int64_t move_duration = now - (start + delay); + // start can be in the future if there's a delay + if (move_duration < 0) { + move_duration = 0; + } + return move_duration; +} + +static float speed(const struct behavior_mouse_move_config *config, float max_speed, + int64_t duration_ms) { + // Calculate the speed based on MouseKeysAccel + // See https://en.wikipedia.org/wiki/Mouse_keys + if (duration_ms == 0) { + return 0; + } + + if (duration_ms > config->time_to_max_speed_ms || config->time_to_max_speed_ms == 0 || + config->acceleration_exponent == 0) { + return max_speed; + } + float time_fraction = (float)duration_ms / config->time_to_max_speed_ms; + return max_speed * powf(time_fraction, config->acceleration_exponent); +} + +static void track_remainder(float *move, float *remainder) { + float new_move = *move + *remainder; + *remainder = new_move - (int)new_move; + *move = (int)new_move; +} + +static float update_movement_1d(const struct behavior_mouse_move_config *config, + struct movement_state_1d *state, int64_t now) { + float move = 0; + if (state->speed == 0) { + state->remainder = 0; + return move; + } + + int64_t move_duration = ms_since_start(state->start_time, now, config->delay_ms); + move = + (move_duration > 0) + ? (speed(config, state->speed, move_duration) * CONFIG_ZMK_MOUSE_TICK_DURATION / 1000) + : 0; + + track_remainder(&(move), &(state->remainder)); + + return move; +} +static struct vector2d update_movement_2d(const struct behavior_mouse_move_config *config, + struct movement_state_2d *state, int64_t now) { + struct vector2d move = {0}; + + move = (struct vector2d){ + .x = update_movement_1d(config, &state->x, now), + .y = update_movement_1d(config, &state->y, now), + }; + + return move; +} + +static bool is_non_zero_1d_movement(int16_t speed) { return speed != 0; } + +static bool is_non_zero_2d_movement(struct movement_state_2d *state) { + return is_non_zero_1d_movement(state->x.speed) || is_non_zero_1d_movement(state->y.speed); +} + +static bool should_be_working(struct behavior_mouse_move_data *data) { + return is_non_zero_2d_movement(&data->state); +} + +static void tick_work_cb(struct k_work *work) { + struct k_work_delayable *d_work = k_work_delayable_from_work(work); + struct behavior_mouse_move_data *data = + CONTAINER_OF(d_work, struct behavior_mouse_move_data, tick_work); + const struct device *dev = data->dev; + const struct behavior_mouse_move_config *cfg = dev->config; + + uint32_t timestamp = k_uptime_get(); + + LOG_INF("tick start times: %lld %lld %lld", data->state.x.start_time, data->state.y.start_time, + timestamp); + + struct vector2d move = update_movement_2d(cfg, &data->state, timestamp); + + int ret = 0; + bool have_x = is_non_zero_1d_movement(move.x); + bool have_y = is_non_zero_1d_movement(move.y); + if (have_x) { + ret = input_report_rel(dev, cfg->x_code, (int16_t)CLAMP(move.x, INT16_MIN, INT16_MAX), + !have_y, K_NO_WAIT); + } + if (have_y) { + ret = input_report_rel(dev, cfg->y_code, (int16_t)CLAMP(move.y, INT16_MIN, INT16_MAX), true, + K_NO_WAIT); + } + + if (should_be_working(data)) { + k_work_schedule(&data->tick_work, K_MSEC(CONFIG_ZMK_MOUSE_TICK_DURATION)); + } +} + +static void set_start_times_for_activity(struct movement_state_2d *state) { + if (state->x.speed != 0 && state->x.start_time == 0) { + state->x.start_time = k_uptime_get(); + } + + if (state->y.speed != 0 && state->y.start_time == 0) { + state->y.start_time = k_uptime_get(); + } +} + +static void update_work_scheduling(const struct device *dev) { + struct behavior_mouse_move_data *data = dev->data; + + set_start_times_for_activity(&data->state); + + if (should_be_working(data)) { + k_work_schedule(&data->tick_work, K_MSEC(CONFIG_ZMK_MOUSE_TICK_DURATION)); + } else { + k_work_cancel_delayable(&data->tick_work); + } +} + +int zmk_input_synth_pointer_adjust_speed(const struct device *dev, int16_t dx, int16_t dy) { + struct behavior_mouse_move_data *data = dev->data; + + LOG_DBG("Adjusting: %d %d", dx, dy); + data->state.x.speed += dx; + data->state.y.speed += dy; + + LOG_DBG("After: %d %d", data->state.x.speed, data->state.y.speed); + + update_work_scheduling(dev); + + return 0; +} + +// static void process_key_state(const struct device *dev, int32_t val, bool pressed) { +// for (int i = 0; i < ZMK_HID_MOUSE_NUM_BUTTONS; i++) { +// if (val & BIT(i)) { +// WRITE_BIT(val, i, 0); +// input_report_key(dev, INPUT_BTN_0 + i, pressed ? 1 : 0, val == 0, K_FOREVER); +// } +// } +// } + +static int behavior_mouse_move_init(const struct device *dev) { + struct behavior_mouse_move_data *data = dev->data; + + data->dev = dev; + k_work_init_delayable(&data->tick_work, tick_work_cb); + + return 0; +}; + +static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + + const struct device *behavior_dev = device_get_binding(binding->behavior_dev); + + LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); + + int16_t x = MOVE_X_DECODE(binding->param1); + int16_t y = MOVE_Y_DECODE(binding->param1); + + zmk_input_synth_pointer_adjust_speed(behavior_dev, x, y); + return 0; +} + +static int on_keymap_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + const struct device *behavior_dev = device_get_binding(binding->behavior_dev); + + LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); + + int16_t x = MOVE_X_DECODE(binding->param1); + int16_t y = MOVE_Y_DECODE(binding->param1); + + zmk_input_synth_pointer_adjust_speed(behavior_dev, -x, -y); + return 0; +} + +static const struct behavior_driver_api behavior_mouse_move_driver_api = { + .binding_pressed = on_keymap_binding_pressed, .binding_released = on_keymap_binding_released}; + +#define KP_INST(n) \ + static struct behavior_mouse_move_data behavior_mouse_move_data_##n = {}; \ + static struct behavior_mouse_move_config behavior_mouse_move_config_##n = { \ + .x_code = DT_INST_PROP(n, x_code), \ + .y_code = DT_INST_PROP(n, y_code), \ + .delay_ms = DT_INST_PROP_OR(n, delay_ms, 0), \ + .time_to_max_speed_ms = DT_INST_PROP(n, time_to_max_speed_ms), \ + .acceleration_exponent = DT_INST_PROP_OR(n, acceleration_exponent, 1), \ + }; \ + DEVICE_DT_INST_DEFINE(n, behavior_mouse_move_init, NULL, &behavior_mouse_move_data_##n, \ + &behavior_mouse_move_config_##n, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_mouse_move_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(KP_INST) diff --git a/app/src/behaviors/behavior_none.c b/app/src/behaviors/behavior_none.c index 613ecbad7e61..3b8eb27e97cd 100644 --- a/app/src/behaviors/behavior_none.c +++ b/app/src/behaviors/behavior_none.c @@ -33,7 +33,7 @@ static const struct behavior_driver_api behavior_none_driver_api = { .binding_released = on_keymap_binding_released, }; -DEVICE_DT_INST_DEFINE(0, behavior_none_init, NULL, NULL, NULL, APPLICATION, +DEVICE_DT_INST_DEFINE(0, behavior_none_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_none_driver_api); #endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ diff --git a/app/src/behaviors/behavior_outputs.c b/app/src/behaviors/behavior_outputs.c index 6ae81a0fdd7d..5bf4b87b7e08 100644 --- a/app/src/behaviors/behavior_outputs.c +++ b/app/src/behaviors/behavior_outputs.c @@ -42,7 +42,7 @@ static const struct behavior_driver_api behavior_outputs_driver_api = { .binding_pressed = on_keymap_binding_pressed, }; -DEVICE_DT_INST_DEFINE(0, behavior_out_init, NULL, NULL, NULL, APPLICATION, +DEVICE_DT_INST_DEFINE(0, behavior_out_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_outputs_driver_api); #endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ diff --git a/app/src/behaviors/behavior_reset.c b/app/src/behaviors/behavior_reset.c index 0b983c847096..0f47c09cef50 100644 --- a/app/src/behaviors/behavior_reset.c +++ b/app/src/behaviors/behavior_reset.c @@ -44,7 +44,7 @@ static const struct behavior_driver_api behavior_reset_driver_api = { static const struct behavior_reset_config behavior_reset_config_##n = { \ .type = DT_INST_PROP(n, type)}; \ DEVICE_DT_INST_DEFINE(n, behavior_reset_init, NULL, NULL, &behavior_reset_config_##n, \ - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ &behavior_reset_driver_api); DT_INST_FOREACH_STATUS_OKAY(RST_INST) diff --git a/app/src/behaviors/behavior_rgb_underglow.c b/app/src/behaviors/behavior_rgb_underglow.c index 0af07f8146d8..84926c3e4ece 100644 --- a/app/src/behaviors/behavior_rgb_underglow.c +++ b/app/src/behaviors/behavior_rgb_underglow.c @@ -149,7 +149,7 @@ static const struct behavior_driver_api behavior_rgb_underglow_driver_api = { .locality = BEHAVIOR_LOCALITY_GLOBAL, }; -DEVICE_DT_INST_DEFINE(0, behavior_rgb_underglow_init, NULL, NULL, NULL, APPLICATION, +DEVICE_DT_INST_DEFINE(0, behavior_rgb_underglow_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_rgb_underglow_driver_api); #endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ diff --git a/app/src/behaviors/behavior_sensor_rotate.c b/app/src/behaviors/behavior_sensor_rotate.c index 822bc206b02b..63eee9ded97d 100644 --- a/app/src/behaviors/behavior_sensor_rotate.c +++ b/app/src/behaviors/behavior_sensor_rotate.c @@ -36,7 +36,7 @@ static int behavior_sensor_rotate_init(const struct device *dev) { return 0; }; }; \ static struct behavior_sensor_rotate_data behavior_sensor_rotate_data_##n = {}; \ DEVICE_DT_INST_DEFINE(n, behavior_sensor_rotate_init, NULL, &behavior_sensor_rotate_data_##n, \ - &behavior_sensor_rotate_config_##n, APPLICATION, \ + &behavior_sensor_rotate_config_##n, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ &behavior_sensor_rotate_driver_api); diff --git a/app/src/behaviors/behavior_sensor_rotate_var.c b/app/src/behaviors/behavior_sensor_rotate_var.c index e6d20cab9d16..9907f75483e6 100644 --- a/app/src/behaviors/behavior_sensor_rotate_var.c +++ b/app/src/behaviors/behavior_sensor_rotate_var.c @@ -28,7 +28,7 @@ static int behavior_sensor_rotate_var_init(const struct device *dev) { return 0; static struct behavior_sensor_rotate_data behavior_sensor_rotate_var_data_##n = {}; \ DEVICE_DT_INST_DEFINE( \ n, behavior_sensor_rotate_var_init, NULL, &behavior_sensor_rotate_var_data_##n, \ - &behavior_sensor_rotate_var_config_##n, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + &behavior_sensor_rotate_var_config_##n, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ &behavior_sensor_rotate_var_driver_api); DT_INST_FOREACH_STATUS_OKAY(SENSOR_ROTATE_VAR_INST) diff --git a/app/src/behaviors/behavior_sticky_key.c b/app/src/behaviors/behavior_sticky_key.c index 6697b9b1bbb1..9d13570dbe0a 100644 --- a/app/src/behaviors/behavior_sticky_key.c +++ b/app/src/behaviors/behavior_sticky_key.c @@ -258,8 +258,9 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { } void behavior_sticky_key_timer_handler(struct k_work *item) { + struct k_work_delayable *d_work = k_work_delayable_from_work(item); struct active_sticky_key *sticky_key = - CONTAINER_OF(item, struct active_sticky_key, release_timer); + CONTAINER_OF(d_work, struct active_sticky_key, release_timer); if (sticky_key->position == ZMK_BHV_STICKY_KEY_POSITION_FREE) { return; } @@ -294,7 +295,7 @@ static struct behavior_sticky_key_data behavior_sticky_key_data; .quick_release = DT_INST_PROP(n, quick_release), \ }; \ DEVICE_DT_INST_DEFINE(n, behavior_sticky_key_init, NULL, &behavior_sticky_key_data, \ - &behavior_sticky_key_config_##n, APPLICATION, \ + &behavior_sticky_key_config_##n, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_sticky_key_driver_api); DT_INST_FOREACH_STATUS_OKAY(KP_INST) diff --git a/app/src/behaviors/behavior_tap_dance.c b/app/src/behaviors/behavior_tap_dance.c index fc685124860f..2c1f35ce907f 100644 --- a/app/src/behaviors/behavior_tap_dance.c +++ b/app/src/behaviors/behavior_tap_dance.c @@ -169,7 +169,9 @@ static int on_tap_dance_binding_released(struct zmk_behavior_binding *binding, } void behavior_tap_dance_timer_handler(struct k_work *item) { - struct active_tap_dance *tap_dance = CONTAINER_OF(item, struct active_tap_dance, release_timer); + struct k_work_delayable *d_work = k_work_delayable_from_work(item); + struct active_tap_dance *tap_dance = + CONTAINER_OF(d_work, struct active_tap_dance, release_timer); if (tap_dance->position == ZMK_BHV_TAP_DANCE_POSITION_FREE) { return; } @@ -251,7 +253,7 @@ static int behavior_tap_dance_init(const struct device *dev) { .behaviors = behavior_tap_dance_config_##n##_bindings, \ .behavior_count = DT_INST_PROP_LEN(n, bindings)}; \ DEVICE_DT_INST_DEFINE(n, behavior_tap_dance_init, NULL, NULL, &behavior_tap_dance_config_##n, \ - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ &behavior_tap_dance_driver_api); DT_INST_FOREACH_STATUS_OKAY(KP_INST) diff --git a/app/src/behaviors/behavior_to_layer.c b/app/src/behaviors/behavior_to_layer.c index c05b83eab94f..24b3b4853757 100644 --- a/app/src/behaviors/behavior_to_layer.c +++ b/app/src/behaviors/behavior_to_layer.c @@ -37,7 +37,7 @@ static const struct behavior_driver_api behavior_to_driver_api = { .binding_released = to_keymap_binding_released, }; -DEVICE_DT_INST_DEFINE(0, behavior_to_init, NULL, NULL, NULL, APPLICATION, +DEVICE_DT_INST_DEFINE(0, behavior_to_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_to_driver_api); #endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ diff --git a/app/src/behaviors/behavior_toggle_layer.c b/app/src/behaviors/behavior_toggle_layer.c index 73a700eda5ff..5c2958aba4c2 100644 --- a/app/src/behaviors/behavior_toggle_layer.c +++ b/app/src/behaviors/behavior_toggle_layer.c @@ -44,6 +44,6 @@ static const struct behavior_tog_config behavior_tog_config = {}; static struct behavior_tog_data behavior_tog_data; DEVICE_DT_INST_DEFINE(0, behavior_tog_init, NULL, &behavior_tog_data, &behavior_tog_config, - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_tog_driver_api); + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_tog_driver_api); #endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ diff --git a/app/src/behaviors/behavior_transparent.c b/app/src/behaviors/behavior_transparent.c index eeb2242db6bb..0baeb05fca33 100644 --- a/app/src/behaviors/behavior_transparent.c +++ b/app/src/behaviors/behavior_transparent.c @@ -33,7 +33,7 @@ static const struct behavior_driver_api behavior_transparent_driver_api = { .binding_released = on_keymap_binding_released, }; -DEVICE_DT_INST_DEFINE(0, behavior_transparent_init, NULL, NULL, NULL, APPLICATION, +DEVICE_DT_INST_DEFINE(0, behavior_transparent_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_transparent_driver_api); #endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ diff --git a/app/src/ble.c b/app/src/ble.c index 8c991c54b803..83eb6bc9abc0 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #if IS_ENABLED(CONFIG_SETTINGS) @@ -98,7 +98,7 @@ bool zmk_ble_active_profile_is_open() { } void set_profile_address(uint8_t index, const bt_addr_le_t *addr) { - char setting_name[15]; + char setting_name[17]; char addr_str[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); @@ -603,7 +603,7 @@ static void zmk_ble_ready(int err) { update_advertising(); } -static int zmk_ble_init(const struct device *_arg) { +static int zmk_ble_init(void) { int err = bt_enable(NULL); if (err) { diff --git a/app/src/combo.c b/app/src/combo.c index 0d5c2a6e237b..d36f7fddcf87 100644 --- a/app/src/combo.c +++ b/app/src/combo.c @@ -537,7 +537,7 @@ ZMK_SUBSCRIPTION(combo, zmk_keycode_state_changed); DT_INST_FOREACH_CHILD(0, COMBO_INST) -static int combo_init() { +static int combo_init(void) { k_work_init_delayable(&timeout_task, combo_timeout_handler); DT_INST_FOREACH_CHILD(0, INITIALIZE_COMBO); return 0; diff --git a/app/src/display/Kconfig b/app/src/display/Kconfig index a20294810805..3e17ff764350 100644 --- a/app/src/display/Kconfig +++ b/app/src/display/Kconfig @@ -29,11 +29,11 @@ endchoice config LV_MEM_CUSTOM default y -config LV_Z_MEM_POOL_MIN_SIZE - default 32 +# config LV_Z_MEM_POOL_MIN_SIZE +# default 32 -config LV_Z_MEM_POOL_MAX_SIZE - default 8192 +# config LV_Z_MEM_POOL_MAX_SIZE +# default 8192 choice ZMK_DISPLAY_STATUS_SCREEN prompt "Default status screen for displays" diff --git a/app/src/endpoints.c b/app/src/endpoints.c index 098e04e27769..cef273be0bcd 100644 --- a/app/src/endpoints.c +++ b/app/src/endpoints.c @@ -302,7 +302,7 @@ static struct zmk_endpoint_instance get_selected_instance(void) { return instance; } -static int zmk_endpoints_init(const struct device *_arg) { +static int zmk_endpoints_init(void) { #if IS_ENABLED(CONFIG_SETTINGS) settings_subsys_init(); diff --git a/app/src/hid.c b/app/src/hid.c index 1ea2afb16216..8a0589573315 100644 --- a/app/src/hid.c +++ b/app/src/hid.c @@ -27,8 +27,9 @@ static uint8_t keys_held = 0; #if IS_ENABLED(CONFIG_ZMK_MOUSE) -static struct zmk_hid_mouse_report mouse_report = {.report_id = ZMK_HID_REPORT_ID_MOUSE, - .body = {.buttons = 0}}; +static struct zmk_hid_mouse_report mouse_report = { + .report_id = ZMK_HID_REPORT_ID_MOUSE, + .body = {.buttons = 0, .d_x = 0, .d_y = 0, .d_scroll_y = 0}}; #endif // IS_ENABLED(CONFIG_ZMK_MOUSE) @@ -426,7 +427,37 @@ int zmk_hid_mouse_buttons_release(zmk_mouse_button_flags_t buttons) { } return 0; } -void zmk_hid_mouse_clear() { memset(&mouse_report.body, 0, sizeof(mouse_report.body)); } + +void zmk_hid_mouse_movement_set(int16_t x, int16_t y) { + mouse_report.body.d_x = x; + mouse_report.body.d_y = y; + LOG_DBG("Mouse movement set to %d/%d", mouse_report.body.d_x, mouse_report.body.d_y); +} + +void zmk_hid_mouse_movement_update(int16_t x, int16_t y) { + mouse_report.body.d_x += x; + mouse_report.body.d_y += y; + LOG_DBG("Mouse movement updated to %d/%d", mouse_report.body.d_x, mouse_report.body.d_y); +} + +void zmk_hid_mouse_scroll_set(int8_t x, int8_t y) { + mouse_report.body.d_scroll_x = x; + mouse_report.body.d_scroll_y = y; + LOG_DBG("Mouse scroll set to %d/%d", mouse_report.body.d_scroll_x, + mouse_report.body.d_scroll_y); +} + +void zmk_hid_mouse_scroll_update(int8_t x, int8_t y) { + mouse_report.body.d_scroll_x += x; + mouse_report.body.d_scroll_y += y; + LOG_DBG("Mouse scroll updated to X: %d/%d", mouse_report.body.d_scroll_x, + mouse_report.body.d_scroll_y); +} + +void zmk_hid_mouse_clear() { + LOG_DBG("Mouse report cleared"); + memset(&mouse_report.body, 0, sizeof(mouse_report.body)); +} #endif // IS_ENABLED(CONFIG_ZMK_MOUSE) diff --git a/app/src/hog.c b/app/src/hog.c index 89a903cb9671..82fe7598c2cd 100644 --- a/app/src/hog.c +++ b/app/src/hog.c @@ -316,32 +316,29 @@ void send_mouse_report_callback(struct k_work *work) { } }; -int zmk_hog_send_mouse_report(struct zmk_hid_mouse_report_body *report) { - struct bt_conn *conn = destination_connection(); - if (conn == NULL) { - return 1; - } - - struct bt_gatt_notify_params notify_params = { - .attr = &hog_svc.attrs[13], - .data = report, - .len = sizeof(*report), - }; +K_WORK_DEFINE(hog_mouse_work, send_mouse_report_callback); - int err = bt_gatt_notify_cb(conn, ¬ify_params); +int zmk_hog_send_mouse_report(struct zmk_hid_mouse_report_body *report) { + int err = k_msgq_put(&zmk_hog_mouse_msgq, report, K_NO_WAIT); if (err) { - LOG_DBG("Error notifying %d", err); - return err; + switch (err) { + case -EAGAIN: { + LOG_WRN("Mouse message queue full, dropping report"); + return err; + } + default: + LOG_WRN("Failed to queue mouse report to send (%d)", err); + return err; + } } - bt_conn_unref(conn); + k_work_submit_to_queue(&hog_work_q, &hog_mouse_work); return 0; }; - #endif // IS_ENABLED(CONFIG_ZMK_MOUSE) -int zmk_hog_init(const struct device *_arg) { +int zmk_hog_init(void) { static const struct k_work_queue_config queue_config = {.name = "HID Over GATT Send Work"}; k_work_queue_start(&hog_work_q, hog_q_stack, K_THREAD_STACK_SIZEOF(hog_q_stack), CONFIG_ZMK_BLE_THREAD_PRIORITY, &queue_config); diff --git a/app/src/main.c b/app/src/main.c index 3fd6b116608f..b5276c1a00fd 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -17,14 +17,23 @@ LOG_MODULE_REGISTER(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include -void main(void) { +#ifdef CONFIG_ZMK_MOUSE +#include +#endif /* CONFIG_ZMK_MOUSE */ + +int main(void) { LOG_INF("Welcome to ZMK!\n"); if (zmk_kscan_init(DEVICE_DT_GET(ZMK_MATRIX_NODE_ID)) != 0) { - return; + return -ENOTSUP; } #ifdef CONFIG_ZMK_DISPLAY zmk_display_init(); #endif /* CONFIG_ZMK_DISPLAY */ + +#ifdef CONFIG_ZMK_MOUSE + zmk_mouse_init(); +#endif /* CONFIG_ZMK_MOUSE */ + return 0; } diff --git a/app/src/mouse.c b/app/src/mouse.c deleted file mode 100644 index c1b9ac0261e2..000000000000 --- a/app/src/mouse.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2021 The ZMK Contributors - * - * SPDX-License-Identifier: MIT - */ - -#include -#include - -LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); - -#include -#include -#include -#include - -static void listener_mouse_button_pressed(const struct zmk_mouse_button_state_changed *ev) { - LOG_DBG("buttons: 0x%02X", ev->buttons); - zmk_hid_mouse_buttons_press(ev->buttons); - zmk_endpoints_send_mouse_report(); -} - -static void listener_mouse_button_released(const struct zmk_mouse_button_state_changed *ev) { - LOG_DBG("buttons: 0x%02X", ev->buttons); - zmk_hid_mouse_buttons_release(ev->buttons); - zmk_endpoints_send_mouse_report(); -} - -int mouse_listener(const zmk_event_t *eh) { - const struct zmk_mouse_button_state_changed *mbt_ev = as_zmk_mouse_button_state_changed(eh); - if (mbt_ev) { - if (mbt_ev->state) { - listener_mouse_button_pressed(mbt_ev); - } else { - listener_mouse_button_released(mbt_ev); - } - return 0; - } - return 0; -} - -ZMK_LISTENER(mouse_listener, mouse_listener); -ZMK_SUBSCRIPTION(mouse_listener, zmk_mouse_button_state_changed); diff --git a/app/src/mouse/Kconfig b/app/src/mouse/Kconfig new file mode 100644 index 000000000000..8eb64f4cc847 --- /dev/null +++ b/app/src/mouse/Kconfig @@ -0,0 +1,40 @@ +# Copyright (c) 2023 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config ZMK_MOUSE + bool "Enable ZMK mouse emulation" + default n + select INPUT + select INPUT_THREAD_PRIORITY_OVERRIDE + +config ZMK_MOUSE_TICK_DURATION + int "Mouse tick duration in ms" + default 16 + +if ZMK_MOUSE + +choice ZMK_MOUSE_WORK_QUEUE + prompt "Work queue selection for mouse events" + default ZMK_MOUSE_WORK_QUEUE_DEDICATED + +config ZMK_MOUSE_WORK_QUEUE_SYSTEM + bool "Use default system work queue for mouse events" + +config ZMK_MOUSE_WORK_QUEUE_DEDICATED + bool "Use dedicated work queue for mouse events" + +endchoice + +if ZMK_MOUSE_WORK_QUEUE_DEDICATED + +config ZMK_MOUSE_DEDICATED_THREAD_STACK_SIZE + int "Stack size for dedicated mouse thread/queue" + default 2048 + +config ZMK_MOUSE_DEDICATED_THREAD_PRIORITY + int "Thread priority for dedicated mouse thread/queue" + default 3 + +endif # ZMK_MOUSE_WORK_QUEUE_DEDICATED + +endif diff --git a/app/src/mouse/hid_input_listener.c b/app/src/mouse/hid_input_listener.c new file mode 100644 index 000000000000..712bb5675c21 --- /dev/null +++ b/app/src/mouse/hid_input_listener.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include + +#include +#include +#include +#include + +void handle_rel_code(struct input_event *evt) { + switch (evt->code) { + case INPUT_REL_X: + zmk_hid_mouse_movement_update(evt->value, 0); + break; + case INPUT_REL_Y: + zmk_hid_mouse_movement_update(0, evt->value); + break; + case INPUT_REL_WHEEL: + zmk_hid_mouse_scroll_update(0, evt->value); + break; + case INPUT_REL_HWHEEL: + zmk_hid_mouse_scroll_update(evt->value, 0); + break; + default: + break; + } +} + +void handle_key_code(struct input_event *evt) { + int8_t btn; + + switch (evt->code) { + case INPUT_BTN_0: + case INPUT_BTN_1: + case INPUT_BTN_2: + case INPUT_BTN_3: + case INPUT_BTN_4: + btn = evt->code - INPUT_BTN_0; + if (evt->value > 0) { + zmk_hid_mouse_button_press(btn); + } else { + zmk_hid_mouse_button_release(btn); + } + break; + default: + break; + } +} + +static void swap_xy(struct input_event *evt) { + switch (evt->code) { + case INPUT_REL_X: + evt->code = INPUT_REL_Y; + break; + case INPUT_REL_Y: + evt->code = INPUT_REL_X; + break; + } +} + +static void filter_with_input_config(struct input_event *evt) { + if (!evt->dev) { + return; + } + + const struct zmk_input_config *cfg = zmk_input_config_get_for_device(evt->dev); + + if (!cfg) { + return; + } + + if (cfg->xy_swap) { + swap_xy(evt); + } + + if ((cfg->x_invert && evt->code == INPUT_REL_X) || + (cfg->y_invert && evt->code == INPUT_REL_Y)) { + evt->value = -(evt->value); + } + + evt->value = (int16_t)((evt->value * cfg->scale_multiplier) / cfg->scale_divisor); +} + +void input_handler(struct input_event *evt) { + // First, filter to update the event data as needed. + filter_with_input_config(evt); + + switch (evt->type) { + case INPUT_EV_REL: + handle_rel_code(evt); + break; + case INPUT_EV_KEY: + handle_key_code(evt); + break; + } + + if (evt->sync) { + zmk_endpoints_send_mouse_report(); + zmk_hid_mouse_scroll_set(0, 0); + zmk_hid_mouse_movement_set(0, 0); + } +} + +INPUT_CALLBACK_DEFINE(NULL, input_handler); diff --git a/app/src/mouse/input_config.c b/app/src/mouse/input_config.c new file mode 100644 index 000000000000..745fb49bac5e --- /dev/null +++ b/app/src/mouse/input_config.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#define DT_DRV_COMPAT zmk_input_configs + +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) + +#define CHILD_CONFIG(inst) \ + { \ + .dev = DEVICE_DT_GET(DT_PHANDLE(inst, device)), \ + .xy_swap = DT_PROP(inst, xy_swap), \ + .x_invert = DT_PROP(inst, x_invert), \ + .y_invert = DT_PROP(inst, y_invert), \ + .scale_multiplier = DT_PROP(inst, scale_multiplier), \ + .scale_divisor = DT_PROP(inst, scale_divisor), \ + }, + +const struct zmk_input_config configs[] = {DT_INST_FOREACH_CHILD(0, CHILD_CONFIG)}; + +const struct zmk_input_config *zmk_input_config_get_for_device(const struct device *dev) { + for (int i = 0; i < ARRAY_SIZE(configs); i++) { + if (configs[i].dev == dev) { + return &configs[i]; + } + } + + return NULL; +} + +#else + +const struct zmk_input_config *zmk_input_config_get_for_device(const struct device *dev) { + return NULL; +} + +#endif \ No newline at end of file diff --git a/app/src/mouse/main.c b/app/src/mouse/main.c new file mode 100644 index 000000000000..e1227425ea58 --- /dev/null +++ b/app/src/mouse/main.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#if IS_ENABLED(CONFIG_ZMK_MOUSE_WORK_QUEUE_DEDICATED) +K_THREAD_STACK_DEFINE(mouse_work_stack_area, CONFIG_ZMK_MOUSE_DEDICATED_THREAD_STACK_SIZE); +static struct k_work_q mouse_work_q; +#endif + +struct k_work_q *zmk_mouse_work_q() { +#if IS_ENABLED(CONFIG_ZMK_MOUSE_WORK_QUEUE_DEDICATED) + return &mouse_work_q; +#else + return &k_sys_work_q; +#endif +} + +int zmk_mouse_init(void) { +#if IS_ENABLED(CONFIG_ZMK_MOUSE_WORK_QUEUE_DEDICATED) + k_work_queue_start(&mouse_work_q, mouse_work_stack_area, + K_THREAD_STACK_SIZEOF(mouse_work_stack_area), + CONFIG_ZMK_MOUSE_DEDICATED_THREAD_PRIORITY, NULL); +#endif + return 0; +} \ No newline at end of file diff --git a/app/src/rgb_underglow.c b/app/src/rgb_underglow.c index b80d403953f5..febe80154807 100644 --- a/app/src/rgb_underglow.c +++ b/app/src/rgb_underglow.c @@ -239,7 +239,7 @@ static void zmk_rgb_underglow_save_state_work() { static struct k_work_delayable underglow_save_work; #endif -static int zmk_rgb_underglow_init(const struct device *_arg) { +static int zmk_rgb_underglow_init(void) { led_strip = DEVICE_DT_GET(STRIP_CHOSEN); #if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_EXT_POWER) diff --git a/app/src/sensors.c b/app/src/sensors.c index 60f2bd2a33f8..34fd49e28bbb 100644 --- a/app/src/sensors.c +++ b/app/src/sensors.c @@ -140,7 +140,7 @@ static void zmk_sensors_init_item(uint8_t i) { #define SENSOR_INIT(idx, _t) zmk_sensors_init_item(idx); -static int zmk_sensors_init(const struct device *_arg) { +static int zmk_sensors_init(void) { LISTIFY(ZMK_KEYMAP_SENSORS_LEN, SENSOR_INIT, (), 0) return 0; diff --git a/app/src/split/bluetooth/central.c b/app/src/split/bluetooth/central.c index 860e89a5f3ef..b8bc75a73799 100644 --- a/app/src/split/bluetooth/central.c +++ b/app/src/split/bluetooth/central.c @@ -685,7 +685,7 @@ int zmk_split_bt_invoke_behavior(uint8_t source, struct zmk_behavior_binding *bi return split_bt_invoke_behavior_payload(wrapper); } -int zmk_split_bt_central_init(const struct device *_arg) { +static int zmk_split_bt_central_init(void) { k_work_queue_start(&split_central_split_run_q, split_central_split_run_q_stack, K_THREAD_STACK_SIZEOF(split_central_split_run_q_stack), CONFIG_ZMK_BLE_THREAD_PRIORITY, NULL); diff --git a/app/src/split/bluetooth/peripheral.c b/app/src/split/bluetooth/peripheral.c index 1d649f712219..3b94aab1ecae 100644 --- a/app/src/split/bluetooth/peripheral.c +++ b/app/src/split/bluetooth/peripheral.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #if IS_ENABLED(CONFIG_SETTINGS) @@ -134,7 +134,7 @@ static struct bt_conn_cb conn_callbacks = { bool zmk_split_bt_peripheral_is_connected() { return is_connected; } -static int zmk_peripheral_ble_init(const struct device *_arg) { +static int zmk_peripheral_ble_init(void) { int err = bt_enable(NULL); if (err) { diff --git a/app/src/split/bluetooth/service.c b/app/src/split/bluetooth/service.c index 620df53e11ca..fc174d2377a9 100644 --- a/app/src/split/bluetooth/service.c +++ b/app/src/split/bluetooth/service.c @@ -227,7 +227,7 @@ int zmk_split_bt_sensor_triggered(uint8_t sensor_index, } #endif /* ZMK_KEYMAP_HAS_SENSORS */ -int service_init(const struct device *_arg) { +static int service_init(void) { static const struct k_work_queue_config queue_config = { .name = "Split Peripheral Notification Queue"}; k_work_queue_start(&service_work_q, service_q_stack, K_THREAD_STACK_SIZEOF(service_q_stack), diff --git a/app/src/usb.c b/app/src/usb.c index 9d27900c3c6e..da4b28103dff 100644 --- a/app/src/usb.c +++ b/app/src/usb.c @@ -65,7 +65,7 @@ void usb_status_cb(enum usb_dc_status_code status, const uint8_t *params) { k_work_submit(&usb_status_notifier_work); }; -static int zmk_usb_init(const struct device *_arg) { +static int zmk_usb_init(void) { int usb_enable_ret; usb_enable_ret = usb_enable(usb_status_cb); diff --git a/app/src/usb_hid.c b/app/src/usb_hid.c index fd58c14bf4a3..5b472721c1ec 100644 --- a/app/src/usb_hid.c +++ b/app/src/usb_hid.c @@ -142,7 +142,7 @@ int zmk_usb_hid_send_mouse_report() { } #endif // IS_ENABLED(CONFIG_ZMK_MOUSE) -static int zmk_usb_hid_init(const struct device *_arg) { +static int zmk_usb_hid_init(void) { hid_dev = device_get_binding("HID_0"); if (hid_dev == NULL) { LOG_ERR("Unable to locate HID device"); diff --git a/app/src/wpm.c b/app/src/wpm.c index 00a5942ecb8b..d906665aa885 100644 --- a/app/src/wpm.c +++ b/app/src/wpm.c @@ -72,7 +72,7 @@ void wpm_expiry_function() { k_work_submit(&wpm_work); } K_TIMER_DEFINE(wpm_timer, wpm_expiry_function, NULL); -int wpm_init() { +static int wpm_init(void) { wpm_state = 0; wpm_update_counter = 0; k_timer_start(&wpm_timer, K_SECONDS(WPM_UPDATE_INTERVAL_SECONDS), diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/events.patterns b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/events.patterns new file mode 100644 index 000000000000..812126fb8285 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/events.patterns @@ -0,0 +1 @@ +s/.*hid_mouse_//p \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/keycode_events.snapshot b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/keycode_events.snapshot new file mode 100644 index 000000000000..99fa148876f8 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/keycode_events.snapshot @@ -0,0 +1,22 @@ +movement_update: Mouse movement updated to -1/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -3/0 +movement_update: Mouse movement updated to -3/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -3/0 +movement_update: Mouse movement updated to -3/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -5/0 +movement_update: Mouse movement updated to -5/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -5/0 +movement_update: Mouse movement updated to -5/-5 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-5 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/native_posix_64.keymap b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/native_posix_64.keymap new file mode 100644 index 000000000000..b1ddbc1d8d0d --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/native_posix_64.keymap @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &mmv MOVE_LEFT &mmv MOVE_UP + &none &none + >; + }; + }; + + input_configs { + compatible = "zmk,input-configs"; + + mmv { + device = <&mmv>; + scale-multiplier = <5>; + scale-divisor = <3>; + }; + }; +}; + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(0,1,100) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/events.patterns b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/events.patterns new file mode 100644 index 000000000000..812126fb8285 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/events.patterns @@ -0,0 +1 @@ +s/.*hid_mouse_//p \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/keycode_events.snapshot b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/keycode_events.snapshot new file mode 100644 index 000000000000..94faacceb619 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/keycode_events.snapshot @@ -0,0 +1,22 @@ +movement_update: Mouse movement updated to 1/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 2/0 +movement_update: Mouse movement updated to 2/2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 2/0 +movement_update: Mouse movement updated to 2/2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 3/0 +movement_update: Mouse movement updated to 3/2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 3/0 +movement_update: Mouse movement updated to 3/3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/native_posix_64.keymap b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/native_posix_64.keymap new file mode 100644 index 000000000000..4767e0ac55e5 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/native_posix_64.keymap @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &mmv MOVE_LEFT &mmv MOVE_UP + &none &none + >; + }; + }; + + input_configs { + compatible = "zmk,input-configs"; + + mmv { + device = <&mmv>; + x-invert; + y-invert; + }; + }; +}; + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(0,1,100) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/events.patterns b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/events.patterns new file mode 100644 index 000000000000..812126fb8285 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/events.patterns @@ -0,0 +1 @@ +s/.*hid_mouse_//p \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/keycode_events.snapshot b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/keycode_events.snapshot new file mode 100644 index 000000000000..5ca5300c1a7e --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/keycode_events.snapshot @@ -0,0 +1,22 @@ +movement_update: Mouse movement updated to 0/-1 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-2 +movement_update: Mouse movement updated to -2/-2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-2 +movement_update: Mouse movement updated to -2/-2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-3 +movement_update: Mouse movement updated to -2/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-3 +movement_update: Mouse movement updated to -3/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -3/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/native_posix_64.keymap b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/native_posix_64.keymap new file mode 100644 index 000000000000..153270231fad --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/native_posix_64.keymap @@ -0,0 +1,37 @@ +#include +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &mmv MOVE_LEFT &mmv MOVE_UP + &none &none + >; + }; + }; + + input_configs { + compatible = "zmk,input-configs"; + + mmv { + device = <&mmv>; + xy-swap; + }; + }; +}; + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(0,1,100) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/move_diagonal/events.patterns b/app/tests/mouse-keys/mouse-move/move_diagonal/events.patterns new file mode 100644 index 000000000000..812126fb8285 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/move_diagonal/events.patterns @@ -0,0 +1 @@ +s/.*hid_mouse_//p \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/move_diagonal/keycode_events.snapshot b/app/tests/mouse-keys/mouse-move/move_diagonal/keycode_events.snapshot new file mode 100644 index 000000000000..91c4f16b9c03 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/move_diagonal/keycode_events.snapshot @@ -0,0 +1,22 @@ +movement_update: Mouse movement updated to -1/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -2/0 +movement_update: Mouse movement updated to -2/-2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -2/0 +movement_update: Mouse movement updated to -2/-2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -3/0 +movement_update: Mouse movement updated to -3/-2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -3/0 +movement_update: Mouse movement updated to -3/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 diff --git a/app/tests/mouse-keys/mouse-move/move_diagonal/native_posix_64.keymap b/app/tests/mouse-keys/mouse-move/move_diagonal/native_posix_64.keymap new file mode 100644 index 000000000000..9dfa5b2a81c1 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/move_diagonal/native_posix_64.keymap @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &mmv MOVE_LEFT &mmv MOVE_UP + &none &none + >; + }; + }; +}; + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(0,1,100) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/move_x/events.patterns b/app/tests/mouse-keys/mouse-move/move_x/events.patterns new file mode 100644 index 000000000000..812126fb8285 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/move_x/events.patterns @@ -0,0 +1 @@ +s/.*hid_mouse_//p \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/move_x/keycode_events.snapshot b/app/tests/mouse-keys/mouse-move/move_x/keycode_events.snapshot new file mode 100644 index 000000000000..dfbc4a76eab4 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/move_x/keycode_events.snapshot @@ -0,0 +1,24 @@ +movement_update: Mouse movement updated to -1/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -2/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -2/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -3/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 1/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 2/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 2/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 3/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 diff --git a/app/tests/mouse-keys/mouse-move/move_x/native_posix_64.keymap b/app/tests/mouse-keys/mouse-move/move_x/native_posix_64.keymap new file mode 100644 index 000000000000..aacacebba907 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/move_x/native_posix_64.keymap @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &mmv MOVE_LEFT &mmv MOVE_RIGHT + &none &none + >; + }; + }; +}; + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,100) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(0,1,100) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/move_y/events.patterns b/app/tests/mouse-keys/mouse-move/move_y/events.patterns new file mode 100644 index 000000000000..812126fb8285 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/move_y/events.patterns @@ -0,0 +1 @@ +s/.*hid_mouse_//p \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/move_y/keycode_events.snapshot b/app/tests/mouse-keys/mouse-move/move_y/keycode_events.snapshot new file mode 100644 index 000000000000..4fd9a25202ca --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/move_y/keycode_events.snapshot @@ -0,0 +1,24 @@ +movement_update: Mouse movement updated to 0/-1 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/1 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 diff --git a/app/tests/mouse-keys/mouse-move/move_y/native_posix_64.keymap b/app/tests/mouse-keys/mouse-move/move_y/native_posix_64.keymap new file mode 100644 index 000000000000..1d914136e280 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/move_y/native_posix_64.keymap @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &mmv MOVE_UP &mmv MOVE_DOWN + &none &none + >; + }; + }; +}; + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,100) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(0,1,100) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/app/west.yml b/app/west.yml index ffa36ca36e98..e66a89c06e90 100644 --- a/app/west.yml +++ b/app/west.yml @@ -4,10 +4,12 @@ manifest: url-base: https://github.com/zephyrproject-rtos - name: zmkfirmware url-base: https://github.com/zmkfirmware + - name: petejohanson + url-base: https://github.com/petejohanson projects: - name: zephyr - remote: zmkfirmware - revision: v3.2.0+zmk-fixes + remote: petejohanson + revision: v3.5.0+zmk-fixes clone-depth: 1 import: name-blocklist: @@ -29,6 +31,5 @@ manifest: - openthread - edtt - trusted-firmware-m - - sof self: west-commands: scripts/west-commands.yml diff --git a/docs/docs/intro.md b/docs/docs/intro.md index d65ac46e405b..cfbcf6955f75 100644 --- a/docs/docs/intro.md +++ b/docs/docs/intro.md @@ -33,7 +33,7 @@ ZMK is currently missing some features found in other popular firmware. This tab | One Shot Keys | ✅ | ✅ | ✅ | | [Combo Keys](features/combos.md) | ✅ | | ✅ | | [Macros](behaviors/macros.md) | ✅ | ✅ | ✅ | -| Mouse Keys | 🚧 | ✅ | ✅ | +| Mouse Keys | ✅ | ✅ | ✅ | | Low Active Power Usage | ✅ | | | | Low Power Sleep States | ✅ | ✅ | | | [Low Power Mode (VCC Shutoff)](behaviors/power.md) | ✅ | ✅ | |