From f24a0bf9c8046a18183a0405178a19887b13da10 Mon Sep 17 00:00:00 2001 From: Joel Spadin Date: Fri, 26 Jan 2024 20:39:35 -0600 Subject: [PATCH 001/127] fix(shields): Add labels to all sensors nodes --- app/boards/shields/crbn/crbn.overlay | 2 +- app/boards/shields/leeloo/leeloo_common.dtsi | 2 +- app/boards/shields/leeloo_micro/leeloo_micro.dtsi | 2 +- app/boards/shields/murphpad/murphpad.keymap | 2 +- app/boards/shields/nibble/nibble.keymap | 2 +- app/boards/shields/snap/snap.keymap | 2 +- .../splitkb_aurora_helix/splitkb_aurora_helix.dtsi | 2 +- .../splitkb_aurora_sofle/splitkb_aurora_sofle.dtsi | 2 +- app/boards/shields/tidbit/tidbit.keymap | 2 +- app/boards/shields/tidbit/tidbit_19key.keymap | 2 +- app/boards/shields/waterfowl/waterfowl.dtsi | 2 +- app/boards/shields/zmk_uno/zmk_uno.overlay | 2 +- app/boards/shields/zmk_uno/zmk_uno_split.dtsi | 10 +++++----- 13 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/boards/shields/crbn/crbn.overlay b/app/boards/shields/crbn/crbn.overlay index 5cc9ec6c..9c68bd0b 100644 --- a/app/boards/shields/crbn/crbn.overlay +++ b/app/boards/shields/crbn/crbn.overlay @@ -46,7 +46,7 @@ status = "okay"; }; - sensors { + sensors: sensors { compatible = "zmk,keymap-sensors"; sensors = <&encoder>; }; diff --git a/app/boards/shields/leeloo/leeloo_common.dtsi b/app/boards/shields/leeloo/leeloo_common.dtsi index e4b29ad4..70896e1c 100644 --- a/app/boards/shields/leeloo/leeloo_common.dtsi +++ b/app/boards/shields/leeloo/leeloo_common.dtsi @@ -60,7 +60,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) status = "disabled"; }; - sensors { + sensors: sensors { compatible = "zmk,keymap-sensors"; sensors = <&left_encoder &right_encoder>; triggers-per-rotation = <30>; diff --git a/app/boards/shields/leeloo_micro/leeloo_micro.dtsi b/app/boards/shields/leeloo_micro/leeloo_micro.dtsi index e9958351..e0ca21cc 100644 --- a/app/boards/shields/leeloo_micro/leeloo_micro.dtsi +++ b/app/boards/shields/leeloo_micro/leeloo_micro.dtsi @@ -58,7 +58,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) steps = <60>; }; - sensors { + sensors: sensors { compatible = "zmk,keymap-sensors"; sensors = <&left_encoder &right_encoder>; triggers-per-rotation = <30>; diff --git a/app/boards/shields/murphpad/murphpad.keymap b/app/boards/shields/murphpad/murphpad.keymap index 069eeea3..fefafb00 100644 --- a/app/boards/shields/murphpad/murphpad.keymap +++ b/app/boards/shields/murphpad/murphpad.keymap @@ -45,7 +45,7 @@ }; }; - sensors { + sensors: sensors { compatible = "zmk,keymap-sensors"; sensors = <&encoder_1 &encoder_2>; triggers-per-rotation = <20>; diff --git a/app/boards/shields/nibble/nibble.keymap b/app/boards/shields/nibble/nibble.keymap index 8b25c5a4..f1b7512e 100644 --- a/app/boards/shields/nibble/nibble.keymap +++ b/app/boards/shields/nibble/nibble.keymap @@ -9,7 +9,7 @@ #include / { - sensors { + sensors: sensors { compatible = "zmk,keymap-sensors"; sensors = <&encoder_1>; triggers-per-rotation = <20>; diff --git a/app/boards/shields/snap/snap.keymap b/app/boards/shields/snap/snap.keymap index 8a95beda..b5c6396a 100644 --- a/app/boards/shields/snap/snap.keymap +++ b/app/boards/shields/snap/snap.keymap @@ -10,7 +10,7 @@ #include / { - sensors { + sensors: sensors { compatible = "zmk,keymap-sensors"; sensors = <&left_encoder &right_encoder>; triggers-per-rotation = <20>; 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 f586d6f6..c3a7b4ed 100644 --- a/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix.dtsi +++ b/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix.dtsi @@ -49,7 +49,7 @@ b-gpios = <&pro_micro 14 GPIO_PULL_UP>; }; - sensors { + sensors: sensors { compatible = "zmk,keymap-sensors"; sensors = <&left_encoder &right_encoder>; triggers-per-rotation = <36>; 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 872c3f69..77877ebe 100644 --- a/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle.dtsi +++ b/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle.dtsi @@ -49,7 +49,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) b-gpios = <&pro_micro 10 GPIO_PULL_UP>; }; - sensors { + sensors: sensors { compatible = "zmk,keymap-sensors"; sensors = <&left_encoder &right_encoder>; triggers-per-rotation = <36>; diff --git a/app/boards/shields/tidbit/tidbit.keymap b/app/boards/shields/tidbit/tidbit.keymap index a98a2eaa..f212bfe3 100644 --- a/app/boards/shields/tidbit/tidbit.keymap +++ b/app/boards/shields/tidbit/tidbit.keymap @@ -14,7 +14,7 @@ }; / { - sensors { + sensors: sensors { compatible = "zmk,keymap-sensors"; sensors = <&encoder_1_top_row>; triggers-per-rotation = <20>; diff --git a/app/boards/shields/tidbit/tidbit_19key.keymap b/app/boards/shields/tidbit/tidbit_19key.keymap index 1be71e7a..a2991a3f 100644 --- a/app/boards/shields/tidbit/tidbit_19key.keymap +++ b/app/boards/shields/tidbit/tidbit_19key.keymap @@ -15,7 +15,7 @@ }; / { - sensors { + sensors: sensors { compatible = "zmk,keymap-sensors"; sensors = <&encoder_4>; }; diff --git a/app/boards/shields/waterfowl/waterfowl.dtsi b/app/boards/shields/waterfowl/waterfowl.dtsi index 62548f06..b18d9289 100644 --- a/app/boards/shields/waterfowl/waterfowl.dtsi +++ b/app/boards/shields/waterfowl/waterfowl.dtsi @@ -73,7 +73,7 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) status = "disabled"; }; - sensors { + sensors: sensors { compatible = "zmk,keymap-sensors"; triggers-per-rotation = <20>; sensors = < diff --git a/app/boards/shields/zmk_uno/zmk_uno.overlay b/app/boards/shields/zmk_uno/zmk_uno.overlay index 07181280..4999c82c 100644 --- a/app/boards/shields/zmk_uno/zmk_uno.overlay +++ b/app/boards/shields/zmk_uno/zmk_uno.overlay @@ -10,7 +10,7 @@ chosen { zmk,matrix-transform = &matrix_transform; }; - sensors { + sensors: sensors { compatible = "zmk,keymap-sensors"; sensors = <&encoder>; triggers-per-rotation = <20>; diff --git a/app/boards/shields/zmk_uno/zmk_uno_split.dtsi b/app/boards/shields/zmk_uno/zmk_uno_split.dtsi index f84aacc8..516213bd 100644 --- a/app/boards/shields/zmk_uno/zmk_uno_split.dtsi +++ b/app/boards/shields/zmk_uno/zmk_uno_split.dtsi @@ -53,9 +53,9 @@ b-gpios = <&arduino_header 14 GPIO_PULL_UP>; }; - sensors { - compatible = "zmk,keymap-sensors"; - sensors = <&encoder &right_encoder>; - triggers-per-rotation = <20>; - }; + sensors: sensors { + compatible = "zmk,keymap-sensors"; + sensors = <&encoder &right_encoder>; + triggers-per-rotation = <20>; + }; }; From c2299e2203c869945d94455d002079b72ce7cdf9 Mon Sep 17 00:00:00 2001 From: Joel Spadin Date: Fri, 26 Jan 2024 21:01:28 -0600 Subject: [PATCH 002/127] fix(shields): Fix deprecated encoder properties Switched remaining shields over from resolution to steps. --- app/boards/shields/crbn/crbn.overlay | 3 ++- app/boards/shields/kyria/kyria_rev3.dtsi | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/boards/shields/crbn/crbn.overlay b/app/boards/shields/crbn/crbn.overlay index 9c68bd0b..af5910d6 100644 --- a/app/boards/shields/crbn/crbn.overlay +++ b/app/boards/shields/crbn/crbn.overlay @@ -42,12 +42,13 @@ compatible = "alps,ec11"; a-gpios = <&pro_micro 20 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; b-gpios = <&pro_micro 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; - resolution = <2>; + steps = <80>; status = "okay"; }; sensors: sensors { compatible = "zmk,keymap-sensors"; sensors = <&encoder>; + triggers-per-rotation = <20>; }; }; diff --git a/app/boards/shields/kyria/kyria_rev3.dtsi b/app/boards/shields/kyria/kyria_rev3.dtsi index a782a6ea..c8cd8df9 100644 --- a/app/boards/shields/kyria/kyria_rev3.dtsi +++ b/app/boards/shields/kyria/kyria_rev3.dtsi @@ -29,13 +29,11 @@ }; &left_encoder { - resolution = <2>; a-gpios = <&pro_micro 20 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; b-gpios = <&pro_micro 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; }; &right_encoder { - resolution = <2>; a-gpios = <&pro_micro 20 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; b-gpios = <&pro_micro 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; }; From be75da096c86d87e414f4089cc27184dc0c6f5bf Mon Sep 17 00:00:00 2001 From: Joel Spadin Date: Fri, 26 Jan 2024 21:03:49 -0600 Subject: [PATCH 003/127] fix(keymap-upgrader): Fix highlight on last line Fixed an issue where a text edit at the very end of a file would cause it to highlight from the start of the edit to the start of the file instead of to the end of the file. --- docs/src/keymap-upgrade/index.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/src/keymap-upgrade/index.ts b/docs/src/keymap-upgrade/index.ts index c46cbe07..0cd34807 100644 --- a/docs/src/keymap-upgrade/index.ts +++ b/docs/src/keymap-upgrade/index.ts @@ -55,7 +55,11 @@ function getLineBreakPositions(text: string) { } function positionToLineNumber(position: number, lineBreaks: number[]) { - const line = lineBreaks.findIndex((lineBreak) => position <= lineBreak); + if (position >= lineBreaks[lineBreaks.length - 1]) { + return lineBreaks.length + 1; + } + + const line = lineBreaks.findIndex((lineBreak) => position < lineBreak); return line < 0 ? 0 : line + 1; } From 3a4cf185a1acdb7494286af964a82e13b13dff34 Mon Sep 17 00:00:00 2001 From: Joel Spadin Date: Fri, 26 Jan 2024 21:07:18 -0600 Subject: [PATCH 004/127] feat(keymap-upgrader): Upgrade encoder resolution Added an upgrade function to the keymap upgrader to replace the encoder "resolution" property with "steps" and (if it is not already present) "triggers-per-rotation". --- docs/src/keymap-upgrade/encoder.ts | 101 +++++++++++++++++++++++++++++ docs/src/keymap-upgrade/index.ts | 2 + docs/src/keymap-upgrade/parser.ts | 74 +++++++++++++++++++-- 3 files changed, 171 insertions(+), 6 deletions(-) create mode 100644 docs/src/keymap-upgrade/encoder.ts diff --git a/docs/src/keymap-upgrade/encoder.ts b/docs/src/keymap-upgrade/encoder.ts new file mode 100644 index 00000000..4ac0c50b --- /dev/null +++ b/docs/src/keymap-upgrade/encoder.ts @@ -0,0 +1,101 @@ +import type { SyntaxNode, Tree } from "web-tree-sitter"; + +import { + getContainingDevicetreeNode, + getDevicetreeNodePath, + findDevicetreeProperty, +} from "./parser"; +import { TextEdit } from "./textedit"; + +const ALPS_EC11_COMPATIBLE = '"alps,ec11"'; +const DEFAULT_RESOLUTION = 4; +const TRIGGERS_PER_ROTATION = 20; +const TRIGGERS_PER_ROTATION_DT = ` + +&sensors { + // Change this to your encoder's number of detents. + // If you have multiple encoders with different detents, see + // https://zmk.dev/docs/config/encoders#keymap-sensor-config + triggers-per-rotation = <${TRIGGERS_PER_ROTATION}>; +};`; + +export function upgradeEncoderResolution(tree: Tree) { + const edits: TextEdit[] = []; + + const resolutionProps = findEncoderResolution(tree); + edits.push(...resolutionProps.flatMap(upgradeResolutionProperty)); + + if (resolutionProps.length > 0) { + edits.push(...addTriggersPerRotation(tree)); + } + + return edits; +} + +function findEncoderResolution(tree: Tree): SyntaxNode[] { + const props = findDevicetreeProperty(tree.rootNode, "resolution", { + recursive: true, + }); + + return props.filter((prop) => { + const node = getContainingDevicetreeNode(prop); + return node && isEncoderNode(node); + }); +} + +function isEncoderNode(node: SyntaxNode) { + // If a compatible property is set, then we know for sure if this is an encoder. + const compatible = findDevicetreeProperty(node, "compatible"); + if (compatible) { + return compatible.childForFieldName("value")?.text === ALPS_EC11_COMPATIBLE; + } + + // Compatible properties rarely appear in a keymap though, so just guess based + // on the node path/reference otherwise. + return getDevicetreeNodePath(node).toLowerCase().includes("encoder"); +} + +function upgradeResolutionProperty(prop: SyntaxNode): TextEdit[] { + const name = prop.childForFieldName("name"); + const value = prop.childForFieldName("value"); + + if (!name || !value) { + return []; + } + + // Try to set the new steps to be triggers-per-rotation * resolution, but fall + // back to a default if the value is something more complex than a single int. + const resolution = value.text.trim().replaceAll(/^<|>$/g, ""); + const steps = + (parseInt(resolution) || DEFAULT_RESOLUTION) * TRIGGERS_PER_ROTATION; + + const hint = `/* Change this to your encoder's number of detents times ${resolution} */`; + + return [ + TextEdit.fromNode(name, "steps"), + TextEdit.fromNode(value, `<${steps}> ${hint}`), + ]; +} + +function addTriggersPerRotation(tree: Tree): TextEdit[] { + // The keymap might already contain "triggers-per-rotation" for example if the + // user already upgraded some but not all "resolution" properties. Don't add + // another one if it already exists. + if (keymapHasTriggersPerRotation(tree)) { + return []; + } + + // Inserting a new property into an existing node while keeping the code + // readable in all cases is hard, so just append a new &sensors node to the + // end of the keymap. + const end = tree.rootNode.endIndex; + return [new TextEdit(end, end, TRIGGERS_PER_ROTATION_DT)]; +} + +function keymapHasTriggersPerRotation(tree: Tree) { + const props = findDevicetreeProperty(tree.rootNode, "triggers-per-rotation", { + recursive: true, + }); + + return props.length > 0; +} diff --git a/docs/src/keymap-upgrade/index.ts b/docs/src/keymap-upgrade/index.ts index 0cd34807..7755fffb 100644 --- a/docs/src/keymap-upgrade/index.ts +++ b/docs/src/keymap-upgrade/index.ts @@ -2,6 +2,7 @@ import { createParser } from "./parser"; import { applyEdits, Range } from "./textedit"; import { upgradeBehaviors } from "./behaviors"; +import { upgradeEncoderResolution } from "./encoder"; import { upgradeHeaders } from "./headers"; import { upgradeKeycodes } from "./keycodes"; import { upgradeNodeNames } from "./nodes"; @@ -11,6 +12,7 @@ export { initParser } from "./parser"; const upgradeFunctions = [ upgradeBehaviors, + upgradeEncoderResolution, upgradeHeaders, upgradeKeycodes, upgradeNodeNames, diff --git a/docs/src/keymap-upgrade/parser.ts b/docs/src/keymap-upgrade/parser.ts index 9b23cdd8..52d6e981 100644 --- a/docs/src/keymap-upgrade/parser.ts +++ b/docs/src/keymap-upgrade/parser.ts @@ -57,9 +57,15 @@ export function captureHasText( /** * Get a list of SyntaxNodes representing a devicetree node with the given path. - * (The same node may be listed multiple times within a file.) + * The same node may be listed multiple times within a file. * - * @param path Absolute path to the node (must start with "/") + * This function does not evaluate which node a reference points to, so given + * a file containing "/ { foo: bar {}; }; &foo {};" searching for "&foo" will + * return the "&foo {}" node but not "foo: bar {}". + * + * @param path Path to the node to find. May be an absolute path such as + * "/foo/bar", a node reference such as "&foo", or a node reference followed by + * a relative path such as "&foo/bar". */ export function findDevicetreeNode( tree: Parser.Tree, @@ -81,6 +87,64 @@ export function findDevicetreeNode( return result; } +export interface FindPropertyOptions { + /** Search in children of the given node as well */ + recursive?: boolean; +} + +/** + * Find all instances of a devicetree property with the given name which are + * descendants of the given syntax node. + * + * @param node Any syntax node + */ +export function findDevicetreeProperty( + node: Parser.SyntaxNode, + name: string, + options: FindPropertyOptions & { recursive: true } +): Parser.SyntaxNode[]; + +/** + * Find a devicetree node's property with the given name, or null if it doesn't + * have one. + * + * @note If the node contains multiple instances of the same property, this + * returns the last once, since that is the one that will actually be applied. + * + * @param node A syntax node for a devicetree node + */ +export function findDevicetreeProperty( + node: Parser.SyntaxNode, + name: string, + options?: FindPropertyOptions +): Parser.SyntaxNode | null; + +export function findDevicetreeProperty( + node: Parser.SyntaxNode, + name: string, + options?: FindPropertyOptions +): Parser.SyntaxNode[] | Parser.SyntaxNode | null { + const query = Devicetree.query( + `(property name: (identifier) @name (#eq? @name "${name}")) @prop` + ); + const matches = query.matches(node); + const props = matches.map(({ captures }) => findCapture("prop", captures)!); + + if (options?.recursive) { + return props; + } + + // The query finds all descendants. Filter to just the properties that belong + // to the given devicetree node. + const childProps = props.filter((prop) => + getContainingDevicetreeNode(prop)?.equals(node) + ); + + // Sort in descending order to select the last instance of the property. + childProps.sort((a, b) => b.startIndex - a.startIndex); + return childProps[0] ?? null; +} + export function getDevicetreeNodePath(node: Parser.SyntaxNode | null) { const parts = getDevicetreeNodePathParts(node); @@ -99,9 +163,7 @@ export function getDevicetreeNodePath(node: Parser.SyntaxNode | null) { return parts[0] === "/" ? path.substring(1) : path; } -export function getDevicetreeNodePathParts( - node: Parser.SyntaxNode | null -): string[] { +function getDevicetreeNodePathParts(node: Parser.SyntaxNode | null): string[] { // There may be intermediate syntax nodes between devicetree nodes, such as // #if blocks, so if we aren't currently on a "node" node, traverse up the // tree until we find one. @@ -115,7 +177,7 @@ export function getDevicetreeNodePathParts( return [...getDevicetreeNodePathParts(dtnode.parent), name]; } -function getContainingDevicetreeNode(node: Parser.SyntaxNode | null) { +export function getContainingDevicetreeNode(node: Parser.SyntaxNode | null) { while (node && node.type !== "node") { node = node.parent; } From 5826b80374625d448cfbfc739dde4fda1e6f2681 Mon Sep 17 00:00:00 2001 From: Joel Spadin Date: Sat, 3 Feb 2024 17:14:49 -0600 Subject: [PATCH 005/127] chore: Fix formatting Fixed the formatting in a file that wasn't passing pre-commit checks. --- docs/docs/behaviors/mod-morph.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/docs/behaviors/mod-morph.md b/docs/docs/behaviors/mod-morph.md index bc1820f2..7ecb9ab8 100644 --- a/docs/docs/behaviors/mod-morph.md +++ b/docs/docs/behaviors/mod-morph.md @@ -92,4 +92,3 @@ For example, the following configuration morphs `LEFT_SHIFT` + `BACKSPACE` into If the first modified key press sends the modifier along with the morphed keycode and [Karabiner-Elements](https://karabiner-elements.pqrs.org/) is running, disable the "Modify Events" toggle from Karabiner's "Devices" settings page for the keyboard running ZMK. ::: - From 4b03fcb70993dc277f5268bfac0e129cfe0b73a3 Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Sun, 4 Feb 2024 13:52:55 -0800 Subject: [PATCH 006/127] fix(boards): Add missing battery header include --- app/boards/arm/corneish_zen/widgets/battery_status.c | 2 +- app/boards/arm/corneish_zen/widgets/peripheral_status.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/boards/arm/corneish_zen/widgets/battery_status.c b/app/boards/arm/corneish_zen/widgets/battery_status.c index 0d5b0dc5..011319c4 100644 --- a/app/boards/arm/corneish_zen/widgets/battery_status.c +++ b/app/boards/arm/corneish_zen/widgets/battery_status.c @@ -6,12 +6,12 @@ */ #include -#include #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include +#include #include "battery_status.h" #include #include diff --git a/app/boards/arm/corneish_zen/widgets/peripheral_status.c b/app/boards/arm/corneish_zen/widgets/peripheral_status.c index 39b62fde..b94d45f6 100644 --- a/app/boards/arm/corneish_zen/widgets/peripheral_status.c +++ b/app/boards/arm/corneish_zen/widgets/peripheral_status.c @@ -6,7 +6,6 @@ */ #include -#include #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); From efbcd3c8f6be2d147949a51503b19bb52e9843ac Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Sun, 4 Feb 2024 13:55:48 -0800 Subject: [PATCH 007/127] fix(boards): Disable ZMK_USB for peripherals --- app/boards/arm/corneish_zen/corneish_zen_v1_right_defconfig | 2 +- app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/boards/arm/corneish_zen/corneish_zen_v1_right_defconfig b/app/boards/arm/corneish_zen/corneish_zen_v1_right_defconfig index 5284159d..d89377bc 100644 --- a/app/boards/arm/corneish_zen/corneish_zen_v1_right_defconfig +++ b/app/boards/arm/corneish_zen/corneish_zen_v1_right_defconfig @@ -39,7 +39,7 @@ CONFIG_FLASH_MAP=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_30PPM=y -CONFIG_ZMK_USB=y +CONFIG_ZMK_USB=n CONFIG_ZMK_BLE=y # enable display drivers diff --git a/app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig b/app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig index 506aa67e..83dc57d4 100644 --- a/app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig +++ b/app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig @@ -35,7 +35,7 @@ CONFIG_FLASH_MAP=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_30PPM=y -CONFIG_ZMK_USB=y +CONFIG_ZMK_USB=n CONFIG_ZMK_BLE=y # enable display drivers From b8846cf6355c5d7ae52a191988054b532a264f0c Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Mon, 5 Feb 2024 21:05:49 -0800 Subject: [PATCH 008/127] refactor(display): Remove unused BAS includes --- app/boards/shields/nice_view/widgets/peripheral_status.c | 1 - app/boards/shields/nice_view/widgets/status.c | 1 - app/src/display/widgets/battery_status.c | 1 - 3 files changed, 3 deletions(-) diff --git a/app/boards/shields/nice_view/widgets/peripheral_status.c b/app/boards/shields/nice_view/widgets/peripheral_status.c index 989681f3..cec0f7b2 100644 --- a/app/boards/shields/nice_view/widgets/peripheral_status.c +++ b/app/boards/shields/nice_view/widgets/peripheral_status.c @@ -6,7 +6,6 @@ */ #include -#include #include #include diff --git a/app/boards/shields/nice_view/widgets/status.c b/app/boards/shields/nice_view/widgets/status.c index 41c09743..3346546e 100644 --- a/app/boards/shields/nice_view/widgets/status.c +++ b/app/boards/shields/nice_view/widgets/status.c @@ -6,7 +6,6 @@ */ #include -#include #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); diff --git a/app/src/display/widgets/battery_status.c b/app/src/display/widgets/battery_status.c index feb054db..06f55f3f 100644 --- a/app/src/display/widgets/battery_status.c +++ b/app/src/display/widgets/battery_status.c @@ -5,7 +5,6 @@ */ #include -#include #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); From f4fce9e15832fd8daee9091d7d77a272aecb8f3e Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 23 Jun 2023 07:17:00 +0000 Subject: [PATCH 009/127] refactor(display): Move new LVGL DPI Kconfig setting. --- app/boards/shields/corne/Kconfig.defconfig | 5 +---- app/boards/shields/corne/corne.dtsi | 1 + app/boards/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 + app/boards/shields/knob_goblin/Kconfig.defconfig | 5 +---- app/boards/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 + app/boards/shields/leeloo_micro/Kconfig.defconfig | 5 +---- app/boards/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 +---- app/boards/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 + app/boards/shields/nice_view/Kconfig.defconfig | 2 +- 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 + app/boards/shields/splitkb_aurora_corne/Kconfig.defconfig | 5 +---- .../splitkb_aurora_corne/splitkb_aurora_corne.dtsi | 1 + app/boards/shields/splitkb_aurora_helix/Kconfig.defconfig | 3 --- .../splitkb_aurora_helix/splitkb_aurora_helix.dtsi | 1 + .../shields/splitkb_aurora_lily58/Kconfig.defconfig | 5 +---- .../splitkb_aurora_lily58/splitkb_aurora_lily58.dtsi | 1 + app/boards/shields/splitkb_aurora_sofle/Kconfig.defconfig | 3 --- .../splitkb_aurora_sofle/splitkb_aurora_sofle.dtsi | 1 + app/boards/shields/splitkb_aurora_sweep/Kconfig.defconfig | 5 +---- .../splitkb_aurora_sweep/splitkb_aurora_sweep.dtsi | 1 + app/boards/shields/tidbit/Kconfig.defconfig | 5 +---- app/boards/shields/tidbit/tidbit.dtsi | 1 + app/boards/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/src/display/Kconfig | 8 ++++---- 46 files changed, 47 insertions(+), 91 deletions(-) diff --git a/app/boards/shields/corne/Kconfig.defconfig b/app/boards/shields/corne/Kconfig.defconfig index 07dd07e9..27d50df3 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 93eb63ad..f6d41e33 100644 --- a/app/boards/shields/corne/corne.dtsi +++ b/app/boards/shields/corne/corne.dtsi @@ -76,6 +76,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 70a312c1..dc10e980 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 c14fbae1..22a72708 100644 --- a/app/boards/shields/elephant42/elephant42.dtsi +++ b/app/boards/shields/elephant42/elephant42.dtsi @@ -53,6 +53,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 04beb792..ba332226 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 cee794ac..a2d804b9 100644 --- a/app/boards/shields/jorne/jorne.dtsi +++ b/app/boards/shields/jorne/jorne.dtsi @@ -92,6 +92,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 d8d468ed..3f08e287 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 53372738..49306ddf 100644 --- a/app/boards/shields/knob_goblin/knob_goblin.overlay +++ b/app/boards/shields/knob_goblin/knob_goblin.overlay @@ -72,6 +72,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 2d162736..36e02963 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 0bb34349..23058f37 100644 --- a/app/boards/shields/kyria/kyria_common.dtsi +++ b/app/boards/shields/kyria/kyria_common.dtsi @@ -53,5 +53,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 046bd49a..a3d95f63 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 70896e1c..df4f228e 100644 --- a/app/boards/shields/leeloo/leeloo_common.dtsi +++ b/app/boards/shields/leeloo/leeloo_common.dtsi @@ -83,6 +83,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 26256120..8af3214d 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 e0ca21cc..bc314205 100644 --- a/app/boards/shields/leeloo_micro/leeloo_micro.dtsi +++ b/app/boards/shields/leeloo_micro/leeloo_micro.dtsi @@ -81,6 +81,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 e77a9c22..169a6ad7 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 f1c7c190..1a326d62 100644 --- a/app/boards/shields/lily58/lily58.dtsi +++ b/app/boards/shields/lily58/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,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 62695c20..984095c7 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 1260522a..afa311d9 100644 --- a/app/boards/shields/lotus58/lotus58.dtsi +++ b/app/boards/shields/lotus58/lotus58.dtsi @@ -82,6 +82,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 e355c641..3737b83f 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 98f086cd..ed190fcb 100644 --- a/app/boards/shields/microdox/microdox_common.dtsi +++ b/app/boards/shields/microdox/microdox_common.dtsi @@ -45,6 +45,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 80e65351..9d80a139 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 f098ec8b..a8234968 100644 --- a/app/boards/shields/murphpad/murphpad.overlay +++ b/app/boards/shields/murphpad/murphpad.overlay @@ -66,6 +66,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 19bddec7..3915ff0f 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 4a847742..59db2d8d 100644 --- a/app/boards/shields/nibble/nibble.overlay +++ b/app/boards/shields/nibble/nibble.overlay @@ -67,6 +67,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 53edc1cc..84fdd7cc 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 diff --git a/app/boards/shields/snap/Kconfig.defconfig b/app/boards/shields/snap/Kconfig.defconfig index e21111e9..0338df48 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 902db143..90eec5ae 100644 --- a/app/boards/shields/snap/snap.dtsi +++ b/app/boards/shields/snap/snap.dtsi @@ -76,6 +76,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 4e7bf884..4eb3d743 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 9ec8c987..f88339d7 100644 --- a/app/boards/shields/sofle/sofle.dtsi +++ b/app/boards/shields/sofle/sofle.dtsi @@ -82,6 +82,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 a28792c7..d3ac6c77 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 58d53028..56833b62 100644 --- a/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne.dtsi +++ b/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne.dtsi @@ -85,6 +85,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 6d7a5569..df32b83b 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 c3a7b4ed..34781ecd 100644 --- a/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix.dtsi +++ b/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix.dtsi @@ -71,6 +71,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 e54e2b43..861db44f 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 b237b69b..93625d28 100644 --- a/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58.dtsi +++ b/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58.dtsi @@ -71,6 +71,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 b53c4c8d..172548e8 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 77877ebe..2586b0c0 100644 --- a/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle.dtsi +++ b/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle.dtsi @@ -71,6 +71,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 83cb1bf6..6a0e3728 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 8b17a4bd..883636de 100644 --- a/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep.dtsi +++ b/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep.dtsi @@ -71,6 +71,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 393fbef1..70bb1d74 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 93451ebc..44fc9192 100644 --- a/app/boards/shields/tidbit/tidbit.dtsi +++ b/app/boards/shields/tidbit/tidbit.dtsi @@ -105,6 +105,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 dbee82b8..1efc3596 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 b18d9289..d46910a3 100644 --- a/app/boards/shields/waterfowl/waterfowl.dtsi +++ b/app/boards/shields/waterfowl/waterfowl.dtsi @@ -100,5 +100,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 e7538c41..07ed7dbe 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 4cd242a9..3151f31c 100644 --- a/app/boards/shields/zodiark/zodiark.dtsi +++ b/app/boards/shields/zodiark/zodiark.dtsi @@ -80,5 +80,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/src/display/Kconfig b/app/src/display/Kconfig index a2029481..3e17ff76 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" From bf4008da023189b885ebcf1c0ccdb729663312e8 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 23 Jun 2023 07:19:57 +0000 Subject: [PATCH 010/127] refactor: All SYS_INIT functions are void args. --- app/boards/arm/mikoto/pinmux.c | 3 +-- app/boards/arm/nrfmicro/pinmux.c | 4 +--- app/boards/arm/puchi_ble/pinmux.c | 4 +--- app/include/zmk/hog.h | 2 -- app/src/activity.c | 2 +- app/src/backlight.c | 2 +- app/src/battery.c | 2 +- app/src/behavior.c | 4 +--- app/src/ble.c | 2 +- app/src/combo.c | 2 +- app/src/endpoints.c | 2 +- app/src/hog.c | 2 +- app/src/rgb_underglow.c | 2 +- app/src/sensors.c | 2 +- app/src/split/bluetooth/central.c | 2 +- app/src/split/bluetooth/peripheral.c | 2 +- app/src/split/bluetooth/service.c | 2 +- app/src/usb.c | 2 +- app/src/usb_hid.c | 2 +- app/src/workqueue.c | 2 +- app/src/wpm.c | 2 +- 21 files changed, 20 insertions(+), 29 deletions(-) diff --git a/app/boards/arm/mikoto/pinmux.c b/app/boards/arm/mikoto/pinmux.c index 524aa17e..c34c2dc8 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/pinmux.c b/app/boards/arm/nrfmicro/pinmux.c index 6362b392..2e6674ad 100644 --- a/app/boards/arm/nrfmicro/pinmux.c +++ b/app/boards/arm/nrfmicro/pinmux.c @@ -11,9 +11,7 @@ #include #include -static int pinmux_nrfmicro_init(const struct device *port) { - ARG_UNUSED(port); - +static int pinmux_nrfmicro_init(void) { #if (CONFIG_BOARD_NRFMICRO_13 || CONFIG_BOARD_NRFMICRO_13_52833) const struct device *p0 = DEVICE_DT_GET(DT_NODELABEL(gpio0)); #if CONFIG_BOARD_NRFMICRO_CHARGER diff --git a/app/boards/arm/puchi_ble/pinmux.c b/app/boards/arm/puchi_ble/pinmux.c index 28178274..8475cfb1 100644 --- a/app/boards/arm/puchi_ble/pinmux.c +++ b/app/boards/arm/puchi_ble/pinmux.c @@ -11,9 +11,7 @@ #include #include -static int pinmux_puchi_ble_init(const struct device *port) { - ARG_UNUSED(port); - +static int pinmux_puchi_ble_init(void) { #if CONFIG_BOARD_PUCHI_BLE_v1 const struct device *p0 = DEVICE_DT_GET(DT_NODELABEL(gpio0)); #if CONFIG_BOARD_PUCHI_BLE_CHARGER diff --git a/app/include/zmk/hog.h b/app/include/zmk/hog.h index 5ea99126..eb6e653f 100644 --- a/app/include/zmk/hog.h +++ b/app/include/zmk/hog.h @@ -9,8 +9,6 @@ #include #include -int zmk_hog_init(const struct device *_arg); - int zmk_hog_send_keyboard_report(struct zmk_hid_keyboard_report_body *body); int zmk_hog_send_consumer_report(struct zmk_hid_consumer_report_body *body); diff --git a/app/src/activity.c b/app/src/activity.c index 58b11b21..330008b3 100644 --- a/app/src/activity.c +++ b/app/src/activity.c @@ -84,7 +84,7 @@ void activity_expiry_function(struct k_timer *_timer) { k_work_submit(&activity_ K_TIMER_DEFINE(activity_timer, activity_expiry_function, NULL); -int activity_init(const struct device *_device) { +static 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 9497f313..f050978f 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 69eee2f4..1295f822 100644 --- a/app/src/battery.c +++ b/app/src/battery.c @@ -92,7 +92,7 @@ static void zmk_battery_start_reporting() { } } -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/behavior.c b/app/src/behavior.c index fd2b0ec1..fa2005ff 100644 --- a/app/src/behavior.c +++ b/app/src/behavior.c @@ -40,9 +40,7 @@ const struct device *z_impl_behavior_get_binding(const char *name) { } #if IS_ENABLED(CONFIG_LOG) -static int check_behavior_names(const struct device *dev) { - ARG_UNUSED(dev); - +static int check_behavior_names(void) { // Behavior names must be unique, but we don't have a good way to enforce this // at compile time, so log an error at runtime if they aren't unique. ptrdiff_t count; diff --git a/app/src/ble.c b/app/src/ble.c index c8509308..f01ed871 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -629,7 +629,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 5003d7f9..61671d33 100644 --- a/app/src/combo.c +++ b/app/src/combo.c @@ -531,7 +531,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/endpoints.c b/app/src/endpoints.c index dbe6bcbc..395d6ba5 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/hog.c b/app/src/hog.c index 20460914..f17f759c 100644 --- a/app/src/hog.c +++ b/app/src/hog.c @@ -398,7 +398,7 @@ int zmk_hog_send_mouse_report(struct zmk_hid_mouse_report_body *report) { #endif // IS_ENABLED(CONFIG_ZMK_MOUSE) -int zmk_hog_init(const struct device *_arg) { +static 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/rgb_underglow.c b/app/src/rgb_underglow.c index ddc0aef1..a7a9b4f0 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(struct k_work *_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 b7aeba0b..4dcda44d 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 95fd7260..abb37a0b 100644 --- a/app/src/split/bluetooth/central.c +++ b/app/src/split/bluetooth/central.c @@ -865,7 +865,7 @@ int zmk_split_bt_update_hid_indicator(zmk_hid_indicators_t indicators) { #endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) -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 dcf3db63..e3129cee 100644 --- a/app/src/split/bluetooth/peripheral.c +++ b/app/src/split/bluetooth/peripheral.c @@ -146,7 +146,7 @@ bool zmk_split_bt_peripheral_is_connected(void) { return is_connected; } bool zmk_split_bt_peripheral_is_bonded(void) { return is_bonded; } -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 d6eb7ce4..505eb363 100644 --- a/app/src/split/bluetooth/service.c +++ b/app/src/split/bluetooth/service.c @@ -265,7 +265,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 dbfece76..cd787618 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 f3542ffa..cd3ef920 100644 --- a/app/src/usb_hid.c +++ b/app/src/usb_hid.c @@ -177,7 +177,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/workqueue.c b/app/src/workqueue.c index 1aa4f59a..e6e55c87 100644 --- a/app/src/workqueue.c +++ b/app/src/workqueue.c @@ -17,7 +17,7 @@ struct k_work_q *zmk_workqueue_lowprio_work_q(void) { return &lowprio_work_q; } -static int workqueue_init(const struct device *_device) { +static int workqueue_init(void) { static const struct k_work_queue_config queue_config = {.name = "Low Priority Work Queue"}; k_work_queue_start(&lowprio_work_q, lowprio_q_stack, K_THREAD_STACK_SIZEOF(lowprio_q_stack), CONFIG_ZMK_LOW_PRIORITY_THREAD_PRIORITY, &queue_config); diff --git a/app/src/wpm.c b/app/src/wpm.c index f15de745..182abf95 100644 --- a/app/src/wpm.c +++ b/app/src/wpm.c @@ -71,7 +71,7 @@ void wpm_expiry_function(struct k_timer *_timer) { k_work_submit(&wpm_work); } K_TIMER_DEFINE(wpm_timer, wpm_expiry_function, NULL); -int wpm_init(const struct device *_device) { +static int wpm_init(void) { wpm_state = 0; wpm_update_counter = 0; k_timer_start(&wpm_timer, K_SECONDS(WPM_UPDATE_INTERVAL_SECONDS), From f7e7c9c10b22d52eca1235ca0440911a8a2aa720 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 23 Jun 2023 07:20:30 +0000 Subject: [PATCH 011/127] fix: Add missing include for k_work types. --- app/module/drivers/kscan/kscan_mock.c | 1 + 1 file changed, 1 insertion(+) diff --git a/app/module/drivers/kscan/kscan_mock.c b/app/module/drivers/kscan/kscan_mock.c index 604e164c..187a1686 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); From fb99496a73c5ba5f727ef98a38348447bfef4d9d Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 23 Jun 2023 07:23:50 +0000 Subject: [PATCH 012/127] chore: Switch to 3.5 Zephyr version. --- app/west.yml | 93 +--------------------------------------------------- 1 file changed, 1 insertion(+), 92 deletions(-) diff --git a/app/west.yml b/app/west.yml index f72f2f39..95ab9200 100644 --- a/app/west.yml +++ b/app/west.yml @@ -1,21 +1,13 @@ manifest: - defaults: - remote: upstream - remotes: - name: zephyrproject-rtos url-base: https://github.com/zephyrproject-rtos - name: zmkfirmware url-base: https://github.com/zmkfirmware - - name: upstream - url-base: https://github.com/zephyrproject-rtos - - name: babblesim - url-base: https://github.com/BabbleSim - group-filter: [-babblesim] projects: - name: zephyr remote: zmkfirmware - revision: v3.2.0+zmk-fixes + revision: v3.5.0+zmk-fixes clone-depth: 1 import: name-blocklist: @@ -38,88 +30,5 @@ manifest: - edtt - trusted-firmware-m - sof - - name: bsim - repo-path: babblesim-manifest - revision: 908ffde6298a937c6549dbfa843a62caab26bfc5 - path: tools/bsim - groups: - - babblesim - - name: babblesim_base - remote: babblesim - repo-path: base.git - path: tools/bsim/components - revision: 02838ca04c4562e68dc876196828d8121679e537 - groups: - - babblesim - - name: babblesim_ext_2G4_libPhyComv1 - remote: babblesim - repo-path: ext_2G4_libPhyComv1.git - path: tools/bsim/components/ext_2G4_libPhyComv1 - revision: 9018113a362fa6c9e8f4b9cab9e5a8f12cc46b94 - groups: - - babblesim - - name: babblesim_ext_2G4_phy_v1 - remote: babblesim - repo-path: ext_2G4_phy_v1.git - path: tools/bsim/components/ext_2G4_phy_v1 - revision: cf2d86e736efac4f12fad5093ed2da2c5b406156 - groups: - - babblesim - - name: babblesim_ext_2G4_channel_NtNcable - remote: babblesim - repo-path: ext_2G4_channel_NtNcable.git - path: tools/bsim/components/ext_2G4_channel_NtNcable - revision: 20a38c997f507b0aa53817aab3d73a462fff7af1 - groups: - - babblesim - - name: babblesim_ext_2G4_channel_multiatt - remote: babblesim - repo-path: ext_2G4_channel_multiatt.git - path: tools/bsim/components/ext_2G4_channel_multiatt - revision: e09bc2d14b1975f969ad19c6ed23eb20e5dc3d09 - groups: - - babblesim - - name: babblesim_ext_2G4_modem_magic - remote: babblesim - repo-path: ext_2G4_modem_magic.git - path: tools/bsim/components/ext_2G4_modem_magic - revision: cb70771794f0bf6f262aa474848611c68ae8f1ed - groups: - - babblesim - - name: babblesim_ext_2G4_modem_BLE_simple - remote: babblesim - repo-path: ext_2G4_modem_BLE_simple.git - path: tools/bsim/components/ext_2G4_modem_BLE_simple - revision: ce975a3259fd0dd761d371b60435242d54794bad - groups: - - babblesim - - name: babblesim_ext_2G4_device_burst_interferer - remote: babblesim - repo-path: ext_2G4_device_burst_interferer.git - path: tools/bsim/components/ext_2G4_device_burst_interferer - revision: 5b5339351d6e6a2368c686c734dc8b2fc65698fc - groups: - - babblesim - - name: babblesim_ext_2G4_device_WLAN_actmod - remote: babblesim - repo-path: ext_2G4_device_WLAN_actmod.git - path: tools/bsim/components/ext_2G4_device_WLAN_actmod - revision: 9cb6d8e72695f6b785e57443f0629a18069d6ce4 - groups: - - babblesim - - name: babblesim_ext_2G4_device_playback - remote: babblesim - repo-path: ext_2G4_device_playback.git - path: tools/bsim/components/ext_2G4_device_playback - revision: 85c645929cf1ce995d8537107d9dcbd12ed64036 - groups: - - babblesim - - name: babblesim_ext_libCryptov1 - remote: babblesim - repo-path: ext_libCryptov1.git - path: tools/bsim/components/ext_libCryptov1 - revision: eed6d7038e839153e340bd333bc43541cb90ba64 - groups: - - babblesim self: west-commands: scripts/west-commands.yml From 0b5afbf9c0f752138d533cf52b1458d4e7c90f77 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 28 Jun 2023 13:34:25 -0700 Subject: [PATCH 013/127] refacter(bluetooth): Proper HCI header include. --- app/src/ble.c | 2 +- app/src/split/bluetooth/peripheral.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/ble.c b/app/src/ble.c index f01ed871..3ed735a1 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) diff --git a/app/src/split/bluetooth/peripheral.c b/app/src/split/bluetooth/peripheral.c index e3129cee..6ce82d0a 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) From bd9c71ab0af29f22eda516b3c3541e83aa51b908 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 16 Oct 2023 06:11:21 +0000 Subject: [PATCH 014/127] fix(sensors): Avoid duplicate Kconfig/DTS name. * Upstream added an equivalent fuel gauge driver, so namespace our Kconfig symbol and DTS compatible for the MAX17048 driver. --- app/module/drivers/sensor/CMakeLists.txt | 2 +- app/module/drivers/sensor/max17048/CMakeLists.txt | 4 ++-- app/module/drivers/sensor/max17048/Kconfig | 10 ++++------ app/module/drivers/sensor/max17048/max17048.c | 2 +- .../{maxim,max17048.yml => zmk,maxim-max17048.yml} | 2 +- 5 files changed, 9 insertions(+), 11 deletions(-) rename app/module/dts/bindings/sensor/{maxim,max17048.yml => zmk,maxim-max17048.yml} (85%) diff --git a/app/module/drivers/sensor/CMakeLists.txt b/app/module/drivers/sensor/CMakeLists.txt index 9654600a..cd1a1c45 100644 --- a/app/module/drivers/sensor/CMakeLists.txt +++ b/app/module/drivers/sensor/CMakeLists.txt @@ -3,4 +3,4 @@ add_subdirectory_ifdef(CONFIG_ZMK_BATTERY battery) add_subdirectory_ifdef(CONFIG_EC11 ec11) -add_subdirectory_ifdef(CONFIG_MAX17048 max17048) +add_subdirectory_ifdef(CONFIG_ZMK_MAX17048 max17048) diff --git a/app/module/drivers/sensor/max17048/CMakeLists.txt b/app/module/drivers/sensor/max17048/CMakeLists.txt index e895fa11..43b7af4d 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 8a7ec16e..432949a2 100644 --- a/app/module/drivers/sensor/max17048/Kconfig +++ b/app/module/drivers/sensor/max17048/Kconfig @@ -1,18 +1,16 @@ # Copyright (c) 2022 The ZMK Contributors # SPDX-License-Identifier: MIT -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 + default y + depends on DT_HAS_ZMK_MAXIM_MAX17048_ENABLED && I2C select ZMK_BATTERY help 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/module/drivers/sensor/max17048/max17048.c b/app/module/drivers/sensor/max17048/max17048.c index 24cfe093..43b30af1 100644 --- a/app/module/drivers/sensor/max17048/max17048.c +++ b/app/module/drivers/sensor/max17048/max17048.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: MIT */ -#define DT_DRV_COMPAT maxim_max17048 +#define DT_DRV_COMPAT zmk_maxim_max17048 #include #include diff --git a/app/module/dts/bindings/sensor/maxim,max17048.yml b/app/module/dts/bindings/sensor/zmk,maxim-max17048.yml similarity index 85% rename from app/module/dts/bindings/sensor/maxim,max17048.yml rename to app/module/dts/bindings/sensor/zmk,maxim-max17048.yml index 786f4b86..765aeee5 100644 --- a/app/module/dts/bindings/sensor/maxim,max17048.yml +++ b/app/module/dts/bindings/sensor/zmk,maxim-max17048.yml @@ -7,6 +7,6 @@ description: > This is a representation of the Maxim max17048 I2C Fuel Gauge. -compatible: "maxim,max17048" +compatible: "zmk,maxim-max17048" include: [i2c-device.yaml] From d06e90e713fd113493bad513513d2f8d88d3a548 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Thu, 9 Nov 2023 00:07:10 -0800 Subject: [PATCH 015/127] fix: Fix syscalls generation setup. --- app/CMakeLists.txt | 3 +++ app/prj.conf | 1 + 2 files changed, 4 insertions(+) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index e5f48976..31471484 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -11,6 +11,9 @@ project(zmk) zephyr_linker_sources(SECTIONS include/linker/zmk-behaviors.ld) 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) diff --git a/app/prj.conf b/app/prj.conf index e69de29b..cd2bc13f 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -0,0 +1 @@ +CONFIG_APPLICATION_DEFINED_SYSCALL=y \ No newline at end of file From ba1a6c08adfaf579292efd24b932033ddd66ce22 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Thu, 9 Nov 2023 00:10:38 -0800 Subject: [PATCH 016/127] refactor: Return int from main function. --- app/src/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index 3fd6b116..9bd7af32 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -17,14 +17,16 @@ LOG_MODULE_REGISTER(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include -void main(void) { +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 */ + + return 0; } From d6de8a3acce86136c2d6fe944ab5afbc3e10be86 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Thu, 9 Nov 2023 00:17:44 -0800 Subject: [PATCH 017/127] refactor: Move to POST_KERNEL phase for behavior inits. --- 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 | 2 +- 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 | 2 +- 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 +- app/src/behaviors/behavior_sensor_rotate_var.c | 2 +- app/src/behaviors/behavior_sticky_key.c | 2 +- app/src/behaviors/behavior_tap_dance.c | 2 +- app/src/behaviors/behavior_to_layer.c | 2 +- app/src/behaviors/behavior_toggle_layer.c | 2 +- app/src/behaviors/behavior_transparent.c | 2 +- docs/docs/development/new-behavior.mdx | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/app/src/behaviors/behavior_backlight.c b/app/src/behaviors/behavior_backlight.c index 42967e39..3f836b73 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, }; -BEHAVIOR_DT_INST_DEFINE(0, behavior_backlight_init, NULL, NULL, NULL, APPLICATION, +BEHAVIOR_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 13ea2495..03bb7d8c 100644 --- a/app/src/behaviors/behavior_bt.c +++ b/app/src/behaviors/behavior_bt.c @@ -56,7 +56,7 @@ static const struct behavior_driver_api behavior_bt_driver_api = { .binding_released = on_keymap_binding_released, }; -BEHAVIOR_DT_INST_DEFINE(0, behavior_bt_init, NULL, NULL, NULL, APPLICATION, +BEHAVIOR_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 53ea489f..d9b3f24e 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), \ }; \ BEHAVIOR_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 0af30b00..a51a9f6d 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, }; -BEHAVIOR_DT_INST_DEFINE(0, behavior_ext_power_init, NULL, NULL, NULL, APPLICATION, +BEHAVIOR_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 146d5cc5..8c28531c 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -748,7 +748,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), \ }; \ BEHAVIOR_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_key_press.c b/app/src/behaviors/behavior_key_press.c index 5374e6dd..566cfcfb 100644 --- a/app/src/behaviors/behavior_key_press.c +++ b/app/src/behaviors/behavior_key_press.c @@ -34,7 +34,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) \ - BEHAVIOR_DT_INST_DEFINE(n, behavior_key_press_init, NULL, NULL, NULL, APPLICATION, \ + BEHAVIOR_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 bf53c384..c93fa722 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), \ }; \ BEHAVIOR_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 db77f814..0dc0f5ab 100644 --- a/app/src/behaviors/behavior_key_toggle.c +++ b/app/src/behaviors/behavior_key_toggle.c @@ -37,7 +37,7 @@ static const struct behavior_driver_api behavior_key_toggle_driver_api = { }; #define KT_INST(n) \ - BEHAVIOR_DT_INST_DEFINE(n, behavior_key_toggle_init, NULL, NULL, NULL, APPLICATION, \ + BEHAVIOR_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 1cb76dbd..acffe3d8 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)}; \ BEHAVIOR_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 176b0f69..3a8bf08c 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 = {}; \ BEHAVIOR_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 94da6441..0c86e605 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; BEHAVIOR_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 d4c392ac..9064a1aa 100644 --- a/app/src/behaviors/behavior_mouse_key_press.c +++ b/app/src/behaviors/behavior_mouse_key_press.c @@ -39,7 +39,7 @@ 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) \ - BEHAVIOR_DT_INST_DEFINE(n, behavior_mouse_key_press_init, NULL, NULL, NULL, APPLICATION, \ + BEHAVIOR_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_none.c b/app/src/behaviors/behavior_none.c index 57208f36..0137622a 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, }; -BEHAVIOR_DT_INST_DEFINE(0, behavior_none_init, NULL, NULL, NULL, APPLICATION, +BEHAVIOR_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 1185aaab..d172c3a1 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, }; -BEHAVIOR_DT_INST_DEFINE(0, behavior_out_init, NULL, NULL, NULL, APPLICATION, +BEHAVIOR_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 6a2731ec..c559f17f 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)}; \ BEHAVIOR_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 7a478eb7..a16ee591 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, }; -BEHAVIOR_DT_INST_DEFINE(0, behavior_rgb_underglow_init, NULL, NULL, NULL, APPLICATION, +BEHAVIOR_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 f77beca1..94bac506 100644 --- a/app/src/behaviors/behavior_sensor_rotate.c +++ b/app/src/behaviors/behavior_sensor_rotate.c @@ -37,7 +37,7 @@ static int behavior_sensor_rotate_init(const struct device *dev) { return 0; }; static struct behavior_sensor_rotate_data behavior_sensor_rotate_data_##n = {}; \ BEHAVIOR_DT_INST_DEFINE(n, behavior_sensor_rotate_init, NULL, \ &behavior_sensor_rotate_data_##n, &behavior_sensor_rotate_config_##n, \ - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ &behavior_sensor_rotate_driver_api); DT_INST_FOREACH_STATUS_OKAY(SENSOR_ROTATE_INST) diff --git a/app/src/behaviors/behavior_sensor_rotate_var.c b/app/src/behaviors/behavior_sensor_rotate_var.c index 0d3d22b2..65a9ce34 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 = {}; \ BEHAVIOR_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 aabb017e..f1131f66 100644 --- a/app/src/behaviors/behavior_sticky_key.c +++ b/app/src/behaviors/behavior_sticky_key.c @@ -298,7 +298,7 @@ static struct behavior_sticky_key_data behavior_sticky_key_data; .quick_release = DT_INST_PROP(n, quick_release), \ }; \ BEHAVIOR_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 306d5ca7..40427ef8 100644 --- a/app/src/behaviors/behavior_tap_dance.c +++ b/app/src/behaviors/behavior_tap_dance.c @@ -251,7 +251,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)}; \ BEHAVIOR_DT_INST_DEFINE(n, behavior_tap_dance_init, NULL, NULL, \ - &behavior_tap_dance_config_##n, APPLICATION, \ + &behavior_tap_dance_config_##n, 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 9a58bf60..1c87a925 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, }; -BEHAVIOR_DT_INST_DEFINE(0, behavior_to_init, NULL, NULL, NULL, APPLICATION, +BEHAVIOR_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 154cf9cd..817462df 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; BEHAVIOR_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 ddf62ce0..c7bf802b 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, }; -BEHAVIOR_DT_INST_DEFINE(0, behavior_transparent_init, NULL, NULL, NULL, APPLICATION, +BEHAVIOR_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/docs/docs/development/new-behavior.mdx b/docs/docs/development/new-behavior.mdx index aec9a5ae..d76474fd 100644 --- a/docs/docs/development/new-behavior.mdx +++ b/docs/docs/development/new-behavior.mdx @@ -175,7 +175,7 @@ BEHAVIOR_DT_INST_DEFINE(0, // // Equal to n for behaviors that do make use of multiple instances) _init, NULL, // Initialization Function, Power Management Device Pointer &_data, &_config, // Behavior Data Pointer, Behavior Configuration Pointer (Both Optional) - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, // Initialization Level, Device Priority + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, // Initialization Level, Device Priority &_driver_api); // API Structure #endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ From 58413ca8c578d9dc39972d4eaaccd73415f167e2 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Thu, 9 Nov 2023 00:20:27 -0800 Subject: [PATCH 018/127] refactor(kscan): Clean up warning about shadowed local. --- app/module/drivers/kscan/kscan_gpio_direct.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/module/drivers/kscan/kscan_gpio_direct.c b/app/module/drivers/kscan/kscan_gpio_direct.c index 5b227784..b5e77f63 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) { From b6d9f3c911bc39095825f35c5df176d95ee07d0a Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Thu, 9 Nov 2023 23:58:28 +0000 Subject: [PATCH 019/127] fix(ble): Ensure large enough string for setting name. * Fix warning related to potentially large number of profiles causing overflow of allocated string for the setting name. --- app/src/ble.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/ble.c b/app/src/ble.c index 3ed735a1..7e1ae7d4 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -98,7 +98,7 @@ bool zmk_ble_active_profile_is_open(void) { } 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)); From 98e3b8b4350d0d588bb8b8a38bf184090886b3ee Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Thu, 9 Nov 2023 23:59:15 +0000 Subject: [PATCH 020/127] refactor: Move to new sys_poweroff API. * Move to new `sys_poweroff` API for our deep sleep functionality. --- app/Kconfig | 5 ++--- app/src/activity.c | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/Kconfig b/app/Kconfig index 0e761bed..3a70f294 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -387,13 +387,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/src/activity.c b/app/src/activity.c index 330008b3..11409151 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) { From a81a2d37a8bacbae0dbc0aba8a8833232f7a1b39 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 10 Nov 2023 00:03:57 +0000 Subject: [PATCH 021/127] refactor: Remove explicit blocklist item. * `sof` is now not enabled by default as a west dep, so need to add it to the blocklist ourselves. --- app/west.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/west.yml b/app/west.yml index 95ab9200..1b502477 100644 --- a/app/west.yml +++ b/app/west.yml @@ -29,6 +29,5 @@ manifest: - openthread - edtt - trusted-firmware-m - - sof self: west-commands: scripts/west-commands.yml From 552347b8a4945f464554c74b261433ebc8f66f43 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 10 Nov 2023 03:51:42 +0000 Subject: [PATCH 022/127] fix(kscan): Adjust composite kscan priority * Composite kscan needs a dedicated priority to be sure it is initialized after the other kscan instances. --- app/module/drivers/kscan/Kconfig | 8 ++++++++ app/module/drivers/kscan/kscan_composite.c | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/module/drivers/kscan/Kconfig b/app/module/drivers/kscan/Kconfig index 6b701936..88848dff 100644 --- a/app/module/drivers/kscan/Kconfig +++ b/app/module/drivers/kscan/Kconfig @@ -14,6 +14,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 97311ef8..2a364324 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); From 94aa7d8d532f1e84e8e8b9fa96c522468dfc259d Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Tue, 14 Nov 2023 23:56:11 +0000 Subject: [PATCH 023/127] chore(ci): Bump to 3.5 Docker images. --- .devcontainer/Dockerfile | 2 +- .github/workflows/ble-test.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/hardware-metadata-validation.yml | 2 +- .github/workflows/test.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 5b69e180..5e123bd5 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 COPY .bashrc tmp RUN mv /tmp/.bashrc ~/.bashrc diff --git a/.github/workflows/ble-test.yml b/.github/workflows/ble-test.yml index d5570533..dd7de632 100644 --- a/.github/workflows/ble-test.yml +++ b/.github/workflows/ble-test.yml @@ -35,7 +35,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 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ca44e61a..c2d1992d 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 needs: compile-matrix strategy: matrix: diff --git a/.github/workflows/hardware-metadata-validation.yml b/.github/workflows/hardware-metadata-validation.yml index f0107a2d..716cd976 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 steps: - uses: actions/checkout@v4 - name: Install dependencies diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ebb63435..0df1f0c6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,7 +35,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 steps: - name: Checkout uses: actions/checkout@v4 From f4e6d704652e0cfc46bd0018deb6cddeb8c1b9ca Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 15 Nov 2023 00:40:36 +0000 Subject: [PATCH 024/127] fix: Proper use of CONTAINER_OF with delayable work. --- app/module/drivers/kscan/kscan_gpio_demux.c | 4 +++- app/module/drivers/kscan/kscan_gpio_matrix.c | 2 +- app/module/drivers/kscan/kscan_mock.c | 3 ++- app/src/behaviors/behavior_hold_tap.c | 3 ++- app/src/behaviors/behavior_sticky_key.c | 3 ++- app/src/behaviors/behavior_tap_dance.c | 4 +++- 6 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/module/drivers/kscan/kscan_gpio_demux.c b/app/module/drivers/kscan/kscan_gpio_demux.c index 2cbe116d..10433c5a 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_matrix.c b/app/module/drivers/kscan/kscan_gpio_matrix.c index 0d8a3190..6e91bf95 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 187a1686..1ffb937e 100644 --- a/app/module/drivers/kscan/kscan_mock.c +++ b/app/module/drivers/kscan/kscan_mock.c @@ -62,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/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 8c28531c..efc96c1a 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -710,7 +710,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); diff --git a/app/src/behaviors/behavior_sticky_key.c b/app/src/behaviors/behavior_sticky_key.c index f1131f66..05f6846b 100644 --- a/app/src/behaviors/behavior_sticky_key.c +++ b/app/src/behaviors/behavior_sticky_key.c @@ -262,8 +262,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; } diff --git a/app/src/behaviors/behavior_tap_dance.c b/app/src/behaviors/behavior_tap_dance.c index 40427ef8..4f6fa1a1 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; } From 802881b625664123a99db75e21e7c9dbe2b75c2c Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 15 Nov 2023 04:22:09 +0000 Subject: [PATCH 025/127] fix(boards): Remove references to PINMUX Kconfig. --- 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/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 --- 9 files changed, 4 insertions(+), 28 deletions(-) diff --git a/app/boards/arm/dz60rgb/dz60rgb_rev1_defconfig b/app/boards/arm/dz60rgb/dz60rgb_rev1_defconfig index 53bc0e11..6b6c8a48 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 267035c9..bd03c305 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 12cf9b1c..05214a68 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 8117cc87..5702c6de 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/nrfmicro/CMakeLists.txt b/app/boards/arm/nrfmicro/CMakeLists.txt index 12cf9b1c..05214a68 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 659e9c5c..38daacde 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 74050f3d..ce08f41d 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 12cf9b1c..05214a68 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 3533104b..0ba7eefd 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 From 413820fc7fba58323a8c2fa0cae8b6c7e59e4548 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 15 Nov 2023 16:06:21 -0800 Subject: [PATCH 026/127] fix(shields): LVGL fixes for nice!view screen * Bump the LVGL mem pool size needed for custom screen. * Fixes for LVGL drawing/label usage. --- app/boards/shields/nice_view/Kconfig.defconfig | 3 +++ app/boards/shields/nice_view/widgets/status.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/boards/shields/nice_view/Kconfig.defconfig b/app/boards/shields/nice_view/Kconfig.defconfig index 84fdd7cc..c31cec89 100644 --- a/app/boards/shields/nice_view/Kconfig.defconfig +++ b/app/boards/shields/nice_view/Kconfig.defconfig @@ -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 3346546e..93139eca 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); From 4fcbe3268a6e0fbbd56a9936d75a0d777c9bd065 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 4 Dec 2023 19:44:42 +0000 Subject: [PATCH 027/127] fix(bt): Updated snapshots for BLE tests. * Core Zephyr changes tweaked the output from the BT stack for our unit tests. --- .../snapshot.log | 12 ++++++------ .../profiles/bond-to-cleared-profile/snapshot.log | 12 ++++++------ .../connnect-and-output-to-selection/snapshot.log | 6 +++--- .../dont-bond-to-taken-profile/snapshot.log | 14 +++++++------- .../snapshot.log | 14 +++++++------- .../snapshot.log | 12 ++++++------ 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/app/tests/ble/profiles/bond-clear-then-bond-second-client/snapshot.log b/app/tests/ble/profiles/bond-clear-then-bond-second-client/snapshot.log index 4939c0d7..077634f2 100644 --- a/app/tests/ble/profiles/bond-clear-then-bond-second-client/snapshot.log +++ b/app/tests/ble/profiles/bond-clear-then-bond-second-client/snapshot.log @@ -1,23 +1,23 @@ profile 0 bt_id: No static addresses stored in controller -profile 0 ble_central: _posix_zephyr_main: [Bluetooth initialized] +profile 0 ble_central: main: [Bluetooth initialized] profile 0 ble_central: start_scan: [Scanning successfully started] -profile 0 ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 +profile 0 ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 profile 0 ble_central: eir_found: [AD]: 9 data_len 0 profile 0 ble_central: eir_found: [AD]: 25 data_len 2 profile 0 ble_central: eir_found: [AD]: 1 data_len 1 profile 0 ble_central: eir_found: [AD]: 2 data_len 4 -profile 0 ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) +profile 0 ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) profile 0 ble_central: connected: [Setting the security for the connection] profile 0 ble_central: pairing_complete: Pairing complete profile 1 bt_id: No static addresses stored in controller -profile 1 ble_central: _posix_zephyr_main: [Bluetooth initialized] +profile 1 ble_central: main: [Bluetooth initialized] profile 1 ble_central: start_scan: [Scanning successfully started] -profile 1 ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 +profile 1 ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 profile 1 ble_central: eir_found: [AD]: 9 data_len 0 profile 1 ble_central: eir_found: [AD]: 25 data_len 2 profile 1 ble_central: eir_found: [AD]: 1 data_len 1 profile 1 ble_central: eir_found: [AD]: 2 data_len 4 -profile 1 ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) +profile 1 ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) profile 1 ble_central: connected: [Setting the security for the connection] profile 1 ble_central: pairing_complete: Pairing complete profile 1 ble_central: discover_conn: [Discovery started for conn] diff --git a/app/tests/ble/profiles/bond-to-cleared-profile/snapshot.log b/app/tests/ble/profiles/bond-to-cleared-profile/snapshot.log index 4939c0d7..077634f2 100644 --- a/app/tests/ble/profiles/bond-to-cleared-profile/snapshot.log +++ b/app/tests/ble/profiles/bond-to-cleared-profile/snapshot.log @@ -1,23 +1,23 @@ profile 0 bt_id: No static addresses stored in controller -profile 0 ble_central: _posix_zephyr_main: [Bluetooth initialized] +profile 0 ble_central: main: [Bluetooth initialized] profile 0 ble_central: start_scan: [Scanning successfully started] -profile 0 ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 +profile 0 ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 profile 0 ble_central: eir_found: [AD]: 9 data_len 0 profile 0 ble_central: eir_found: [AD]: 25 data_len 2 profile 0 ble_central: eir_found: [AD]: 1 data_len 1 profile 0 ble_central: eir_found: [AD]: 2 data_len 4 -profile 0 ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) +profile 0 ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) profile 0 ble_central: connected: [Setting the security for the connection] profile 0 ble_central: pairing_complete: Pairing complete profile 1 bt_id: No static addresses stored in controller -profile 1 ble_central: _posix_zephyr_main: [Bluetooth initialized] +profile 1 ble_central: main: [Bluetooth initialized] profile 1 ble_central: start_scan: [Scanning successfully started] -profile 1 ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 +profile 1 ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 profile 1 ble_central: eir_found: [AD]: 9 data_len 0 profile 1 ble_central: eir_found: [AD]: 25 data_len 2 profile 1 ble_central: eir_found: [AD]: 1 data_len 1 profile 1 ble_central: eir_found: [AD]: 2 data_len 4 -profile 1 ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) +profile 1 ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) profile 1 ble_central: connected: [Setting the security for the connection] profile 1 ble_central: pairing_complete: Pairing complete profile 1 ble_central: discover_conn: [Discovery started for conn] diff --git a/app/tests/ble/profiles/connnect-and-output-to-selection/snapshot.log b/app/tests/ble/profiles/connnect-and-output-to-selection/snapshot.log index 092bb034..62cb2d6d 100644 --- a/app/tests/ble/profiles/connnect-and-output-to-selection/snapshot.log +++ b/app/tests/ble/profiles/connnect-and-output-to-selection/snapshot.log @@ -1,12 +1,12 @@ bt_id: No static addresses stored in controller - ble_central: _posix_zephyr_main: [Bluetooth initialized] + ble_central: main: [Bluetooth initialized] ble_central: start_scan: [Scanning successfully started] - ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 + ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 ble_central: eir_found: [AD]: 9 data_len 0 ble_central: eir_found: [AD]: 25 data_len 2 ble_central: eir_found: [AD]: 1 data_len 1 ble_central: eir_found: [AD]: 2 data_len 4 - ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) + ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) ble_central: connected: [Setting the security for the connection] ble_central: pairing_complete: Pairing complete ble_central: discover_conn: [Discovery started for conn] diff --git a/app/tests/ble/profiles/dont-bond-to-taken-profile/snapshot.log b/app/tests/ble/profiles/dont-bond-to-taken-profile/snapshot.log index d41eae79..6ea4fc72 100644 --- a/app/tests/ble/profiles/dont-bond-to-taken-profile/snapshot.log +++ b/app/tests/ble/profiles/dont-bond-to-taken-profile/snapshot.log @@ -1,23 +1,23 @@ profile 0 bt_id: No static addresses stored in controller -profile 0 ble_central: _posix_zephyr_main: [Bluetooth initialized] +profile 0 ble_central: main: [Bluetooth initialized] profile 0 ble_central: start_scan: [Scanning successfully started] -profile 0 ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 +profile 0 ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 profile 0 ble_central: eir_found: [AD]: 9 data_len 0 profile 0 ble_central: eir_found: [AD]: 25 data_len 2 profile 0 ble_central: eir_found: [AD]: 1 data_len 1 profile 0 ble_central: eir_found: [AD]: 2 data_len 4 -profile 0 ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) +profile 0 ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) profile 0 ble_central: connected: [Setting the security for the connection] profile 0 ble_central: pairing_complete: Pairing complete profile 1 bt_id: No static addresses stored in controller -profile 1 ble_central: _posix_zephyr_main: [Bluetooth initialized] +profile 1 ble_central: main: [Bluetooth initialized] profile 1 ble_central: start_scan: [Scanning successfully started] -profile 1 ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 +profile 1 ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 profile 1 ble_central: eir_found: [AD]: 9 data_len 0 profile 1 ble_central: eir_found: [AD]: 25 data_len 2 profile 1 ble_central: eir_found: [AD]: 1 data_len 1 profile 1 ble_central: eir_found: [AD]: 2 data_len 4 -profile 1 ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) +profile 1 ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) profile 1 ble_central: connected: [Setting the security for the connection] -profile 1 bt_smp: reason 0x8 +profile 1 bt_smp: pairing failed (peer reason 0x8) profile 1 ble_central: security_changed: [Security Change Failed] diff --git a/app/tests/ble/profiles/first-and-second-profile-paired-then-send-data/snapshot.log b/app/tests/ble/profiles/first-and-second-profile-paired-then-send-data/snapshot.log index a03bbb09..1a88748d 100644 --- a/app/tests/ble/profiles/first-and-second-profile-paired-then-send-data/snapshot.log +++ b/app/tests/ble/profiles/first-and-second-profile-paired-then-send-data/snapshot.log @@ -1,19 +1,19 @@ profile 0 bt_id: No static addresses stored in controller -profile 0 ble_central: _posix_zephyr_main: [Bluetooth initialized] +profile 0 ble_central: main: [Bluetooth initialized] profile 0 ble_central: start_scan: [Scanning successfully started] -profile 0 ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 +profile 0 ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 profile 0 ble_central: eir_found: [AD]: 9 data_len 0 profile 0 ble_central: eir_found: [AD]: 25 data_len 2 profile 0 ble_central: eir_found: [AD]: 1 data_len 1 profile 0 ble_central: eir_found: [AD]: 2 data_len 4 -profile 0 ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) +profile 0 ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) profile 0 ble_central: connected: [Setting the security for the connection] profile 0 ble_central: pairing_complete: Pairing complete profile 0 ble_central: discover_conn: [Discovery started for conn] -profile 0 ble_central: discover_func: [ATTRIBUTE] handle 23 profile 1 bt_id: No static addresses stored in controller -profile 1 ble_central: _posix_zephyr_main: [Bluetooth initialized] +profile 1 ble_central: main: [Bluetooth initialized] profile 1 ble_central: start_scan: [Scanning successfully started] +profile 0 ble_central: discover_func: [ATTRIBUTE] handle 23 profile 0 ble_central: discover_func: [ATTRIBUTE] handle 28 profile 0 ble_central: discover_func: [ATTRIBUTE] handle 30 profile 0 ble_central: discover_func: [SUBSCRIBED] @@ -21,12 +21,12 @@ profile 0 ble_central: notify_func: payload profile 0 00 00 04 00 00 00 00 00 |........ profile 0 ble_central: notify_func: payload profile 0 00 00 00 00 00 00 00 00 |........ -profile 1 ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 +profile 1 ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 profile 1 ble_central: eir_found: [AD]: 9 data_len 0 profile 1 ble_central: eir_found: [AD]: 25 data_len 2 profile 1 ble_central: eir_found: [AD]: 1 data_len 1 profile 1 ble_central: eir_found: [AD]: 2 data_len 4 -profile 1 ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) +profile 1 ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) profile 1 ble_central: connected: [Setting the security for the connection] profile 1 ble_central: pairing_complete: Pairing complete profile 1 ble_central: discover_conn: [Discovery started for conn] diff --git a/app/tests/ble/profiles/reconnect-then-output-to-selection/snapshot.log b/app/tests/ble/profiles/reconnect-then-output-to-selection/snapshot.log index bf6cc49e..2323de6f 100644 --- a/app/tests/ble/profiles/reconnect-then-output-to-selection/snapshot.log +++ b/app/tests/ble/profiles/reconnect-then-output-to-selection/snapshot.log @@ -1,22 +1,22 @@ bt_id: No static addresses stored in controller - ble_central: _posix_zephyr_main: [Bluetooth initialized] + ble_central: main: [Bluetooth initialized] ble_central: start_scan: [Scanning successfully started] - ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 + ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 ble_central: eir_found: [AD]: 9 data_len 0 ble_central: eir_found: [AD]: 25 data_len 2 ble_central: eir_found: [AD]: 1 data_len 1 ble_central: eir_found: [AD]: 2 data_len 4 - ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) + ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) ble_central: connected: [Setting the security for the connection] ble_central: pairing_complete: Pairing complete - ble_central: disconnected: [Disconnected]: ED:3B:20:15:18:12 (random) (reason 0x16) + ble_central: disconnected: [Disconnected]: FD:9E:B2:48:47:39 (random) (reason 0x16) ble_central: start_scan: [Scanning successfully started] - ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 + ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 ble_central: eir_found: [AD]: 9 data_len 0 ble_central: eir_found: [AD]: 25 data_len 2 ble_central: eir_found: [AD]: 1 data_len 1 ble_central: eir_found: [AD]: 2 data_len 4 - ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) + ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) ble_central: connected: [Setting the security for the connection] ble_central: discover_conn: [Discovery started for conn] ble_central: discover_func: [ATTRIBUTE] handle 23 From b3f1d769f09635da74fe3878b113d5797a1227d3 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 4 Dec 2023 12:58:13 -0800 Subject: [PATCH 028/127] fix(bt): Fixes for BLE test BSIM bits. --- .github/workflows/ble-test.yml | 2 +- .../snapshot.log | 12 ++++++------ .../snapshot.log | 6 +++--- .../snapshot.log | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ble-test.yml b/.github/workflows/ble-test.yml index dd7de632..867c7f7e 100644 --- a/.github/workflows/ble-test.yml +++ b/.github/workflows/ble-test.yml @@ -69,7 +69,7 @@ jobs: run: make everything - name: Test ${{ matrix.test }} working-directory: app - run: BSIM_COMPONENTS_PATH="${GITHUB_WORKSPACE}/tools/bsim/components/" BSIM_OUT_PATH="${GITHUB_WORKSPACE}/tools/bsim/" ./run-ble-test.sh tests/ble/${{ matrix.test }} + run: BSIM_COMPONENTS_PATH="${GITHUB_WORKSPACE}/tools/bsim/components" BSIM_OUT_PATH="${GITHUB_WORKSPACE}/tools/bsim" ./run-ble-test.sh tests/ble/${{ matrix.test }} - name: Archive artifacts if: ${{ always() }} uses: actions/upload-artifact@v4 diff --git a/app/tests/ble/profiles/overwrite-enabled-reconnect-without-bond-then-output-to-selection/snapshot.log b/app/tests/ble/profiles/overwrite-enabled-reconnect-without-bond-then-output-to-selection/snapshot.log index da2a0c77..6c0bac58 100644 --- a/app/tests/ble/profiles/overwrite-enabled-reconnect-without-bond-then-output-to-selection/snapshot.log +++ b/app/tests/ble/profiles/overwrite-enabled-reconnect-without-bond-then-output-to-selection/snapshot.log @@ -1,22 +1,22 @@ bt_id: No static addresses stored in controller - ble_central: _posix_zephyr_main: [Bluetooth initialized] + ble_central: main: [Bluetooth initialized] ble_central: start_scan: [Scanning successfully started] - ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 + ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 ble_central: eir_found: [AD]: 9 data_len 0 ble_central: eir_found: [AD]: 25 data_len 2 ble_central: eir_found: [AD]: 1 data_len 1 ble_central: eir_found: [AD]: 2 data_len 4 - ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) + ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) ble_central: connected: [Setting the security for the connection] ble_central: pairing_complete: Pairing complete - ble_central: disconnected: [Disconnected]: ED:3B:20:15:18:12 (random) (reason 0x16) + ble_central: disconnected: [Disconnected]: FD:9E:B2:48:47:39 (random) (reason 0x16) ble_central: start_scan: [Scanning successfully started] - ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 + ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 ble_central: eir_found: [AD]: 9 data_len 0 ble_central: eir_found: [AD]: 25 data_len 2 ble_central: eir_found: [AD]: 1 data_len 1 ble_central: eir_found: [AD]: 2 data_len 4 - ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) + ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) ble_central: connected: [Setting the security for the connection] ble_central: pairing_complete: Pairing complete ble_central: discover_conn: [Discovery started for conn] diff --git a/app/tests/ble/security/read-hid-after-connect-with-auto-sec/snapshot.log b/app/tests/ble/security/read-hid-after-connect-with-auto-sec/snapshot.log index 1ec7918f..0ab1bea5 100644 --- a/app/tests/ble/security/read-hid-after-connect-with-auto-sec/snapshot.log +++ b/app/tests/ble/security/read-hid-after-connect-with-auto-sec/snapshot.log @@ -1,12 +1,12 @@ bt_id: No static addresses stored in controller - ble_central: _posix_zephyr_main: [Bluetooth initialized] + ble_central: main: [Bluetooth initialized] ble_central: start_scan: [Scanning successfully started] - ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 + ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 ble_central: eir_found: [AD]: 9 data_len 0 ble_central: eir_found: [AD]: 25 data_len 2 ble_central: eir_found: [AD]: 1 data_len 1 ble_central: eir_found: [AD]: 2 data_len 4 - ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) + ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) ble_central: pairing_complete: Pairing complete ble_central: read_cb: Read err: 0, length 8 ble_central: read_cb: Read err: 0, length 12 diff --git a/app/tests/ble/security/read-hid-after-connect-without-auto-sec/snapshot.log b/app/tests/ble/security/read-hid-after-connect-without-auto-sec/snapshot.log index fc32198c..2157fd03 100644 --- a/app/tests/ble/security/read-hid-after-connect-without-auto-sec/snapshot.log +++ b/app/tests/ble/security/read-hid-after-connect-without-auto-sec/snapshot.log @@ -1,10 +1,10 @@ bt_id: No static addresses stored in controller - ble_central: _posix_zephyr_main: [Bluetooth initialized] + ble_central: main: [Bluetooth initialized] ble_central: start_scan: [Scanning successfully started] - ble_central: device_found: [DEVICE]: ED:3B:20:15:18:12 (random), AD evt type 0, AD data len 15, RSSI -59 + ble_central: device_found: [DEVICE]: FD:9E:B2:48:47:39 (random), AD evt type 0, AD data len 15, RSSI -59 ble_central: eir_found: [AD]: 9 data_len 0 ble_central: eir_found: [AD]: 25 data_len 2 ble_central: eir_found: [AD]: 1 data_len 1 ble_central: eir_found: [AD]: 2 data_len 4 - ble_central: connected: [Connected]: ED:3B:20:15:18:12 (random) - ble_central: read_cb: Read err: 15, length 0 + ble_central: connected: [Connected]: FD:9E:B2:48:47:39 (random) + ble_central: read_cb: Read err: 5, length 0 From 3968d9febd434123d7ac3296a934e5913141277d Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 4 Dec 2023 13:55:42 -0800 Subject: [PATCH 029/127] feat(boards): Make `west flash` work with new UF2 runner. --- app/boards/arm/adv360pro/board.cmake | 1 + app/boards/arm/bluemicro840/board.cmake | 2 +- app/boards/arm/bt60/board.cmake | 2 +- app/boards/arm/ckp/board.cmake | 1 + app/boards/arm/corneish_zen/board.cmake | 2 +- app/boards/arm/glove80/board.cmake | 2 +- app/boards/arm/mikoto/board.cmake | 2 +- app/boards/arm/nice60/board.cmake | 1 + app/boards/arm/nice_nano/board.cmake | 2 +- app/boards/arm/nrfmicro/board.cmake | 2 +- app/boards/arm/pillbug/board.cmake | 1 + app/boards/arm/puchi_ble/board.cmake | 2 +- app/boards/arm/s40nc/board.cmake | 1 + 13 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/boards/arm/adv360pro/board.cmake b/app/boards/arm/adv360pro/board.cmake index 6d62a8a1..bee7f6ad 100644 --- a/app/boards/arm/adv360pro/board.cmake +++ b/app/boards/arm/adv360pro/board.cmake @@ -5,4 +5,5 @@ board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/bluemicro840/board.cmake b/app/boards/arm/bluemicro840/board.cmake index fa847d50..73fa64a9 100644 --- a/app/boards/arm/bluemicro840/board.cmake +++ b/app/boards/arm/bluemicro840/board.cmake @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MIT board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") -include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/bt60/board.cmake b/app/boards/arm/bt60/board.cmake index fa847d50..73fa64a9 100644 --- a/app/boards/arm/bt60/board.cmake +++ b/app/boards/arm/bt60/board.cmake @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MIT board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") -include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/ckp/board.cmake b/app/boards/arm/ckp/board.cmake index b7feee2e..73fa64a9 100644 --- a/app/boards/arm/ckp/board.cmake +++ b/app/boards/arm/ckp/board.cmake @@ -1,4 +1,5 @@ # SPDX-License-Identifier: MIT board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/corneish_zen/board.cmake b/app/boards/arm/corneish_zen/board.cmake index fa847d50..73fa64a9 100644 --- a/app/boards/arm/corneish_zen/board.cmake +++ b/app/boards/arm/corneish_zen/board.cmake @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MIT board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") -include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/glove80/board.cmake b/app/boards/arm/glove80/board.cmake index 36030db7..ed0e07a5 100644 --- a/app/boards/arm/glove80/board.cmake +++ b/app/boards/arm/glove80/board.cmake @@ -2,5 +2,5 @@ # SPDX-License-Identifier: MIT board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") -include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/mikoto/board.cmake b/app/boards/arm/mikoto/board.cmake index fa847d50..73fa64a9 100644 --- a/app/boards/arm/mikoto/board.cmake +++ b/app/boards/arm/mikoto/board.cmake @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MIT board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") -include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/nice60/board.cmake b/app/boards/arm/nice60/board.cmake index 2aca938a..669907b9 100644 --- a/app/boards/arm/nice60/board.cmake +++ b/app/boards/arm/nice60/board.cmake @@ -3,5 +3,6 @@ set(OPENOCD_NRF5_SUBFAMILY nrf52) board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) diff --git a/app/boards/arm/nice_nano/board.cmake b/app/boards/arm/nice_nano/board.cmake index fa847d50..73fa64a9 100644 --- a/app/boards/arm/nice_nano/board.cmake +++ b/app/boards/arm/nice_nano/board.cmake @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MIT board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") -include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/nrfmicro/board.cmake b/app/boards/arm/nrfmicro/board.cmake index fa847d50..73fa64a9 100644 --- a/app/boards/arm/nrfmicro/board.cmake +++ b/app/boards/arm/nrfmicro/board.cmake @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MIT board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") -include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/pillbug/board.cmake b/app/boards/arm/pillbug/board.cmake index 992f395d..d9d4ed92 100644 --- a/app/boards/arm/pillbug/board.cmake +++ b/app/boards/arm/pillbug/board.cmake @@ -2,5 +2,6 @@ set(OPENOCD_NRF5_SUBFAMILY nrf52) board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) diff --git a/app/boards/arm/puchi_ble/board.cmake b/app/boards/arm/puchi_ble/board.cmake index 3b5c4aea..fd74278a 100644 --- a/app/boards/arm/puchi_ble/board.cmake +++ b/app/boards/arm/puchi_ble/board.cmake @@ -2,5 +2,5 @@ # SPDX-License-Identifier: MIT board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") -include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/s40nc/board.cmake b/app/boards/arm/s40nc/board.cmake index c50b2d9d..d31c7167 100644 --- a/app/boards/arm/s40nc/board.cmake +++ b/app/boards/arm/s40nc/board.cmake @@ -3,5 +3,6 @@ set(OPENOCD_NRF5_SUBFAMILY nrf52) board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) From 8e9b4fa57c69f2ec88883f1dddd0529bed1fa2e8 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 4 Dec 2023 14:39:41 -0800 Subject: [PATCH 030/127] fix(boards): Make `&bootloader` work on nrf52 for now. * Use `NRF_STORE_REBOOT_TYPE_GPREGRET` to get bootloader behavior to work for now until retained bootmode is implemented. --- app/Kconfig | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/Kconfig b/app/Kconfig index 3a70f294..4d6d8401 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -37,6 +37,17 @@ config BT_DIS_MODEL config BT_DIS_MANUF default "ZMK Project" +# Hardware specific overrides + +if SOC_SERIES_NRF52X + +# Default on for our usage until boards implement retained bootmode. +config NRF_STORE_REBOOT_TYPE_GPREGRET + bool + default y + +endif + menu "HID" choice ZMK_HID_REPORT_TYPE From 324ada1d20a6069ff23e47c7ed0ed3e13ddae44c Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 4 Dec 2023 22:47:31 +0000 Subject: [PATCH 031/127] fix(boards): Remove unused pin settings. * Remove unused pin settings that used deprecated devicetree properties. --- app/boards/arm/bt60/bt60.dtsi | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/app/boards/arm/bt60/bt60.dtsi b/app/boards/arm/bt60/bt60.dtsi index ba106c65..655d2576 100644 --- a/app/boards/arm/bt60/bt60.dtsi +++ b/app/boards/arm/bt60/bt60.dtsi @@ -70,18 +70,6 @@ status = "okay"; }; -&i2c0 { - compatible = "nordic,nrf-twi"; - sda-pin = <17>; - scl-pin = <20>; -}; - -&uart0 { - compatible = "nordic,nrf-uarte"; - tx-pin = <6>; - rx-pin = <8>; -}; - &usbd { status = "okay"; cdc_acm_uart: cdc_acm_uart { From a6c03994932994be26cfeb05aa680470ccb97031 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 11 Dec 2023 16:35:16 -0800 Subject: [PATCH 032/127] fix(bluetooth): Remove LLCP impl override. --- app/Kconfig | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/Kconfig b/app/Kconfig index 4d6d8401..f9192da4 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -183,11 +183,6 @@ config ZMK_BLE_PASSKEY_ENTRY config BT_SMP_ALLOW_UNAUTH_OVERWRITE imply ZMK_BLE_PASSKEY_ENTRY -choice BT_LL_SW_LLCP_IMPL - default BT_LL_SW_LLCP_LEGACY if !ZMK_BLE_EXPERIMENTAL_CONN - -endchoice - config BT_CTLR_PHY_2M default n if ZMK_BLE_EXPERIMENTAL_CONN From aeb5bed3d69ded562cc0025d737a64a6c12b240f Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Sun, 14 Jan 2024 19:19:23 +0000 Subject: [PATCH 033/127] fix(kscan): Adjust charlieplex init level/priority. --- app/module/drivers/kscan/kscan_gpio_charlieplex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/module/drivers/kscan/kscan_gpio_charlieplex.c b/app/module/drivers/kscan/kscan_gpio_charlieplex.c index f450af2b..a4867aa3 100644 --- a/app/module/drivers/kscan/kscan_gpio_charlieplex.c +++ b/app/module/drivers/kscan/kscan_gpio_charlieplex.c @@ -414,7 +414,7 @@ static const struct kscan_driver_api kscan_charlieplex_api = { COND_THIS_INTERRUPT(n, (.interrupt = KSCAN_INTR_CFG_INIT(n), ))}; \ \ DEVICE_DT_INST_DEFINE(n, &kscan_charlieplex_init, NULL, &kscan_charlieplex_data_##n, \ - &kscan_charlieplex_config_##n, APPLICATION, \ - CONFIG_APPLICATION_INIT_PRIORITY, &kscan_charlieplex_api); + &kscan_charlieplex_config_##n, POST_KERNEL, CONFIG_KSCAN_INIT_PRIORITY, \ + &kscan_charlieplex_api); DT_INST_FOREACH_STATUS_OKAY(KSCAN_CHARLIEPLEX_INIT); From d9c0ded40292a4a0cacc257748c116c2b934034a Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Tue, 16 Jan 2024 16:42:31 -0800 Subject: [PATCH 034/127] fix(shields): Fix use of deprecated Zephyr header. --- app/boards/shields/nice_view/widgets/peripheral_status.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/boards/shields/nice_view/widgets/peripheral_status.c b/app/boards/shields/nice_view/widgets/peripheral_status.c index cec0f7b2..b9da1996 100644 --- a/app/boards/shields/nice_view/widgets/peripheral_status.c +++ b/app/boards/shields/nice_view/widgets/peripheral_status.c @@ -6,7 +6,7 @@ */ #include -#include +#include #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); From b2a0a357e132dc81f64ff2d39096d1a433a8d40f Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 17 Jan 2024 14:48:17 -0800 Subject: [PATCH 035/127] fix(display): Set a default mem size for built-in * Set a reasonable default LVGL mem pool size for our built-in status screen. --- app/src/display/Kconfig | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/display/Kconfig b/app/src/display/Kconfig index 3e17ff76..356b4760 100644 --- a/app/src/display/Kconfig +++ b/app/src/display/Kconfig @@ -29,11 +29,8 @@ endchoice config LV_MEM_CUSTOM default y -# config LV_Z_MEM_POOL_MIN_SIZE -# default 32 - -# config LV_Z_MEM_POOL_MAX_SIZE -# default 8192 + config LV_Z_MEM_POOL_SIZE + default 4096 if ZMK_DISPLAY_STATUS_SCREEN_BUILT_IN choice ZMK_DISPLAY_STATUS_SCREEN prompt "Default status screen for displays" From cd6f8a680ced404d5b12e1caeed6ca8ecfb2732d Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 29 Jan 2024 08:36:02 +0000 Subject: [PATCH 036/127] fix(ble): Update security test for changes in 3.5. --- .../security/read-hid-after-connect-with-auto-sec/snapshot.log | 1 - 1 file changed, 1 deletion(-) diff --git a/app/tests/ble/security/read-hid-after-connect-with-auto-sec/snapshot.log b/app/tests/ble/security/read-hid-after-connect-with-auto-sec/snapshot.log index 0ab1bea5..b8ee29eb 100644 --- a/app/tests/ble/security/read-hid-after-connect-with-auto-sec/snapshot.log +++ b/app/tests/ble/security/read-hid-after-connect-with-auto-sec/snapshot.log @@ -10,4 +10,3 @@ ble_central: pairing_complete: Pairing complete ble_central: read_cb: Read err: 0, length 8 ble_central: read_cb: Read err: 0, length 12 - ble_central: read_cb: Read err: 10, length 0 From 18e5a1a26b141b2ff25db9ade00fa68bc29e2ef6 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 15 Jan 2024 01:24:49 +0000 Subject: [PATCH 037/127] feat: Add Zephyr 3.5 blog post. --- docs/blog/2024-02-09-zephyr-3-5.md | 143 +++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 docs/blog/2024-02-09-zephyr-3-5.md diff --git a/docs/blog/2024-02-09-zephyr-3-5.md b/docs/blog/2024-02-09-zephyr-3-5.md new file mode 100644 index 00000000..b3fec6cb --- /dev/null +++ b/docs/blog/2024-02-09-zephyr-3-5.md @@ -0,0 +1,143 @@ +--- +title: "Zephyr 3.5 Update" +author: Pete Johanson +author_title: Project Creator +author_url: https://gitlab.com/petejohanson +author_image_url: https://www.gravatar.com/avatar/2001ceff7e9dc753cf96fcb2e6f41110 +tags: [firmware, zephyr, core] +--- + +I'm happy to announce that we have completed the [work](https://github.com/zmkfirmware/zmk/pull/1995) to upgrade ZMK to [Zephyr 3.5](https://docs.zephyrproject.org/3.5.0/releases/release-notes-3.5.html)! + +[petejohanson] did the upgrade work to adjust ZMK for the Zephyr changes: + +- Add `west flash` support to all UF2 capable boards. +- Adjust for LVGL DTS/Kconfig changes +- Zephyr core API changes, including `CONTAINER_OF` work API changes, init priority/callback, and others + +## Getting The Changes + +Use the following steps to update to the latest tooling in order to properly use the new ZMK changes: + +### User Config Repositories Using GitHub Actions + +Existing user config repositories using Github Actions to build will pull down Zephyr 3.5 automatically, however if you created your user config a while ago, you may need to update it to reference our shared build configuration to leverage the correct Docker image. + +1. Replace the contents of your `.github/workflows/build.yml` with: + + ```yaml + on: [push, pull_request, workflow_dispatch] + + jobs: + build: + uses: zmkfirmware/zmk/.github/workflows/build-user-config.yml@main + ``` + +1. If it doesn't exist already, add a new file to your repository named `build.yaml`: + + ```yaml + # This file generates the GitHub Actions matrix + # For simple board + shield combinations, add them + # to the top level board and shield arrays, for more + # control, add individual board + shield combinations to + # the `include` property, e.g: + # + # board: [ "nice_nano_v2" ] + # shield: [ "corne_left", "corne_right" ] + # include: + # - board: bdn9_rev2 + # - board: nice_nano_v2 + # shield: reviung41 + # + --- + ``` + +and then update it as appropriate to build the right shields/boards for your configuration. + +### VS Code & Docker (Dev Container) + +If you build locally using VS Code & Docker then: + +- Pull the latest ZMK `main` with `git pull` for your ZMK checkout +- Reload the project +- If you are prompted to rebuild the remote container, click `Rebuild` +- Otherwise, press `F1` and run `Remote Containers: Rebuild Container` +- Once the container has rebuilt and reloaded, run `west update` to pull the updated Zephyr version and its dependencies. + +Once the container has rebuilt, VS Code will be running the 3.5 Docker image. + +### Local Host Development + +The following steps will get you building ZMK locally against Zephyr 3.5: + +- Run the updated [toolchain installation](/docs/development/setup#toolchain-installation) steps, and once completed, remove the previously installed SDK version (optional, existing SDK should still work) +- Install the latest version of `west` by running `pip3 install --user --update west`. +- Pull the latest ZMK `main` with `git pull` for your ZMK checkout +- Run `west update` to pull the updated Zephyr version and its dependencies + +From there, you should be ready to build as normal! + +## Board/Shield Changes + +The following changes have [already been completed](https://github.com/zmkfirmware/zmk/pull/1995/commits) for all boards/shields in ZMK `main` branch. For existing or new PRs, or out of tree boards, the following changes are necessary to properly work with the latest changes. + +### West Flash Support + +If you have a custom board for a target that has a UF2 supporting bootloader, you can easily add support for +flashing via `west flash`. Note that using `west flash` isn't mandatory, it is merely a convenient way to automate copying to the mass storage device, which you can continue to do manually. +To add support, add a line to your board's `board.cmake` file like so: + +``` +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) +``` + +### LVGL DTS/Kconfig Changes + +Two items were changed for LVGL use for displays that may need adjusting for custom shields: + +#### DPI Kconfig Rename + +The old `LV_Z_DPI` Kconfig symbol was promoted to a Kconfig in upstream LVGL, and is now named `LV_DPI_DEF`. You +will need to replace this symbol in your board/shield's `Kconfig.defconfig` file. + +#### SSD1306 OLED Inverse Refactor + +Inverting black/white pixels has moved out of the Kconfig system and into a new DTS property. If you have a custom +shield that uses an SSD1306, you should: + +- Remove any override for the `SSD1306_REVERSE_MODE` from your Kconfig files. +- Add the new `inversion-on;` boolean property to the SSD1306 node in your devicetree file. + +### Maxim max17048 Sensor Driver + +Upstream Zephyr has added a driver for the max17048 fuel gauge, but using the new [fuel gauge API](https://docs.zephyrproject.org/3.5.0/hardware/peripherals/fuel_gauge.html) that ZMK +does not yet consume. To avoid a conflict with the new upstream and keep our existing sensor driver, our driver has been renamed to be namespaced with a ZMK prefix. The following changes are needed for any boards using the driver: + +- Change the `compatible` value for the node to be `zmk,maxim-17048`, e.g. `compatible = "zmk,maxim-max17048";`. +- If enabling the driver explicitly via Kconfig, rename `MAX17048` to the new `ZMK_MAX17048` in your `Kconfig.defconfig` or `_defconfig` files. + +## Upcoming Changes + +Moving to Zephyr 3.5 will unblock several exciting efforts that were dependent on that Zephyr release. + +### BLE Stability Improvements + +Many users have reported various BLE issues with some hardware combinations, including challenges with updated +Intel drivers, and macOS general stability problems. The Zephyr 3.5 release includes many fixes for the BT host and controller portions that, combined with some small upcoming ZMK changes, have been reported to completely resolve previous issues. Further focused testing will immediately commence to fully verify the ZMK changes before +making them the default. + +If you'd like to test those changes, enable `CONFIG_ZMK_BLE_EXPERIMENTAL_CONN=y` for your builds. + +### Pointer Integration + +The Zephyr 3.5 release includes a new [input subsystem](https://docs.zephyrproject.org/3.5.0/services/input/index.html) that we will be leveraging for our upcoming pointer support. The open PR for that work is now unblocked and further testing and code review will begin to work on getting that feature integrated into ZMK as well. + +### Power Domains + +Several power domain related changes are now available as well, which were a necessity for continued work on the improved peripheral power handling that's planned to supersede the existing "VCC cutoff" code that currently exists but causes problems for builds that include multiple powered peripherals like Displays + RGB. + +## Thanks! + +Thanks to all the testers who have helped verify ZMK functionality on the newer Zephyr version. + +[petejohanson]: https://github.com/petejohanson From 2d6c9f797c7eb3a0eef26833303ecf1565e0bde2 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 5 Feb 2024 12:49:58 -0800 Subject: [PATCH 038/127] refactor(display): Move to proper SPI ready API. --- app/module/drivers/display/il0323.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/module/drivers/display/il0323.c b/app/module/drivers/display/il0323.c index 6555e5c1..372897aa 100644 --- a/app/module/drivers/display/il0323.c +++ b/app/module/drivers/display/il0323.c @@ -341,7 +341,7 @@ static int il0323_controller_init(const struct device *dev) { static int il0323_init(const struct device *dev) { const struct il0323_cfg *cfg = dev->config; - if (!spi_is_ready(&cfg->spi)) { + if (!spi_is_ready_dt(&cfg->spi)) { LOG_ERR("SPI device not ready for IL0323"); return -EIO; } From 4bcecd98f8b2d0870d6c1e904b5a38cb9c7eb5b8 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 5 Feb 2024 13:12:18 -0800 Subject: [PATCH 039/127] fix(display): Tweaks to memory Kconfig settings. * Don't default heap mempool by default now that there's a dedicated LVGL mempool * Set proper defaults for CiZ display hardware/custom screen. * Double the dedicated display thread stack size for CiZ. --- app/Kconfig | 3 --- app/boards/arm/corneish_zen/Kconfig.defconfig | 7 +++++++ app/boards/arm/corneish_zen/corneish_zen_v1_left_defconfig | 2 +- .../arm/corneish_zen/corneish_zen_v1_right_defconfig | 2 +- app/boards/arm/corneish_zen/corneish_zen_v2_left_defconfig | 2 +- .../arm/corneish_zen/corneish_zen_v2_right_defconfig | 2 +- app/module/drivers/display/il0323.c | 1 + 7 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/Kconfig b/app/Kconfig index f9192da4..14456b5f 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -599,9 +599,6 @@ endmenu #ZMK endmenu -config HEAP_MEM_POOL_SIZE - default 8192 if ZMK_DISPLAY - config KERNEL_BIN_NAME default "zmk" diff --git a/app/boards/arm/corneish_zen/Kconfig.defconfig b/app/boards/arm/corneish_zen/Kconfig.defconfig index f3cc959e..11f932b5 100644 --- a/app/boards/arm/corneish_zen/Kconfig.defconfig +++ b/app/boards/arm/corneish_zen/Kconfig.defconfig @@ -57,6 +57,13 @@ config IL0323 config ZMK_DISPLAY_BLANK_ON_IDLE default n +# Needed for the IL0323 driver which allocs memory to clear the display +config HEAP_MEM_POOL_SIZE + default 1024 + + config LV_Z_MEM_POOL_SIZE + default 4096 + endif # ZMK_DISPLAY menuconfig CUSTOM_WIDGET_BATTERY_STATUS diff --git a/app/boards/arm/corneish_zen/corneish_zen_v1_left_defconfig b/app/boards/arm/corneish_zen/corneish_zen_v1_left_defconfig index d7382556..d4de8ed3 100644 --- a/app/boards/arm/corneish_zen/corneish_zen_v1_left_defconfig +++ b/app/boards/arm/corneish_zen/corneish_zen_v1_left_defconfig @@ -44,7 +44,7 @@ CONFIG_ZMK_BLE=y # enable display drivers CONFIG_ZMK_DISPLAY_WORK_QUEUE_DEDICATED=y -CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_STACK_SIZE=2048 +CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_STACK_SIZE=4096 CONFIG_LV_Z_BITS_PER_PIXEL=1 CONFIG_LV_COLOR_DEPTH_1=y CONFIG_LV_DPI_DEF=145 diff --git a/app/boards/arm/corneish_zen/corneish_zen_v1_right_defconfig b/app/boards/arm/corneish_zen/corneish_zen_v1_right_defconfig index d89377bc..ad78217f 100644 --- a/app/boards/arm/corneish_zen/corneish_zen_v1_right_defconfig +++ b/app/boards/arm/corneish_zen/corneish_zen_v1_right_defconfig @@ -44,7 +44,7 @@ CONFIG_ZMK_BLE=y # enable display drivers CONFIG_ZMK_DISPLAY_WORK_QUEUE_DEDICATED=y -CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_STACK_SIZE=2048 +CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_STACK_SIZE=4096 CONFIG_LV_Z_BITS_PER_PIXEL=1 CONFIG_LV_COLOR_DEPTH_1=y CONFIG_LV_DPI_DEF=145 diff --git a/app/boards/arm/corneish_zen/corneish_zen_v2_left_defconfig b/app/boards/arm/corneish_zen/corneish_zen_v2_left_defconfig index 29a5f878..b6670fd8 100644 --- a/app/boards/arm/corneish_zen/corneish_zen_v2_left_defconfig +++ b/app/boards/arm/corneish_zen/corneish_zen_v2_left_defconfig @@ -40,7 +40,7 @@ CONFIG_ZMK_BLE=y # enable display drivers CONFIG_ZMK_DISPLAY_WORK_QUEUE_DEDICATED=y -CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_STACK_SIZE=2048 +CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_STACK_SIZE=4096 CONFIG_LV_Z_BITS_PER_PIXEL=1 CONFIG_LV_COLOR_DEPTH_1=y CONFIG_LV_DPI_DEF=145 diff --git a/app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig b/app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig index 83dc57d4..90cfe769 100644 --- a/app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig +++ b/app/boards/arm/corneish_zen/corneish_zen_v2_right_defconfig @@ -40,7 +40,7 @@ CONFIG_ZMK_BLE=y # enable display drivers CONFIG_ZMK_DISPLAY_WORK_QUEUE_DEDICATED=y -CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_STACK_SIZE=2048 +CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_STACK_SIZE=4096 CONFIG_LV_Z_BITS_PER_PIXEL=1 CONFIG_LV_COLOR_DEPTH_1=y CONFIG_LV_DPI_DEF=145 diff --git a/app/module/drivers/display/il0323.c b/app/module/drivers/display/il0323.c index 372897aa..c9d72fc5 100644 --- a/app/module/drivers/display/il0323.c +++ b/app/module/drivers/display/il0323.c @@ -177,6 +177,7 @@ static int il0323_clear_and_write_buffer(const struct device *dev, uint8_t patte line = k_malloc(IL0323_NUMOF_PAGES); if (line == NULL) { + LOG_ERR("Failed to allocate memory for the clear"); return -ENOMEM; } From edc72c1166d565c30480ec895bf0aa5d7bd29d2a Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 7 Feb 2024 07:03:29 +0000 Subject: [PATCH 040/127] chore(docs): Update Zephyr links to 3.5.0 versions. --- docs/docs/config/backlight.md | 6 +-- docs/docs/config/battery.md | 4 +- docs/docs/config/displays.md | 8 ++-- docs/docs/config/index.md | 16 ++++---- docs/docs/config/kscan.md | 6 +-- docs/docs/config/system.md | 2 +- .../development/boards-shields-keymaps.md | 10 ++--- docs/docs/development/build-flash.mdx | 8 ++-- docs/docs/development/new-behavior.mdx | 16 ++++---- docs/docs/development/new-shield.mdx | 4 +- docs/docs/development/setup.mdx | 40 +++++++++---------- docs/docs/development/usb-logging.mdx | 2 +- docs/docs/faq.md | 8 ++-- docs/docs/features/bluetooth.md | 2 +- docs/docs/intro.md | 2 +- 15 files changed, 67 insertions(+), 67 deletions(-) diff --git a/docs/docs/config/backlight.md b/docs/docs/config/backlight.md index 0db12910..3d554c57 100644 --- a/docs/docs/config/backlight.md +++ b/docs/docs/config/backlight.md @@ -26,7 +26,7 @@ The `*_START` settings only determine the initial backlight state. Any changes y ## Devicetree -Applies to: [`/chosen` node](https://docs.zephyrproject.org/latest/build/dts/intro.html#aliases-and-chosen-nodes) +Applies to: [`/chosen` node](https://docs.zephyrproject.org/3.5.0/build/dts/intro.html#aliases-and-chosen-nodes) | Property | Type | Description | | --------------- | ---- | -------------------------------------------- | @@ -34,7 +34,7 @@ Applies to: [`/chosen` node](https://docs.zephyrproject.org/latest/build/dts/int See the Zephyr devicetree bindings for LED drivers: -- [gpio-leds](https://docs.zephyrproject.org/3.0.0/reference/devicetree/bindings/gpio/gpio-leds.html) -- [pwm-leds](https://docs.zephyrproject.org/latest/build/dts/api/bindings/led/pwm-leds.html) +- [gpio-leds](https://docs.zephyrproject.org/3.5.0/build/dts/api/bindings/led/gpio-leds.html) +- [pwm-leds](https://docs.zephyrproject.org/3.5.0/build/dts/api/bindings/led/pwm-leds.html) See the [backlight feature page](../features/backlight.mdx) for examples of the properties that must be set to enable backlighting. diff --git a/docs/docs/config/battery.md b/docs/docs/config/battery.md index 8327a0b8..cc725e43 100644 --- a/docs/docs/config/battery.md +++ b/docs/docs/config/battery.md @@ -30,7 +30,7 @@ On macOS the BLE battery reporting packets can cause the computer to wakeup from ### Devicetree -Applies to: [`/chosen` node](https://docs.zephyrproject.org/latest/guides/dts/intro.html#aliases-and-chosen-nodes) +Applies to: [`/chosen` node](https://docs.zephyrproject.org/3.5.0/guides/dts/intro.html#aliases-and-chosen-nodes) | Property | Type | Description | | ------------- | ---- | --------------------------------------------- | @@ -44,7 +44,7 @@ Driver for reading the voltage of a battery using an ADC connected to a voltage Applies to: `compatible = "zmk,battery-voltage-divider"` -See [Zephyr's voltage divider documentation](https://docs.zephyrproject.org/latest/build/dts/api/bindings/adc/voltage-divider.html). +See [Zephyr's voltage divider documentation](https://docs.zephyrproject.org/3.5.0/build/dts/api/bindings/adc/voltage-divider.html). ## nRF VDDH Battery Sensor diff --git a/docs/docs/config/displays.md b/docs/docs/config/displays.md index e22f0da8..96a0074a 100644 --- a/docs/docs/config/displays.md +++ b/docs/docs/config/displays.md @@ -51,14 +51,14 @@ You must also configure the driver for your display. ZMK provides the following - [IL0323](https://github.com/zmkfirmware/zmk/blob/main/app/module/drivers/display/Kconfig.il0323) -Zephyr provides several display drivers as well. Search for the name of your display in [Zephyr's Kconfig options](https://docs.zephyrproject.org/latest/kconfig.html) documentation. +Zephyr provides several display drivers as well. Search for the name of your display in [Zephyr's Kconfig options](https://docs.zephyrproject.org/3.5.0/kconfig.html) documentation. ## Devicetree See the Devicetree bindings for your display. Here are the bindings for common displays: - [IL0323](https://github.com/zmkfirmware/zmk/blob/main/app/module/dts/bindings/display/gooddisplay%2Cil0323.yaml) -- [SSD1306 (i2c)](https://docs.zephyrproject.org/latest/build/dts/api/bindings/display/solomon,ssd1306fb-i2c.html) -- [SSD1306 (spi)](https://docs.zephyrproject.org/latest/build/dts/api/bindings/display/solomon,ssd1306fb-spi.html) +- [SSD1306 (i2c)](https://docs.zephyrproject.org/3.5.0/build/dts/api/bindings/display/solomon,ssd1306fb-i2c.html) +- [SSD1306 (spi)](https://docs.zephyrproject.org/3.5.0/build/dts/api/bindings/display/solomon,ssd1306fb-spi.html) -A full list of drivers provided by Zephyr can be found in [Zephyr's Devicetree bindings index](https://docs.zephyrproject.org/latest/build/dts/api/bindings.html). +A full list of drivers provided by Zephyr can be found in [Zephyr's Devicetree bindings index](https://docs.zephyrproject.org/3.5.0/build/dts/api/bindings.html). diff --git a/docs/docs/config/index.md b/docs/docs/config/index.md index 3a430a8b..c8da6d7c 100644 --- a/docs/docs/config/index.md +++ b/docs/docs/config/index.md @@ -44,7 +44,7 @@ ZMK will search the board folder for the following config files: Shared config files (excluding any `_left` or `_right` suffix) are not currently supported in board folders. -For more documentation on creating and configuring a new board, see [Zephyr's board porting guide](https://docs.zephyrproject.org/latest/hardware/porting/board_porting.html#write-kconfig-files). +For more documentation on creating and configuring a new board, see [Zephyr's board porting guide](https://docs.zephyrproject.org/3.5.0/hardware/porting/board_porting.html#write-kconfig-files). ### Shield Folder @@ -63,7 +63,7 @@ ZMK will search the shield folder for the following config files: Shared config files (excluding any `_left` or `_right` suffix) are not currently supported in shield folders. -For more documentation on creating and configuring a new shield, see [Zephyr's shield documentation](https://docs.zephyrproject.org/latest/hardware/porting/shields.html) and [ZMK's new keyboard shield](../development/new-shield.mdx) guide. +For more documentation on creating and configuring a new shield, see [Zephyr's shield documentation](https://docs.zephyrproject.org/3.5.0/hardware/porting/shields.html) and [ZMK's new keyboard shield](../development/new-shield.mdx) guide. ## Kconfig Files @@ -79,7 +79,7 @@ CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y The list of available settings is determined by various files in ZMK whose names start with `Kconfig`. Files ending with `_defconfig` use the same syntax, but are intended for setting configuration specific to the hardware which users typically won't need to change. Note that options are _not_ prefixed with `CONFIG_` in these files. -See [Zephyr's Kconfig documentation](https://docs.zephyrproject.org/latest/build/kconfig/index.html) for more details on Kconfig files. +See [Zephyr's Kconfig documentation](https://docs.zephyrproject.org/3.5.0/build/kconfig/index.html) for more details on Kconfig files. ### KConfig Value Types @@ -128,7 +128,7 @@ Devicetree files look like this: Devicetree properties apply to specific nodes in the tree instead of globally. The properties that can be set for each node are determined by `.yaml` files in ZMK in the various `dts/bindings` folders. -See [Zephyr's Devicetree guide](https://docs.zephyrproject.org/latest/build/dts/index.html) for more details on Devicetree files. +See [Zephyr's Devicetree guide](https://docs.zephyrproject.org/3.5.0/build/dts/index.html) for more details on Devicetree files. ### Changing Devicetree Properties @@ -149,7 +149,7 @@ The part before the colon, `kscan0`, is a label. This is optional, and it provid The `compatible` property indicates what type of node it is. Search this documentation for the text inside the quotes to see which properties the node supports. You can also search ZMK for a file whose name is the value of the `compatible` property with a `.yaml` file extension. -To set a property, see below for examples for common property types, or see [Zephyr's Devicetree documentation](https://docs.zephyrproject.org/latest/build/dts/intro.html#writing-property-values) for more details on the syntax for properties. +To set a property, see below for examples for common property types, or see [Zephyr's Devicetree documentation](https://docs.zephyrproject.org/3.5.0/build/dts/intro.html#writing-property-values) for more details on the syntax for properties. To change a property for an existing node, first find the node you want to change and find its label. Next, outside of any other node, write an ampersand (`&`) followed by the node's label, an opening curly brace (`{`), one or more new property values, a closing curly brace (`}`), and a semicolon (`;`). @@ -174,7 +174,7 @@ If the node you want to edit doesn't have a label, you can also write a new tree ### Devicetree Property Types -These are some of the property types you will see most often when working with ZMK. [Zephyr's Devicetree bindings documentation](https://docs.zephyrproject.org/latest/build/dts/bindings.html) provides more detailed information and a full list of types. +These are some of the property types you will see most often when working with ZMK. [Zephyr's Devicetree bindings documentation](https://docs.zephyrproject.org/3.5.0/build/dts/bindings.html) provides more detailed information and a full list of types. #### bool @@ -228,14 +228,14 @@ Example: `property = <&none &mo 1>;` Values can also be split into multiple blocks, e.g. `property = <&none>, <&mo 1>;` -See the documentation for "phandle-array" in [Zephyr's Devicetree bindings documentation](https://docs.zephyrproject.org/latest/build/dts/bindings.html) +See the documentation for "phandle-array" in [Zephyr's Devicetree bindings documentation](https://docs.zephyrproject.org/3.5.0/build/dts/bindings.html) for more details on how parameters are associated with nodes. #### GPIO array This is just a phandle array. The documentation lists this as a different type to make it clear which properties expect an array of GPIOs. -Each item in the array should be a label for a GPIO node (the names of which differ between hardware platforms) followed by an index and configuration flags. See [Zephyr's GPIO documentation](https://docs.zephyrproject.org/latest/hardware/peripherals/gpio.html) for a full list of flags. +Each item in the array should be a label for a GPIO node (the names of which differ between hardware platforms) followed by an index and configuration flags. See [Zephyr's GPIO documentation](https://docs.zephyrproject.org/3.5.0/hardware/peripherals/gpio.html) for a full list of flags. Example: diff --git a/docs/docs/config/kscan.md b/docs/docs/config/kscan.md index 045c35ca..15457cb0 100644 --- a/docs/docs/config/kscan.md +++ b/docs/docs/config/kscan.md @@ -25,7 +25,7 @@ If the debounce press/release values are set to any value other than `-1`, they ### Devicetree -Applies to: [`/chosen` node](https://docs.zephyrproject.org/latest/guides/dts/intro.html#aliases-and-chosen-nodes) +Applies to: [`/chosen` node](https://docs.zephyrproject.org/3.5.0/guides/dts/intro.html#aliases-and-chosen-nodes) | Property | Type | Description | | ---------------------- | ---- | ------------------------------------------------------------- | @@ -84,7 +84,7 @@ By default, a switch will drain current through the internal pull up/down resist `toggle-mode` applies to all switches handled by the instance of the driver. To use a toggle switch with other, non-toggle, direct GPIO switches, create two instances of the direct GPIO driver, one with `toggle-mode` and the other without. Then, use a [composite driver](#composite-driver) to combine them. -Assuming the switches connect each GPIO pin to the ground, the [GPIO flags](https://docs.zephyrproject.org/3.2.0/hardware/peripherals/gpio.html#api-reference) for the elements in `input-gpios` should be `(GPIO_ACTIVE_LOW | GPIO_PULL_UP)`: +Assuming the switches connect each GPIO pin to the ground, the [GPIO flags](https://docs.zephyrproject.org/3.5.0/hardware/peripherals/gpio.html#api-reference) for the elements in `input-gpios` should be `(GPIO_ACTIVE_LOW | GPIO_PULL_UP)`: ```dts kscan0: kscan { @@ -131,7 +131,7 @@ The `diode-direction` property must be one of: | `"row2col"` | Diodes point from rows to columns (cathodes are connected to columns) | | `"col2row"` | Diodes point from columns to rows (cathodes are connected to rows) | -Given the `diode-direction`, the [GPIO flags](https://docs.zephyrproject.org/3.2.0/hardware/peripherals/gpio.html#api-reference) for the elements in `row-` and `col-gpios` should be set appropriately. +Given the `diode-direction`, the [GPIO flags](https://docs.zephyrproject.org/3.5.0/hardware/peripherals/gpio.html#api-reference) for the elements in `row-` and `col-gpios` should be set appropriately. The output pins (e.g. columns for `col2row`) should have the flag `GPIO_ACTIVE_HIGH`, and input pins (e.g. rows for `col2row`) should have the flags `(GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)`: ```dts diff --git a/docs/docs/config/system.md b/docs/docs/config/system.md index 9407772c..83f2f065 100644 --- a/docs/docs/config/system.md +++ b/docs/docs/config/system.md @@ -80,7 +80,7 @@ By default USB Boot protocol support is disabled, however certain situations suc ### Bluetooth -See [Zephyr's Bluetooth stack architecture documentation](https://docs.zephyrproject.org/latest/guides/bluetooth/bluetooth-arch.html) +See [Zephyr's Bluetooth stack architecture documentation](https://docs.zephyrproject.org/3.5.0/connectivity/bluetooth/bluetooth-arch.html) for more information on configuring Bluetooth. | Config | Type | Description | Default | diff --git a/docs/docs/development/boards-shields-keymaps.md b/docs/docs/development/boards-shields-keymaps.md index 3595cb17..d449a1c1 100644 --- a/docs/docs/development/boards-shields-keymaps.md +++ b/docs/docs/development/boards-shields-keymaps.md @@ -6,7 +6,7 @@ title: Boards, Shields, and Keymaps The foundational elements needed to get a specific keyboard working with ZMK can be broken down into: -- A [KSCAN driver](https://docs.zephyrproject.org/3.2.0/reference/peripherals/kscan.html), which uses `compatible="zmk,kscan-gpio-matrix"` for GPIO matrix based keyboards, or uses `compatible="zmk,kscan-gpio-direct"` for small direct wires. +- A [KSCAN driver](https://docs.zephyrproject.org/3.5.0/reference/peripherals/kscan.html), which uses `compatible="zmk,kscan-gpio-matrix"` for GPIO matrix based keyboards, or uses `compatible="zmk,kscan-gpio-direct"` for small direct wires. - An optional matrix transform, which defines how the KSCAN row/column events are translated into logical "key positions". This is required for non-rectangular keyboards/matrices, where the key positions don't naturally follow the row/columns from the GPIO matrix. - A keymap, which binds each key position to a behavior, e.g. key press, mod-tap, momentary layer, in a set of layers. @@ -27,8 +27,8 @@ in the `app/boards/${arch}/${board_name}` directory, e.g. `app/boards/arm/planck - A `${board_name}_defconfig` file that forces specific Kconfig settings that are specific to this hardware configuration. Mostly this is SoC settings around the specific hardware configuration. - `${board_name}.dts` which contains all the devicetree definitions, including: - An `#include` line that pulls in the specific microprocessor that is used, e.g. `#include `. - - A [chosen](https://docs.zephyrproject.org/3.2.0/guides/dts/intro.html#aliases-and-chosen-nodes) node named `zmk,kscan` which references the configured KSCAN driver (usually a GPIO matrix) - - (Optional) A [chosen](https://docs.zephyrproject.org/3.2.0/guides/dts/intro.html#aliases-and-chosen-nodes) node named `zmk,matrix-transform` that defines the mapping from KSCAN row/column values to the logical key position for the keyboard. + - A [chosen](https://docs.zephyrproject.org/3.5.0/guides/dts/intro.html#aliases-and-chosen-nodes) node named `zmk,kscan` which references the configured KSCAN driver (usually a GPIO matrix) + - (Optional) A [chosen](https://docs.zephyrproject.org/3.5.0/guides/dts/intro.html#aliases-and-chosen-nodes) node named `zmk,matrix-transform` that defines the mapping from KSCAN row/column values to the logical key position for the keyboard. - A `board.cmake` file with CMake directives for how to flash to the device. - A `${board_name}.keymap` file that includes the default keymap for that keyboard. Users will be able to override this keymap in their user configs. @@ -47,6 +47,6 @@ in the `app/boards/shields/${board_name}` directory, e.g. `app/boards/shields/cl - A `Kconfig.shield` that defines the toplevel Kconfig value for the shield, which uses a supplied utility to function to default the value based on the shield list, e.g. `def_bool $(shields_list_contains,clueboard_california)`. - A `Kconfig.defconfig` file to set default values for things like `ZMK_KEYBOARD_NAME` - A `${shield_name}.overlay` file, which is a devicetree overlay file, that includes: - - A [chosen](https://docs.zephyrproject.org/3.2.0/guides/dts/intro.html#aliases-and-chosen-nodes) node named `zmk,kscan` which references the configured KSCAN driver (usually a GPIO matrix). For these keyboards, to be compatible with any Pro Micro compatible boards, the KSCAN configuration should reference the [nexus node](https://docs.zephyrproject.org/3.2.0/guides/porting/shields.html#gpio-nexus-nodes) that ZMK has standardized on. In particular, the `&pro_micro` aliases can be used to reference the standard digital pins of a Pro Micro for shields. - - (Optional) A [chosen](https://docs.zephyrproject.org/3.2.0/guides/dts/intro.html#aliases-and-chosen-nodes) node named `zmk,matrix-transform` that defines the mapping from KSCAN row/column values to the logical key position for the keyboard. + - A [chosen](https://docs.zephyrproject.org/3.5.0/guides/dts/intro.html#aliases-and-chosen-nodes) node named `zmk,kscan` which references the configured KSCAN driver (usually a GPIO matrix). For these keyboards, to be compatible with any Pro Micro compatible boards, the KSCAN configuration should reference the [nexus node](https://docs.zephyrproject.org/3.5.0/guides/porting/shields.html#gpio-nexus-nodes) that ZMK has standardized on. In particular, the `&pro_micro` aliases can be used to reference the standard digital pins of a Pro Micro for shields. + - (Optional) A [chosen](https://docs.zephyrproject.org/3.5.0/guides/dts/intro.html#aliases-and-chosen-nodes) node named `zmk,matrix-transform` that defines the mapping from KSCAN row/column values to the logical key position for the keyboard. - A `keymap/keymap.overlay` file that includes the default keymap for that keyboard. Users will be able to override this keymap in their user configs. diff --git a/docs/docs/development/build-flash.mdx b/docs/docs/development/build-flash.mdx index ece474bd..c0c7563a 100644 --- a/docs/docs/development/build-flash.mdx +++ b/docs/docs/development/build-flash.mdx @@ -16,7 +16,7 @@ an onboard MCU, or one that uses an MCU board addon. ### Keyboard (Shield) + MCU Board -ZMK treats keyboards that take an MCU addon board as [shields](https://docs.zephyrproject.org/3.2.0/guides/porting/shields.html), and treats the smaller MCU board as the true [board](https://docs.zephyrproject.org/3.2.0/guides/porting/board_porting.html) +ZMK treats keyboards that take an MCU addon board as [shields](https://docs.zephyrproject.org/3.5.0/guides/porting/shields.html), and treats the smaller MCU board as the true [board](https://docs.zephyrproject.org/3.5.0/guides/porting/board_porting.html) Given the following: @@ -32,7 +32,7 @@ west build -b proton_c -- -DSHIELD=kyria_left ### Keyboard With Onboard MCU -Keyboards with onboard MCU chips are simply treated as the [board](https://docs.zephyrproject.org/3.2.0/guides/porting/board_porting.html) as far as Zephyrâ„¢ is concerned. +Keyboards with onboard MCU chips are simply treated as the [board](https://docs.zephyrproject.org/3.5.0/guides/porting/board_porting.html) as far as Zephyrâ„¢ is concerned. Given the following: @@ -79,7 +79,7 @@ Build times can be significantly reduced after the initial build by omitting all ### Building with external modules -ZMK supports loading additional boards, shields, code, etc. from [external Zephyr modules](https://docs.zephyrproject.org/3.2.0/develop/modules.html), facilitating out-of-tree management and versioning independent of the ZMK repository. To build with any additional modules, use the `ZMK_EXTRA_MODULES` define added to your `west build` command. +ZMK supports loading additional boards, shields, code, etc. from [external Zephyr modules](https://docs.zephyrproject.org/3.5.0/develop/modules.html), facilitating out-of-tree management and versioning independent of the ZMK repository. To build with any additional modules, use the `ZMK_EXTRA_MODULES` define added to your `west build` command. For instance, building with the `my-vendor-keebs-module` checked out to your documents directory, you would build like: @@ -144,7 +144,7 @@ west flash ## Multi-CPU and Dual-Chip Bluetooth Boards -Zephyr supports running the Bluetooth host and controller on separate processors. In such a configuration, ZMK always runs on the host processor, but you may need to build and flash separate firmware for the controller. Zephyr provides sample code which can be used as the controller firmware for Bluetooth HCI over [RPMsg](https://docs.zephyrproject.org/3.2.0/samples/bluetooth/hci_rpmsg/README.html), [SPI](https://docs.zephyrproject.org/3.2.0/samples/bluetooth/hci_spi/README.html), [UART](https://docs.zephyrproject.org/3.2.0/samples/bluetooth/hci_uart/README.html), and [USB](https://docs.zephyrproject.org/3.2.0/samples/bluetooth/hci_usb/README.html). See [Zephyr's Bluetooth Stack Architecture documentation](https://docs.zephyrproject.org/3.2.0/connectivity/bluetooth/bluetooth-arch.html) for more details. +Zephyr supports running the Bluetooth host and controller on separate processors. In such a configuration, ZMK always runs on the host processor, but you may need to build and flash separate firmware for the controller. Zephyr provides sample code which can be used as the controller firmware for Bluetooth HCI over [RPMsg](https://docs.zephyrproject.org/3.5.0/samples/bluetooth/hci_rpmsg/README.html), [SPI](https://docs.zephyrproject.org/3.5.0/samples/bluetooth/hci_spi/README.html), [UART](https://docs.zephyrproject.org/3.5.0/samples/bluetooth/hci_uart/README.html), and [USB](https://docs.zephyrproject.org/3.5.0/samples/bluetooth/hci_usb/README.html). See [Zephyr's Bluetooth Stack Architecture documentation](https://docs.zephyrproject.org/3.5.0/connectivity/bluetooth/bluetooth-arch.html) for more details. The following documentation shows how to build and flash ZMK for boards that use a dual-chip configuration. diff --git a/docs/docs/development/new-behavior.mdx b/docs/docs/development/new-behavior.mdx index d76474fd..702547cc 100644 --- a/docs/docs/development/new-behavior.mdx +++ b/docs/docs/development/new-behavior.mdx @@ -28,8 +28,8 @@ Before developing new behaviors, developers should have a working knowledge of t The following resources are provided for those seeking further understanding: - [Embedded Linux Wiki - Device Tree Usage](https://elinux.org/Device_Tree_Usage) -- [Zephyr Devicetree API](https://docs.zephyrproject.org/latest/build/dts/api/api.html) -- [Zephyr Device Driver Model](https://docs.zephyrproject.org/latest/kernel/drivers/index.html) +- [Zephyr Devicetree API](https://docs.zephyrproject.org/3.5.0/build/dts/api/api.html) +- [Zephyr Device Driver Model](https://docs.zephyrproject.org/3.5.0/kernel/drivers/index.html) ::: @@ -116,7 +116,7 @@ These are additional variables required to configure a particular instance of a - `phandles` :::info -For more information on additional `properties`, refer to [Zephyr's documentation on Devicetree bindings](https://docs.zephyrproject.org/latest/build/dts/bindings.html#properties). +For more information on additional `properties`, refer to [Zephyr's documentation on Devicetree bindings](https://docs.zephyrproject.org/3.5.0/build/dts/bindings.html#properties). ::: ### Creating the driver (`.c`) @@ -124,8 +124,8 @@ For more information on additional `properties`, refer to [Zephyr's documentatio :::info Developing drivers for behaviors in ZMK makes extensive use of the Zephyr Devicetree API and Device Driver Model. Links to the Zephyr Project Documentation for both of these concepts can be found below: -- [Zephyr Devicetree API](https://docs.zephyrproject.org/latest/build/dts/api/api.html) -- [Zephyr Device Driver Model](https://docs.zephyrproject.org/latest/kernel/drivers/index.html) +- [Zephyr Devicetree API](https://docs.zephyrproject.org/3.5.0/build/dts/api/api.html) +- [Zephyr Device Driver Model](https://docs.zephyrproject.org/3.5.0/kernel/drivers/index.html) ::: @@ -192,7 +192,7 @@ The dependencies required for any ZMK behavior are: - `device.h`: [Zephyr Device APIs](https://docs.zephyrproject.org/apidoc/latest/group__device__model.html) - `drivers/behavior.h`: ZMK Behavior Functions (e.g. [`locality`](#api-structure), `behavior_keymap_binding_pressed`, `behavior_keymap_binding_released`, `behavior_sensor_keymap_binding_triggered`) -- `logging/log.h`: [Zephyr Logging APIs](https://docs.zephyrproject.org/latest/services/logging/index.html) (for more information on USB Logging in ZMK, see [USB Logging](usb-logging.mdx)). +- `logging/log.h`: [Zephyr Logging APIs](https://docs.zephyrproject.org/3.5.0/services/logging/index.html) (for more information on USB Logging in ZMK, see [USB Logging](usb-logging.mdx)). - `zmk/behavior.h`: ZMK Behavior Information (e.g. parameters, position and timestamp of events) - `return` values: - `ZMK_BEHAVIOR_OPAQUE`: Used to terminate `on__binding_pressed` and `on__binding_released` functions that accept `(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event)` as parameters @@ -249,7 +249,7 @@ Listeners, defined by the `ZMK_LISTENER(mod, cb)` function, take in a listener n `BEHAVIOR_DT_INST_DEFINE` is a special ZMK macro. It forwards all the parameters to Zephyr's `DEVICE_DT_INST_DEFINE` macro to define the driver instance, then it adds the driver to a list of ZMK behaviors so they can be found by `zmk_behavior_get_binding()`. :::info -For more information on this function, refer to [Zephyr's documentation on the Device Driver Model](https://docs.zephyrproject.org/latest/kernel/drivers/index.html#c.DEVICE_DT_INST_DEFINE). +For more information on this function, refer to [Zephyr's documentation on the Device Driver Model](https://docs.zephyrproject.org/3.5.0/kernel/drivers/index.html#c.DEVICE_DT_INST_DEFINE). ::: The example `BEHAVIOR_DT_INST_DEFINE` call can be left as is with the first parameter, the instance number, equal to `0` for behaviors that only require a single instance (e.g. external power, backlighting, accessing layers). For behaviors that can have multiple instances (e.g. hold-taps, tap-dances, sticky-keys), `BEHAVIOR_DT_INST_DEFINE` can be placed inside a `#define` statement, usually formatted as `#define _INST(n)`, that sets up any [data pointers](#data-pointers-optional) and/or [configuration pointers](#configuration-pointers-optional) that are unique to each instance. @@ -312,7 +312,7 @@ The fourth cell of `BEHAVIOR_DT_INST_DEFINE` can be set to `NULL` instead if ins ##### Configuration Pointers (Optional) -The configuration `struct` stores the properties declared from the behavior's `.yaml` for **each new instance** of the behavior. As seen in the `#define KP_INST(n)` of the hold-tap example, the configuration `struct`, `behavior__config_##n`, for each instance number, `n`, can be initialized using the [Zephyr Devicetree Instance-based APIs](https://docs.zephyrproject.org/latest/build/dts/api/api.html#instance-based-apis), which extract the values from the `properties` of each instance of the [devicetree binding](#creating-the-devicetree-binding-yaml) from a user's keymap or [predefined use-case `.dtsi` files](#defining-common-use-cases-for-the-behavior-dtsi-optional) stored in `app/dts/behaviors/`. We illustrate this further by comparing the [`#define KP_INST(n)` from the hold-tap driver](#behavior_dt_inst_define) and the [`properties` of the hold-tap devicetree binding.](#creating-the-devicetree-binding-yaml) +The configuration `struct` stores the properties declared from the behavior's `.yaml` for **each new instance** of the behavior. As seen in the `#define KP_INST(n)` of the hold-tap example, the configuration `struct`, `behavior__config_##n`, for each instance number, `n`, can be initialized using the [Zephyr Devicetree Instance-based APIs](https://docs.zephyrproject.org/3.5.0/build/dts/api/api.html#instance-based-apis), which extract the values from the `properties` of each instance of the [devicetree binding](#creating-the-devicetree-binding-yaml) from a user's keymap or [predefined use-case `.dtsi` files](#defining-common-use-cases-for-the-behavior-dtsi-optional) stored in `app/dts/behaviors/`. We illustrate this further by comparing the [`#define KP_INST(n)` from the hold-tap driver](#behavior_dt_inst_define) and the [`properties` of the hold-tap devicetree binding.](#creating-the-devicetree-binding-yaml) The fifth cell of `BEHAVIOR_DT_INST_DEFINE` can be set to `NULL` instead if instance-specific configurations are not required. diff --git a/docs/docs/development/new-shield.mdx b/docs/docs/development/new-shield.mdx index 2f52839b..96d83ce0 100644 --- a/docs/docs/development/new-shield.mdx +++ b/docs/docs/development/new-shield.mdx @@ -15,7 +15,7 @@ This guide will walk through the steps necessary to add ZMK support for a keyboa The high level steps are: -- From a template, create a new [Zephyr module](https://docs.zephyrproject.org/3.2.0/develop/modules.html) housed in a git repository containing one or more custom shields. +- From a template, create a new [Zephyr module](https://docs.zephyrproject.org/3.5.0/develop/modules.html) housed in a git repository containing one or more custom shields. - Create a new shield directory. - Add the base Kconfig files. - Add the shield overlay file to define the KSCAN driver for detecting key press/release. @@ -25,7 +25,7 @@ The high level steps are: - Update the `build.yaml` file from the repository template to have some sample builds of the firmware to test. - Add support for features such as encoders, OLED displays, or RGB underglow. -It may be helpful to review the upstream [shields documentation](https://docs.zephyrproject.org/3.2.0/guides/porting/shields.html#shields) to get a proper understanding of the underlying system before continuing. +It may be helpful to review the upstream [shields documentation](https://docs.zephyrproject.org/3.5.0/guides/porting/shields.html#shields) to get a proper understanding of the underlying system before continuing. :::note ZMK support for split keyboards requires a few more files than single boards to ensure proper connectivity between the central and peripheral units. Check the following guides thoroughly to ensure that all the files are in place. diff --git a/docs/docs/development/setup.mdx b/docs/docs/development/setup.mdx index 63f1bff8..bc275804 100644 --- a/docs/docs/development/setup.mdx +++ b/docs/docs/development/setup.mdx @@ -46,22 +46,22 @@ The docker container already includes `west`. Skip past the following section to -Open Zephyr's [Getting Started Guide](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html) and follow the instructions under these sections: +Open Zephyr's [Getting Started Guide](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html) and follow the instructions under these sections: -- [Select and Update OS](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html#select-and-update-os) -- [Install Dependencies](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html#install-dependencies) -- [Install Zephyr SDK](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html#install-zephyr-sdk) +- [Select and Update OS](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html#select-and-update-os) +- [Install Dependencies](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html#install-dependencies) +- [Install Zephyr SDK](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html#install-zephyr-sdk) Return to this guide once you are finished with each section. -Open Zephyr's [Getting Started Guide](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html) and follow the instructions under these sections: +Open Zephyr's [Getting Started Guide](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html) and follow the instructions under these sections: -- [Select and Update OS](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html#select-and-update-os) -- [Install Dependencies](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html#install-dependencies) -- [Install Zephyr SDK](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html#install-zephyr-sdk) +- [Select and Update OS](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html#select-and-update-os) +- [Install Dependencies](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html#install-dependencies) +- [Install Zephyr SDK](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html#install-zephyr-sdk) Return to this guide once you are finished with each section. @@ -70,11 +70,11 @@ Return to this guide once you are finished with each section. -Open Zephyr's [Getting Started Guide](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html) and follow the instructions under these sections: +Open Zephyr's [Getting Started Guide](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html) and follow the instructions under these sections: -- [Select and Update OS](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html#select-and-update-os) -- [Install Dependencies](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html#install-dependencies) -- [Install Zephyr SDK](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html#install-zephyr-sdk) +- [Select and Update OS](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html#select-and-update-os) +- [Install Dependencies](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html#install-dependencies) +- [Install Zephyr SDK](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html#install-zephyr-sdk) Return to this guide once you are finished with each section. @@ -83,16 +83,16 @@ Return to this guide once you are finished with each section. #### Install Base Dependencies -Open Zephyr's [Getting Started Guide](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html) and follow the instructions for Ubuntu under these sections: +Open Zephyr's [Getting Started Guide](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html) and follow the instructions for Ubuntu under these sections: -- [Select and Update OS](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html#select-and-update-os) -- [Install Dependencies](https://docs.zephyrproject.org/3.2.0/develop/getting_started/index.html#install-dependencies) +- [Select and Update OS](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html#select-and-update-os) +- [Install Dependencies](https://docs.zephyrproject.org/3.5.0/develop/getting_started/index.html#install-dependencies) Return to this guide once you are finished with each section. #### Install Cross-Compile Toolchain -Because Raspberry OS runs on the same architecture (but different ABI) as ARM keyboard MCUs, the operating system's installed [cross compilers](https://docs.zephyrproject.org/3.2.0/develop/toolchains/other_x_compilers.html) can be used to target the different ABI. Building for non-ARM MCUs has not been tested. +Because Raspberry OS runs on the same architecture (but different ABI) as ARM keyboard MCUs, the operating system's installed [cross compilers](https://docs.zephyrproject.org/3.5.0/develop/toolchains/other_x_compilers.html) can be used to target the different ABI. Building for non-ARM MCUs has not been tested. First, the cross compiler should be installed: @@ -100,7 +100,7 @@ First, the cross compiler should be installed: sudo apt install gcc-arm-none-eabi ``` -Next, we'll configure Zephyr with some [environment variables](https://docs.zephyrproject.org/3.2.0/develop/env_vars.html#env-vars) needed to find the cross compiler. Create a file named `~/.zephyrrc` if it doesn't exist, and add these lines to it: +Next, we'll configure Zephyr with some [environment variables](https://docs.zephyrproject.org/3.5.0/develop/env_vars.html#env-vars) needed to find the cross compiler. Create a file named `~/.zephyrrc` if it doesn't exist, and add these lines to it: ```sh export ZEPHYR_TOOLCHAIN_VARIANT=cross-compile @@ -110,16 +110,16 @@ export CROSS_COMPILE=/usr/bin/arm-none-eabi- -Follow Zephyr's [Install Linux Host Dependencies](https://docs.zephyrproject.org/3.2.0/develop/getting_started/installation_linux.html) documentation for Fedora. +Follow Zephyr's [Install Linux Host Dependencies](https://docs.zephyrproject.org/3.5.0/develop/getting_started/installation_linux.html) documentation for Fedora. ### Install West -`west` is the [Zephyr® Project's meta-tool](https://docs.zephyrproject.org/3.2.0/develop/west/index.html) used to configure and build Zephyr OS applications. +`west` is the [Zephyr® Project's meta-tool](https://docs.zephyrproject.org/3.5.0/develop/west/index.html) used to configure and build Zephyr OS applications. -West can be installed by using the `pip` python package manager. The [Zephyrâ„¢ instructions](https://docs.zephyrproject.org/3.2.0/develop/west/install.html) are summarized here: +West can be installed by using the `pip` python package manager. The [Zephyrâ„¢ instructions](https://docs.zephyrproject.org/3.5.0/develop/west/install.html) are summarized here: Date: Thu, 8 Feb 2024 18:44:05 +0000 Subject: [PATCH 041/127] fix(pm): Tweaks for deep sleep/PM. * Restore enabling of PM_DEVICE, make ZMK_SLEEP work with the ZMK Uno shield on nrf52840dk_nrf52840 board. --- app/Kconfig | 3 +++ app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/Kconfig b/app/Kconfig index 14456b5f..8155efd0 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -399,6 +399,9 @@ config ZMK_SLEEP 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/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay index 5ac7af7c..05c7ed9d 100644 --- a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay +++ b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay @@ -20,5 +20,6 @@ encoder: &qdec0 { led-pre = <0>; steps = <80>; pinctrl-0 = <&qdec_default>; - pinctrl-names = "default"; + pinctrl-1 = <&qdec_default>; + pinctrl-names = "default", "sleep"; }; From 50a303b8bb86b3f6ef1853c0c7ef841e043eb615 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 9 Feb 2024 18:50:06 +0000 Subject: [PATCH 042/127] fix(pm): Restore sleep suspension of devices. * After the move to `sys_poweroff`, restore the behavior of suspending devices before entering sleep state. --- app/CMakeLists.txt | 4 ++ app/include/linker/zmk-pm-devices.ld | 9 ++++ app/src/activity.c | 66 ++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 app/include/linker/zmk-pm-devices.ld diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 31471484..6ef00311 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -8,6 +8,10 @@ set(ZEPHYR_EXTRA_MODULES "${ZMK_EXTRA_MODULES};${CMAKE_CURRENT_SOURCE_DIR}/modul find_package(Zephyr REQUIRED HINTS ../zephyr) project(zmk) +if(CONFIG_ZMK_SLEEP) + zephyr_linker_sources(SECTIONS include/linker/zmk-pm-devices.ld) +endif() + zephyr_linker_sources(SECTIONS include/linker/zmk-behaviors.ld) zephyr_linker_sources(RODATA include/linker/zmk-events.ld) diff --git a/app/include/linker/zmk-pm-devices.ld b/app/include/linker/zmk-pm-devices.ld new file mode 100644 index 00000000..93ec5025 --- /dev/null +++ b/app/include/linker/zmk-pm-devices.ld @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +ITERABLE_SECTION_RAM(zmk_pm_device_slots, 4) diff --git a/app/src/activity.c b/app/src/activity.c index 11409151..8f421f85 100644 --- a/app/src/activity.c +++ b/app/src/activity.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include @@ -24,6 +26,63 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #endif +// Reimplement some of the device work from Zephyr PM to work with the new `sys_poweroff` API. +// TODO: Tweak this to smarter runtime PM of subsystems on sleep. + +#ifdef CONFIG_PM_DEVICE +TYPE_SECTION_START_EXTERN(const struct device *, zmk_pm_device_slots); + +#if !defined(CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE) +/* Number of devices successfully suspended. */ +static size_t zmk_num_susp; + +static int zmk_pm_suspend_devices(void) { + const struct device *devs; + size_t devc; + + devc = z_device_get_all_static(&devs); + + zmk_num_susp = 0; + + for (const struct device *dev = devs + devc - 1; dev >= devs; dev--) { + int ret; + + /* + * Ignore uninitialized devices, busy devices, wake up sources, and + * devices with runtime PM enabled. + */ + if (!device_is_ready(dev) || pm_device_is_busy(dev) || pm_device_state_is_locked(dev) || + pm_device_wakeup_is_enabled(dev) || pm_device_runtime_is_enabled(dev)) { + continue; + } + + ret = pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND); + /* ignore devices not supporting or already at the given state */ + if ((ret == -ENOSYS) || (ret == -ENOTSUP) || (ret == -EALREADY)) { + continue; + } else if (ret < 0) { + LOG_ERR("Device %s did not enter %s state (%d)", dev->name, + pm_device_state_str(PM_DEVICE_STATE_SUSPENDED), ret); + return ret; + } + + TYPE_SECTION_START(zmk_pm_device_slots)[zmk_num_susp] = dev; + zmk_num_susp++; + } + + return 0; +} + +static void zmk_pm_resume_devices(void) { + for (int i = (zmk_num_susp - 1); i >= 0; i--) { + pm_device_action_run(TYPE_SECTION_START(zmk_pm_device_slots)[i], PM_DEVICE_ACTION_RESUME); + } + + zmk_num_susp = 0; +} +#endif /* !CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE */ +#endif /* CONFIG_PM_DEVICE */ + bool is_usb_power_present(void) { #if IS_ENABLED(CONFIG_USB_DEVICE_STACK) return zmk_usb_is_powered(); @@ -70,6 +129,13 @@ 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); + + if (zmk_pm_suspend_devices() < 0) { + LOG_ERR("Failed to suspend all the devices"); + zmk_pm_resume_devices(); + return; + } + sys_poweroff(); } else #endif /* IS_ENABLED(CONFIG_ZMK_SLEEP) */ From f72f415c5bd23a89d7e50b1a8e22ede70c0db9e3 Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Fri, 9 Feb 2024 15:10:35 -0500 Subject: [PATCH 043/127] fix(docs): More Zephyr docs link updates. Co-authored-by: Cem Aksoylar --- docs/docs/config/backlight.md | 2 +- docs/docs/config/battery.md | 4 ++-- docs/docs/config/index.md | 2 +- docs/docs/config/kscan.md | 2 +- docs/docs/development/boards-shields-keymaps.md | 8 ++++---- docs/docs/development/build-flash.mdx | 4 ++-- docs/docs/development/new-behavior.mdx | 2 +- docs/docs/development/new-shield.mdx | 2 +- docs/docs/faq.md | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/docs/config/backlight.md b/docs/docs/config/backlight.md index 3d554c57..eeba3a8a 100644 --- a/docs/docs/config/backlight.md +++ b/docs/docs/config/backlight.md @@ -26,7 +26,7 @@ The `*_START` settings only determine the initial backlight state. Any changes y ## Devicetree -Applies to: [`/chosen` node](https://docs.zephyrproject.org/3.5.0/build/dts/intro.html#aliases-and-chosen-nodes) +Applies to: [`/chosen` node](https://docs.zephyrproject.org/3.5.0/build/dts/intro-syntax-structure.html#aliases-and-chosen-nodes) | Property | Type | Description | | --------------- | ---- | -------------------------------------------- | diff --git a/docs/docs/config/battery.md b/docs/docs/config/battery.md index cc725e43..68de8fb8 100644 --- a/docs/docs/config/battery.md +++ b/docs/docs/config/battery.md @@ -30,7 +30,7 @@ On macOS the BLE battery reporting packets can cause the computer to wakeup from ### Devicetree -Applies to: [`/chosen` node](https://docs.zephyrproject.org/3.5.0/guides/dts/intro.html#aliases-and-chosen-nodes) +Applies to: [`/chosen` node](https://docs.zephyrproject.org/3.5.0/build/dts/intro-syntax-structure.html#aliases-and-chosen-nodes) | Property | Type | Description | | ------------- | ---- | --------------------------------------------- | @@ -44,7 +44,7 @@ Driver for reading the voltage of a battery using an ADC connected to a voltage Applies to: `compatible = "zmk,battery-voltage-divider"` -See [Zephyr's voltage divider documentation](https://docs.zephyrproject.org/3.5.0/build/dts/api/bindings/adc/voltage-divider.html). +See [Zephyr's voltage divider documentation](https://docs.zephyrproject.org/3.5.0/build/dts/api/bindings/iio/afe/voltage-divider.html). ## nRF VDDH Battery Sensor diff --git a/docs/docs/config/index.md b/docs/docs/config/index.md index c8da6d7c..d542d435 100644 --- a/docs/docs/config/index.md +++ b/docs/docs/config/index.md @@ -149,7 +149,7 @@ The part before the colon, `kscan0`, is a label. This is optional, and it provid The `compatible` property indicates what type of node it is. Search this documentation for the text inside the quotes to see which properties the node supports. You can also search ZMK for a file whose name is the value of the `compatible` property with a `.yaml` file extension. -To set a property, see below for examples for common property types, or see [Zephyr's Devicetree documentation](https://docs.zephyrproject.org/3.5.0/build/dts/intro.html#writing-property-values) for more details on the syntax for properties. +To set a property, see below for examples for common property types, or see [Zephyr's Devicetree documentation](https://docs.zephyrproject.org/3.5.0/build/dts/intro-syntax-structure.html#writing-property-values) for more details on the syntax for properties. To change a property for an existing node, first find the node you want to change and find its label. Next, outside of any other node, write an ampersand (`&`) followed by the node's label, an opening curly brace (`{`), one or more new property values, a closing curly brace (`}`), and a semicolon (`;`). diff --git a/docs/docs/config/kscan.md b/docs/docs/config/kscan.md index 15457cb0..b49529d9 100644 --- a/docs/docs/config/kscan.md +++ b/docs/docs/config/kscan.md @@ -25,7 +25,7 @@ If the debounce press/release values are set to any value other than `-1`, they ### Devicetree -Applies to: [`/chosen` node](https://docs.zephyrproject.org/3.5.0/guides/dts/intro.html#aliases-and-chosen-nodes) +Applies to: [`/chosen` node](https://docs.zephyrproject.org/3.5.0/build/dts/intro-syntax-structure.html#aliases-and-chosen-nodes) | Property | Type | Description | | ---------------------- | ---- | ------------------------------------------------------------- | diff --git a/docs/docs/development/boards-shields-keymaps.md b/docs/docs/development/boards-shields-keymaps.md index d449a1c1..e936f992 100644 --- a/docs/docs/development/boards-shields-keymaps.md +++ b/docs/docs/development/boards-shields-keymaps.md @@ -27,8 +27,8 @@ in the `app/boards/${arch}/${board_name}` directory, e.g. `app/boards/arm/planck - A `${board_name}_defconfig` file that forces specific Kconfig settings that are specific to this hardware configuration. Mostly this is SoC settings around the specific hardware configuration. - `${board_name}.dts` which contains all the devicetree definitions, including: - An `#include` line that pulls in the specific microprocessor that is used, e.g. `#include `. - - A [chosen](https://docs.zephyrproject.org/3.5.0/guides/dts/intro.html#aliases-and-chosen-nodes) node named `zmk,kscan` which references the configured KSCAN driver (usually a GPIO matrix) - - (Optional) A [chosen](https://docs.zephyrproject.org/3.5.0/guides/dts/intro.html#aliases-and-chosen-nodes) node named `zmk,matrix-transform` that defines the mapping from KSCAN row/column values to the logical key position for the keyboard. + - A [chosen](https://docs.zephyrproject.org/3.5.0/build/dts/intro-syntax-structure.html#aliases-and-chosen-nodes) node named `zmk,kscan` which references the configured KSCAN driver (usually a GPIO matrix) + - (Optional) A [chosen](https://docs.zephyrproject.org/3.5.0/build/dts/intro-syntax-structure.html#aliases-and-chosen-nodes) node named `zmk,matrix-transform` that defines the mapping from KSCAN row/column values to the logical key position for the keyboard. - A `board.cmake` file with CMake directives for how to flash to the device. - A `${board_name}.keymap` file that includes the default keymap for that keyboard. Users will be able to override this keymap in their user configs. @@ -47,6 +47,6 @@ in the `app/boards/shields/${board_name}` directory, e.g. `app/boards/shields/cl - A `Kconfig.shield` that defines the toplevel Kconfig value for the shield, which uses a supplied utility to function to default the value based on the shield list, e.g. `def_bool $(shields_list_contains,clueboard_california)`. - A `Kconfig.defconfig` file to set default values for things like `ZMK_KEYBOARD_NAME` - A `${shield_name}.overlay` file, which is a devicetree overlay file, that includes: - - A [chosen](https://docs.zephyrproject.org/3.5.0/guides/dts/intro.html#aliases-and-chosen-nodes) node named `zmk,kscan` which references the configured KSCAN driver (usually a GPIO matrix). For these keyboards, to be compatible with any Pro Micro compatible boards, the KSCAN configuration should reference the [nexus node](https://docs.zephyrproject.org/3.5.0/guides/porting/shields.html#gpio-nexus-nodes) that ZMK has standardized on. In particular, the `&pro_micro` aliases can be used to reference the standard digital pins of a Pro Micro for shields. - - (Optional) A [chosen](https://docs.zephyrproject.org/3.5.0/guides/dts/intro.html#aliases-and-chosen-nodes) node named `zmk,matrix-transform` that defines the mapping from KSCAN row/column values to the logical key position for the keyboard. + - A [chosen](https://docs.zephyrproject.org/3.5.0/build/dts/intro-syntax-structure.html#aliases-and-chosen-nodes) node named `zmk,kscan` which references the configured KSCAN driver (usually a GPIO matrix). For these keyboards, to be compatible with any Pro Micro compatible boards, the KSCAN configuration should reference the [nexus node](https://docs.zephyrproject.org/3.5.0/hardware/porting/shields.html#gpio-nexus-nodes) that ZMK has standardized on. In particular, the `&pro_micro` aliases can be used to reference the standard digital pins of a Pro Micro for shields. + - (Optional) A [chosen](https://docs.zephyrproject.org/3.5.0/build/dts/intro-syntax-structure.html#aliases-and-chosen-nodes) node named `zmk,matrix-transform` that defines the mapping from KSCAN row/column values to the logical key position for the keyboard. - A `keymap/keymap.overlay` file that includes the default keymap for that keyboard. Users will be able to override this keymap in their user configs. diff --git a/docs/docs/development/build-flash.mdx b/docs/docs/development/build-flash.mdx index c0c7563a..2cbcf5b8 100644 --- a/docs/docs/development/build-flash.mdx +++ b/docs/docs/development/build-flash.mdx @@ -16,7 +16,7 @@ an onboard MCU, or one that uses an MCU board addon. ### Keyboard (Shield) + MCU Board -ZMK treats keyboards that take an MCU addon board as [shields](https://docs.zephyrproject.org/3.5.0/guides/porting/shields.html), and treats the smaller MCU board as the true [board](https://docs.zephyrproject.org/3.5.0/guides/porting/board_porting.html) +ZMK treats keyboards that take an MCU addon board as [shields](https://docs.zephyrproject.org/3.5.0/hardware/porting/shields.html), and treats the smaller MCU board as the true [board](https://docs.zephyrproject.org/3.5.0/hardware/porting/board_porting.html) Given the following: @@ -32,7 +32,7 @@ west build -b proton_c -- -DSHIELD=kyria_left ### Keyboard With Onboard MCU -Keyboards with onboard MCU chips are simply treated as the [board](https://docs.zephyrproject.org/3.5.0/guides/porting/board_porting.html) as far as Zephyrâ„¢ is concerned. +Keyboards with onboard MCU chips are simply treated as the [board](https://docs.zephyrproject.org/3.5.0/hardware/porting/board_porting.html) as far as Zephyrâ„¢ is concerned. Given the following: diff --git a/docs/docs/development/new-behavior.mdx b/docs/docs/development/new-behavior.mdx index 702547cc..cabc417f 100644 --- a/docs/docs/development/new-behavior.mdx +++ b/docs/docs/development/new-behavior.mdx @@ -116,7 +116,7 @@ These are additional variables required to configure a particular instance of a - `phandles` :::info -For more information on additional `properties`, refer to [Zephyr's documentation on Devicetree bindings](https://docs.zephyrproject.org/3.5.0/build/dts/bindings.html#properties). +For more information on additional `properties`, refer to [Zephyr's documentation on Devicetree bindings](https://docs.zephyrproject.org/3.5.0/build/dts/bindings-syntax.html#properties). ::: ### Creating the driver (`.c`) diff --git a/docs/docs/development/new-shield.mdx b/docs/docs/development/new-shield.mdx index 96d83ce0..0dcface3 100644 --- a/docs/docs/development/new-shield.mdx +++ b/docs/docs/development/new-shield.mdx @@ -25,7 +25,7 @@ The high level steps are: - Update the `build.yaml` file from the repository template to have some sample builds of the firmware to test. - Add support for features such as encoders, OLED displays, or RGB underglow. -It may be helpful to review the upstream [shields documentation](https://docs.zephyrproject.org/3.5.0/guides/porting/shields.html#shields) to get a proper understanding of the underlying system before continuing. +It may be helpful to review the upstream [shields documentation](https://docs.zephyrproject.org/3.5.0/hardware/porting/shields.html#shields) to get a proper understanding of the underlying system before continuing. :::note ZMK support for split keyboards requires a few more files than single boards to ensure proper connectivity between the central and peripheral units. Check the following guides thoroughly to ensure that all the files are in place. diff --git a/docs/docs/faq.md b/docs/docs/faq.md index 21e5e7da..2100b972 100644 --- a/docs/docs/faq.md +++ b/docs/docs/faq.md @@ -9,7 +9,7 @@ As a best-in-class RTOS, Zephyrâ„¢ brings many [benefits](https://www.zephyrproj - A _single_ platform [supporting](https://docs.zephyrproject.org/3.5.0/boards/index.html) many architectures, processors and boards. - Optimization for low-powered, small memory footprint devices. -- Powerful hardware abstraction and configuration using [DeviceTree](https://docs.zephyrproject.org/3.5.0/guides/dts/index.html) and [Kconfig](https://docs.zephyrproject.org/3.5.0/build/kconfig/index.html). +- Powerful hardware abstraction and configuration using [DeviceTree](https://docs.zephyrproject.org/3.5.0/build/dts/index.html) and [Kconfig](https://docs.zephyrproject.org/3.5.0/build/kconfig/index.html). - A BLE stack that periodically obtains [qualification](https://docs.zephyrproject.org/3.5.0/connectivity/bluetooth/bluetooth-qual.html) listings, making it easier for final products to obtain qualification from the Bluetooth® SIG. - Multi-processor support, which is critical for power efficiency in upcoming MCUs. - Permissive licensing with its Apache 2.0 open source [license](https://www.apache.org/licenses/LICENSE-2.0). From cdcf4ebfb6d53b6230a65a85f060b6343db3b40b Mon Sep 17 00:00:00 2001 From: honorless <86894501+lesshonor@users.noreply.github.com> Date: Sat, 10 Feb 2024 11:01:24 -0500 Subject: [PATCH 044/127] feat(boards): allow use of blackpill_f401cc --- .../blackpill_f401cc/blackpill_f401cc.zmk.yml | 9 ++++ app/boards/blackpill_f401cc.conf | 6 +++ app/boards/blackpill_f401cc.overlay | 50 +++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 app/boards/arm/blackpill_f401cc/blackpill_f401cc.zmk.yml create mode 100644 app/boards/blackpill_f401cc.conf create mode 100644 app/boards/blackpill_f401cc.overlay diff --git a/app/boards/arm/blackpill_f401cc/blackpill_f401cc.zmk.yml b/app/boards/arm/blackpill_f401cc/blackpill_f401cc.zmk.yml new file mode 100644 index 00000000..329b7371 --- /dev/null +++ b/app/boards/arm/blackpill_f401cc/blackpill_f401cc.zmk.yml @@ -0,0 +1,9 @@ +file_format: "1" +id: blackpill_f401cc +name: BlackPill F401CC +type: board +arch: arm +outputs: + - usb +url: https://github.com/WeActStudio/WeActStudio.MiniSTM32F4x1 +exposes: [blackpill] diff --git a/app/boards/blackpill_f401cc.conf b/app/boards/blackpill_f401cc.conf new file mode 100644 index 00000000..c4252425 --- /dev/null +++ b/app/boards/blackpill_f401cc.conf @@ -0,0 +1,6 @@ +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_UART_INTERRUPT_DRIVEN=n +CONFIG_ZMK_USB=y +CONFIG_ZMK_KSCAN_MATRIX_POLLING=y diff --git a/app/boards/blackpill_f401cc.overlay b/app/boards/blackpill_f401cc.overlay new file mode 100644 index 00000000..6ed4c3cf --- /dev/null +++ b/app/boards/blackpill_f401cc.overlay @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +/ { + blackpill: connector { + compatible = "blackpill"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map + = <2 0 &gpioc 13 0> /* PC13 */ + , <3 0 &gpioc 14 0> /* PC14 */ + , <4 0 &gpioc 15 0> /* PC15 */ + , <10 0 &gpioa 0 0> /* PA0 */ + , <11 0 &gpioa 1 0> /* PA1 */ + , <12 0 &gpioa 2 0> /* PA2 */ + , <13 0 &gpioa 3 0> /* PA3 */ + , <14 0 &gpioa 4 0> /* PA4 */ + , <15 0 &gpioa 5 0> /* PA5 */ + , <16 0 &gpioa 6 0> /* PA6 */ + , <17 0 &gpioa 7 0> /* PA7 */ + , <18 0 &gpiob 0 0> /* PB0 */ + , <19 0 &gpiob 1 0> /* PB1 */ + , <20 0 &gpiob 2 0> /* PB2 */ + , <21 0 &gpiob 10 0> /* PB10 */ + , <25 0 &gpiob 12 0> /* PB12 */ + , <26 0 &gpiob 13 0> /* PB13 */ + , <27 0 &gpiob 14 0> /* PB14 */ + , <28 0 &gpiob 15 0> /* PB15 */ + , <29 0 &gpioa 8 0> /* PA8 */ + , <30 0 &gpioa 9 0> /* PA9 */ + , <31 0 &gpioa 10 0> /* PA10 */ + , <38 0 &gpioa 15 0> /* PA15 */ + , <39 0 &gpiob 3 0> /* PB3 */ + , <40 0 &gpiob 4 0> /* PB4 */ + , <41 0 &gpiob 5 0> /* PB5 */ + , <42 0 &gpiob 6 0> /* PB6 */ + , <43 0 &gpiob 7 0> /* PB7 */ + , <45 0 &gpiob 8 0> /* PB8 */ + , <46 0 &gpiob 9 0> /* PB9 */ + ; + }; +}; + +blackpill_i2c: &i2c1 {}; +blackpill_spi: &spi1 {}; +blackpill_serial: &usart1 {}; From 40adb3858df5509bd6c67b0477e8832fe769a507 Mon Sep 17 00:00:00 2001 From: honorless <86894501+lesshonor@users.noreply.github.com> Date: Sat, 10 Feb 2024 18:41:03 -0500 Subject: [PATCH 045/127] refactor(boards): remove superfluous conf settings --- app/boards/blackpill_f401ce.conf | 1 - app/boards/blackpill_f411ce.conf | 1 - 2 files changed, 2 deletions(-) diff --git a/app/boards/blackpill_f401ce.conf b/app/boards/blackpill_f401ce.conf index 07e304cf..c4252425 100644 --- a/app/boards/blackpill_f401ce.conf +++ b/app/boards/blackpill_f401ce.conf @@ -3,5 +3,4 @@ CONFIG_SERIAL=n CONFIG_UART_CONSOLE=n CONFIG_UART_INTERRUPT_DRIVEN=n CONFIG_ZMK_USB=y -CONFIG_ZMK_BLE=n CONFIG_ZMK_KSCAN_MATRIX_POLLING=y diff --git a/app/boards/blackpill_f411ce.conf b/app/boards/blackpill_f411ce.conf index 07e304cf..c4252425 100644 --- a/app/boards/blackpill_f411ce.conf +++ b/app/boards/blackpill_f411ce.conf @@ -3,5 +3,4 @@ CONFIG_SERIAL=n CONFIG_UART_CONSOLE=n CONFIG_UART_INTERRUPT_DRIVEN=n CONFIG_ZMK_USB=y -CONFIG_ZMK_BLE=n CONFIG_ZMK_KSCAN_MATRIX_POLLING=y From c7fb418e88bc3d5e82f04976c06a1aeeb9b5c736 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 14 Feb 2024 19:47:54 +0000 Subject: [PATCH 046/127] fix(build): Used a fixed temp dir for caching. * Improve GHA caching by using a fixed temporary directory when using one. --- .github/workflows/build-user-config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-user-config.yml b/.github/workflows/build-user-config.yml index af57520b..d8ea057e 100644 --- a/.github/workflows/build-user-config.yml +++ b/.github/workflows/build-user-config.yml @@ -68,7 +68,8 @@ jobs: run: | if [ -e zephyr/module.yml ]; then export zmk_load_arg=" -DZMK_EXTRA_MODULES='${GITHUB_WORKSPACE}'" - export new_tmp_dir=$(mktemp -d) + new_tmp_dir="${TMPDIR:-/tmp}/zmk-config" + mkdir -p "${new_tmp_dir}" echo "base_dir=${new_tmp_dir}" >> $GITHUB_ENV else echo "base_dir=${GITHUB_WORKSPACE}" >> $GITHUB_ENV From 0f49fa9ae49b3373ea701c3ecd9da3e149ca8d64 Mon Sep 17 00:00:00 2001 From: ctranstrum Date: Wed, 14 Feb 2024 18:29:19 -0700 Subject: [PATCH 047/127] fix(behavior): Proper init priority for ext_power. --- app/src/behaviors/behavior_ext_power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/behaviors/behavior_ext_power.c b/app/src/behaviors/behavior_ext_power.c index a51a9f6d..b2aff3c8 100644 --- a/app/src/behaviors/behavior_ext_power.c +++ b/app/src/behaviors/behavior_ext_power.c @@ -75,6 +75,6 @@ static const struct behavior_driver_api behavior_ext_power_driver_api = { }; BEHAVIOR_DT_INST_DEFINE(0, behavior_ext_power_init, NULL, NULL, NULL, POST_KERNEL, - CONFIG_APPLICATION_INIT_PRIORITY, &behavior_ext_power_driver_api); + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_ext_power_driver_api); #endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ From 604af2ebd318a2b8865f98db55b411a8e07f24c2 Mon Sep 17 00:00:00 2001 From: Dennis <47061464+dennisorlando@users.noreply.github.com> Date: Sun, 18 Feb 2024 06:51:09 +0100 Subject: [PATCH 048/127] feat(docs): Add pointers for peripheral battery monitoring (#2177) Co-authored-by: Cem Aksoylar Fixes #2166 --- docs/docs/config/battery.md | 11 +++++++++++ docs/docs/features/battery.md | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/docs/config/battery.md b/docs/docs/config/battery.md index 68de8fb8..463dc087 100644 --- a/docs/docs/config/battery.md +++ b/docs/docs/config/battery.md @@ -28,6 +28,17 @@ On macOS the BLE battery reporting packets can cause the computer to wakeup from ::: +### Peripheral battery monitoring + +You can [configure ZMK to allow support for peripheral battery monitoring over BLE](system.md#split-keyboards) (e.g. when having a split keyboard with two independent and wirelessly connected sides). +If you want to report the battery levels of both sides of a split keyboard, you should have both `CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_PROXY` and `CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING` set to `y`. + +:::note[Displaying both battery levels on your host] + +Host support for multiple battery levels is undefined. It appears that in most of the cases only the main battery is being reported. In order to correctly display all the battery values, you probably need a special application or script. + +::: + ### Devicetree Applies to: [`/chosen` node](https://docs.zephyrproject.org/3.5.0/build/dts/intro-syntax-structure.html#aliases-and-chosen-nodes) diff --git a/docs/docs/features/battery.md b/docs/docs/features/battery.md index 4bfeb129..29142eed 100644 --- a/docs/docs/features/battery.md +++ b/docs/docs/features/battery.md @@ -5,7 +5,7 @@ sidebar_label: Battery Level If your keyboard has a battery sensor, ZMK will report its battery level to the connected bluetooth host and show it on the keyboard's display, if it has one. -For split keyboards, only the battery level of the central (usually left) side is reported over bluetooth. +For split keyboards, only the battery level of the central (usually left) side is reported over bluetooth by default. ZMK can be [configured to report the battery levels for peripherals](../config/battery.md#peripheral-battery-monitoring), but not many host systems will display this information without additional configuration or the use of third party utilities. :::note From fda6a5f18534ac7c480fdec5854f063432733f69 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Sat, 17 Feb 2024 21:32:24 -0800 Subject: [PATCH 049/127] fix(boards): Tweaks for Ferris rev0.2 for Zephyr. * Enable missing clock and set up USB pinctrl. --- app/boards/arm/ferris/ferris_rev02.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/boards/arm/ferris/ferris_rev02.dts b/app/boards/arm/ferris/ferris_rev02.dts index eb219420..4fecd280 100644 --- a/app/boards/arm/ferris/ferris_rev02.dts +++ b/app/boards/arm/ferris/ferris_rev02.dts @@ -112,6 +112,9 @@ &usb { status = "okay"; + + pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; + pinctrl-names = "default"; cdc_acm_uart: cdc_acm_uart { compatible = "zephyr,cdc-acm-uart"; }; @@ -121,6 +124,10 @@ status = "okay"; }; +&clk_hsi48 { + status = "okay"; +}; + &pll { prediv = <1>; mul = <6>; From a9ae6796a088730d7377f660e78af17f11bb87c7 Mon Sep 17 00:00:00 2001 From: zhiayang <500236+zhiayang@users.noreply.github.com> Date: Mon, 19 Feb 2024 19:15:19 -0500 Subject: [PATCH 050/127] fix(display): Proper initial display of battery status * fix initial display of battery status on displays, and also fix a null deref --- app/boards/arm/corneish_zen/widgets/battery_status.c | 4 +++- app/boards/shields/nice_view/widgets/status.c | 4 +++- app/src/display/widgets/battery_status.c | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/boards/arm/corneish_zen/widgets/battery_status.c b/app/boards/arm/corneish_zen/widgets/battery_status.c index 011319c4..39b811b5 100644 --- a/app/boards/arm/corneish_zen/widgets/battery_status.c +++ b/app/boards/arm/corneish_zen/widgets/battery_status.c @@ -66,8 +66,10 @@ void battery_status_update_cb(struct battery_status_state state) { } static struct battery_status_state battery_status_get_state(const zmk_event_t *eh) { + const struct zmk_battery_state_changed *ev = as_zmk_battery_state_changed(eh); + return (struct battery_status_state) { - .level = zmk_battery_state_of_charge(), + .level = (ev != NULL) ? ev->state_of_charge : zmk_battery_state_of_charge(), #if IS_ENABLED(CONFIG_USB_DEVICE_STACK) .usb_present = zmk_usb_is_powered(), #endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ diff --git a/app/boards/shields/nice_view/widgets/status.c b/app/boards/shields/nice_view/widgets/status.c index 93139eca..061b7127 100644 --- a/app/boards/shields/nice_view/widgets/status.c +++ b/app/boards/shields/nice_view/widgets/status.c @@ -210,8 +210,10 @@ static void battery_status_update_cb(struct battery_status_state state) { } static struct battery_status_state battery_status_get_state(const zmk_event_t *eh) { + const struct zmk_battery_state_changed *ev = as_zmk_battery_state_changed(eh); + return (struct battery_status_state) { - .level = zmk_battery_state_of_charge(), + .level = (ev != NULL) ? ev->state_of_charge : zmk_battery_state_of_charge(), #if IS_ENABLED(CONFIG_USB_DEVICE_STACK) .usb_present = zmk_usb_is_powered(), #endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ diff --git a/app/src/display/widgets/battery_status.c b/app/src/display/widgets/battery_status.c index 06f55f3f..bec6964b 100644 --- a/app/src/display/widgets/battery_status.c +++ b/app/src/display/widgets/battery_status.c @@ -9,6 +9,7 @@ #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); +#include #include #include #include @@ -63,8 +64,9 @@ void battery_status_update_cb(struct battery_status_state state) { static struct battery_status_state battery_status_get_state(const zmk_event_t *eh) { const struct zmk_battery_state_changed *ev = as_zmk_battery_state_changed(eh); + return (struct battery_status_state) { - .level = ev->state_of_charge, + .level = (ev != NULL) ? ev->state_of_charge : zmk_battery_state_of_charge(), #if IS_ENABLED(CONFIG_USB_DEVICE_STACK) .usb_present = zmk_usb_is_powered(), #endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ From c082f8d80280a41fd4d023cd35d71309af167119 Mon Sep 17 00:00:00 2001 From: ton-im Date: Tue, 20 Feb 2024 08:32:12 +0800 Subject: [PATCH 051/127] fix(boards): Add ext power init delay for nrfMicro * Address issues with OLED init occurring before display is powered. --- app/boards/arm/nrfmicro/nrfmicro_11.dts | 1 + app/boards/arm/nrfmicro/nrfmicro_11_flipped.dts | 1 + app/boards/arm/nrfmicro/nrfmicro_13.dts | 1 + app/boards/arm/nrfmicro/nrfmicro_13_52833.dts | 1 + 4 files changed, 4 insertions(+) diff --git a/app/boards/arm/nrfmicro/nrfmicro_11.dts b/app/boards/arm/nrfmicro/nrfmicro_11.dts index c0c02ee9..652df101 100644 --- a/app/boards/arm/nrfmicro/nrfmicro_11.dts +++ b/app/boards/arm/nrfmicro/nrfmicro_11.dts @@ -31,6 +31,7 @@ EXT_POWER { compatible = "zmk,ext-power-generic"; control-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + init-delay-ms = <50>; }; }; diff --git a/app/boards/arm/nrfmicro/nrfmicro_11_flipped.dts b/app/boards/arm/nrfmicro/nrfmicro_11_flipped.dts index df3b224b..5095d648 100644 --- a/app/boards/arm/nrfmicro/nrfmicro_11_flipped.dts +++ b/app/boards/arm/nrfmicro/nrfmicro_11_flipped.dts @@ -31,6 +31,7 @@ EXT_POWER { compatible = "zmk,ext-power-generic"; control-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + init-delay-ms = <50>; }; }; diff --git a/app/boards/arm/nrfmicro/nrfmicro_13.dts b/app/boards/arm/nrfmicro/nrfmicro_13.dts index f5ae81c9..7a6a5d4d 100644 --- a/app/boards/arm/nrfmicro/nrfmicro_13.dts +++ b/app/boards/arm/nrfmicro/nrfmicro_13.dts @@ -32,6 +32,7 @@ EXT_POWER { compatible = "zmk,ext-power-generic"; control-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + init-delay-ms = <50>; }; vbatt: vbatt { diff --git a/app/boards/arm/nrfmicro/nrfmicro_13_52833.dts b/app/boards/arm/nrfmicro/nrfmicro_13_52833.dts index d6c88692..ff2e027f 100644 --- a/app/boards/arm/nrfmicro/nrfmicro_13_52833.dts +++ b/app/boards/arm/nrfmicro/nrfmicro_13_52833.dts @@ -32,6 +32,7 @@ EXT_POWER { compatible = "zmk,ext-power-generic"; control-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + init-delay-ms = <50>; }; vbatt: vbatt { From ccf038017993dd2e7f00bdd355e28c5009621dd5 Mon Sep 17 00:00:00 2001 From: honorless <86894501+lesshonor@users.noreply.github.com> Date: Sun, 11 Feb 2024 21:52:23 -0500 Subject: [PATCH 052/127] refactor: remove redundant Kconfig defaults bool symbols implicitly default to n. --- app/Kconfig | 5 ----- app/Kconfig.behaviors | 1 - app/src/display/Kconfig | 1 - 3 files changed, 7 deletions(-) diff --git a/app/Kconfig b/app/Kconfig index 8155efd0..bb6997a4 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -177,7 +177,6 @@ config ZMK_BLE_EXPERIMENTAL_FEATURES config ZMK_BLE_PASSKEY_ENTRY bool "Require passkey entry on the keyboard to complete pairing" - default n select RING_BUFFER config BT_SMP_ALLOW_UNAUTH_OVERWRITE @@ -216,7 +215,6 @@ config ZMK_BLE_MOUSE_REPORT_QUEUE_SIZE config ZMK_BLE_CLEAR_BONDS_ON_START bool "Configuration that clears all bond information from the keyboard on startup." - default n # HID GATT notifications sent this way are *not* picked up by Linux, and possibly others. config BT_GATT_NOTIFY_MULTIPLE @@ -373,7 +371,6 @@ menu "Mouse Options" config ZMK_MOUSE bool "Enable ZMK mouse emulation" - default n #Mouse Options endmenu @@ -382,7 +379,6 @@ menu "Power Management" config ZMK_BATTERY_REPORTING bool "Battery level detection/reporting" - default n select SENSOR select ZMK_LOW_PRIORITY_WORK_QUEUE imply BT_BAS if ZMK_BLE @@ -616,7 +612,6 @@ config FPU config ZMK_WPM bool "Calculate WPM" - default n config ZMK_KEYMAP_SENSORS bool "Enable Keymap Sensors support" diff --git a/app/Kconfig.behaviors b/app/Kconfig.behaviors index 11bc8c59..7a1e44f6 100644 --- a/app/Kconfig.behaviors +++ b/app/Kconfig.behaviors @@ -14,7 +14,6 @@ config ZMK_BEHAVIOR_MOUSE_KEY_PRESS config ZMK_BEHAVIOR_SENSOR_ROTATE_COMMON bool - default n config ZMK_BEHAVIOR_SENSOR_ROTATE bool diff --git a/app/src/display/Kconfig b/app/src/display/Kconfig index 356b4760..1cde0fe4 100644 --- a/app/src/display/Kconfig +++ b/app/src/display/Kconfig @@ -3,7 +3,6 @@ menuconfig ZMK_DISPLAY bool "Enable ZMK Display" - default n select DISPLAY select LVGL select LV_CONF_MINIMAL From b44ec381f69233d1c2d32c6501189e4e339ff876 Mon Sep 17 00:00:00 2001 From: Seth Milliken Date: Fri, 9 Feb 2024 01:02:49 -0800 Subject: [PATCH 053/127] feat(boards): add encoder support to planck --- app/boards/arm/planck/planck_rev6.dts | 14 ++++++++++++++ app/boards/arm/planck/planck_rev6.keymap | 6 ++++++ app/boards/arm/planck/planck_rev6.zmk.yml | 1 + app/boards/arm/planck/planck_rev6_defconfig | 4 ++++ 4 files changed, 25 insertions(+) diff --git a/app/boards/arm/planck/planck_rev6.dts b/app/boards/arm/planck/planck_rev6.dts index b6f6fca4..5b8e16b2 100644 --- a/app/boards/arm/planck/planck_rev6.dts +++ b/app/boards/arm/planck/planck_rev6.dts @@ -44,6 +44,20 @@ ; }; + encoder: encoder { + compatible = "alps,ec11"; + a-gpios = <&gpiob 12 GPIO_PULL_UP>; + b-gpios = <&gpiob 13 GPIO_PULL_UP>; + steps = <80>; + status = "disabled"; + }; + + sensors: sensors { + compatible = "zmk,keymap-sensors"; + sensors = <&encoder>; + triggers-per-rotation = <20>; + }; + layout_grid_transform: keymap_transform_0 { compatible = "zmk,matrix-transform"; diff --git a/app/boards/arm/planck/planck_rev6.keymap b/app/boards/arm/planck/planck_rev6.keymap index 65138057..1386eadd 100644 --- a/app/boards/arm/planck/planck_rev6.keymap +++ b/app/boards/arm/planck/planck_rev6.keymap @@ -7,6 +7,11 @@ #include #include +/* Uncomment this block if using an encoder */ +//&encoder { +// status = "okay"; +//}; + / { keymap { compatible = "zmk,keymap"; @@ -23,6 +28,7 @@ &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp SLASH &kp RET &trans &kp LCTL &kp LALT &kp LGUI &mo 1 &trans &kp SPACE &mo 2 &kp LEFT &kp DOWN &kp UP &kp RIGHT >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; }; lower { diff --git a/app/boards/arm/planck/planck_rev6.zmk.yml b/app/boards/arm/planck/planck_rev6.zmk.yml index 56c00006..f9d42424 100644 --- a/app/boards/arm/planck/planck_rev6.zmk.yml +++ b/app/boards/arm/planck/planck_rev6.zmk.yml @@ -5,6 +5,7 @@ type: board arch: arm features: - keys + - encoder outputs: - usb url: https://olkb.com/collections/planck diff --git a/app/boards/arm/planck/planck_rev6_defconfig b/app/boards/arm/planck/planck_rev6_defconfig index ce08f41d..f4530639 100644 --- a/app/boards/arm/planck/planck_rev6_defconfig +++ b/app/boards/arm/planck/planck_rev6_defconfig @@ -14,3 +14,7 @@ CONFIG_GPIO=y CONFIG_CLOCK_CONTROL=y CONFIG_ZMK_USB=y + +# Uncomment these two lines to add support for encoder to your firmware +#CONFIG_EC11=y +#CONFIG_EC11_TRIGGER_OWN_THREAD=y From 104c73d303dea42d8abe23230035597e5cfa4863 Mon Sep 17 00:00:00 2001 From: Xudong Zheng <7pkvm5aw@slicealias.com> Date: Thu, 9 Nov 2023 10:42:56 -0500 Subject: [PATCH 054/127] refactor: address transport switch enumeration warning When building without USB or Bluetooth, the compiler emits a warning due to ZMK_TRANSPORT_USB or ZMK_TRANSPORT_BLE not being handled. --- app/src/endpoints.c | 48 +++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/app/src/endpoints.c b/app/src/endpoints.c index 395d6ba5..f8452d93 100644 --- a/app/src/endpoints.c +++ b/app/src/endpoints.c @@ -122,57 +122,69 @@ struct zmk_endpoint_instance zmk_endpoints_selected(void) { static int send_keyboard_report(void) { switch (current_instance.transport) { -#if IS_ENABLED(CONFIG_ZMK_USB) case ZMK_TRANSPORT_USB: { +#if IS_ENABLED(CONFIG_ZMK_USB) int err = zmk_usb_hid_send_keyboard_report(); if (err) { LOG_ERR("FAILED TO SEND OVER USB: %d", err); } return err; - } +#else + LOG_ERR("USB endpoint is not supported"); + return -ENOTSUP; #endif /* IS_ENABLED(CONFIG_ZMK_USB) */ + } -#if IS_ENABLED(CONFIG_ZMK_BLE) case ZMK_TRANSPORT_BLE: { +#if IS_ENABLED(CONFIG_ZMK_BLE) struct zmk_hid_keyboard_report *keyboard_report = zmk_hid_get_keyboard_report(); int err = zmk_hog_send_keyboard_report(&keyboard_report->body); if (err) { LOG_ERR("FAILED TO SEND OVER HOG: %d", err); } return err; - } +#else + LOG_ERR("BLE HOG endpoint is not supported"); + return -ENOTSUP; #endif /* IS_ENABLED(CONFIG_ZMK_BLE) */ } + } - LOG_ERR("Unsupported endpoint transport %d", current_instance.transport); + LOG_ERR("Unhandled endpoint transport %d", current_instance.transport); return -ENOTSUP; } static int send_consumer_report(void) { switch (current_instance.transport) { -#if IS_ENABLED(CONFIG_ZMK_USB) case ZMK_TRANSPORT_USB: { +#if IS_ENABLED(CONFIG_ZMK_USB) int err = zmk_usb_hid_send_consumer_report(); if (err) { LOG_ERR("FAILED TO SEND OVER USB: %d", err); } return err; - } +#else + LOG_ERR("USB endpoint is not supported"); + return -ENOTSUP; #endif /* IS_ENABLED(CONFIG_ZMK_USB) */ + } -#if IS_ENABLED(CONFIG_ZMK_BLE) case ZMK_TRANSPORT_BLE: { +#if IS_ENABLED(CONFIG_ZMK_BLE) struct zmk_hid_consumer_report *consumer_report = zmk_hid_get_consumer_report(); int err = zmk_hog_send_consumer_report(&consumer_report->body); if (err) { LOG_ERR("FAILED TO SEND OVER HOG: %d", err); } return err; - } +#else + LOG_ERR("BLE HOG endpoint is not supported"); + return -ENOTSUP; #endif /* IS_ENABLED(CONFIG_ZMK_BLE) */ } + } - LOG_ERR("Unsupported endpoint transport %d", current_instance.transport); + LOG_ERR("Unhandled endpoint transport %d", current_instance.transport); return -ENOTSUP; } @@ -194,29 +206,35 @@ int zmk_endpoints_send_report(uint16_t usage_page) { #if IS_ENABLED(CONFIG_ZMK_MOUSE) int zmk_endpoints_send_mouse_report() { switch (current_instance.transport) { -#if IS_ENABLED(CONFIG_ZMK_USB) case ZMK_TRANSPORT_USB: { +#if IS_ENABLED(CONFIG_ZMK_USB) int err = zmk_usb_hid_send_mouse_report(); if (err) { LOG_ERR("FAILED TO SEND OVER USB: %d", err); } return err; - } +#else + LOG_ERR("USB endpoint is not supported"); + return -ENOTSUP; #endif /* IS_ENABLED(CONFIG_ZMK_USB) */ + } -#if IS_ENABLED(CONFIG_ZMK_BLE) case ZMK_TRANSPORT_BLE: { +#if IS_ENABLED(CONFIG_ZMK_BLE) struct zmk_hid_mouse_report *mouse_report = zmk_hid_get_mouse_report(); int err = zmk_hog_send_mouse_report(&mouse_report->body); if (err) { LOG_ERR("FAILED TO SEND OVER HOG: %d", err); } return err; - } +#else + LOG_ERR("BLE HOG endpoint is not supported"); + return -ENOTSUP; #endif /* IS_ENABLED(CONFIG_ZMK_BLE) */ } + } - LOG_ERR("Unsupported endpoint transport %d", current_instance.transport); + LOG_ERR("Unhandled endpoint transport %d", current_instance.transport); return -ENOTSUP; } #endif // IS_ENABLED(CONFIG_ZMK_MOUSE) From c007d6035778fc3e34d56e82756e747c745085b8 Mon Sep 17 00:00:00 2001 From: Theo Lemay Date: Mon, 22 May 2023 19:34:29 -0700 Subject: [PATCH 055/127] feat(behaviors): hold while undecided --- .../behaviors/zmk,behavior-hold-tap.yaml | 4 + app/src/behaviors/behavior_hold_tap.c | 111 ++++++++++++++---- .../1-tap/events.patterns | 4 + .../1-tap/keycode_events.snapshot | 8 ++ .../1-tap/native_posix_64.keymap | 36 ++++++ .../2-hold/events.patterns | 4 + .../2-hold/keycode_events.snapshot | 6 + .../2-hold/native_posix_64.keymap | 36 ++++++ .../3-linger/events.patterns | 4 + .../3-linger/keycode_events.snapshot | 8 ++ .../3-linger/native_posix_64.keymap | 37 ++++++ .../4-linger-sk/events.patterns | 4 + .../4-linger-sk/keycode_events.snapshot | 7 ++ .../4-linger-sk/native_posix_64.keymap | 37 ++++++ docs/docs/behaviors/hold-tap.mdx | 12 ++ docs/docs/config/behaviors.md | 22 ++-- 16 files changed, 306 insertions(+), 34 deletions(-) create mode 100644 app/tests/hold-tap/hold-while-undecided/1-tap/events.patterns create mode 100644 app/tests/hold-tap/hold-while-undecided/1-tap/keycode_events.snapshot create mode 100644 app/tests/hold-tap/hold-while-undecided/1-tap/native_posix_64.keymap create mode 100644 app/tests/hold-tap/hold-while-undecided/2-hold/events.patterns create mode 100644 app/tests/hold-tap/hold-while-undecided/2-hold/keycode_events.snapshot create mode 100644 app/tests/hold-tap/hold-while-undecided/2-hold/native_posix_64.keymap create mode 100644 app/tests/hold-tap/hold-while-undecided/3-linger/events.patterns create mode 100644 app/tests/hold-tap/hold-while-undecided/3-linger/keycode_events.snapshot create mode 100644 app/tests/hold-tap/hold-while-undecided/3-linger/native_posix_64.keymap create mode 100644 app/tests/hold-tap/hold-while-undecided/4-linger-sk/events.patterns create mode 100644 app/tests/hold-tap/hold-while-undecided/4-linger-sk/keycode_events.snapshot create mode 100644 app/tests/hold-tap/hold-while-undecided/4-linger-sk/native_posix_64.keymap diff --git a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml index 57575411..76f14d12 100644 --- a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml +++ b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml @@ -37,6 +37,10 @@ properties: - "balanced" - "tap-preferred" - "tap-unless-interrupted" + hold-while-undecided: + type: boolean + hold-while-undecided-linger: + type: boolean retro-tap: type: boolean hold-trigger-key-positions: diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index efc96c1a..01587caf 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -45,6 +45,7 @@ enum status { }; enum decision_moment { + HT_KEY_DOWN, HT_KEY_UP, HT_OTHER_KEY_DOWN, HT_OTHER_KEY_UP, @@ -59,6 +60,8 @@ struct behavior_hold_tap_config { int quick_tap_ms; int require_prior_idle_ms; enum flavor flavor; + bool hold_while_undecided; + bool hold_while_undecided_linger; bool retro_tap; bool hold_trigger_on_release; int32_t hold_trigger_key_positions_len; @@ -387,47 +390,87 @@ static inline const char *decision_moment_str(enum decision_moment decision_mome } } -static int press_binding(struct active_hold_tap *hold_tap) { - if (hold_tap->config->retro_tap && hold_tap->status == STATUS_HOLD_TIMER) { - return 0; - } - +static int press_hold_binding(struct active_hold_tap *hold_tap) { struct zmk_behavior_binding_event event = { .position = hold_tap->position, .timestamp = hold_tap->timestamp, }; struct zmk_behavior_binding binding = {0}; - if (hold_tap->status == STATUS_HOLD_TIMER || hold_tap->status == STATUS_HOLD_INTERRUPT) { - binding.behavior_dev = hold_tap->config->hold_behavior_dev; - binding.param1 = hold_tap->param_hold; - } else { - binding.behavior_dev = hold_tap->config->tap_behavior_dev; - binding.param1 = hold_tap->param_tap; - store_last_hold_tapped(hold_tap); - } + binding.behavior_dev = hold_tap->config->hold_behavior_dev; + binding.param1 = hold_tap->param_hold; return behavior_keymap_binding_pressed(&binding, event); } +static int press_tap_binding(struct active_hold_tap *hold_tap) { + struct zmk_behavior_binding_event event = { + .position = hold_tap->position, + .timestamp = hold_tap->timestamp, + }; + + struct zmk_behavior_binding binding = {0}; + binding.behavior_dev = hold_tap->config->tap_behavior_dev; + binding.param1 = hold_tap->param_tap; + store_last_hold_tapped(hold_tap); + return behavior_keymap_binding_pressed(&binding, event); +} + +static int release_hold_binding(struct active_hold_tap *hold_tap) { + struct zmk_behavior_binding_event event = { + .position = hold_tap->position, + .timestamp = hold_tap->timestamp, + }; + + struct zmk_behavior_binding binding = {0}; + binding.behavior_dev = hold_tap->config->hold_behavior_dev; + binding.param1 = hold_tap->param_hold; + return behavior_keymap_binding_released(&binding, event); +} + +static int release_tap_binding(struct active_hold_tap *hold_tap) { + struct zmk_behavior_binding_event event = { + .position = hold_tap->position, + .timestamp = hold_tap->timestamp, + }; + + struct zmk_behavior_binding binding = {0}; + binding.behavior_dev = hold_tap->config->tap_behavior_dev; + binding.param1 = hold_tap->param_tap; + return behavior_keymap_binding_released(&binding, event); +} + +static int press_binding(struct active_hold_tap *hold_tap) { + if (hold_tap->config->retro_tap && hold_tap->status == STATUS_HOLD_TIMER) { + return 0; + } + + if (hold_tap->status == STATUS_HOLD_TIMER || hold_tap->status == STATUS_HOLD_INTERRUPT) { + if (hold_tap->config->hold_while_undecided) { + // the hold is already active, so we don't need to press it again + return 0; + } else { + return press_hold_binding(hold_tap); + } + } else { + if (hold_tap->config->hold_while_undecided && + !hold_tap->config->hold_while_undecided_linger) { + // time to release the hold before pressing the tap + release_hold_binding(hold_tap); + } + return press_tap_binding(hold_tap); + } +} + static int release_binding(struct active_hold_tap *hold_tap) { if (hold_tap->config->retro_tap && hold_tap->status == STATUS_HOLD_TIMER) { return 0; } - struct zmk_behavior_binding_event event = { - .position = hold_tap->position, - .timestamp = hold_tap->timestamp, - }; - - struct zmk_behavior_binding binding = {0}; if (hold_tap->status == STATUS_HOLD_TIMER || hold_tap->status == STATUS_HOLD_INTERRUPT) { - binding.behavior_dev = hold_tap->config->hold_behavior_dev; - binding.param1 = hold_tap->param_hold; + return release_hold_binding(hold_tap); } else { - binding.behavior_dev = hold_tap->config->tap_behavior_dev; - binding.param1 = hold_tap->param_tap; + return release_tap_binding(hold_tap); } - return behavior_keymap_binding_released(&binding, event); } static bool is_first_other_key_pressed_trigger_key(struct active_hold_tap *hold_tap) { @@ -474,6 +517,12 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, return; } + if (hold_tap->config->hold_while_undecided && decision_moment == HT_KEY_DOWN) { + LOG_DBG("%d hold behavior pressed while undecided", hold_tap->position); + press_hold_binding(hold_tap); + return; + } + // If the hold-tap behavior is still undecided, attempt to decide it. switch (hold_tap->config->flavor) { case FLAVOR_HOLD_PREFERRED: @@ -561,6 +610,8 @@ static int on_hold_tap_binding_pressed(struct zmk_behavior_binding *binding, decide_hold_tap(hold_tap, HT_QUICK_TAP); } + decide_hold_tap(hold_tap, HT_KEY_DOWN); + // if this behavior was queued we have to adjust the timer to only // wait for the remaining time. int32_t tapping_term_ms_left = (hold_tap->timestamp + cfg->tapping_term_ms) - k_uptime_get(); @@ -588,6 +639,10 @@ static int on_hold_tap_binding_released(struct zmk_behavior_binding *binding, decide_retro_tap(hold_tap); release_binding(hold_tap); + if (hold_tap->config->hold_while_undecided && hold_tap->config->hold_while_undecided_linger) { + release_hold_binding(hold_tap); + } + if (work_cancel_result == -EINPROGRESS) { // let the timer handler clean up // if we'd clear now, the timer may call back for an uninitialized active_hold_tap. @@ -685,6 +740,12 @@ static int keycode_state_changed_listener(const zmk_event_t *eh) { return ZMK_EV_EVENT_BUBBLE; } + // hold-while-undecided can produce a mod, but we don't want to capture it. + if (undecided_hold_tap->config->hold_while_undecided && + undecided_hold_tap->status == STATUS_UNDECIDED) { + return ZMK_EV_EVENT_BUBBLE; + } + // only key-up events will bubble through position_state_changed_listener // if a undecided_hold_tap is active. LOG_DBG("%d capturing 0x%02X %s event", undecided_hold_tap->position, ev->keycode, @@ -743,6 +804,8 @@ static int behavior_hold_tap_init(const struct device *dev) { ? DT_INST_PROP(n, quick_tap_ms) \ : DT_INST_PROP(n, require_prior_idle_ms), \ .flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \ + .hold_while_undecided = DT_INST_PROP(n, hold_while_undecided), \ + .hold_while_undecided_linger = DT_INST_PROP(n, hold_while_undecided_linger), \ .retro_tap = DT_INST_PROP(n, retro_tap), \ .hold_trigger_on_release = DT_INST_PROP(n, hold_trigger_on_release), \ .hold_trigger_key_positions = DT_INST_PROP(n, hold_trigger_key_positions), \ diff --git a/app/tests/hold-tap/hold-while-undecided/1-tap/events.patterns b/app/tests/hold-tap/hold-while-undecided/1-tap/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/hold-while-undecided/1-tap/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/hold-while-undecided/1-tap/keycode_events.snapshot b/app/tests/hold-tap/hold-while-undecided/1-tap/keycode_events.snapshot new file mode 100644 index 00000000..7cbc8268 --- /dev/null +++ b/app/tests/hold-tap/hold-while-undecided/1-tap/keycode_events.snapshot @@ -0,0 +1,8 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 hold behavior pressed while undecided +kp_pressed: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +ht_decide: 0 decided tap (balanced decision moment key-up) +kp_released: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-while-undecided/1-tap/native_posix_64.keymap b/app/tests/hold-tap/hold-while-undecided/1-tap/native_posix_64.keymap new file mode 100644 index 00000000..09396dd8 --- /dev/null +++ b/app/tests/hold-tap/hold-while-undecided/1-tap/native_posix_64.keymap @@ -0,0 +1,36 @@ +#include +#include +#include + +/ { + behaviors { + ht_bal: behavior_hold_tap_balanced { + compatible = "zmk,behavior-hold-tap"; + label = "HOLD_TAP_BALANCED"; + #binding-cells = <2>; + flavor = "balanced"; + tapping-term-ms = <300>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + hold-while-undecided; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &ht_bal LEFT_SHIFT A &ht_bal LEFT_CONTROL B + &kp D &kp RIGHT_CONTROL>; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; diff --git a/app/tests/hold-tap/hold-while-undecided/2-hold/events.patterns b/app/tests/hold-tap/hold-while-undecided/2-hold/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/hold-while-undecided/2-hold/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/hold-while-undecided/2-hold/keycode_events.snapshot b/app/tests/hold-tap/hold-while-undecided/2-hold/keycode_events.snapshot new file mode 100644 index 00000000..d9eed612 --- /dev/null +++ b/app/tests/hold-tap/hold-while-undecided/2-hold/keycode_events.snapshot @@ -0,0 +1,6 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 hold behavior pressed while undecided +kp_pressed: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +ht_decide: 0 decided hold-timer (balanced decision moment timer) +kp_released: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-while-undecided/2-hold/native_posix_64.keymap b/app/tests/hold-tap/hold-while-undecided/2-hold/native_posix_64.keymap new file mode 100644 index 00000000..e3eaa8e0 --- /dev/null +++ b/app/tests/hold-tap/hold-while-undecided/2-hold/native_posix_64.keymap @@ -0,0 +1,36 @@ +#include +#include +#include + +/ { + behaviors { + ht_bal: behavior_hold_tap_balanced { + compatible = "zmk,behavior-hold-tap"; + label = "HOLD_TAP_BALANCED"; + #binding-cells = <2>; + flavor = "balanced"; + tapping-term-ms = <100>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + hold-while-undecided; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &ht_bal LEFT_SHIFT A &ht_bal LEFT_CONTROL B + &kp D &kp RIGHT_CONTROL>; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,150) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; diff --git a/app/tests/hold-tap/hold-while-undecided/3-linger/events.patterns b/app/tests/hold-tap/hold-while-undecided/3-linger/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/hold-while-undecided/3-linger/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/hold-while-undecided/3-linger/keycode_events.snapshot b/app/tests/hold-tap/hold-while-undecided/3-linger/keycode_events.snapshot new file mode 100644 index 00000000..55c9bb32 --- /dev/null +++ b/app/tests/hold-tap/hold-while-undecided/3-linger/keycode_events.snapshot @@ -0,0 +1,8 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 hold behavior pressed while undecided +kp_pressed: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +ht_decide: 0 decided tap (balanced decision moment key-up) +kp_pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-while-undecided/3-linger/native_posix_64.keymap b/app/tests/hold-tap/hold-while-undecided/3-linger/native_posix_64.keymap new file mode 100644 index 00000000..4b694eb2 --- /dev/null +++ b/app/tests/hold-tap/hold-while-undecided/3-linger/native_posix_64.keymap @@ -0,0 +1,37 @@ +#include +#include +#include + +/ { + behaviors { + ht_bal: behavior_hold_tap_balanced { + compatible = "zmk,behavior-hold-tap"; + label = "HOLD_TAP_BALANCED"; + #binding-cells = <2>; + flavor = "balanced"; + tapping-term-ms = <100>; + quick-tap-ms = <300>; + bindings = <&kp>, <&kp>; + hold-while-undecided; + hold-while-undecided-linger; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &ht_bal LEFT_SHIFT A &ht_bal LEFT_CONTROL B + &kp D &kp RIGHT_CONTROL>; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; diff --git a/app/tests/hold-tap/hold-while-undecided/4-linger-sk/events.patterns b/app/tests/hold-tap/hold-while-undecided/4-linger-sk/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/hold-while-undecided/4-linger-sk/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/hold-while-undecided/4-linger-sk/keycode_events.snapshot b/app/tests/hold-tap/hold-while-undecided/4-linger-sk/keycode_events.snapshot new file mode 100644 index 00000000..74f88195 --- /dev/null +++ b/app/tests/hold-tap/hold-while-undecided/4-linger-sk/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 hold behavior pressed while undecided +kp_pressed: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +ht_decide: 0 decided tap (balanced decision moment key-up) +kp_pressed: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-while-undecided/4-linger-sk/native_posix_64.keymap b/app/tests/hold-tap/hold-while-undecided/4-linger-sk/native_posix_64.keymap new file mode 100644 index 00000000..a748ae51 --- /dev/null +++ b/app/tests/hold-tap/hold-while-undecided/4-linger-sk/native_posix_64.keymap @@ -0,0 +1,37 @@ +#include +#include +#include + +/ { + behaviors { + ht_bal: behavior_hold_tap_balanced { + compatible = "zmk,behavior-hold-tap"; + label = "HOLD_TAP_BALANCED"; + #binding-cells = <2>; + flavor = "balanced"; + tapping-term-ms = <100>; + quick-tap-ms = <200>; + bindings = <&kp>, <&sk>; + hold-while-undecided; + hold-while-undecided-linger; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &ht_bal LEFT_SHIFT LEFT_SHIFT &ht_bal LEFT_SHIFT LEFT_CONTROL + &kp D &kp RIGHT_CONTROL>; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; diff --git a/docs/docs/behaviors/hold-tap.mdx b/docs/docs/behaviors/hold-tap.mdx index 26af9f1d..191e820d 100644 --- a/docs/docs/behaviors/hold-tap.mdx +++ b/docs/docs/behaviors/hold-tap.mdx @@ -83,6 +83,18 @@ For example, if you press `&mt LEFT_SHIFT A` and then release it without pressin }; ``` +#### `hold-while-undecided` + +If enabled, the hold behavior will immediately be held on hold-tap press, and will release before the behavior is sent in the event the hold-tap resolves into a tap. With most modifiers this will not affect typing, and is useful for using modifiers with the mouse. + +:::note Alt/Win/Cmd behavior +In some applications/desktop environments, pressing Alt keycodes by itself will have its own behavior like activate a menu and Gui keycodes will bring up the start menu or an application launcher. +::: + +#### `hold-while-undecided-linger` + +If your tap behavior activates the same modifier as the hold behavior, and you want to avoid a double tap when transitioning from the hold to the tap, you can use `hold-while-undecided-linger`. When enabled, the hold behavior will continue to be held until _after_ the tap behavior is released. For example, if the hold is `&kp LGUI` and the tap is `&sk LGUI`, then with `hold-while-undecided-linger` enabled, the host will see `LGUI` held down continuously until the sticky key is finished, instead of seeing a release and press when transitioning from hold to sticky key. + #### Positional hold-tap and `hold-trigger-key-positions` Including `hold-trigger-key-positions` in your hold-tap definition turns on the positional hold-tap feature. With positional hold-tap enabled, if you press any key **NOT** listed in `hold-trigger-key-positions` before `tapping-term-ms` expires, it will produce a tap. diff --git a/docs/docs/config/behaviors.md b/docs/docs/config/behaviors.md index c31de5dd..f8d2fe39 100644 --- a/docs/docs/config/behaviors.md +++ b/docs/docs/config/behaviors.md @@ -57,16 +57,18 @@ Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml](htt Applies to: `compatible = "zmk,behavior-hold-tap"` -| Property | Type | Description | Default | -| ---------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------- | ------------------ | -| `#binding-cells` | int | Must be `<2>` | | -| `bindings` | phandle array | A list of two behaviors (without parameters): one for hold and one for tap | | -| `flavor` | string | Adjusts how the behavior chooses between hold and tap | `"hold-preferred"` | -| `tapping-term-ms` | int | How long in milliseconds the key must be held to trigger a hold | | -| `quick-tap-ms` | int | Tap twice within this period (in milliseconds) to trigger a tap, even when held | -1 (disabled) | -| `require-prior-idle-ms` | int | Triggers a tap immediately if any non-modifier key was pressed within `require-prior-idle-ms` of the hold-tap. | -1 (disabled) | -| `retro-tap` | bool | Triggers the tap behavior on release if no other key was pressed during a hold | false | -| `hold-trigger-key-positions` | array | If set, pressing the hold-tap and then any key position _not_ in the list triggers a tap. | | +| Property | Type | Description | Default | +| ----------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------- | ------------------ | +| `#binding-cells` | int | Must be `<2>` | | +| `bindings` | phandle array | A list of two behaviors (without parameters): one for hold and one for tap | | +| `flavor` | string | Adjusts how the behavior chooses between hold and tap | `"hold-preferred"` | +| `tapping-term-ms` | int | How long in milliseconds the key must be held to trigger a hold | | +| `quick-tap-ms` | int | Tap twice within this period (in milliseconds) to trigger a tap, even when held | -1 (disabled) | +| `require-prior-idle-ms` | int | Triggers a tap immediately if any non-modifier key was pressed within `require-prior-idle-ms` of the hold-tap. | -1 (disabled) | +| `retro-tap` | bool | Triggers the tap behavior on release if no other key was pressed during a hold | false | +| `hold-while-undecided` | bool | Triggers the hold behavior immediately on press and releases before a tap | false | +| `hold-while-undecided-linger` | bool | Continues to hold the hold behavior until after the tap is released | false | +| `hold-trigger-key-positions` | array | If set, pressing the hold-tap and then any key position _not_ in the list triggers a tap. | | This behavior forwards the first parameter it receives to the parameter of the first behavior specified in `bindings`, and second parameter to the parameter of the second behavior. From 8b20874c99ea191afbfc5ec3169e7f211986a853 Mon Sep 17 00:00:00 2001 From: Theo Lemay Date: Mon, 18 Dec 2023 21:34:38 -0500 Subject: [PATCH 056/127] chore: remove label in test --- .../hold-tap/hold-while-undecided/1-tap/native_posix_64.keymap | 2 -- .../hold-tap/hold-while-undecided/2-hold/native_posix_64.keymap | 2 -- .../hold-while-undecided/3-linger/native_posix_64.keymap | 2 -- .../hold-while-undecided/4-linger-sk/native_posix_64.keymap | 2 -- 4 files changed, 8 deletions(-) diff --git a/app/tests/hold-tap/hold-while-undecided/1-tap/native_posix_64.keymap b/app/tests/hold-tap/hold-while-undecided/1-tap/native_posix_64.keymap index 09396dd8..5f42c30c 100644 --- a/app/tests/hold-tap/hold-while-undecided/1-tap/native_posix_64.keymap +++ b/app/tests/hold-tap/hold-while-undecided/1-tap/native_posix_64.keymap @@ -6,7 +6,6 @@ behaviors { ht_bal: behavior_hold_tap_balanced { compatible = "zmk,behavior-hold-tap"; - label = "HOLD_TAP_BALANCED"; #binding-cells = <2>; flavor = "balanced"; tapping-term-ms = <300>; @@ -18,7 +17,6 @@ keymap { compatible = "zmk,keymap"; - label ="Default keymap"; default_layer { bindings = < diff --git a/app/tests/hold-tap/hold-while-undecided/2-hold/native_posix_64.keymap b/app/tests/hold-tap/hold-while-undecided/2-hold/native_posix_64.keymap index e3eaa8e0..381a7414 100644 --- a/app/tests/hold-tap/hold-while-undecided/2-hold/native_posix_64.keymap +++ b/app/tests/hold-tap/hold-while-undecided/2-hold/native_posix_64.keymap @@ -6,7 +6,6 @@ behaviors { ht_bal: behavior_hold_tap_balanced { compatible = "zmk,behavior-hold-tap"; - label = "HOLD_TAP_BALANCED"; #binding-cells = <2>; flavor = "balanced"; tapping-term-ms = <100>; @@ -18,7 +17,6 @@ keymap { compatible = "zmk,keymap"; - label ="Default keymap"; default_layer { bindings = < diff --git a/app/tests/hold-tap/hold-while-undecided/3-linger/native_posix_64.keymap b/app/tests/hold-tap/hold-while-undecided/3-linger/native_posix_64.keymap index 4b694eb2..0a296b70 100644 --- a/app/tests/hold-tap/hold-while-undecided/3-linger/native_posix_64.keymap +++ b/app/tests/hold-tap/hold-while-undecided/3-linger/native_posix_64.keymap @@ -6,7 +6,6 @@ behaviors { ht_bal: behavior_hold_tap_balanced { compatible = "zmk,behavior-hold-tap"; - label = "HOLD_TAP_BALANCED"; #binding-cells = <2>; flavor = "balanced"; tapping-term-ms = <100>; @@ -19,7 +18,6 @@ keymap { compatible = "zmk,keymap"; - label ="Default keymap"; default_layer { bindings = < diff --git a/app/tests/hold-tap/hold-while-undecided/4-linger-sk/native_posix_64.keymap b/app/tests/hold-tap/hold-while-undecided/4-linger-sk/native_posix_64.keymap index a748ae51..557076bc 100644 --- a/app/tests/hold-tap/hold-while-undecided/4-linger-sk/native_posix_64.keymap +++ b/app/tests/hold-tap/hold-while-undecided/4-linger-sk/native_posix_64.keymap @@ -6,7 +6,6 @@ behaviors { ht_bal: behavior_hold_tap_balanced { compatible = "zmk,behavior-hold-tap"; - label = "HOLD_TAP_BALANCED"; #binding-cells = <2>; flavor = "balanced"; tapping-term-ms = <100>; @@ -19,7 +18,6 @@ keymap { compatible = "zmk,keymap"; - label ="Default keymap"; default_layer { bindings = < From c9c620d19f603ea0c9d4264eff885912803ff74d Mon Sep 17 00:00:00 2001 From: Theo Lemay Date: Sat, 3 Feb 2024 17:25:50 -0500 Subject: [PATCH 057/127] fix: inline initialise --- app/src/behaviors/behavior_hold_tap.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 01587caf..204e50f4 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -396,9 +396,8 @@ static int press_hold_binding(struct active_hold_tap *hold_tap) { .timestamp = hold_tap->timestamp, }; - struct zmk_behavior_binding binding = {0}; - binding.behavior_dev = hold_tap->config->hold_behavior_dev; - binding.param1 = hold_tap->param_hold; + struct zmk_behavior_binding binding = {.behavior_dev = hold_tap->config->hold_behavior_dev, + .param1 = hold_tap->param_hold}; return behavior_keymap_binding_pressed(&binding, event); } @@ -408,9 +407,8 @@ static int press_tap_binding(struct active_hold_tap *hold_tap) { .timestamp = hold_tap->timestamp, }; - struct zmk_behavior_binding binding = {0}; - binding.behavior_dev = hold_tap->config->tap_behavior_dev; - binding.param1 = hold_tap->param_tap; + struct zmk_behavior_binding binding = {.behavior_dev = hold_tap->config->tap_behavior_dev, + .param1 = hold_tap->param_tap}; store_last_hold_tapped(hold_tap); return behavior_keymap_binding_pressed(&binding, event); } @@ -421,9 +419,8 @@ static int release_hold_binding(struct active_hold_tap *hold_tap) { .timestamp = hold_tap->timestamp, }; - struct zmk_behavior_binding binding = {0}; - binding.behavior_dev = hold_tap->config->hold_behavior_dev; - binding.param1 = hold_tap->param_hold; + struct zmk_behavior_binding binding = {.behavior_dev = hold_tap->config->hold_behavior_dev, + .param1 = hold_tap->param_hold}; return behavior_keymap_binding_released(&binding, event); } @@ -433,9 +430,8 @@ static int release_tap_binding(struct active_hold_tap *hold_tap) { .timestamp = hold_tap->timestamp, }; - struct zmk_behavior_binding binding = {0}; - binding.behavior_dev = hold_tap->config->tap_behavior_dev; - binding.param1 = hold_tap->param_tap; + struct zmk_behavior_binding binding = {.behavior_dev = hold_tap->config->tap_behavior_dev, + .param1 = hold_tap->param_tap}; return behavior_keymap_binding_released(&binding, event); } From db7b197790c57c3fb5b8281bd8242286921ae77c Mon Sep 17 00:00:00 2001 From: Andrew Kannan Date: Wed, 28 Feb 2024 13:39:04 -0500 Subject: [PATCH 058/127] fix(docs): Add underglow brightness min/max (#2180) --- docs/docs/config/underglow.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/docs/config/underglow.md b/docs/docs/config/underglow.md index 1209e60e..e742e791 100644 --- a/docs/docs/config/underglow.md +++ b/docs/docs/config/underglow.md @@ -28,6 +28,8 @@ Definition file: [zmk/app/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/ | `CONFIG_ZMK_RGB_UNDERGLOW_SPD_START` | int | Default effect speed (1-5) | 3 | | `CONFIG_ZMK_RGB_UNDERGLOW_EFF_START` | int | Default effect index from the effect list (see below) | 0 | | `CONFIG_ZMK_RGB_UNDERGLOW_ON_START` | bool | Default on state | y | +| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_MIN` | int | Minimum brightness in percent (0-100) | 0 | +| `CONFIG_ZMK_RGB_UNDERGLOW_BRT_MAX` | int | Maximum brightness in percent (0-100) | 100 | Values for `CONFIG_ZMK_RGB_UNDERGLOW_EFF_START`: From 37af94edde7b42f1894484831b6d958bc4b27124 Mon Sep 17 00:00:00 2001 From: Thomas Huber <113915837+huber-th@users.noreply.github.com> Date: Sun, 3 Mar 2024 21:05:00 -0800 Subject: [PATCH 059/127] feat(docs): Add warning to new shield docs how Kconfig treats whitspaces Added a warning to the shield section explaining that Kconfig does not ignore whitespaces on function calls and therefore adding whitespaces after the comma will break functionality. --- docs/docs/development/new-shield.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/docs/development/new-shield.mdx b/docs/docs/development/new-shield.mdx index 0dcface3..2cd82bc6 100644 --- a/docs/docs/development/new-shield.mdx +++ b/docs/docs/development/new-shield.mdx @@ -79,6 +79,10 @@ config SHIELD_MY_BOARD def_bool $(shields_list_contains,my_board) ``` +:::warning +Kconfig uses only commas for delimiters, and keeps all whitespaces in the function call. Therefore do not add a whitespace after the comma when configuring your shield as this would be treated as  my_board (with a leading whitespace) and will cause issues. +::: + This will make sure that a new configuration value named `SHIELD_MY_BOARD` is set to true whenever `my_board` is used as the shield name, either as the `SHIELD` variable [in a local build](build-flash.mdx) or in your `build.yaml` file [when using Github Actions](../customization). Note that this configuration value will be used in `Kconfig.defconfig` to set other properties about your shield, so make sure that they match. **For split boards**, you will need to add configurations for the left and right sides. For example, if your split halves are named `my_board_left` and `my_board_right`, it would look like this: From 08ab45fc7875a042c787d353ff0e3512319af030 Mon Sep 17 00:00:00 2001 From: Thomas Huber <113915837+huber-th@users.noreply.github.com> Date: Sun, 3 Mar 2024 21:10:14 -0800 Subject: [PATCH 060/127] feat(CONTRIBUTING.md): Add info regarding ESLint --- CONTRIBUTING.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fe7292a8..bcc2aef1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -86,6 +86,12 @@ documentation to areas not currently covered are greatly appreciated. ZMK uses `prettier` to format documentation files. You can run prettier with `npm run prettier:format`. You can setup git to run prettier automatically when you commit by installing the pre-commit hooks: `pip3 install pre-commit`, `pre-commit install`. +### Linting + +This repository utilizes ESLint for code linting to ensure consistent code style and identify potential errors or bugs early in the development process. + +You can run ESLint with `npm run lint` to verify your changes. + ## Code Contributions ### Development Setup From 2adaa00d1092e41ce11dfae46ce7d2a5bad97ead Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 8 Mar 2024 10:17:02 -0800 Subject: [PATCH 061/127] fix(build): Properly board revision keymaps. * Handle board keymap location for boards with Zephyr board revisions included. * Includes bare non-revision file and a revision specific keymap in case newer revision changes the layout/key positions. --- app/keymap-module/modules/modules.cmake | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/app/keymap-module/modules/modules.cmake b/app/keymap-module/modules/modules.cmake index c286809d..f513bcc4 100644 --- a/app/keymap-module/modules/modules.cmake +++ b/app/keymap-module/modules/modules.cmake @@ -63,6 +63,13 @@ if(DEFINED SHIELD) string(REPLACE " " ";" SHIELD_AS_LIST "${SHIELD}") endif() +string(FIND "${BOARD}" "@" REVISION_SEPARATOR_INDEX) +if(NOT (REVISION_SEPARATOR_INDEX EQUAL -1)) + math(EXPR BOARD_REVISION_INDEX "${REVISION_SEPARATOR_INDEX} + 1") + string(SUBSTRING ${BOARD} ${BOARD_REVISION_INDEX} -1 BOARD_REVISION) + string(SUBSTRING ${BOARD} 0 ${REVISION_SEPARATOR_INDEX} BOARD) +endif() + foreach(root ${BOARD_ROOT}) set(shield_dir ${root}/boards/shields) # Match the Kconfig.shield files in the shield directories to make sure we are @@ -107,6 +114,21 @@ foreach(root ${BOARD_ROOT}) endif() endforeach() +if(EXISTS ${BOARD_DIR}/revision.cmake) + # Board provides revision handling. + include(${BOARD_DIR}/revision.cmake) +elseif(BOARD_REVISION) + message(WARNING "Board revision ${BOARD_REVISION} specified for ${BOARD}, \ + but board has no revision so revision will be ignored.") +endif() + +if(DEFINED BOARD_REVISION) + string(REPLACE "." "_" BOARD_REVISION_STRING ${BOARD_REVISION}) + set(KEYMAP_BOARD_REVISION_PREFIX "${BOARD}_${BOARD_REVISION_STRING}") +else() + set(KEYMAP_BOARD_REVISION_PREFIX "") +endif() + # Give a shield like `kyria_rev2_left` we want to use `kyria_rev2` and `kyria` as candidate names for # overlay/conf/keymap files. if(DEFINED SHIELD) @@ -178,7 +200,7 @@ endif() if(NOT KEYMAP_FILE) foreach(keymap_dir ${KEYMAP_DIRS}) - foreach(keymap_prefix ${shield_candidate_names} ${SHIELD_AS_LIST} ${SHIELD_DIR} ${BOARD} ${BOARD_DIR_NAME}) + foreach(keymap_prefix ${shield_candidate_names} ${SHIELD_AS_LIST} ${SHIELD_DIR} ${KEYMAP_BOARD_REVISION_PREFIX} ${BOARD} ${BOARD_DIR_NAME}) if (EXISTS ${keymap_dir}/${keymap_prefix}.keymap) set(KEYMAP_FILE "${keymap_dir}/${keymap_prefix}.keymap" CACHE STRING "Selected keymap file") message(STATUS "Using keymap file: ${KEYMAP_FILE}") From 610a806c848ba53a454bbc66631fa3f3faaef19f Mon Sep 17 00:00:00 2001 From: Joel Spadin Date: Sun, 26 Nov 2023 12:27:12 -0600 Subject: [PATCH 062/127] feat: Add function to erase all settings Added a zmk_settings_erase() function to clear all saved settings. This does not go through Zephyr's settings subsystem, but instead directly clears the data from the setting storage backend, so a reboot is needed for it to take effect. --- app/CMakeLists.txt | 1 + app/include/zmk/settings.h | 15 ++++++++++ app/src/settings/CMakeLists.txt | 7 +++++ app/src/settings/reset_settings_fcb.c | 15 ++++++++++ app/src/settings/reset_settings_file.c | 23 +++++++++++++++ app/src/settings/reset_settings_none.c | 12 ++++++++ app/src/settings/reset_settings_nvs.c | 39 ++++++++++++++++++++++++++ 7 files changed, 112 insertions(+) create mode 100644 app/include/zmk/settings.h create mode 100644 app/src/settings/CMakeLists.txt create mode 100644 app/src/settings/reset_settings_fcb.c create mode 100644 app/src/settings/reset_settings_file.c create mode 100644 app/src/settings/reset_settings_none.c create mode 100644 app/src/settings/reset_settings_nvs.c diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 6ef00311..b12d0474 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -99,5 +99,6 @@ target_sources_ifdef(CONFIG_ZMK_LOW_PRIORITY_WORK_QUEUE app PRIVATE src/workqueu target_sources(app PRIVATE src/main.c) add_subdirectory(src/display/) +add_subdirectory_ifdef(CONFIG_SETTINGS src/settings/) zephyr_cc_option(-Wfatal-errors) diff --git a/app/include/zmk/settings.h b/app/include/zmk/settings.h new file mode 100644 index 00000000..5567d61b --- /dev/null +++ b/app/include/zmk/settings.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +/** + * Erases all saved settings. + * + * @note This does not automatically update any code using Zephyr's settings + * subsystem. This should typically be followed by a call to sys_reboot(). + */ +int zmk_settings_erase(void); diff --git a/app/src/settings/CMakeLists.txt b/app/src/settings/CMakeLists.txt new file mode 100644 index 00000000..63bcd7f9 --- /dev/null +++ b/app/src/settings/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2023 The ZMK Contributors +# SPDX-License-Identifier: MIT + +target_sources_ifdef(CONFIG_SETTINGS_NONE app PRIVATE reset_settings_none.c) +target_sources_ifdef(CONFIG_SETTINGS_FCB app PRIVATE reset_settings_fcb.c) +target_sources_ifdef(CONFIG_SETTINGS_FILE app PRIVATE reset_settings_file.c) +target_sources_ifdef(CONFIG_SETTINGS_NVS app PRIVATE reset_settings_nvs.c) diff --git a/app/src/settings/reset_settings_fcb.c b/app/src/settings/reset_settings_fcb.c new file mode 100644 index 00000000..1d555d34 --- /dev/null +++ b/app/src/settings/reset_settings_fcb.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +int zmk_settings_erase(void) { + LOG_ERR("Settings reset is not implemented for deprecated FCB backend."); + return -ENOSYS; +} diff --git a/app/src/settings/reset_settings_file.c b/app/src/settings/reset_settings_file.c new file mode 100644 index 00000000..1d142868 --- /dev/null +++ b/app/src/settings/reset_settings_file.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +#include + +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +int zmk_settings_erase(void) { + LOG_INF("Erasing settings file"); + + int rc = fs_unlink(CONFIG_SETTINGS_FS_FILE); + if (rc) { + LOG_ERR("Failed to unlink '%s': %d", CONFIG_SETTINGS_FS_FILE, rc); + } + + return rc; +} diff --git a/app/src/settings/reset_settings_none.c b/app/src/settings/reset_settings_none.c new file mode 100644 index 00000000..c5e0ae04 --- /dev/null +++ b/app/src/settings/reset_settings_none.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +int zmk_settings_erase(void) { + // No storage backend; nothing to do + return 0; +} diff --git a/app/src/settings/reset_settings_nvs.c b/app/src/settings/reset_settings_nvs.c new file mode 100644 index 00000000..65157b3d --- /dev/null +++ b/app/src/settings/reset_settings_nvs.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include + +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +// SETTINGS_PARTITION must match settings_nvs.c +#if DT_HAS_CHOSEN(zephyr_settings_partition) +#define SETTINGS_PARTITION DT_FIXED_PARTITION_ID(DT_CHOSEN(zephyr_settings_partition)) +#else +#define SETTINGS_PARTITION FIXED_PARTITION_ID(storage_partition) +#endif + +int zmk_settings_erase(void) { + LOG_INF("Erasing settings flash partition"); + + const struct flash_area *fa; + int rc = flash_area_open(SETTINGS_PARTITION, &fa); + if (rc) { + LOG_ERR("Failed to open settings flash: %d", rc); + return rc; + } + + rc = flash_area_erase(fa, 0, fa->fa_size); + if (rc) { + LOG_ERR("Failed to erase settings flash: %d", rc); + } + + flash_area_close(fa); + + return rc; +} From 1dfcfc7d3f074e538900a6df684cc99e92c60a21 Mon Sep 17 00:00:00 2001 From: Joel Spadin Date: Sun, 26 Nov 2023 12:28:27 -0600 Subject: [PATCH 063/127] feat(shields): Make settings_reset shield reset all settings Added a new CONFIG_ZMK_SETTINGS_RESET_ON_START option which enables init code to call zmk_settings_erase(), and changed the settings_reset shield to use it instead of CONFIG_ZMK_BLE_CLEAR_BONDS_ON_START, so it now resets all settings instead of just clearing BLE bonds. CONFIG_ZMK_BLE_CLEAR_BONDS_ON_START is left in place for now in case someone still needs it. It may be replaced in the future once we find a better way to repair a broken split connection. --- app/Kconfig | 3 +++ .../settings_reset/settings_reset.conf | 5 ++++- app/src/settings/CMakeLists.txt | 2 ++ app/src/settings/reset_settings_on_start.c | 19 +++++++++++++++++++ docs/docs/config/system.md | 13 +++++++------ 5 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 app/src/settings/reset_settings_on_start.c diff --git a/app/Kconfig b/app/Kconfig index bb6997a4..3f797abd 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -565,6 +565,9 @@ endmenu if SETTINGS +config ZMK_SETTINGS_RESET_ON_START + bool "Delete all persistent settings when the keyboard boots" + config ZMK_SETTINGS_SAVE_DEBOUNCE int "Milliseconds to debounce settings saves" default 60000 diff --git a/app/boards/shields/settings_reset/settings_reset.conf b/app/boards/shields/settings_reset/settings_reset.conf index 8052a6cf..4ed84df8 100644 --- a/app/boards/shields/settings_reset/settings_reset.conf +++ b/app/boards/shields/settings_reset/settings_reset.conf @@ -1 +1,4 @@ -CONFIG_ZMK_BLE_CLEAR_BONDS_ON_START=y +CONFIG_SETTINGS=y +CONFIG_ZMK_SETTINGS_RESET_ON_START=y +# Disable BLE so splits don't try to re-pair until normal firmware is flashed. +CONFIG_ZMK_BLE=n diff --git a/app/src/settings/CMakeLists.txt b/app/src/settings/CMakeLists.txt index 63bcd7f9..28664a4e 100644 --- a/app/src/settings/CMakeLists.txt +++ b/app/src/settings/CMakeLists.txt @@ -5,3 +5,5 @@ target_sources_ifdef(CONFIG_SETTINGS_NONE app PRIVATE reset_settings_none.c) target_sources_ifdef(CONFIG_SETTINGS_FCB app PRIVATE reset_settings_fcb.c) target_sources_ifdef(CONFIG_SETTINGS_FILE app PRIVATE reset_settings_file.c) target_sources_ifdef(CONFIG_SETTINGS_NVS app PRIVATE reset_settings_nvs.c) + +target_sources_ifdef(CONFIG_ZMK_SETTINGS_RESET_ON_START app PRIVATE reset_settings_on_start.c) diff --git a/app/src/settings/reset_settings_on_start.c b/app/src/settings/reset_settings_on_start.c new file mode 100644 index 00000000..3b3890f4 --- /dev/null +++ b/app/src/settings/reset_settings_on_start.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#include + +static int reset_settings_init(const struct device *dev) { + ARG_UNUSED(dev); + return zmk_settings_erase(); +} + +// Reset after the kernel is initialized but before any application code to +// ensure settings are cleared before anything tries to use them. +SYS_INIT(reset_settings_init, POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/docs/docs/config/system.md b/docs/docs/config/system.md index 83f2f065..d60fa24e 100644 --- a/docs/docs/config/system.md +++ b/docs/docs/config/system.md @@ -13,12 +13,13 @@ Definition file: [zmk/app/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/ ### General -| Config | Type | Description | Default | -| ----------------------------------- | ------ | ----------------------------------------------------------------------------- | ------- | -| `CONFIG_ZMK_KEYBOARD_NAME` | string | The name of the keyboard (max 16 characters) | | -| `CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE` | int | Milliseconds to wait after a setting change before writing it to flash memory | 60000 | -| `CONFIG_ZMK_WPM` | bool | Enable calculating words per minute | n | -| `CONFIG_HEAP_MEM_POOL_SIZE` | int | Size of the heap memory pool | 8192 | +| Config | Type | Description | Default | +| ------------------------------------ | ------ | ----------------------------------------------------------------------------- | ------- | +| `CONFIG_ZMK_KEYBOARD_NAME` | string | The name of the keyboard (max 16 characters) | | +| `CONFIG_ZMK_SETTINGS_RESET_ON_START` | bool | Clears all persistent settings from the keyboard at startup | n | +| `CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE` | int | Milliseconds to wait after a setting change before writing it to flash memory | 60000 | +| `CONFIG_ZMK_WPM` | bool | Enable calculating words per minute | n | +| `CONFIG_HEAP_MEM_POOL_SIZE` | int | Size of the heap memory pool | 8192 | ### HID From 14b06a36bf5acecb52db57daf29046b334bf18df Mon Sep 17 00:00:00 2001 From: Joel Spadin Date: Sun, 4 Feb 2024 12:34:26 -0600 Subject: [PATCH 064/127] docs: Update settings_reset documentation Updated the section for troubleshooting split halves unable to pair now that the settings_reset shield resets all settings and explicitly disables CONFIG_ZMK_BLE: - Added a note that all settings will be reset. - Removed the section about immediately putting the halves into bootloader mode to prevent pairing, as this is not necessary anymore. - Added a note that you will not be able to see or pair the Bluetooth keyboard until you have flashed regular firmware again. - Added a sentence to clarify that you will need to re-pair the keyboard to all host devices. Also added some text describing common scenarios where this procedure might be needed. --- docs/docs/troubleshooting.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/docs/docs/troubleshooting.md b/docs/docs/troubleshooting.md index 769852d1..bfa92218 100644 --- a/docs/docs/troubleshooting.md +++ b/docs/docs/troubleshooting.md @@ -68,7 +68,20 @@ A common mistake that leads to this error is to use [key press keycodes](behavio ### Split Keyboard Halves Unable to Pair -Split keyboard halves pairing issue can be resolved by flashing a settings reset firmware to both controllers. You will first need to acquire the reset UF2 image file with one of the following options: +Split keyboard halves will automatically pair with one another, but there are some cases where this breaks, and the pairing needs to be reset, for example: + +- Switching which halves are the central/peripheral. +- Replacing the controller for one of the halves. + +These issues can be resolved by flashing a settings reset firmware to both controllers. + +:::warning + +This procedure will erase all settings, such as Bluetooth profiles, output selection, RGB underglow color, etc. + +::: + +First, acquire the reset UF2 image file with one of the following options: #### Option 1: Build Reset UF2 in 'zmk-config' @@ -101,8 +114,16 @@ Save the file, commit the changes and push them to GitHub. Download the new firm Perform the following steps to reset both halves of your split keyboard: 1. Put each half of the split keyboard into bootloader mode. -1. Flash one of the halves of the split with the downloaded settings reset UF2 image. Immediately after flashing the chosen half, put it into bootloader mode to avoid accidental bonding between the halves. +1. Flash one of the halves of the split with the downloaded settings reset UF2 image. 1. Repeat step 2 with the other half of the split keyboard. 1. Flash the actual image for each half of the split keyboard (e.g `my_board_left.uf2` to the left half, `my_board_right.uf2` to the right half). After completing these steps, pair the halves of the split keyboard together by resetting them at the same time. Most commonly, this is done by grounding the reset pins for each of your keyboard's microcontrollers or pressing the reset buttons at the same time. + +Once this is done, you can remove/forget the keyboard on each host device and pair it again. + +:::info + +The settings reset firmware has Bluetooth disabled to prevent the two sides from automatically re-pairing until you are done resetting them both. You will not be able to pair your keyboard or see it in any Bluetooth device lists until you have flashed the normal firmware again. + +::: From a77288f5274b8cd64aed5dc03bb6c03ec205240f Mon Sep 17 00:00:00 2001 From: Joel Spadin Date: Sat, 24 Feb 2024 12:14:37 -0600 Subject: [PATCH 065/127] fix: Update settings reset for Zephyr 3.5 --- app/src/settings/reset_settings_on_start.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/src/settings/reset_settings_on_start.c b/app/src/settings/reset_settings_on_start.c index 3b3890f4..47f5e8f2 100644 --- a/app/src/settings/reset_settings_on_start.c +++ b/app/src/settings/reset_settings_on_start.c @@ -4,16 +4,10 @@ * SPDX-License-Identifier: MIT */ -#include #include #include -static int reset_settings_init(const struct device *dev) { - ARG_UNUSED(dev); - return zmk_settings_erase(); -} - // Reset after the kernel is initialized but before any application code to // ensure settings are cleared before anything tries to use them. -SYS_INIT(reset_settings_init, POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY); +SYS_INIT(zmk_settings_erase, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); From 388ad71385efe858a73c24c8dd7a373485ff4c83 Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Mon, 18 Mar 2024 16:54:47 +0000 Subject: [PATCH 066/127] feat(build): Explicit missing keymap node error * Explicit error if zmk,keymap not set * Document keymap error --------- Co-authored-by: Cem Aksoylar --- app/src/keymap.c | 6 ++++++ docs/docs/troubleshooting.md | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/app/src/keymap.c b/app/src/keymap.c index 75a2dcbe..94bd1204 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -31,6 +31,12 @@ static uint8_t _zmk_keymap_layer_default = 0; #define DT_DRV_COMPAT zmk_keymap +#if !DT_NODE_EXISTS(DT_DRV_INST(0)) + +#error "Keymap node not found, check a keymap is available and is has compatible = "zmk,keymap" set" + +#endif + #define TRANSFORMED_LAYER(node) \ { LISTIFY(DT_PROP_LEN(node, bindings), ZMK_KEYMAP_EXTRACT_BINDING, (, ), node) } diff --git a/docs/docs/troubleshooting.md b/docs/docs/troubleshooting.md index bfa92218..1f3c1706 100644 --- a/docs/docs/troubleshooting.md +++ b/docs/docs/troubleshooting.md @@ -40,6 +40,10 @@ West build errors usually indicate syntax problems in the `.keymap` fi If you are reviewing these errors in the GitHub Actions tab, they can be found in the `West Build` step of the build process. ::: +#### Keymap error + +If you get an error stating `Keymap node not found, check a keymap is available and is has compatible = "zmk,keymap" set` this is an indication that the build process cannot find the keymap. Double check that the `.keymap` file is present and has been discovered by the build process. This can be checked by looking for a line in the build log stating `-- Using keymap file: /path/to/keymap/file/.keymap`. Inside the keymap file ensure the keymap node has `compatible = zmk,keymap` and it's not misspelled. For more information see the [Keymap](features/keymaps.mdx) and [Config](config/index.md) documentation. + #### devicetree error A `devicetree error` followed by a reference to the line number on `.keymap` refers to an issue at the exact line position in that file. For example, below error message indicates a missing `;` at line 109 of the `cradio.keymap` file: From bddee70b6b73ccd8f3ff299d5b36dd0537e639e1 Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Tue, 27 Feb 2024 11:08:58 -0800 Subject: [PATCH 067/127] refactor(docs): Remove outdated Windows battery advice and unnecessary header --- docs/docs/features/bluetooth.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/docs/docs/features/bluetooth.md b/docs/docs/features/bluetooth.md index c4e91faf..307ac7e1 100644 --- a/docs/docs/features/bluetooth.md +++ b/docs/docs/features/bluetooth.md @@ -56,18 +56,6 @@ This setting can also improve the connection strength between the keyboard halve If you want to test bluetooth output on your keyboard and are powering it through the USB connection rather than a battery, you will be able to pair with a host device but may not see keystrokes sent. In this case you need to use the [output selection behavior](../behaviors/outputs.md) to prefer sending keystrokes over bluetooth rather than USB. This might be necessary even if you are not powering from a device capable of receiving USB inputs, such as a USB charger. -## Known Issues - -There are a few known issues related to BLE and ZMK: - -### Windows Battery Reporting - -There is a known issue with Windows failing to update the battery information after connecting to a ZMK keyboard. You can work around this Windows bug by overriding a [Bluetooth config variable](../config/bluetooth.md) to force battery notifications even if a host neglects to subscribe to them: - -```ini -CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION=n -``` - ### macOS Connected But Not Working If you attempt to pair a ZMK keyboard from macOS in a way that causes a bonding issue, macOS may report the keyboard as connected, but fail to actually work. If this occurs: From aa6cfe250d3324f918742c4e0ff232264d44f42c Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Tue, 27 Feb 2024 11:25:15 -0800 Subject: [PATCH 068/127] feat(docs): Document refreshing the HID descriptor --- docs/docs/features/bluetooth.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/docs/features/bluetooth.md b/docs/docs/features/bluetooth.md index 307ac7e1..1f2d7955 100644 --- a/docs/docs/features/bluetooth.md +++ b/docs/docs/features/bluetooth.md @@ -36,6 +36,19 @@ Failure to manage the profiles can result in unexpected/broken behavior with hos Management of the bluetooth in ZMK is accomplished using the [`&bt` behavior](../behaviors/bluetooth.md). Be sure to refer to that documentation to learn how to manage profiles, switch between connected hosts, etc. +## Refreshing the HID Descriptor + +Enabling certain features or behaviors in ZMK changes the data structure that ZMK sends over USB or BLE to host devices. +This in turn requires [HID report descriptors](https://docs.kernel.org/hid/hidintro.html) to be modified for the reports to be parsed correctly. +Firmware changes that would modify the descriptor include the following: + +- Changing any of the settings under the [HID category](../config/system.md#hid), including enabling/disabling NKRO or HID indicators +- Enabling mouse features, such as adding [mouse keys](../behaviors/mouse-emulation.md) to your keymap + +While the descriptor refresh happens on boot for USB, hosts will frequently cache this descriptor for BLE devices. +In order to refresh this cache, you need to remove the keyboard from the host device, clear the profile associated with the host on the keyboard, then pair again. +For Windows systems you might need to follow the instructions in [this troubleshooting section](#windows-connected-but-not-working) below. + ## Troubleshooting ### Connectivity Issues From 325e2077817c096feef696a057e29ef4807d3d14 Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Tue, 27 Feb 2024 11:30:33 -0800 Subject: [PATCH 069/127] feat(docs): Add pointers to HID descriptor refresh --- docs/docs/behaviors/mouse-emulation.md | 7 ++++++- docs/docs/config/system.md | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/docs/behaviors/mouse-emulation.md b/docs/docs/behaviors/mouse-emulation.md index 9ed0dd8e..7b80bae6 100644 --- a/docs/docs/behaviors/mouse-emulation.md +++ b/docs/docs/behaviors/mouse-emulation.md @@ -8,7 +8,12 @@ sidebar_label: Mouse Emulation Mouse emulation behaviors send mouse events. Currently, only mouse button presses are supported, but movement and scroll action support is planned for the future. -Whenever the Mouse Emulation feature is turned on or off, the HID protocol used to communicate events to hosts changes. Unfortunately, those changes are not always detected automatically, and might require re-pairing your keyboard to your devices to work over bluetooth. If mouse behaviors are still not recognized by your device after doing that, you can try [these troubleshooting steps](../features/bluetooth.md#windows-connected-but-not-working). +:::warning[Refreshing the HID descriptor] + +Enabling or disabling the mouse emulation feature modifies the HID report descriptor and requires it to be [refreshed](../features/bluetooth.md#refreshing-the-hid-descriptor). +The mouse functionality will not work over BLE until that is done. + +::: ## Configuration Option diff --git a/docs/docs/config/system.md b/docs/docs/config/system.md index d60fa24e..675830e4 100644 --- a/docs/docs/config/system.md +++ b/docs/docs/config/system.md @@ -23,6 +23,12 @@ Definition file: [zmk/app/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/ ### HID +:::warning[Refreshing the HID descriptor] + +Making changes to any of the settings in this section modifies the HID report descriptor and requires it to be [refreshed](../features/bluetooth.md#refreshing-the-hid-descriptor). + +::: + | Config | Type | Description | Default | | ------------------------------------- | ---- | -------------------------------------------------------------- | ------- | | `CONFIG_ZMK_HID_INDICATORS` | bool | Enable reciept of HID/LED indicator state from connected hosts | n | From c6e0551fb0d29e4bbba967b4ea0264a1b2440b80 Mon Sep 17 00:00:00 2001 From: Hans Kruse Date: Mon, 18 Mar 2024 18:06:09 +0100 Subject: [PATCH 070/127] fix(hid): Fix typo in HID usage alias --- app/include/dt-bindings/zmk/hid_usage.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/include/dt-bindings/zmk/hid_usage.h b/app/include/dt-bindings/zmk/hid_usage.h index 0555f004..8c0e9470 100644 --- a/app/include/dt-bindings/zmk/hid_usage.h +++ b/app/include/dt-bindings/zmk/hid_usage.h @@ -1109,7 +1109,7 @@ #define HID_USAGE_CONSUMER_AC_RENAME (0x298) // Sel #define HID_USAGE_CONSUMER_AC_MERGE (0x299) // Sel #define HID_USAGE_CONSUMER_AC_SPLIT (0x29A) // Sel -#define HID_USAGE_CONSUMER_AC_DISRIBUTE_HORIZONTALLY (0x29B) // Sel +#define HID_USAGE_CONSUMER_AC_DISTRIBUTE_HORIZONTALLY (0x29B) // Sel #define HID_USAGE_CONSUMER_AC_DISTRIBUTE_VERTICALLY (0x29C) // Sel #define HID_USAGE_CONSUMER_AC_NEXT_KEYBOARD_LAYOUT_SELECT (0x29D) // Sel #define HID_USAGE_CONSUMER_AC_NAVIGATION_GUIDANCE (0x29E) // Sel @@ -2563,4 +2563,4 @@ #define HID_USAGE_FIDO_UNDEFINED (0x00) #define HID_USAGE_FIDO_U2F_AUTHENTICATOR_DEVICE (0x01) // CA #define HID_USAGE_FIDO_INPUT_REPORT_DATA (0x20) // DV -#define HID_USAGE_FIDO_OUTPUT_REPORT_DATA (0x21) // DV \ No newline at end of file +#define HID_USAGE_FIDO_OUTPUT_REPORT_DATA (0x21) // DV From 3a3897968461141bcf6cf2fadef039ea9ecbd727 Mon Sep 17 00:00:00 2001 From: honorless <86894501+lesshonor@users.noreply.github.com> Date: Mon, 8 Jan 2024 21:21:14 -0500 Subject: [PATCH 071/127] refactor: replace tapping_term_ms with tapping-term-ms * The underscore form of this property is deprecated. --- app/boards/arm/ferris/ferris_rev02.keymap | 2 +- app/boards/shields/clog/clog.keymap | 2 +- app/boards/shields/hummingbird/hummingbird.keymap | 2 +- app/boards/shields/osprette/osprette.keymap | 2 +- .../shields/splitkb_aurora_sweep/splitkb_aurora_sweep.keymap | 2 +- app/tests/hold-tap/balanced/6-retro-tap/native_posix_64.keymap | 2 +- .../hold-tap/hold-preferred/6-retro-tap/native_posix_64.keymap | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/boards/arm/ferris/ferris_rev02.keymap b/app/boards/arm/ferris/ferris_rev02.keymap index dc298ec8..9733570c 100644 --- a/app/boards/arm/ferris/ferris_rev02.keymap +++ b/app/boards/arm/ferris/ferris_rev02.keymap @@ -21,7 +21,7 @@ hm: homerow_mods { compatible = "zmk,behavior-hold-tap"; #binding-cells = <2>; - tapping_term_ms = <200>; + tapping-term-ms = <200>; flavor = "tap-preferred"; bindings = <&kp>, <&kp>; }; diff --git a/app/boards/shields/clog/clog.keymap b/app/boards/shields/clog/clog.keymap index 885404f7..d00b00c9 100644 --- a/app/boards/shields/clog/clog.keymap +++ b/app/boards/shields/clog/clog.keymap @@ -15,7 +15,7 @@ &mt { flavor = "tap-preferred"; - tapping_term_ms = <140>; + tapping-term-ms = <140>; }; / { diff --git a/app/boards/shields/hummingbird/hummingbird.keymap b/app/boards/shields/hummingbird/hummingbird.keymap index 9f1a24c2..0b9ee76b 100644 --- a/app/boards/shields/hummingbird/hummingbird.keymap +++ b/app/boards/shields/hummingbird/hummingbird.keymap @@ -20,7 +20,7 @@ hm: homerow_mods { compatible = "zmk,behavior-hold-tap"; #binding-cells = <2>; - tapping_term_ms = <225>; + tapping-term-ms = <225>; flavor = "tap-preferred"; bindings = <&kp>, <&kp>; }; diff --git a/app/boards/shields/osprette/osprette.keymap b/app/boards/shields/osprette/osprette.keymap index 9c9213b6..77e62fa0 100644 --- a/app/boards/shields/osprette/osprette.keymap +++ b/app/boards/shields/osprette/osprette.keymap @@ -15,7 +15,7 @@ &mt { flavor = "tap-preferred"; - tapping_term_ms = <140>; + tapping-term-ms = <140>; }; / { diff --git a/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep.keymap b/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep.keymap index 4b57beac..9198a557 100644 --- a/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep.keymap +++ b/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep.keymap @@ -11,7 +11,7 @@ &mt { // flavor = "tap-preferred"; - // tapping_term_ms = <200>; + // tapping-term-ms = <200>; }; / { diff --git a/app/tests/hold-tap/balanced/6-retro-tap/native_posix_64.keymap b/app/tests/hold-tap/balanced/6-retro-tap/native_posix_64.keymap index f9bda1cf..c820d191 100644 --- a/app/tests/hold-tap/balanced/6-retro-tap/native_posix_64.keymap +++ b/app/tests/hold-tap/balanced/6-retro-tap/native_posix_64.keymap @@ -8,7 +8,7 @@ compatible = "zmk,behavior-hold-tap"; #binding-cells = <2>; flavor = "balanced"; - tapping_term_ms = <300>; + tapping-term-ms = <300>; bindings = <&kp>, <&kp>; retro-tap; }; diff --git a/app/tests/hold-tap/hold-preferred/6-retro-tap/native_posix_64.keymap b/app/tests/hold-tap/hold-preferred/6-retro-tap/native_posix_64.keymap index 8aa29dec..0b80ea95 100644 --- a/app/tests/hold-tap/hold-preferred/6-retro-tap/native_posix_64.keymap +++ b/app/tests/hold-tap/hold-preferred/6-retro-tap/native_posix_64.keymap @@ -8,7 +8,7 @@ compatible = "zmk,behavior-hold-tap"; #binding-cells = <2>; flavor = "hold-preferred"; - tapping_term_ms = <300>; + tapping-term-ms = <300>; bindings = <&kp>, <&kp>; retro-tap; }; From 6f2e19ff88efcd4ca9da2da4996d10f24d30b333 Mon Sep 17 00:00:00 2001 From: honorless <86894501+lesshonor@users.noreply.github.com> Date: Mon, 8 Jan 2024 21:29:11 -0500 Subject: [PATCH 072/127] refactor: replace quick_tap_ms with quick-tap-ms * The underscore form of this property is deprecated. --- app/boards/arm/ferris/ferris_rev02.keymap | 2 +- app/boards/shields/hummingbird/hummingbird.keymap | 2 +- app/boards/shields/jian/jian.keymap | 4 ++-- app/tests/tap-dance/behavior_keymap.dtsi | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/boards/arm/ferris/ferris_rev02.keymap b/app/boards/arm/ferris/ferris_rev02.keymap index 9733570c..b7668416 100644 --- a/app/boards/arm/ferris/ferris_rev02.keymap +++ b/app/boards/arm/ferris/ferris_rev02.keymap @@ -14,7 +14,7 @@ #define SYM_L 4 // Using layer taps on thumbs, having quick tap as well helps w/ repeating space/backspace -< { quick_tap_ms = <200>; }; +< { quick-tap-ms = <200>; }; / { behaviors { diff --git a/app/boards/shields/hummingbird/hummingbird.keymap b/app/boards/shields/hummingbird/hummingbird.keymap index 0b9ee76b..c96071f6 100644 --- a/app/boards/shields/hummingbird/hummingbird.keymap +++ b/app/boards/shields/hummingbird/hummingbird.keymap @@ -13,7 +13,7 @@ #define SYM_L 3 // Using layer taps on thumbs, having quick tap as well helps w/ repeating space/backspace -< { quick_tap_ms = <200>; }; +< { quick-tap-ms = <200>; }; / { behaviors { diff --git a/app/boards/shields/jian/jian.keymap b/app/boards/shields/jian/jian.keymap index e8f7dcc8..bfd2918c 100644 --- a/app/boards/shields/jian/jian.keymap +++ b/app/boards/shields/jian/jian.keymap @@ -13,8 +13,8 @@ #define RSE 2 #define ADJ 3 -< { quick_tap_ms = <200>; }; -&mt { quick_tap_ms = <200>; }; +< { quick-tap-ms = <200>; }; +&mt { quick-tap-ms = <200>; }; / { keymap { diff --git a/app/tests/tap-dance/behavior_keymap.dtsi b/app/tests/tap-dance/behavior_keymap.dtsi index 66ffdf2e..e45aba40 100644 --- a/app/tests/tap-dance/behavior_keymap.dtsi +++ b/app/tests/tap-dance/behavior_keymap.dtsi @@ -8,7 +8,7 @@ compatible = "zmk,behavior-hold-tap"; #binding-cells = <2>; tapping-term-ms = <200>; - quick_tap_ms = <0>; + quick-tap-ms = <0>; flavor = "tap-preferred"; bindings = <&kp>, <&kp>; }; From 8929355ac018ba293f53d6759c9f130d67751e09 Mon Sep 17 00:00:00 2001 From: Pablo Date: Mon, 18 Mar 2024 14:19:27 -0300 Subject: [PATCH 073/127] fix(keymap): Replace some keypad keycodes * Change KP_MULTIPLY to ASTRK in defaults keymap --- app/boards/arm/corneish_zen/corneish_zen.keymap | 6 +++--- app/boards/shields/corne/corne.keymap | 6 +++--- app/boards/shields/iris/iris.keymap | 8 ++++---- app/boards/shields/lily58/lily58.keymap | 8 ++++---- app/boards/shields/microdox/microdox.keymap | 6 +++--- app/boards/shields/sofle/sofle.keymap | 10 +++++----- .../splitkb_aurora_corne/splitkb_aurora_corne.keymap | 6 +++--- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/app/boards/arm/corneish_zen/corneish_zen.keymap b/app/boards/arm/corneish_zen/corneish_zen.keymap index 636c0513..06eee01c 100644 --- a/app/boards/arm/corneish_zen/corneish_zen.keymap +++ b/app/boards/arm/corneish_zen/corneish_zen.keymap @@ -58,9 +58,9 @@ // | SHFT | | | | | | | _ | + | { | } | "|" | ~ | // | GUI | | SPC | | ENT | | ALT | bindings = < -&kp TAB &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp KP_MULTIPLY &kp LPAR &kp RPAR &kp BSPC -&kp LCTRL &trans &trans &trans &trans &trans &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp BSLH &kp GRAVE -&kp LSHFT &trans &trans &trans &trans &trans &kp UNDER &kp PLUS &kp LBRC &kp RBRC &kp PIPE &kp TILDE +&kp TAB &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp ASTRK &kp LPAR &kp RPAR &kp BSPC +&kp LCTRL &trans &trans &trans &trans &trans &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp BSLH &kp GRAVE +&kp LSHFT &trans &trans &trans &trans &trans &kp UNDER &kp PLUS &kp LBRC &kp RBRC &kp PIPE &kp TILDE &kp LGUI &trans &kp SPACE &kp RET &trans &kp RALT >; }; diff --git a/app/boards/shields/corne/corne.keymap b/app/boards/shields/corne/corne.keymap index 0555cf41..01350bd5 100644 --- a/app/boards/shields/corne/corne.keymap +++ b/app/boards/shields/corne/corne.keymap @@ -46,9 +46,9 @@ // | SHFT | | | | | | | _ | + | { | } | "|" | ~ | // | GUI | | SPC | | ENT | | ALT | bindings = < - &kp TAB &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp KP_MULTIPLY &kp LPAR &kp RPAR &kp BSPC - &kp LCTRL &trans &trans &trans &trans &trans &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp BSLH &kp GRAVE - &kp LSHFT &trans &trans &trans &trans &trans &kp UNDER &kp PLUS &kp LBRC &kp RBRC &kp PIPE &kp TILDE + &kp TAB &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp ASTRK &kp LPAR &kp RPAR &kp BSPC + &kp LCTRL &trans &trans &trans &trans &trans &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp BSLH &kp GRAVE + &kp LSHFT &trans &trans &trans &trans &trans &kp UNDER &kp PLUS &kp LBRC &kp RBRC &kp PIPE &kp TILDE &kp LGUI &trans &kp SPACE &kp RET &trans &kp RALT >; }; diff --git a/app/boards/shields/iris/iris.keymap b/app/boards/shields/iris/iris.keymap index 209c2277..1846509f 100644 --- a/app/boards/shields/iris/iris.keymap +++ b/app/boards/shields/iris/iris.keymap @@ -36,10 +36,10 @@ // | | | | | | | | | | | _ | + | { | } | "|" | // | | | | | | | | bindings = < -&bt BT_CLR &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &trans &trans &trans &trans &trans &trans -&kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 -&kp GRAVE &kp EXCL &kp AT &kp HASH &kp DOLLAR &kp PRCNT &kp CARET &kp AMPS &kp KP_MULTIPLY &kp LPAR &kp RPAR &kp TILDE -&trans &trans &trans &trans &trans &trans &trans &trans &trans &kp MINUS &kp KP_PLUS &kp LBRC &kp RBRC &kp PIPE +&bt BT_CLR &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &trans &trans &trans &trans &trans &trans +&kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 +&kp GRAVE &kp EXCL &kp AT &kp HASH &kp DOLLAR &kp PRCNT &kp CARET &kp AMPS &kp ASTRK &kp LPAR &kp RPAR &kp TILDE +&trans &trans &trans &trans &trans &trans &trans &trans &trans &kp MINUS &kp PLUS &kp LBRC &kp RBRC &kp PIPE &trans &trans &trans &trans &trans &trans >; }; diff --git a/app/boards/shields/lily58/lily58.keymap b/app/boards/shields/lily58/lily58.keymap index 7df3277f..75a2e8ae 100644 --- a/app/boards/shields/lily58/lily58.keymap +++ b/app/boards/shields/lily58/lily58.keymap @@ -39,10 +39,10 @@ // | | | | | | | | | | | _ | + | { | } | "|" | // | | | | | | | | | | bindings = < -&bt BT_CLR &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &trans &trans &trans &trans &trans &trans -&kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 -&kp GRAVE &kp EXCL &kp AT &kp HASH &kp DOLLAR &kp PRCNT &kp CARET &kp AMPS &kp KP_MULTIPLY &kp LPAR &kp RPAR &kp TILDE -&trans &ext_power EP_ON &ext_power EP_OFF &ext_power EP_TOG &trans &trans &trans &trans &trans &kp MINUS &kp KP_PLUS &kp LBRC &kp RBRC &kp PIPE +&bt BT_CLR &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &trans &trans &trans &trans &trans &trans +&kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 +&kp GRAVE &kp EXCL &kp AT &kp HASH &kp DOLLAR &kp PRCNT &kp CARET &kp AMPS &kp ASTRK &kp LPAR &kp RPAR &kp TILDE +&trans &ext_power EP_ON &ext_power EP_OFF &ext_power EP_TOG &trans &trans &trans &trans &trans &kp MINUS &kp PLUS &kp LBRC &kp RBRC &kp PIPE &trans &trans &trans &trans &trans &trans &trans &trans >; diff --git a/app/boards/shields/microdox/microdox.keymap b/app/boards/shields/microdox/microdox.keymap index c9298ff8..34b2984b 100644 --- a/app/boards/shields/microdox/microdox.keymap +++ b/app/boards/shields/microdox/microdox.keymap @@ -46,9 +46,9 @@ // | | | | | | | _ | + | [ | ] | \ | // | GUI | | SPC | | ENT | | ALT | bindings = < - &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp KP_MULTIPLY &kp LPAR &kp RPAR - &trans &trans &trans &trans &trans &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp PIPE - &trans &trans &trans &trans &trans &trans &trans &trans &trans &kp BSLH + &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp ASTRK &kp LPAR &kp RPAR + &trans &trans &trans &trans &trans &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp PIPE + &trans &trans &trans &trans &trans &trans &trans &trans &trans &kp BSLH &kp LGUI &trans &kp SPACE &kp RET &trans &kp RALT >; }; diff --git a/app/boards/shields/sofle/sofle.keymap b/app/boards/shields/sofle/sofle.keymap index ed9f0f4f..c9db56ce 100644 --- a/app/boards/shields/sofle/sofle.keymap +++ b/app/boards/shields/sofle/sofle.keymap @@ -58,11 +58,11 @@ // | | = | - | + | { | } | | | | [ | ] | ; | : | \ | | // | | | | | | | | | | | | bindings = < -&trans &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 -&kp GRAVE &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp F12 -&trans &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp KP_MULTIPLY &kp LPAR &kp RPAR &kp PIPE -&trans &kp EQUAL &kp MINUS &kp KP_PLUS &kp LBRC &kp RBRC &trans &trans &kp LBKT &kp RBKT &kp SEMI &kp COLON &kp BSLH &trans - &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans +&trans &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 +&kp GRAVE &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp F12 +&trans &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp ASTRK &kp LPAR &kp RPAR &kp PIPE +&trans &kp EQUAL &kp MINUS &kp PLUS &kp LBRC &kp RBRC &trans &trans &kp LBKT &kp RBKT &kp SEMI &kp COLON &kp BSLH &trans + &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans >; sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>; diff --git a/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne.keymap b/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne.keymap index 0555cf41..01350bd5 100644 --- a/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne.keymap +++ b/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne.keymap @@ -46,9 +46,9 @@ // | SHFT | | | | | | | _ | + | { | } | "|" | ~ | // | GUI | | SPC | | ENT | | ALT | bindings = < - &kp TAB &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp KP_MULTIPLY &kp LPAR &kp RPAR &kp BSPC - &kp LCTRL &trans &trans &trans &trans &trans &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp BSLH &kp GRAVE - &kp LSHFT &trans &trans &trans &trans &trans &kp UNDER &kp PLUS &kp LBRC &kp RBRC &kp PIPE &kp TILDE + &kp TAB &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp ASTRK &kp LPAR &kp RPAR &kp BSPC + &kp LCTRL &trans &trans &trans &trans &trans &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp BSLH &kp GRAVE + &kp LSHFT &trans &trans &trans &trans &trans &kp UNDER &kp PLUS &kp LBRC &kp RBRC &kp PIPE &kp TILDE &kp LGUI &trans &kp SPACE &kp RET &trans &kp RALT >; }; From 341534aa15ebcb1d42f917d2a530f21dd823cae2 Mon Sep 17 00:00:00 2001 From: Theo Lemay Date: Sun, 28 May 2023 23:59:48 -0700 Subject: [PATCH 074/127] feat(behaviors): lazy sticky keys --- .../behaviors/zmk,behavior-sticky-key.yaml | 2 + app/src/behaviors/behavior_sticky_key.c | 93 ++++++++++++++----- .../10-callum-mods/keycode_events.snapshot | 2 +- .../11-lazy-timeout-during/events.patterns | 1 + .../keycode_events.snapshot | 6 ++ .../native_posix_64.keymap | 37 ++++++++ .../11-lazy-timeout/events.patterns | 1 + .../11-lazy-timeout/keycode_events.snapshot | 4 + .../11-lazy-timeout/native_posix_64.keymap | 43 +++++++++ app/tests/sticky-keys/11-lazy/events.patterns | 1 + .../11-lazy/keycode_events.snapshot | 16 ++++ .../11-lazy/native_posix_64.keymap | 67 +++++++++++++ .../keycode_events.snapshot | 4 +- .../keycode_events.snapshot | 2 +- .../keycode_events.snapshot | 2 +- .../keycode_events.snapshot | 4 +- docs/docs/behaviors/sticky-key.md | 6 ++ docs/docs/config/behaviors.md | 1 + 18 files changed, 260 insertions(+), 32 deletions(-) create mode 100644 app/tests/sticky-keys/11-lazy-timeout-during/events.patterns create mode 100644 app/tests/sticky-keys/11-lazy-timeout-during/keycode_events.snapshot create mode 100644 app/tests/sticky-keys/11-lazy-timeout-during/native_posix_64.keymap create mode 100644 app/tests/sticky-keys/11-lazy-timeout/events.patterns create mode 100644 app/tests/sticky-keys/11-lazy-timeout/keycode_events.snapshot create mode 100644 app/tests/sticky-keys/11-lazy-timeout/native_posix_64.keymap create mode 100644 app/tests/sticky-keys/11-lazy/events.patterns create mode 100644 app/tests/sticky-keys/11-lazy/keycode_events.snapshot create mode 100644 app/tests/sticky-keys/11-lazy/native_posix_64.keymap diff --git a/app/dts/bindings/behaviors/zmk,behavior-sticky-key.yaml b/app/dts/bindings/behaviors/zmk,behavior-sticky-key.yaml index 172f20a2..a0e52879 100644 --- a/app/dts/bindings/behaviors/zmk,behavior-sticky-key.yaml +++ b/app/dts/bindings/behaviors/zmk,behavior-sticky-key.yaml @@ -16,5 +16,7 @@ properties: required: true quick-release: type: boolean + lazy: + type: boolean ignore-modifiers: type: boolean diff --git a/app/src/behaviors/behavior_sticky_key.c b/app/src/behaviors/behavior_sticky_key.c index 05f6846b..193a2370 100644 --- a/app/src/behaviors/behavior_sticky_key.c +++ b/app/src/behaviors/behavior_sticky_key.c @@ -33,6 +33,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); struct behavior_sticky_key_config { uint32_t release_after_ms; bool quick_release; + bool lazy; bool ignore_modifiers; struct zmk_behavior_binding behavior; }; @@ -146,8 +147,11 @@ static int on_sticky_key_binding_pressed(struct zmk_behavior_binding *binding, return ZMK_BEHAVIOR_OPAQUE; } - press_sticky_key_behavior(sticky_key, event.timestamp); LOG_DBG("%d new sticky_key", event.position); + if (!sticky_key->config->lazy) { + // press the key now if it's not lazy + press_sticky_key_behavior(sticky_key, event.timestamp); + } return ZMK_BEHAVIOR_OPAQUE; } @@ -191,14 +195,21 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { return ZMK_EV_EVENT_BUBBLE; } - // keep track whether the event has been reraised, so we only reraise it once - bool event_reraised = false; + // we want to make sure every sticky key is given a chance to lazy press their behavior before + // the event gets reraised, and release their behavior after the event is reraised, so we keep + // track of them. this allows us to ensure the sticky key is pressed and released "around" the + // other key, especially in the case of lazy keys. + struct active_sticky_key *sticky_keys_to_press_before_reraise[ZMK_BHV_STICKY_KEY_MAX_HELD]; + struct active_sticky_key *sticky_keys_to_release_after_reraise[ZMK_BHV_STICKY_KEY_MAX_HELD]; // reraising the event frees it, so make a copy of any event data we might // need after it's been freed. const struct zmk_keycode_state_changed ev_copy = *ev; for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) { + sticky_keys_to_press_before_reraise[i] = NULL; + sticky_keys_to_release_after_reraise[i] = NULL; + struct active_sticky_key *sticky_key = &active_sticky_keys[i]; if (sticky_key->position == ZMK_BHV_STICKY_KEY_POSITION_FREE) { continue; @@ -212,14 +223,6 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { continue; } - // If this event was queued, the timer may be triggered late or not at all. - // Release the sticky key if the timer should've run out in the meantime. - if (sticky_key->release_at != 0 && ev_copy.timestamp > sticky_key->release_at) { - stop_timer(sticky_key); - release_sticky_key_behavior(sticky_key, sticky_key->release_at); - continue; - } - if (ev_copy.state) { // key down if (sticky_key->config->ignore_modifiers && is_mod(ev_copy.usage_page, ev_copy.keycode)) { @@ -231,17 +234,30 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { // this sticky key is already in use for a keycode continue; } + + // we don't want the timer to release the sticky key before the other key is released + stop_timer(sticky_key); + + // If this event was queued, the timer may be triggered late or not at all. + // Release the sticky key if the timer should've run out in the meantime. + if (sticky_key->release_at != 0 && ev_copy.timestamp > sticky_key->release_at) { + // If the key is lazy, a release is not needed on timeout + if (sticky_key->config->lazy) { + clear_sticky_key(sticky_key); + } else { + release_sticky_key_behavior(sticky_key, sticky_key->release_at); + } + continue; + } + + if (sticky_key->config->lazy) { + // if the sticky key is lazy, we need to press it before the event is reraised + sticky_keys_to_press_before_reraise[i] = sticky_key; + } if (sticky_key->timer_started) { - stop_timer(sticky_key); if (sticky_key->config->quick_release) { // immediately release the sticky key after the key press is handled. - if (!event_reraised) { - struct zmk_keycode_state_changed_event dupe_ev = - copy_raised_zmk_keycode_state_changed(ev); - ZMK_EVENT_RAISE_AFTER(dupe_ev, behavior_sticky_key); - event_reraised = true; - } - release_sticky_key_behavior(sticky_key, ev_copy.timestamp); + sticky_keys_to_release_after_reraise[i] = sticky_key; } } sticky_key->modified_key_usage_page = ev_copy.usage_page; @@ -251,14 +267,35 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { sticky_key->modified_key_usage_page == ev_copy.usage_page && sticky_key->modified_key_keycode == ev_copy.keycode) { stop_timer(sticky_key); - release_sticky_key_behavior(sticky_key, ev_copy.timestamp); + sticky_keys_to_release_after_reraise[i] = sticky_key; } } } - if (event_reraised) { - return ZMK_EV_EVENT_CAPTURED; + + // give each sticky key a chance to press their behavior before the event is reraised + for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) { + struct active_sticky_key *sticky_key = sticky_keys_to_press_before_reraise[i]; + if (sticky_key) { + press_sticky_key_behavior(sticky_key, ev_copy.timestamp); + } } - return ZMK_EV_EVENT_BUBBLE; + // give each sticky key a chance to release their behavior after the event is reraised, lazily + // reraising. keep track whether the event has been reraised so we only reraise it once + bool event_reraised = false; + for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) { + struct active_sticky_key *sticky_key = sticky_keys_to_release_after_reraise[i]; + if (sticky_key) { + if (!event_reraised) { + struct zmk_keycode_state_changed_event dupe_ev = + copy_raised_zmk_keycode_state_changed(ev); + ZMK_EVENT_RAISE_AFTER(dupe_ev, behavior_sticky_key); + event_reraised = true; + } + release_sticky_key_behavior(sticky_key, ev_copy.timestamp); + } + } + + return event_reraised ? ZMK_EV_EVENT_CAPTURED : ZMK_EV_EVENT_BUBBLE; } void behavior_sticky_key_timer_handler(struct k_work *item) { @@ -271,7 +308,12 @@ void behavior_sticky_key_timer_handler(struct k_work *item) { if (sticky_key->timer_cancelled) { sticky_key->timer_cancelled = false; } else { - release_sticky_key_behavior(sticky_key, sticky_key->release_at); + // If the key is lazy, a release is not needed on timeout + if (sticky_key->config->lazy) { + clear_sticky_key(sticky_key); + } else { + release_sticky_key_behavior(sticky_key, sticky_key->release_at); + } } } @@ -295,8 +337,9 @@ static struct behavior_sticky_key_data behavior_sticky_key_data; static struct behavior_sticky_key_config behavior_sticky_key_config_##n = { \ .behavior = ZMK_KEYMAP_EXTRACT_BINDING(0, DT_DRV_INST(n)), \ .release_after_ms = DT_INST_PROP(n, release_after_ms), \ - .ignore_modifiers = DT_INST_PROP(n, ignore_modifiers), \ .quick_release = DT_INST_PROP(n, quick_release), \ + .lazy = DT_INST_PROP(n, lazy), \ + .ignore_modifiers = DT_INST_PROP(n, ignore_modifiers), \ }; \ BEHAVIOR_DT_INST_DEFINE(n, behavior_sticky_key_init, NULL, &behavior_sticky_key_data, \ &behavior_sticky_key_config_##n, POST_KERNEL, \ diff --git a/app/tests/sticky-keys/10-callum-mods/keycode_events.snapshot b/app/tests/sticky-keys/10-callum-mods/keycode_events.snapshot index 3e46e581..29be00ff 100644 --- a/app/tests/sticky-keys/10-callum-mods/keycode_events.snapshot +++ b/app/tests/sticky-keys/10-callum-mods/keycode_events.snapshot @@ -1,8 +1,8 @@ pressed: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 released: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 released: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 -released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/sticky-keys/11-lazy-timeout-during/events.patterns b/app/tests/sticky-keys/11-lazy-timeout-during/events.patterns new file mode 100644 index 00000000..b1342af4 --- /dev/null +++ b/app/tests/sticky-keys/11-lazy-timeout-during/events.patterns @@ -0,0 +1 @@ +s/.*hid_listener_keycode_//p diff --git a/app/tests/sticky-keys/11-lazy-timeout-during/keycode_events.snapshot b/app/tests/sticky-keys/11-lazy-timeout-during/keycode_events.snapshot new file mode 100644 index 00000000..8fc9315f --- /dev/null +++ b/app/tests/sticky-keys/11-lazy-timeout-during/keycode_events.snapshot @@ -0,0 +1,6 @@ +pressed: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/sticky-keys/11-lazy-timeout-during/native_posix_64.keymap b/app/tests/sticky-keys/11-lazy-timeout-during/native_posix_64.keymap new file mode 100644 index 00000000..fb60ba41 --- /dev/null +++ b/app/tests/sticky-keys/11-lazy-timeout-during/native_posix_64.keymap @@ -0,0 +1,37 @@ +#include +#include +#include + +/* this test ensures that timing out while the other key is being held results in correct behavior */ + +&sk { + lazy; + release-after-ms = <50>; +}; + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &sk LEFT_CONTROL &kp A + &sk LEFT_SHIFT &sk LEFT_ALT>; + }; + }; +}; + +&kscan { + events = < + /* tap sk LEFT_CONTROL */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + /* tap A */ + ZMK_MOCK_PRESS(0,1,60) + ZMK_MOCK_RELEASE(0,1,10) + /* tap A */ + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; diff --git a/app/tests/sticky-keys/11-lazy-timeout/events.patterns b/app/tests/sticky-keys/11-lazy-timeout/events.patterns new file mode 100644 index 00000000..b1342af4 --- /dev/null +++ b/app/tests/sticky-keys/11-lazy-timeout/events.patterns @@ -0,0 +1 @@ +s/.*hid_listener_keycode_//p diff --git a/app/tests/sticky-keys/11-lazy-timeout/keycode_events.snapshot b/app/tests/sticky-keys/11-lazy-timeout/keycode_events.snapshot new file mode 100644 index 00000000..4d560461 --- /dev/null +++ b/app/tests/sticky-keys/11-lazy-timeout/keycode_events.snapshot @@ -0,0 +1,4 @@ +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/sticky-keys/11-lazy-timeout/native_posix_64.keymap b/app/tests/sticky-keys/11-lazy-timeout/native_posix_64.keymap new file mode 100644 index 00000000..d6b34149 --- /dev/null +++ b/app/tests/sticky-keys/11-lazy-timeout/native_posix_64.keymap @@ -0,0 +1,43 @@ +#include +#include +#include + +/* this test ensures that lazy sticky keys don't emit anything on timeout */ + +&sk { + lazy; + release-after-ms = <50>; +}; + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &sk LEFT_CONTROL &kp A + &sk LEFT_SHIFT &sk LEFT_ALT>; + }; + }; +}; + +&kscan { + events = < + /* tap sk LEFT_CONTROL */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + /* tap sk LEFT_SHIFT */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,60) + /* tap sk LEFT_ALT */ + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_RELEASE(1,1,60) + /* tap A */ + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + /* tap A */ + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; diff --git a/app/tests/sticky-keys/11-lazy/events.patterns b/app/tests/sticky-keys/11-lazy/events.patterns new file mode 100644 index 00000000..b1342af4 --- /dev/null +++ b/app/tests/sticky-keys/11-lazy/events.patterns @@ -0,0 +1 @@ +s/.*hid_listener_keycode_//p diff --git a/app/tests/sticky-keys/11-lazy/keycode_events.snapshot b/app/tests/sticky-keys/11-lazy/keycode_events.snapshot new file mode 100644 index 00000000..1c1f8614 --- /dev/null +++ b/app/tests/sticky-keys/11-lazy/keycode_events.snapshot @@ -0,0 +1,16 @@ +pressed: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x1D implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x1D implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/sticky-keys/11-lazy/native_posix_64.keymap b/app/tests/sticky-keys/11-lazy/native_posix_64.keymap new file mode 100644 index 00000000..4eea1fb9 --- /dev/null +++ b/app/tests/sticky-keys/11-lazy/native_posix_64.keymap @@ -0,0 +1,67 @@ +#include +#include +#include + +/* this test verifies that lazy sticky keys work similarly to regular sticky keys, and includes cases from 10-callum-mods and 8-lsk-osk. + the only difference is that the lazy key does not exit the sticky layer */ + +&sk { + lazy; +}; + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &sk LEFT_CONTROL &sl 1 + &kp A &mo 1>; + }; + + lower_layer { + bindings = < + &sk LEFT_CONTROL &kp X + &sk LEFT_SHIFT &kp Z>; + }; + }; +}; + +&kscan { + events = < + /* tap LEFT_CONTROL on base layer */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + /* tap A */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + + /* tap sl lower_layer */ + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + /* tap sk LEFT_CONTROL */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + /* tap Z */ + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_RELEASE(1,1,10) + + /* press mo lower_layer */ + ZMK_MOCK_PRESS(1,1,10) + /* tap sk LEFT_CONTROL */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + /* tap sk LEFT_SHIFT */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + /* release mo lower_layer */ + ZMK_MOCK_RELEASE(1,1,10) + /* tap A (with left control and left shift enabled) */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + /* tap A (no sticky keys anymore) */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup/keycode_events.snapshot b/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup/keycode_events.snapshot index addbca8c..1b4c078c 100644 --- a/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup/keycode_events.snapshot +++ b/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup/keycode_events.snapshot @@ -1,8 +1,8 @@ pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 -released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 -released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/sticky-keys/4-os-dn-up-kcdn-timer-kcup/keycode_events.snapshot b/app/tests/sticky-keys/4-os-dn-up-kcdn-timer-kcup/keycode_events.snapshot index 6e004ec2..1b091a6a 100644 --- a/app/tests/sticky-keys/4-os-dn-up-kcdn-timer-kcup/keycode_events.snapshot +++ b/app/tests/sticky-keys/4-os-dn-up-kcdn-timer-kcup/keycode_events.snapshot @@ -1,4 +1,4 @@ pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 -released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/sticky-keys/7-os-dn-up-kc1dn-kc2dn-kc1up-kc2up/keycode_events.snapshot b/app/tests/sticky-keys/7-os-dn-up-kc1dn-kc2dn-kc1up-kc2up/keycode_events.snapshot index 3c757bbb..2b1619b4 100644 --- a/app/tests/sticky-keys/7-os-dn-up-kc1dn-kc2dn-kc1up-kc2up/keycode_events.snapshot +++ b/app/tests/sticky-keys/7-os-dn-up-kc1dn-kc2dn-kc1up-kc2up/keycode_events.snapshot @@ -1,6 +1,6 @@ pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00 -released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/sticky-keys/8-lsk-osk-combination/keycode_events.snapshot b/app/tests/sticky-keys/8-lsk-osk-combination/keycode_events.snapshot index f1aa915b..0c4054f7 100644 --- a/app/tests/sticky-keys/8-lsk-osk-combination/keycode_events.snapshot +++ b/app/tests/sticky-keys/8-lsk-osk-combination/keycode_events.snapshot @@ -1,8 +1,8 @@ pressed: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 -released: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 -released: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00 diff --git a/docs/docs/behaviors/sticky-key.md b/docs/docs/behaviors/sticky-key.md index f40bb521..8c3962f5 100644 --- a/docs/docs/behaviors/sticky-key.md +++ b/docs/docs/behaviors/sticky-key.md @@ -34,6 +34,12 @@ By default, sticky keys stay pressed for a second if you don't press any other k Some typists may find that using a sticky shift key interspersed with rapid typing results in two or more capitalized letters instead of one. This happens as the sticky key is active until the next key is released, under which other keys may be pressed and will receive the modifier. You can enable the `quick-release` setting to instead deactivate the sticky key on the next key being pressed, as opposed to released. +#### `lazy` + +By default, sticky keys are activated on press until another key is pressed. You can enable the `lazy` setting to instead activate the sticky key right _before_ the other key is pressed. This is useful for mouse interaction or situations where you don't want the host to see anything during a sticky-key timeout, for example `&sk LGUI`, which can trigger a menu if pressed alone. + +Note that tapping a lazy sticky key will not trigger other behaviors such as the release of other sticky keys or layers. If you want to use a lazy sticky key to activate the release of a sticky layer, potential solutions include wrappping the sticky key in a simple macro which presses the sticky behavior around the sticky key press, doing the same with `&mo LAYER`, or triggering a tap of some key like `K_CANCEL` on sticky key press. + #### `ignore-modifiers` This setting is enabled by default. It ensures that if a sticky key modifier is pressed before a previously pressed sticky key is released, the modifiers will get combined so you can add more sticky keys or press a regular key to apply the modifiers. This is to accommodate _callum-style mods_ where you are prone to rolling sticky keys. If you want sticky key modifiers to only chain after release, you can disable this setting. Please note that activating multiple modifiers via [modifier functions](https://zmk.dev/docs/codes/modifiers#modifier-functions) such as `&sk LS(LALT)`, require `ignore-modifiers` enabled in order to function properly. diff --git a/docs/docs/config/behaviors.md b/docs/docs/config/behaviors.md index f8d2fe39..1a5b899a 100644 --- a/docs/docs/config/behaviors.md +++ b/docs/docs/config/behaviors.md @@ -230,6 +230,7 @@ Applies to: `compatible = "zmk,behavior-sticky-key"` | `bindings` | phandle array | A behavior (without parameters) to trigger | | | `release-after-ms` | int | Releases the key after this many milliseconds if no other key is pressed | 1000 | | `quick-release` | bool | Release the sticky key on the next key press instead of release | false | +| `lazy` | bool | Wait until the next key press to activate the sticky key behavior | false | | `ignore-modifiers` | bool | If enabled, pressing a modifier key does not cancel the sticky key | true | This behavior forwards the one parameter it receives to the parameter of the behavior specified in `bindings`. From 94d9d837e3674a7127190a00361c899197a66ba4 Mon Sep 17 00:00:00 2001 From: Theo Lemay Date: Mon, 18 Dec 2023 17:34:42 -0500 Subject: [PATCH 075/127] refactor: extract duplicate logic --- app/src/behaviors/behavior_sticky_key.c | 47 +++++++++++++------------ 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/app/src/behaviors/behavior_sticky_key.c b/app/src/behaviors/behavior_sticky_key.c index 193a2370..2c279c3b 100644 --- a/app/src/behaviors/behavior_sticky_key.c +++ b/app/src/behaviors/behavior_sticky_key.c @@ -121,6 +121,15 @@ static inline int release_sticky_key_behavior(struct active_sticky_key *sticky_k return behavior_keymap_binding_released(&binding, event); } +static inline int on_sticky_key_timeout(struct active_sticky_key *sticky_key) { + // If the key is lazy, a release is not needed on timeout + if (sticky_key->config->lazy) { + clear_sticky_key(sticky_key); + } else { + release_sticky_key_behavior(sticky_key, sticky_key->release_at); + } +} + static int stop_timer(struct active_sticky_key *sticky_key) { int timer_cancel_result = k_work_cancel_delayable(&sticky_key->release_timer); if (timer_cancel_result == -EINPROGRESS) { @@ -241,12 +250,7 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { // If this event was queued, the timer may be triggered late or not at all. // Release the sticky key if the timer should've run out in the meantime. if (sticky_key->release_at != 0 && ev_copy.timestamp > sticky_key->release_at) { - // If the key is lazy, a release is not needed on timeout - if (sticky_key->config->lazy) { - clear_sticky_key(sticky_key); - } else { - release_sticky_key_behavior(sticky_key, sticky_key->release_at); - } + on_sticky_key_timeout(sticky_key); continue; } @@ -275,24 +279,28 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { // give each sticky key a chance to press their behavior before the event is reraised for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) { struct active_sticky_key *sticky_key = sticky_keys_to_press_before_reraise[i]; - if (sticky_key) { - press_sticky_key_behavior(sticky_key, ev_copy.timestamp); + if (!sticky_key) { + continue; } + + press_sticky_key_behavior(sticky_key, ev_copy.timestamp); } // give each sticky key a chance to release their behavior after the event is reraised, lazily // reraising. keep track whether the event has been reraised so we only reraise it once bool event_reraised = false; for (int i = 0; i < ZMK_BHV_STICKY_KEY_MAX_HELD; i++) { struct active_sticky_key *sticky_key = sticky_keys_to_release_after_reraise[i]; - if (sticky_key) { - if (!event_reraised) { - struct zmk_keycode_state_changed_event dupe_ev = - copy_raised_zmk_keycode_state_changed(ev); - ZMK_EVENT_RAISE_AFTER(dupe_ev, behavior_sticky_key); - event_reraised = true; - } - release_sticky_key_behavior(sticky_key, ev_copy.timestamp); + if (!sticky_key) { + continue; } + + if (!event_reraised) { + struct zmk_keycode_state_changed_event dupe_ev = + copy_raised_zmk_keycode_state_changed(ev); + ZMK_EVENT_RAISE_AFTER(dupe_ev, behavior_sticky_key); + event_reraised = true; + } + release_sticky_key_behavior(sticky_key, ev_copy.timestamp); } return event_reraised ? ZMK_EV_EVENT_CAPTURED : ZMK_EV_EVENT_BUBBLE; @@ -308,12 +316,7 @@ void behavior_sticky_key_timer_handler(struct k_work *item) { if (sticky_key->timer_cancelled) { sticky_key->timer_cancelled = false; } else { - // If the key is lazy, a release is not needed on timeout - if (sticky_key->config->lazy) { - clear_sticky_key(sticky_key); - } else { - release_sticky_key_behavior(sticky_key, sticky_key->release_at); - } + on_sticky_key_timeout(sticky_key); } } From af7e4198ae3cd2fab16320ebb0ee3a5215e0f674 Mon Sep 17 00:00:00 2001 From: Theo Lemay Date: Mon, 18 Dec 2023 21:31:29 -0500 Subject: [PATCH 076/127] chore: remove label in test --- .../sticky-keys/11-lazy-timeout-during/native_posix_64.keymap | 1 - app/tests/sticky-keys/11-lazy-timeout/native_posix_64.keymap | 1 - app/tests/sticky-keys/11-lazy/native_posix_64.keymap | 1 - 3 files changed, 3 deletions(-) diff --git a/app/tests/sticky-keys/11-lazy-timeout-during/native_posix_64.keymap b/app/tests/sticky-keys/11-lazy-timeout-during/native_posix_64.keymap index fb60ba41..75d997cb 100644 --- a/app/tests/sticky-keys/11-lazy-timeout-during/native_posix_64.keymap +++ b/app/tests/sticky-keys/11-lazy-timeout-during/native_posix_64.keymap @@ -12,7 +12,6 @@ / { keymap { compatible = "zmk,keymap"; - label ="Default keymap"; default_layer { bindings = < diff --git a/app/tests/sticky-keys/11-lazy-timeout/native_posix_64.keymap b/app/tests/sticky-keys/11-lazy-timeout/native_posix_64.keymap index d6b34149..05db46c8 100644 --- a/app/tests/sticky-keys/11-lazy-timeout/native_posix_64.keymap +++ b/app/tests/sticky-keys/11-lazy-timeout/native_posix_64.keymap @@ -12,7 +12,6 @@ / { keymap { compatible = "zmk,keymap"; - label ="Default keymap"; default_layer { bindings = < diff --git a/app/tests/sticky-keys/11-lazy/native_posix_64.keymap b/app/tests/sticky-keys/11-lazy/native_posix_64.keymap index 4eea1fb9..193354e2 100644 --- a/app/tests/sticky-keys/11-lazy/native_posix_64.keymap +++ b/app/tests/sticky-keys/11-lazy/native_posix_64.keymap @@ -12,7 +12,6 @@ / { keymap { compatible = "zmk,keymap"; - label ="Default keymap"; default_layer { bindings = < From ce743f2b3566d198e06cb3afe3d335f90f377244 Mon Sep 17 00:00:00 2001 From: Theo Lemay <16546293+theol0403@users.noreply.github.com> Date: Fri, 29 Dec 2023 23:07:19 -0500 Subject: [PATCH 077/127] chore: fix whitespace --- app/tests/sticky-keys/11-lazy/native_posix_64.keymap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/tests/sticky-keys/11-lazy/native_posix_64.keymap b/app/tests/sticky-keys/11-lazy/native_posix_64.keymap index 193354e2..80319872 100644 --- a/app/tests/sticky-keys/11-lazy/native_posix_64.keymap +++ b/app/tests/sticky-keys/11-lazy/native_posix_64.keymap @@ -2,7 +2,7 @@ #include #include -/* this test verifies that lazy sticky keys work similarly to regular sticky keys, and includes cases from 10-callum-mods and 8-lsk-osk. +/* this test verifies that lazy sticky keys work similarly to regular sticky keys, and includes cases from 10-callum-mods and 8-lsk-osk. the only difference is that the lazy key does not exit the sticky layer */ &sk { From 736c5fb46eeb570e81a3f1dd0a6dc10b17b31769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=95=E3=82=A3=E3=83=AB=E3=82=BF=E3=83=BC=E3=83=9A?= =?UTF-8?q?=E3=83=BC=E3=83=91=E3=83=BC?= <76888457+filterpaper@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:51:47 +0800 Subject: [PATCH 078/127] feat(docs): Add a note on macOS v14.3 file copy error message --- docs/docs/troubleshooting.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/docs/troubleshooting.md b/docs/docs/troubleshooting.md index 1f3c1706..808808c4 100644 --- a/docs/docs/troubleshooting.md +++ b/docs/docs/troubleshooting.md @@ -27,6 +27,10 @@ Variations of the warnings shown below occur when flashing the `.uf2` macOS 13.0 (Ventura) Finder may report an error code 100093 when copying `.uf2` files into microcontrollers. This bug is limited to the operating system's Finder. You can work around it by copying on Terminal command line or use a third party file manager. Issue is fixed in macOS version 13.1. +### macOS Sonoma error + +macOS 14.x (Sonoma) Finder may report an "Error code -36" when copying `.uf2` files into microcontrollers. A similar "fcopyfile failed: Input/output error" will also be reported when copying is performed using Terminal command line. These errors can be ignored because they are reported when the bootloader disconnects automatically after the uf2 file is copied successfully. + ### CMake Error An error along the lines of `CMake Error at (zmk directory)/zephyr/cmake/generic_toolchain.cmake:64 (include): include could not find load file:` during firmware compilation indicates that the Zephyr Environment Variables are not properly defined. From 828943156ab5619f54be629dcee7c0ffc74a22be Mon Sep 17 00:00:00 2001 From: Theo Lemay <16546293+theol0403@users.noreply.github.com> Date: Mon, 18 Mar 2024 18:34:45 -0400 Subject: [PATCH 079/127] fix(docs): Fix hold-tap info callout (#2211) The hold-while-undecided callout does not properly render in the docs. This fixes it. --- docs/docs/behaviors/hold-tap.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/behaviors/hold-tap.mdx b/docs/docs/behaviors/hold-tap.mdx index 191e820d..5217cf79 100644 --- a/docs/docs/behaviors/hold-tap.mdx +++ b/docs/docs/behaviors/hold-tap.mdx @@ -87,7 +87,7 @@ For example, if you press `&mt LEFT_SHIFT A` and then release it without pressin If enabled, the hold behavior will immediately be held on hold-tap press, and will release before the behavior is sent in the event the hold-tap resolves into a tap. With most modifiers this will not affect typing, and is useful for using modifiers with the mouse. -:::note Alt/Win/Cmd behavior +:::info[Alt/Win/Cmd behavior] In some applications/desktop environments, pressing Alt keycodes by itself will have its own behavior like activate a menu and Gui keycodes will bring up the start menu or an application launcher. ::: From 1f7cd7a107789055bf58ac6c01af502773cef76a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=95=E3=82=A3=E3=83=AB=E3=82=BF=E3=83=BC=E3=83=9A?= =?UTF-8?q?=E3=83=BC=E3=83=91=E3=83=BC?= <76888457+filterpaper@users.noreply.github.com> Date: Tue, 19 Mar 2024 10:49:16 +0800 Subject: [PATCH 080/127] feat(docs): Add troubleshooting section for empty_file error --- docs/docs/troubleshooting.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/docs/troubleshooting.md b/docs/docs/troubleshooting.md index 808808c4..2e9ab4dc 100644 --- a/docs/docs/troubleshooting.md +++ b/docs/docs/troubleshooting.md @@ -56,6 +56,14 @@ A `devicetree error` followed by a reference to the line number on `.k devicetree error: /__w/zmk-config/zmk-config/config/cradio.keymap:109 (column 4): parse error: expected ';' or ',' ``` +A `devicetree error` followed by an `empty_file.c` reference with `lacks #binding-cells` string indicates possible problems with improper parameters for specific bindings: + +``` +devicetree error: lacks #binding-cells +``` + +This error can be triggered by incorrect binding syntax such as `&kp BT_SEL 0` instead of `&bt BT_SEL 0`. + #### devicetree_unfixed.h error A `devicetree_unfixed.h` error that follows with an "undeclared here" string indicates a problem with key bindings, like behavior nodes (e.g. `&kp` or `&mt`) with incorrect number of parameters: From 3a3eed2960b9388b8554eb778d56dfd99a477962 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Tue, 19 Mar 2024 10:50:04 -0700 Subject: [PATCH 081/127] fix: Add settings reset on start init priority. * Add a dedicated settings reset on start init priority and default it to lower priority (high number) than default FLASH_INIT_PRIORITY to be sure flash is initialized before we open the area. --- app/Kconfig | 13 +++++++++++++ app/src/settings/reset_settings_on_start.c | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app/Kconfig b/app/Kconfig index 3f797abd..c430bcb2 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -568,6 +568,19 @@ if SETTINGS config ZMK_SETTINGS_RESET_ON_START bool "Delete all persistent settings when the keyboard boots" +if ZMK_SETTINGS_RESET_ON_START + +config ZMK_SETTINGS_RESET_ON_START_INIT_PRIORITY + int "Settings Reset ON Start Initialization Priority" + default 60 + help + Initialization priority for the settings reset on start. Must be lower priority/ + higher value than FLASH_INIT_PRIORITY if using the NVS/Flash settings backend. + + +endif + + config ZMK_SETTINGS_SAVE_DEBOUNCE int "Milliseconds to debounce settings saves" default 60000 diff --git a/app/src/settings/reset_settings_on_start.c b/app/src/settings/reset_settings_on_start.c index 47f5e8f2..0f6d4fae 100644 --- a/app/src/settings/reset_settings_on_start.c +++ b/app/src/settings/reset_settings_on_start.c @@ -10,4 +10,4 @@ // Reset after the kernel is initialized but before any application code to // ensure settings are cleared before anything tries to use them. -SYS_INIT(zmk_settings_erase, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(zmk_settings_erase, POST_KERNEL, CONFIG_ZMK_SETTINGS_RESET_ON_START_INIT_PRIORITY); From 931a36ff4ad0b30c8165024bbfc0286d05b74b53 Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Wed, 28 Feb 2024 00:09:27 -0800 Subject: [PATCH 082/127] feat(docs): Add a note on using BT with dual boot systems --- docs/docs/features/bluetooth.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/docs/features/bluetooth.md b/docs/docs/features/bluetooth.md index 1f2d7955..28ba2136 100644 --- a/docs/docs/features/bluetooth.md +++ b/docs/docs/features/bluetooth.md @@ -69,6 +69,11 @@ This setting can also improve the connection strength between the keyboard halve If you want to test bluetooth output on your keyboard and are powering it through the USB connection rather than a battery, you will be able to pair with a host device but may not see keystrokes sent. In this case you need to use the [output selection behavior](../behaviors/outputs.md) to prefer sending keystrokes over bluetooth rather than USB. This might be necessary even if you are not powering from a device capable of receiving USB inputs, such as a USB charger. +### Issues with dual boot setups + +Since ZMK associates pairing/bond keys with hardware addresses of hosts, you cannot pair to two different operating systems in a dual boot system at the same time. +While you can find [documented workarounds](https://wiki.archlinux.org/title/bluetooth#Dual_boot_pairing) that involve copying pairing keys across operating systems and use both OS with a single profile, they can be fairly involved and should be followed with caution. + ### macOS Connected But Not Working If you attempt to pair a ZMK keyboard from macOS in a way that causes a bonding issue, macOS may report the keyboard as connected, but fail to actually work. If this occurs: From 44358798d3dae71cc1af118e5a5bc5792f9f7761 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 15 Mar 2024 21:00:37 +0000 Subject: [PATCH 083/127] feat: Add ability to fetch battery voltage. * To be able to use the Zephyr `voltage-divider` driver, add a mode for fetching raw voltage from the sensor and do state of charge calculation outside of the driver. --- app/Kconfig | 14 ++++++++++++++ app/src/battery.c | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/app/Kconfig b/app/Kconfig index c430bcb2..21e97ac6 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -383,6 +383,20 @@ config ZMK_BATTERY_REPORTING select ZMK_LOW_PRIORITY_WORK_QUEUE imply BT_BAS if ZMK_BLE +if ZMK_BATTERY_REPORTING + +choice ZMK_BATTERY_REPORTING_FETCH_MODE + prompt "Battery Reporting Fetch Mode" + +config ZMK_BATTERY_REPORTING_FETCH_MODE_STATE_OF_CHARGE + bool "State of charge" + +config ZMK_BATTERY_REPORTING_FETCH_MODE_LITHIUM_VOLTAGE + bool "Lithium Voltage" + +endchoice +endif + config ZMK_IDLE_TIMEOUT int "Milliseconds of inactivity before entering idle state (OLED shutoff, etc)" default 30000 diff --git a/app/src/battery.c b/app/src/battery.c index 1295f822..ae79d5f7 100644 --- a/app/src/battery.c +++ b/app/src/battery.c @@ -34,11 +34,29 @@ static const struct device *const battery = DEVICE_DT_GET(DT_CHOSEN(zmk_battery) static const struct device *battery; #endif +#if IS_ENABLED(CONFIG_ZMK_BATTERY_REPORTING_FETCH_MODE_LITHIUM_VOLTAGE) +static uint8_t lithium_ion_mv_to_pct(int16_t bat_mv) { + // Simple linear approximation of a battery based off adafruit's discharge graph: + // https://learn.adafruit.com/li-ion-and-lipoly-batteries/voltages + + if (bat_mv >= 4200) { + return 100; + } else if (bat_mv <= 3450) { + return 0; + } + + return bat_mv * 2 / 15 - 459; +} + +#endif // IS_ENABLED(CONFIG_ZMK_BATTERY_REPORTING_FETCH_MODE_LITHIUM_VOLTAGE) + static int zmk_battery_update(const struct device *battery) { struct sensor_value state_of_charge; + int rc; - int rc = sensor_sample_fetch_chan(battery, SENSOR_CHAN_GAUGE_STATE_OF_CHARGE); +#if IS_ENABLED(CONFIG_ZMK_BATTERY_REPORTING_FETCH_MODE_STATE_OF_CHARGE) + rc = sensor_sample_fetch_chan(battery, SENSOR_CHAN_GAUGE_STATE_OF_CHARGE); if (rc != 0) { LOG_DBG("Failed to fetch battery values: %d", rc); return rc; @@ -50,6 +68,28 @@ static int zmk_battery_update(const struct device *battery) { LOG_DBG("Failed to get battery state of charge: %d", rc); return rc; } +#elif IS_ENABLED(CONFIG_ZMK_BATTERY_REPORTING_FETCH_MODE_LITHIUM_VOLTAGE) + rc = sensor_sample_fetch_chan(battery, SENSOR_CHAN_VOLTAGE); + if (rc != 0) { + LOG_DBG("Failed to fetch battery values: %d", rc); + return rc; + } + + struct sensor_value voltage; + rc = sensor_channel_get(battery, SENSOR_CHAN_VOLTAGE, &voltage); + + if (rc != 0) { + LOG_DBG("Failed to get battery voltage: %d", rc); + return rc; + } + + uint16_t mv = voltage.val1 * 1000 + (voltage.val2 / 1000); + state_of_charge.val1 = lithium_ion_mv_to_pct(mv); + + LOG_DBG("State of change %d from %d mv", state_of_charge.val1, mv); +#else +#error "Not a supported reporting fetch mode" +#endif if (last_state_of_charge != state_of_charge.val1) { last_state_of_charge = state_of_charge.val1; From f2d8b9b0a31398d9880de6a960b41e3603b3b837 Mon Sep 17 00:00:00 2001 From: Thomas Huber <113915837+huber-th@users.noreply.github.com> Date: Wed, 20 Mar 2024 07:18:44 -0700 Subject: [PATCH 084/127] feat(docs): Add Behavior overview page Co-authored-by: Cem Aksoylar --- docs/docs/behaviors/index.mdx | 82 +++++++++++++++++++++++++++++++++++ docs/sidebars.js | 1 + 2 files changed, 83 insertions(+) create mode 100644 docs/docs/behaviors/index.mdx diff --git a/docs/docs/behaviors/index.mdx b/docs/docs/behaviors/index.mdx new file mode 100644 index 00000000..32f4b29a --- /dev/null +++ b/docs/docs/behaviors/index.mdx @@ -0,0 +1,82 @@ +--- +title: Behavior Overview +sidebar_label: Overview +--- + +# Behaviors Overview + +"Behaviors" are bindings that are assigned to and triggered by key positions on keymap layers, sensors (like an encoder) or combos. They describe what happens e.g. when a certain key position is pressed or released, or an encoder triggers a rotation event. They can also be recursively invoked by other behaviors, such as macros. + +Below is a summary of pre-defined behavior bindings and user-definable behaviors available in ZMK, with references to documentation pages describing them. + +## Key press behaviors + +| Binding | Behavior | Description | +| ------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `&kp` | [Key Press](key-press.md) | Send keycodes to the connected host when a key is pressed | +| `&mt` | [Mod Tap](mod-tap.md) | Sends a different key press depending on whether a key is held or tapped | +| `&kt` | [Key Toggle](key-toggle.md) | Toggles the press of a key. If the key is not currently pressed, key toggle will press it, holding it until the key toggle is pressed again or the key is released in some other way. If the key is currently pressed, key toggle will release it | +| `&sk` | [Sticky Key](sticky-key.md) | Stays pressed until another key is pressed, then is released. It is often used for modifier keys like shift, which allows typing capital letters without holding it down | +| `&gresc` | [Grave Escape](mod-morph.md#behavior-binding) | Sends Grave Accent `` ` `` keycode if shift or GUI is held, sends Escape keycode otherwise | +| `&caps_word` | [Caps Word](caps-word.md) | Behaves similar to caps lock, but automatically deactivates when any key not in a continue list is pressed, or if the caps word key is pressed again | +| `&key_repeat` | [Key Repeat](key-repeat.md) | Sends again whatever keycode was last sent | + +## Miscellaneous behaviors + +| Binding | Behavior | Description | +| -------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `&trans` | [Transparent](misc.md#transparent) | Passes the key press down to the next active layer in the stack for processing | +| `&none` | [None](misc.md#none) | Swallows and stops the key press, no keycode will be sent nor will the key press be passed down to the next active layer in the stack | + +## Layer navigation behaviors + +| Binding | Behavior | Description | +| ------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| `&mo` | [Momentary Layer](layers.md#momentary-layer) | Enables a layer while a key is pressed | +| `<` | [Layer-tap](layers.md#layer-tap) | Enables a layer when a key is held, and outputs a key press when the key is only tapped for a short time | +| `&to` | [To Layer](layers.md#to-layer) | Enables a layer and disables all other layers except the default layer | +| `&tog` | [Toggle Layer](layers.md#toggle-layer) | Enables a layer until the layer is manually disabled | +| `&sl` | [Sticky Layer](sticky-layer.md) | Activates a layer until another key is pressed, then deactivates it | + +## Mouse emulation behaviors + +| Binding | Behavior | Description | +| ------- | ----------------------------------------------------------- | ------------------------------- | +| `&mkp` | [Mouse Button Press](mouse-emulation.md#mouse-button-press) | Emulates pressing mouse buttons | + +## Reset behaviors + +| Binding | Behavior | Description | +| ------------- | --------------------------------- | ---------------------------------------------------------------------------------------- | +| `&sys_reset` | [Reset](reset.md#reset) | Resets the keyboard and re-runs the firmware flashed to the device | +| `&bootloader` | [Bootloader](reset.md#bootloader) | Resets the keyboard and puts it into bootloader mode, allowing you to flash new firmware | + +## Output selection behaviors + +| Binding | Behavior | Description | +| ------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| `&bt` | [Bluetooth](bluetooth.md#bluetooth-behavior) | Completes a bluetooth action given on press, for example switching between devices | +| `&out` | [Output Selection](outputs.md#output-selection-behavior) | Allows selecting whether output is sent to the USB or bluetooth connection when both are connected | + +## Lighting behaviors + +| Binding | Behavior | Description | +| --------- | ---------------------------------------------- | ---------------------------------------------------------------------------- | +| `&rgb_ug` | [RGB Underglow](underglow.md#behavior-binding) | Controls the RGB underglow, usually placed underneath the keyboard | +| `&bl` | [Backlight](backlight.md#behavior-binding) | Controls the keyboard backlighting, usually placed through or under switches | + +## Power management behaviors + +| Binding | Behavior | Description | +| ------------ | --------------------------------------------- | --------------------------------------------------------------- | +| `&ext_power` | [Power management](power.md#behavior-binding) | Allows enabling or disabling the VCC power output to save power | + +## User-defined behaviors + +| Behavior | Description | +| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [Macros](macros.md) | Allows configuring a list of other behaviors to invoke when the key is pressed and/or released | +| [Hold-Tap](hold-tap.mdx) | Invokes different behaviors depending on key press duration or interrupting keys. This is the basis for [layer-tap](layers.md#layer-tap) and [mod-tap](mod-tap.md) | +| [Tap Dance](tap-dance.mdx) | Invokes different behaviors corresponding to how many times a key is pressed | +| [Mod-Morph](mod-morph.md) | Invokes different behaviors depending on whether a specified modifier is held during a key press | +| [Sensor Rotation](sensor-rotate.md) | Invokes different behaviors depending on whether a sensor is rotated clockwise or counter-clockwise | diff --git a/docs/sidebars.js b/docs/sidebars.js index 284eb09b..37613d56 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -22,6 +22,7 @@ module.exports = { "features/beta-testing", ], Behaviors: [ + "behaviors/index", "behaviors/key-press", "behaviors/layers", "behaviors/misc", From c684cee76f6732d1da3dc23564b64e9a1ea08671 Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Sun, 24 Mar 2024 17:58:20 -0700 Subject: [PATCH 085/127] refactor(docs): Refer to overview page for behaviors --- docs/docs/development/new-behavior.mdx | 2 +- docs/docs/development/new-shield.mdx | 2 +- docs/docs/features/keymaps.mdx | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/docs/development/new-behavior.mdx b/docs/docs/development/new-behavior.mdx index cabc417f..914abf52 100644 --- a/docs/docs/development/new-behavior.mdx +++ b/docs/docs/development/new-behavior.mdx @@ -8,7 +8,7 @@ import TabItem from "@theme/TabItem"; ## Overview -This document outlines how to develop a behavior for ZMK and prepare the changes for a pull request. +This document outlines how to develop a [behavior](../behaviors/index.mdx) for ZMK and prepare the changes for a pull request. Behaviors are assigned to key positions and determine what happens when they are pressed and released. They are implemented in Zephyr as "devices": they consist of a devicetree binding file, which specifies the properties of the behavior, and a driver written in C code. This allows for the ability to create unique instances of these behaviors in [keymaps](../features/keymaps.mdx) or devicetree-source-include files (`.dtsi`). While instances of behaviors stored in keymaps are created by end-users for their personal needs, the instances that live in the .dtsi files are stored and documented in ZMK directly, which removes the need for end-users to set up common use-cases of these behaviors in their personal keymaps. diff --git a/docs/docs/development/new-shield.mdx b/docs/docs/development/new-shield.mdx index 2cd82bc6..e99332a8 100644 --- a/docs/docs/development/new-shield.mdx +++ b/docs/docs/development/new-shield.mdx @@ -386,7 +386,7 @@ The two `#include` lines at the top of the keymap are required in order to bring ### Keymap Behaviors -For the full documentation on the available behaviors for use in keymaps, start with reviewing [`kp`](../behaviors/key-press.md) and then use the sidebar to review the others available within ZMK. +For documentation on the available behaviors for use in keymaps, see the [overview page for behaviors](../behaviors/index.mdx). ## Metadata diff --git a/docs/docs/features/keymaps.mdx b/docs/docs/features/keymaps.mdx index c8d46ef9..105ca794 100644 --- a/docs/docs/features/keymaps.mdx +++ b/docs/docs/features/keymaps.mdx @@ -33,7 +33,7 @@ For example, the simplest behavior in ZMK is the "key press" behavior, which res (a certain spot on the keyboard), and when that position is pressed, send a keycode to the host, and when the key position is released, updates the host to notify of the keycode being released. -For the full set of possible behaviors, start at the [Key Press](../behaviors/key-press.md) behavior. +For the full set of possible behaviors, see the [overview page for behaviors](../behaviors/index.mdx). ## Layers @@ -128,11 +128,9 @@ that defines just one layer for this keymap: Each layer should have: -1. A `bindings` property this will be a list of behavior bindings, one for each key position for the keyboard. +1. A `bindings` property this will be a list of [behavior bindings](../behaviors/index.mdx), one for each key position for the keyboard. 1. (Optional) A `sensor-bindings` property that will be a list of behavior bindings for each sensor on the keyboard. (Currently, only encoders are supported as sensor hardware, but in the future devices like trackpoints would be supported the same way) -For the full set of possible behaviors, start at the [Key Press](../behaviors/key-press.md) behavior. - ### Complete Example Putting this all together, a complete [`kyria.keymap`](https://github.com/zmkfirmware/zmk/blob/main/app/boards/shields/kyria/kyria.keymap) looks like: From 94c3b9a24607c966e28d44b6634c6084a21f84b2 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Sun, 24 Mar 2024 21:09:16 +0000 Subject: [PATCH 086/127] feat(build): Allow specifying snippets for a build. * Allow using snippets https://docs.zephyrproject.org/latest/build/snippets/using.html for user builds in a `snippets` array properly. --- .github/workflows/build-user-config.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-user-config.yml b/.github/workflows/build-user-config.yml index d8ea057e..c3e4789d 100644 --- a/.github/workflows/build-user-config.yml +++ b/.github/workflows/build-user-config.yml @@ -65,6 +65,7 @@ jobs: board: ${{ matrix.board }} shield: ${{ matrix.shield }} artifact_name: ${{ matrix.artifact-name }} + snippet: ${{ matrix.snippet }} run: | if [ -e zephyr/module.yml ]; then export zmk_load_arg=" -DZMK_EXTRA_MODULES='${GITHUB_WORKSPACE}'" @@ -75,7 +76,12 @@ jobs: echo "base_dir=${GITHUB_WORKSPACE}" >> $GITHUB_ENV fi + if [ -n "${snippet}" ]; then + extra_west_args="-S \"${snippet}\"" + fi + echo "zephyr_version=${ZEPHYR_VERSION}" >> $GITHUB_ENV + echo "extra_west_args=${extra_west_args}" >> $GITHUB_ENV echo "extra_cmake_args=${shield:+-DSHIELD=\"$shield\"}${zmk_load_arg}" >> $GITHUB_ENV echo "display_name=${shield:+$shield - }${board}" >> $GITHUB_ENV echo "artifact_name=${artifact_name:-${shield:+$shield-}${board}-zmk}" >> $GITHUB_ENV @@ -120,7 +126,7 @@ jobs: - name: West Build (${{ env.display_name }}) working-directory: ${{ env.base_dir }} shell: sh -x {0} - run: west build -s zmk/app -d "${{ env.build_dir }}" -b "${{ matrix.board }}" -- -DZMK_CONFIG=${{ env.base_dir }}/${{ inputs.config_path }} ${{ env.extra_cmake_args }} ${{ matrix.cmake-args }} + run: west build -s zmk/app -d "${{ env.build_dir }}" -b "${{ matrix.board }}" ${{ env.extra_west_args }} -- -DZMK_CONFIG=${{ env.base_dir }}/${{ inputs.config_path }} ${{ env.extra_cmake_args }} ${{ matrix.cmake-args }} - name: ${{ env.display_name }} Kconfig file run: | From e806cd6da1cd8239f6bf549f2956c567c31cccbc Mon Sep 17 00:00:00 2001 From: Thomas Huber <113915837+huber-th@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:20:53 -0700 Subject: [PATCH 087/127] feat(gitignore): add clangd cache folder --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 4ddd0852..1ef282a9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,14 @@ /zephyr /zmk-config /build + +# macOS *.DS_Store + +# Python __pycache__ .python-version .venv + +# clangd +app/.cache/ From 58ccc5970dc804857d81609857d4217278ec025c Mon Sep 17 00:00:00 2001 From: Thomas Huber <113915837+huber-th@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:16:34 -0700 Subject: [PATCH 088/127] fix(build): Modify function return type Change return type of `sticky_key_timeout` function to `void` given it does not return any value to remove compiler warnings. --- app/src/behaviors/behavior_sticky_key.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/behaviors/behavior_sticky_key.c b/app/src/behaviors/behavior_sticky_key.c index 2c279c3b..b0e9f3ed 100644 --- a/app/src/behaviors/behavior_sticky_key.c +++ b/app/src/behaviors/behavior_sticky_key.c @@ -121,7 +121,7 @@ static inline int release_sticky_key_behavior(struct active_sticky_key *sticky_k return behavior_keymap_binding_released(&binding, event); } -static inline int on_sticky_key_timeout(struct active_sticky_key *sticky_key) { +static inline void on_sticky_key_timeout(struct active_sticky_key *sticky_key) { // If the key is lazy, a release is not needed on timeout if (sticky_key->config->lazy) { clear_sticky_key(sticky_key); From adb3a13dc583e1876d5aa17da0ade4c1024cad7d Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 15 Mar 2023 21:48:30 -0400 Subject: [PATCH 089/127] feat: Add soft on/off support. Initial work on a soft on/off support for ZMK. Triggering soft off puts the device into deep sleep with only a specific GPIO pin configured to wake the device, avoiding waking from other key presses in the matrix like the normal deep sleep. Co-authored-by: Cem Aksoylar --- app/CMakeLists.txt | 4 + app/Kconfig | 9 + app/Kconfig.behaviors | 10 + app/dts/behaviors.dtsi | 1 + app/dts/behaviors/soft_off.dtsi | 15 ++ .../bindings/zmk,behavior-key-scanned.yaml | 31 +++ app/dts/bindings/zmk,behavior-key.yaml | 31 +++ .../bindings/zmk,soft-off-wakeup-sources.yaml | 14 ++ app/dts/bindings/zmk,wakeup-trigger-key.yaml | 18 ++ app/include/zmk/pm.h | 9 + app/src/behavior_key.c | 159 ++++++++++++++ app/src/behavior_key_scanned.c | 194 ++++++++++++++++++ app/src/kscan.c | 6 + app/src/pm.c | 59 ++++++ app/src/wakeup_trigger_key.c | 87 ++++++++ docs/docs/behaviors/soft-off.md | 38 ++++ docs/docs/development/new-shield.mdx | 1 + docs/docs/features/soft-off.md | 164 +++++++++++++++ docs/sidebars.js | 2 + 19 files changed, 852 insertions(+) create mode 100644 app/dts/behaviors/soft_off.dtsi create mode 100644 app/dts/bindings/zmk,behavior-key-scanned.yaml create mode 100644 app/dts/bindings/zmk,behavior-key.yaml create mode 100644 app/dts/bindings/zmk,soft-off-wakeup-sources.yaml create mode 100644 app/dts/bindings/zmk,wakeup-trigger-key.yaml create mode 100644 app/include/zmk/pm.h create mode 100644 app/src/behavior_key.c create mode 100644 app/src/behavior_key_scanned.c create mode 100644 app/src/pm.c create mode 100644 app/src/wakeup_trigger_key.c create mode 100644 docs/docs/behaviors/soft-off.md create mode 100644 docs/docs/features/soft-off.md diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index b12d0474..ac83091c 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -29,7 +29,11 @@ target_sources(app PRIVATE src/matrix_transform.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) +target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_KEY app PRIVATE src/behavior_key.c) +target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_KEY_SCANNED app PRIVATE src/behavior_key_scanned.c) +target_sources_ifdef(CONFIG_ZMK_PM_SOFT_OFF app PRIVATE src/pm.c) target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/ext_power_generic.c) +target_sources_ifdef(CONFIG_ZMK_WAKEUP_TRIGGER_KEY app PRIVATE src/wakeup_trigger_key.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) diff --git a/app/Kconfig b/app/Kconfig index 21e97ac6..60a959d4 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -423,6 +423,15 @@ config ZMK_EXT_POWER bool "Enable support to control external power output" default y +config ZMK_PM_SOFT_OFF + bool "Soft-off support" + select PM_DEVICE + +config ZMK_WAKEUP_TRIGGER_KEY + bool "Hardware supported wakeup (GPIO)" + default y + depends on DT_HAS_ZMK_WAKEUP_TRIGGER_KEY_ENABLED && ZMK_PM_SOFT_OFF + #Power Management endmenu diff --git a/app/Kconfig.behaviors b/app/Kconfig.behaviors index 7a1e44f6..e5e0c4d7 100644 --- a/app/Kconfig.behaviors +++ b/app/Kconfig.behaviors @@ -1,6 +1,16 @@ # Copyright (c) 2023 The ZMK Contributors # SPDX-License-Identifier: MIT +config ZMK_BEHAVIOR_KEY + bool + default y + depends on DT_HAS_ZMK_BEHAVIOR_KEY_ENABLED + +config ZMK_BEHAVIOR_KEY_SCANNED + bool + default y + depends on DT_HAS_ZMK_BEHAVIOR_KEY_SCANNED_ENABLED + config ZMK_BEHAVIOR_KEY_TOGGLE bool default y diff --git a/app/dts/behaviors.dtsi b/app/dts/behaviors.dtsi index 23f2fee2..fde75271 100644 --- a/app/dts/behaviors.dtsi +++ b/app/dts/behaviors.dtsi @@ -20,3 +20,4 @@ #include #include #include +#include diff --git a/app/dts/behaviors/soft_off.dtsi b/app/dts/behaviors/soft_off.dtsi new file mode 100644 index 00000000..fa6571a1 --- /dev/null +++ b/app/dts/behaviors/soft_off.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +/ { + behaviors { + /omit-if-no-ref/ soft_off: behavior_soft_off { + compatible = "zmk,behavior-soft-off"; + label = "SOFTOFF"; + #binding-cells = <0>; + }; + }; +}; diff --git a/app/dts/bindings/zmk,behavior-key-scanned.yaml b/app/dts/bindings/zmk,behavior-key-scanned.yaml new file mode 100644 index 00000000..bdb3abaf --- /dev/null +++ b/app/dts/bindings/zmk,behavior-key-scanned.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2023 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: | + Driver for a dedicated key triggered by matrix scanning for invoking a connected behavior. + +compatible: "zmk,behavior-key-scanned" + +include: base.yaml + +properties: + key: + type: phandle + required: true + description: The GPIO key that triggers wake via interrupt + bindings: + type: phandle + required: true + description: The GPIO key that triggers wake via interrupt + debounce-press-ms: + type: int + default: 5 + description: Debounce time for key press in milliseconds. Use 0 for eager debouncing. + debounce-release-ms: + type: int + default: 5 + description: Debounce time for key release in milliseconds. + debounce-scan-period-ms: + type: int + default: 1 + description: Time between reads in milliseconds when any key is pressed. diff --git a/app/dts/bindings/zmk,behavior-key.yaml b/app/dts/bindings/zmk,behavior-key.yaml new file mode 100644 index 00000000..ff7a585e --- /dev/null +++ b/app/dts/bindings/zmk,behavior-key.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2023 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: | + Driver for a dedicated key for invoking a connected behavior. + +compatible: "zmk,behavior-key" + +include: base.yaml + +properties: + key: + type: phandle + required: true + description: The GPIO key that triggers wake via interrupt + bindings: + type: phandle + required: true + description: The GPIO key that triggers wake via interrupt + debounce-press-ms: + type: int + default: 5 + description: Debounce time for key press in milliseconds. Use 0 for eager debouncing. + debounce-release-ms: + type: int + default: 5 + description: Debounce time for key release in milliseconds. + debounce-scan-period-ms: + type: int + default: 1 + description: Time between reads in milliseconds when any key is pressed. diff --git a/app/dts/bindings/zmk,soft-off-wakeup-sources.yaml b/app/dts/bindings/zmk,soft-off-wakeup-sources.yaml new file mode 100644 index 00000000..f98039a0 --- /dev/null +++ b/app/dts/bindings/zmk,soft-off-wakeup-sources.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2023 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: | + Description of all possible wakeup-sources from a forces + soft-off state. + +compatible: "zmk,soft-off-wakeup-sources" + +properties: + wakeup-sources: + type: phandles + required: true + description: List of wakeup-sources that should be enabled to wake the system from forces soft-off state. diff --git a/app/dts/bindings/zmk,wakeup-trigger-key.yaml b/app/dts/bindings/zmk,wakeup-trigger-key.yaml new file mode 100644 index 00000000..fa7636d1 --- /dev/null +++ b/app/dts/bindings/zmk,wakeup-trigger-key.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2023 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: | + Driver for a dedicated key for waking the device from sleep + +compatible: "zmk,wakeup-trigger-key" + +include: base.yaml + +properties: + trigger: + type: phandle + required: true + description: The GPIO key that triggers wake via interrupt + extra-gpios: + type: phandle-array + description: Optional set of pins that should be set active before sleeping. diff --git a/app/include/zmk/pm.h b/app/include/zmk/pm.h new file mode 100644 index 00000000..dff217af --- /dev/null +++ b/app/include/zmk/pm.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +int zmk_pm_soft_off(void); \ No newline at end of file diff --git a/app/src/behavior_key.c b/app/src/behavior_key.c new file mode 100644 index 00000000..3633ce39 --- /dev/null +++ b/app/src/behavior_key.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_key + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +struct behavior_key_config { + struct zmk_debounce_config debounce_config; + int32_t debounce_scan_period_ms; + struct gpio_dt_spec key; +}; + +struct behavior_key_data { + struct zmk_behavior_binding binding; + struct zmk_debounce_state debounce_state; + struct gpio_callback key_callback; + const struct device *dev; + struct k_work_delayable update_work; + uint32_t read_time; +}; + +static void bk_enable_interrupt(const struct device *dev) { + const struct behavior_key_config *config = dev->config; + + gpio_pin_interrupt_configure_dt(&config->key, GPIO_INT_LEVEL_ACTIVE); +} + +static void bk_disable_interrupt(const struct device *dev) { + const struct behavior_key_config *config = dev->config; + + gpio_pin_interrupt_configure_dt(&config->key, GPIO_INT_DISABLE); +} + +static void bk_read(const struct device *dev) { + const struct behavior_key_config *config = dev->config; + struct behavior_key_data *data = dev->data; + + zmk_debounce_update(&data->debounce_state, gpio_pin_get_dt(&config->key), + config->debounce_scan_period_ms, &config->debounce_config); + + if (zmk_debounce_get_changed(&data->debounce_state)) { + const bool pressed = zmk_debounce_is_pressed(&data->debounce_state); + + struct zmk_behavior_binding_event event = {.position = INT32_MAX, + .timestamp = k_uptime_get()}; + + if (pressed) { + behavior_keymap_binding_pressed(&data->binding, event); + } else { + behavior_keymap_binding_released(&data->binding, event); + } + } + + if (zmk_debounce_is_active(&data->debounce_state)) { + data->read_time += config->debounce_scan_period_ms; + + k_work_reschedule(&data->update_work, K_TIMEOUT_ABS_MS(data->read_time)); + } else { + bk_enable_interrupt(dev); + } +} + +static void bk_update_work(struct k_work *work) { + struct k_work_delayable *dwork = CONTAINER_OF(work, struct k_work_delayable, work); + struct behavior_key_data *data = CONTAINER_OF(dwork, struct behavior_key_data, update_work); + bk_read(data->dev); +} + +static void bk_gpio_irq_callback(const struct device *port, struct gpio_callback *cb, + const gpio_port_pins_t pin) { + struct behavior_key_data *data = CONTAINER_OF(cb, struct behavior_key_data, key_callback); + + bk_disable_interrupt(data->dev); + + data->read_time = k_uptime_get(); + k_work_reschedule(&data->update_work, K_NO_WAIT); +} + +static int behavior_key_init(const struct device *dev) { + const struct behavior_key_config *config = dev->config; + struct behavior_key_data *data = dev->data; + + if (!device_is_ready(config->key.port)) { + LOG_ERR("GPIO port is not ready"); + return -ENODEV; + } + + k_work_init_delayable(&data->update_work, bk_update_work); + data->dev = dev; + + gpio_pin_configure_dt(&config->key, GPIO_INPUT); + gpio_init_callback(&data->key_callback, bk_gpio_irq_callback, BIT(config->key.pin)); + gpio_add_callback(config->key.port, &data->key_callback); + + while (gpio_pin_get_dt(&config->key)) { + k_sleep(K_MSEC(100)); + } + + bk_enable_interrupt(dev); + + return 0; +} + +static int behavior_key_pm_action(const struct device *dev, enum pm_device_action action) { + const struct behavior_key_config *config = dev->config; + struct behavior_key_data *data = dev->data; + + int ret; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + bk_disable_interrupt(dev); + ret = gpio_remove_callback(config->key.port, &data->key_callback); + break; + case PM_DEVICE_ACTION_RESUME: + ret = gpio_add_callback(config->key.port, &data->key_callback); + bk_enable_interrupt(dev); + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} + +#define BK_INST(n) \ + const struct behavior_key_config bk_config_##n = { \ + .key = GPIO_DT_SPEC_GET(DT_INST_PHANDLE(n, key), gpios), \ + .debounce_config = \ + { \ + .debounce_press_ms = DT_INST_PROP(n, debounce_press_ms), \ + .debounce_release_ms = DT_INST_PROP(n, debounce_release_ms), \ + }, \ + .debounce_scan_period_ms = DT_INST_PROP(n, debounce_scan_period_ms), \ + }; \ + struct behavior_key_data bk_data_##n = { \ + .binding = ZMK_KEYMAP_EXTRACT_BINDING(0, DT_DRV_INST(n)), \ + }; \ + PM_DEVICE_DT_INST_DEFINE(n, behavior_key_pm_action); \ + DEVICE_DT_INST_DEFINE(n, behavior_key_init, PM_DEVICE_DT_INST_GET(n), &bk_data_##n, \ + &bk_config_##n, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); + +DT_INST_FOREACH_STATUS_OKAY(BK_INST) diff --git a/app/src/behavior_key_scanned.c b/app/src/behavior_key_scanned.c new file mode 100644 index 00000000..c961b292 --- /dev/null +++ b/app/src/behavior_key_scanned.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_key_scanned + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +struct behavior_key_scanned_config { + struct zmk_debounce_config debounce_config; + int32_t debounce_scan_period_ms; + struct gpio_dt_spec key; +}; + +struct behavior_key_scanned_data { + struct zmk_behavior_binding binding; + struct zmk_debounce_state debounce_state; + struct gpio_callback key_callback; + const struct device *dev; + struct k_work_delayable update_work; + uint32_t read_time; + bool pin_active; + bool active_scan_detected; + struct k_sem sem; +}; + +static void bks_enable_interrupt(const struct device *dev, bool active_scanning) { + const struct behavior_key_scanned_config *config = dev->config; + + gpio_pin_interrupt_configure_dt(&config->key, active_scanning ? GPIO_INT_EDGE_TO_ACTIVE + : GPIO_INT_LEVEL_ACTIVE); +} + +static void bks_disable_interrupt(const struct device *dev) { + const struct behavior_key_scanned_config *config = dev->config; + + gpio_pin_interrupt_configure_dt(&config->key, GPIO_INT_DISABLE); +} + +static void bks_read(const struct device *dev) { + const struct behavior_key_scanned_config *config = dev->config; + struct behavior_key_scanned_data *data = dev->data; + + if (k_sem_take(&data->sem, K_NO_WAIT) < 0) { + // k_work_reschedule(&data->update_work, K_NO_WAIT); + return; + } + + zmk_debounce_update(&data->debounce_state, data->active_scan_detected, + config->debounce_scan_period_ms, &config->debounce_config); + + if (zmk_debounce_get_changed(&data->debounce_state)) { + const bool pressed = zmk_debounce_is_pressed(&data->debounce_state); + + struct zmk_behavior_binding_event event = {.position = INT32_MAX, + .timestamp = k_uptime_get()}; + + if (pressed) { + behavior_keymap_binding_pressed(&data->binding, event); + } else { + behavior_keymap_binding_released(&data->binding, event); + } + } + + if (zmk_debounce_is_active(&data->debounce_state)) { + data->active_scan_detected = false; + data->read_time += config->debounce_scan_period_ms; + + k_work_schedule(&data->update_work, K_TIMEOUT_ABS_MS(data->read_time)); + } else { + bks_enable_interrupt(dev, false); + } + + k_sem_give(&data->sem); +} + +static void bks_update_work(struct k_work *work) { + struct k_work_delayable *dwork = CONTAINER_OF(work, struct k_work_delayable, work); + struct behavior_key_scanned_data *data = + CONTAINER_OF(dwork, struct behavior_key_scanned_data, update_work); + bks_read(data->dev); +} + +static void bks_gpio_irq_callback(const struct device *port, struct gpio_callback *cb, + const gpio_port_pins_t pin) { + struct behavior_key_scanned_data *data = + CONTAINER_OF(cb, struct behavior_key_scanned_data, key_callback); + const struct behavior_key_scanned_config *config = data->dev->config; + + uint32_t time = k_uptime_get(); + + if (k_sem_take(&data->sem, K_MSEC(10)) < 0) { + LOG_ERR("FAILED TO TAKE THE SEMAPHORE"); + // Do more? + return; + } + + data->active_scan_detected = true; + data->read_time = time; + + if (!zmk_debounce_is_active(&data->debounce_state)) { + // When we get that very first interrupt, we need to schedule the update checks to fall in + // between each of the real scans, so we can do our checks for state *after* each scan has + // occurred. + k_work_reschedule(&data->update_work, + K_TIMEOUT_ABS_MS(time + (config->debounce_scan_period_ms / 2))); + + bks_enable_interrupt(data->dev, true); + } + + k_sem_give(&data->sem); +} + +static int behavior_key_scanned_init(const struct device *dev) { + const struct behavior_key_scanned_config *config = dev->config; + struct behavior_key_scanned_data *data = dev->data; + + if (!device_is_ready(config->key.port)) { + LOG_ERR("GPIO port is not ready"); + return -ENODEV; + } + + k_work_init_delayable(&data->update_work, bks_update_work); + k_sem_init(&data->sem, 1, 1); + data->dev = dev; + + gpio_pin_configure_dt(&config->key, GPIO_INPUT); + gpio_init_callback(&data->key_callback, bks_gpio_irq_callback, BIT(config->key.pin)); + gpio_add_callback(config->key.port, &data->key_callback); + + while (gpio_pin_get_dt(&config->key)) { + k_sleep(K_MSEC(100)); + } + + bks_enable_interrupt(dev, false); + + return 0; +} + +static int behavior_key_scanned_pm_action(const struct device *dev, enum pm_device_action action) { + const struct behavior_key_scanned_config *config = dev->config; + struct behavior_key_scanned_data *data = dev->data; + + int ret; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + bks_disable_interrupt(dev); + ret = gpio_remove_callback(config->key.port, &data->key_callback); + break; + case PM_DEVICE_ACTION_RESUME: + ret = gpio_add_callback(config->key.port, &data->key_callback); + bks_enable_interrupt(dev, false); + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} + +#define BK_INST(n) \ + const struct behavior_key_scanned_config bks_config_##n = { \ + .key = GPIO_DT_SPEC_GET(DT_INST_PHANDLE(n, key), gpios), \ + .debounce_config = \ + { \ + .debounce_press_ms = DT_INST_PROP(n, debounce_press_ms), \ + .debounce_release_ms = DT_INST_PROP(n, debounce_release_ms), \ + }, \ + .debounce_scan_period_ms = DT_INST_PROP(n, debounce_scan_period_ms), \ + }; \ + struct behavior_key_scanned_data bks_data_##n = { \ + .binding = ZMK_KEYMAP_EXTRACT_BINDING(0, DT_DRV_INST(n)), \ + }; \ + PM_DEVICE_DT_INST_DEFINE(n, behavior_key_scanned_pm_action); \ + DEVICE_DT_INST_DEFINE(n, behavior_key_scanned_init, PM_DEVICE_DT_INST_GET(n), &bks_data_##n, \ + &bks_config_##n, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(BK_INST) diff --git a/app/src/kscan.c b/app/src/kscan.c index ff55290a..c04ce2d8 100644 --- a/app/src/kscan.c +++ b/app/src/kscan.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -75,6 +76,11 @@ int zmk_kscan_init(const struct device *dev) { kscan_config(dev, zmk_kscan_callback); kscan_enable_callback(dev); +#if IS_ENABLED(CONFIG_PM_DEVICE) + if (pm_device_wakeup_is_capable(dev)) { + pm_device_wakeup_enable(dev, true); + } +#endif // IS_ENABLED(CONFIG_PM_DEVICE) return 0; } diff --git a/app/src/pm.c b/app/src/pm.c new file mode 100644 index 00000000..af126239 --- /dev/null +++ b/app/src/pm.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#define HAS_WAKERS DT_HAS_COMPAT_STATUS_OKAY(zmk_soft_off_wakeup_sources) + +#if HAS_WAKERS + +#define DEVICE_WITH_SEP(node_id, prop, idx) DEVICE_DT_GET(DT_PROP_BY_IDX(node_id, prop, idx)), + +const struct device *soft_off_wakeup_sources[] = { + DT_FOREACH_PROP_ELEM(DT_INST(0, zmk_soft_off_wakeup_sources), wakeup_sources, DEVICE_WITH_SEP)}; + +#endif + +int zmk_pm_soft_off(void) { +#if IS_ENABLED(CONFIG_PM_DEVICE) + size_t device_count; + const struct device *devs; + + device_count = z_device_get_all_static(&devs); + + // There may be some matrix/direct kscan devices that would be used for wakeup + // from normal "inactive goes to sleep" behavior, so disable them as wakeup devices + // and then suspend them so we're ready to take over setting up our system + // and then putting it into an off state. + for (int i = 0; i < device_count; i++) { + const struct device *dev = &devs[i]; + + LOG_DBG("soft-on-off pressed cb: suspend device"); + if (pm_device_wakeup_is_enabled(dev)) { + pm_device_wakeup_enable(dev, false); + } + pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND); + } +#endif // IS_ENABLED(CONFIG_PM_DEVICE) + +#if HAS_WAKERS + for (int i = 0; i < ARRAY_SIZE(soft_off_wakeup_sources); i++) { + const struct device *dev = soft_off_wakeup_sources[i]; + pm_device_wakeup_enable(dev, true); + pm_device_action_run(dev, PM_DEVICE_ACTION_RESUME); + } +#endif // HAS_WAKERS + + LOG_DBG("soft-on-off interrupt: go to sleep"); + return pm_state_force(0U, &(struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0}); +} diff --git a/app/src/wakeup_trigger_key.c b/app/src/wakeup_trigger_key.c new file mode 100644 index 00000000..0cc4f250 --- /dev/null +++ b/app/src/wakeup_trigger_key.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#define DT_DRV_COMPAT zmk_wakeup_trigger_key + +struct wakeup_trigger_key_config { + struct gpio_dt_spec trigger; + size_t extra_gpios_count; + struct gpio_dt_spec extra_gpios[]; +}; + +static int zmk_wakeup_trigger_key_init(const struct device *dev) { +#if IS_ENABLED(CONFIG_PM_DEVICE) + pm_device_init_suspended(dev); + pm_device_wakeup_enable(dev, true); +#endif + + return 0; +} + +#if IS_ENABLED(CONFIG_PM_DEVICE) + +static int wakeup_trigger_key_pm_action(const struct device *dev, enum pm_device_action action) { + const struct wakeup_trigger_key_config *config = dev->config; + int ret = 0; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + ret = gpio_pin_interrupt_configure_dt(&config->trigger, GPIO_INT_LEVEL_ACTIVE); + if (ret < 0) { + LOG_ERR("Failed to configure wakeup trigger key GPIO pin interrupt (%d)", ret); + return ret; + } + + for (int i = 0; i < config->extra_gpios_count; i++) { + ret = gpio_pin_configure_dt(&config->extra_gpios[i], GPIO_OUTPUT_ACTIVE); + if (ret < 0) { + LOG_WRN("Failed to set extra GPIO pin active for waker (%d)", ret); + } + } + break; + case PM_DEVICE_ACTION_SUSPEND: + + ret = gpio_pin_interrupt_configure_dt(&config->trigger, GPIO_INT_DISABLE); + if (ret < 0) { + LOG_ERR("Failed to configure wakeup trigger key GPIO pin interrupt (%d)", ret); + return ret; + } + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} + +#endif // IS_ENABLED(CONFIG_PM_DEVICE) + +#define WAKEUP_TRIGGER_EXTRA_GPIO_SPEC(idx, n) \ + GPIO_DT_SPEC_GET_BY_IDX(DT_DRV_INST(n), extra_gpios, idx) + +#define WAKEUP_TRIGGER_KEY_INST(n) \ + const struct wakeup_trigger_key_config wtk_cfg_##n = { \ + .trigger = GPIO_DT_SPEC_GET(DT_INST_PROP(n, trigger), gpios), \ + .extra_gpios = {LISTIFY(DT_PROP_LEN_OR(DT_DRV_INST(n), extra_gpios, 0), \ + WAKEUP_TRIGGER_EXTRA_GPIO_SPEC, (, ), n)}, \ + .extra_gpios_count = DT_PROP_LEN_OR(DT_DRV_INST(n), extra_gpios, 0), \ + }; \ + PM_DEVICE_DT_INST_DEFINE(n, wakeup_trigger_key_pm_action); \ + DEVICE_DT_INST_DEFINE(n, zmk_wakeup_trigger_key_init, PM_DEVICE_DT_INST_GET(n), NULL, \ + &wtk_cfg_##n, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); + +DT_INST_FOREACH_STATUS_OKAY(WAKEUP_TRIGGER_KEY_INST) diff --git a/docs/docs/behaviors/soft-off.md b/docs/docs/behaviors/soft-off.md new file mode 100644 index 00000000..05374004 --- /dev/null +++ b/docs/docs/behaviors/soft-off.md @@ -0,0 +1,38 @@ +--- +title: Soft Off Behavior +sidebar_label: Soft Off +--- + +## Summary + +The soft off behavior is used to force the keyboard into an off state. Depending on the specific keyboard hardware, the keyboard can be turned back on again either with a dedicated on/off button that is available, or using the reset button found on the device. + +For more information, see the [Soft Off Feature](../features/soft-off.md) page. + +### Behavior Binding + +- Reference: `&soft_off` + +Example: + +``` +&soft_off +``` + +### Configuration + +#### Hold Time + +By default, the keyboard will be turned off as soon as the key bound to the behavior is released, even if the key is only tapped briefly. If you would prefer that the key need be held a certain amount of time before releasing, you can set the `hold-time-ms` to a non-zero value in your keymap: + +``` +&soft_off { + hold-time-ms = <5000>; // Only turn off it the key is held for 5 seconds or longer. +}; + +/ { + keymap { + ... + }; +}; +``` diff --git a/docs/docs/development/new-shield.mdx b/docs/docs/development/new-shield.mdx index e99332a8..867ccbc8 100644 --- a/docs/docs/development/new-shield.mdx +++ b/docs/docs/development/new-shield.mdx @@ -171,6 +171,7 @@ this might look something like: kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; diode-direction = "col2row"; + wakeup-source; col-gpios = <&pro_micro 15 GPIO_ACTIVE_HIGH> diff --git a/docs/docs/features/soft-off.md b/docs/docs/features/soft-off.md new file mode 100644 index 00000000..b0206825 --- /dev/null +++ b/docs/docs/features/soft-off.md @@ -0,0 +1,164 @@ +--- +title: Soft Off Feature +sidebar_label: Soft Off +--- + +Similar to the deep sleep feature that sends the keyboard into a low power state after a certain period of inactivity, the soft off feature is used to turn the keyboard on and off explicitly. Depending on the keyboard, this may be through a dedicated on/off push button, or merely through an additional binding in the keymap to turn the device off and the existing reset button to turn the device back on. + +The feature is intended as an alternative to using a hardware switch to physically cut power from the battery to the keyboard. This can be useful for existing PCBs not designed for wireless that don't have a power switch, or for new designs that favor a push button on/off like found on other devices. + +:::note + +The power off is accomplished by putting the MCU into a "soft off" state. Power is _not_ technically removed from the entire system, but the device will only be woken from the state by a few possible events. + +::: + +Once powered off, the keyboard will only wake up when: + +- You press the same button/sequence that you pressed to power off the keyboard, or +- You press a reset button found on the keyboard. + +## Soft Off With Existing Designs + +For existing designs, using soft off is as simple as placing the [Soft Off Behavior](../behaviors/soft-off.md) in your keymap and then invoking it. For splits, at least for now, you'll need to place it somewhere on each side of your keymap and trigger on both sides, starting from the peripheral side first. + +You can then wake up the keyboard by pressing the reset button once, and repeating this for each side for split keyboards. + +## Adding Soft On/Off To New Designs + +### Hardware Design + +ZMK's soft on/off requires a dedicated GPIO pin to be used to trigger powering off, and to wake the core from the +soft off state when it goes active again later. + +#### Simple Direct Pin + +The simplest way to achieve this is with a push button between a GPIO pin and ground. + +#### Matrix-Integrated Hardware Combo + +Another, more complicated option is to tie two of the switch outputs in the matrix together through an AND gate and connect that to the dedicated GPIO pin. This way you can use a key combination in your existing keyboard matrix to trigger soft on/off. To make this work best, the two switches used should both be driven by the same matrix input pin so that both will be active simultaneously on the AND gate inputs. The alternative is to use a combination of diodes and capacitors to ensure both pins are active/high at the same time even if scanning sets them high at different times. + +### Firmware Changes + +Several items work together to make both triggering soft off properly, and setting up the device to _wake_ from soft off work as expected. + +#### GPIO Key + +Zephyr's basic GPIO Key concept is used to configure the GPIO pin that will be used for both triggering soft off and waking the device later. Here is an example for a keyboard with a dedicated on/off push button that is a direct wire between the GPIO pin and ground: + +``` +/ { + keys { + compatible = "gpio-keys"; + wakeup_key: wakeup_key { + gpios = <&gpio0 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + }; + }; +}; +``` + +GPIO keys are defined using child nodes under the `gpio-keys` compatible node. Each child needs just one property defined: + +- The `gpios` property should be a phandle-array with a fully defined GPIO pin and with the correct pull up/down and active high/low flags set. In the above example the soft on/off would be triggered by pulling the specified pin low, typically by pressing a switch that has the other leg connected to ground. + +#### Behavior Key + +Next, we will create a new "behavior key". Behavior keys are an easy way to tie a keymap behavior to a GPIO key outside of the normal keymap processing. They do _not_ do the normal keymap processing, so they are only suitable for use with basic behaviors, not complicated macros, hold-taps, etc. + +In this case, we will be creating a dedicated instance of the [Soft Off Behavior](../behaviors/soft-off.md) that will be used only for our hardware on/off button, then binding it to our key: + +``` +/ { + behaviors { + hw_soft_off: behavior_hw_soft_off { + compatible = "zmk,behavior-soft-off"; + #binding-cells = <0>; + label = "HW_SO"; + hold-time-ms = <5000>; + }; + }; + + soft_off_behavior_key { + compatible = "zmk,behavior-key"; + bindings = <&hw_soft_off>; + key = <&wakeup_key>; + }; +}; +``` + +Here are the properties for the behavior key node: + +- The `compatible` property for the node must be `zmk,behavior-key`. +- The `bindings` property is a phandle to the soft off behavior defined above. +- The `key` property is a phandle to the GPIO key defined earlier. + +If you have set up your on/off to be controlled by a matrix-integrated combo, the behavior key needs use a different driver that will handle detecting the pressed state when the pin is toggled by the other matrix kscan driver: + +``` +/ { + soft_off_behavior_key { + compatible = "zmk,behavior-key-scanned"; + status = "okay"; + bindings = <&hw_soft_off>; + key = <&wakeup_key>; + }; +}; +``` + +Note that the only difference from the `soft_off_behavior_key` definition for GPIO keys above is the `compatible` value of `zmk,behavior-key-scanned`. + +#### Wakeup Sources + +Zephyr has general support for the concept of a device as a "wakeup source", which ZMK has not previously used. Adding soft off requires properly updating the existing `kscan` devices with the `wakeup-source` property, e.g.: + +``` +/ { + kscan0: kscan_0 { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + diode-direction = "col2row"; + wakeup-source; + + ... + }; +}; +``` + +#### Soft Off Waker + +Next, we need to add another device which will be enabled only when the keyboard is going into soft off state, and will configure the previously declared GPIO key with the correct interrupt configuration to wake the device from soft off once it is pressed. + +``` +/ { + wakeup_source: wakeup_source { + compatible = "zmk,wakeup-trigger-key"; + + trigger = <&wakeup_key>; + wakeup-source; + }; +}; +``` + +Here are the properties for the node: + +- The `compatible` property for the node must be `zmk,wakeup-trigger-key`. +- The `trigger` property is a phandle to the GPIO key defined earlier. +- The `wakeup-source` property signals to Zephyr this device should not be suspended during the shutdown procedure. +- An optional `output-gpios` property contains a list of GPIO pins (including the appropriate flags) to set active before going into power off, if needed to ensure the GPIO pin will trigger properly to wake the keyboard. This is only needed for matrix integrated combos. For those keyboards, the list should include the matrix output needs needed so the combo hardware is properly "driven" when the keyboard is off. + +Once that is declared, we will list it in an additional configuration section so that the ZMK soft off process knows it needs to enable this device as part of the soft off processing: + +``` +/ { + soft_off_wakers { + compatible = "zmk,soft-off-wakeup-sources"; + wakeup-sources = <&wakeup_source>; + }; +}; +``` + +Here are the properties for the node: + +- The `compatible` property for the node must be `zmk,soft-off-wakeup-sources`. +- The `wakeup-sources` property is a [phandle array](../config/index.md#devicetree-property-types) pointing to all the devices that should be enabled during the shutdown process to be sure they can later wake the keyboard. diff --git a/docs/sidebars.js b/docs/sidebars.js index 37613d56..ebf0aef7 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -19,6 +19,7 @@ module.exports = { "features/underglow", "features/backlight", "features/battery", + "features/soft-off", "features/beta-testing", ], Behaviors: [ @@ -44,6 +45,7 @@ module.exports = { "behaviors/underglow", "behaviors/backlight", "behaviors/power", + "behaviors/soft-off", ], Codes: [ "codes/index", From 738c3c0e3b3878ddaebafae65becdf5e5f68fe86 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 13 Sep 2023 19:58:53 +0000 Subject: [PATCH 090/127] feat(kscan): Add PM support to GPIO kscan drivers. * Add PM device hook to the kscan direct & matrix drivers. --- app/module/drivers/kscan/kscan_gpio_direct.c | 27 +++++++++++++++++++- app/module/drivers/kscan/kscan_gpio_matrix.c | 27 +++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/app/module/drivers/kscan/kscan_gpio_direct.c b/app/module/drivers/kscan/kscan_gpio_direct.c index b5e77f63..2bc35f4c 100644 --- a/app/module/drivers/kscan/kscan_gpio_direct.c +++ b/app/module/drivers/kscan/kscan_gpio_direct.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -318,6 +319,28 @@ static int kscan_direct_init(const struct device *dev) { return 0; } +#if IS_ENABLED(CONFIG_PM_DEVICE) + +static int kscan_direct_pm_action(const struct device *dev, enum pm_device_action action) { + int ret = 0; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + kscan_direct_disable(dev); + break; + case PM_DEVICE_ACTION_RESUME: + kscan_direct_enable(dev); + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} + +#endif // IS_ENABLED(CONFIG_PM_DEVICE) + static const struct kscan_driver_api kscan_direct_api = { .config = kscan_direct_configure, .enable_callback = kscan_direct_enable, @@ -354,7 +377,9 @@ static const struct kscan_driver_api kscan_direct_api = { .toggle_mode = DT_INST_PROP(n, toggle_mode), \ }; \ \ - DEVICE_DT_INST_DEFINE(n, &kscan_direct_init, NULL, &kscan_direct_data_##n, \ + PM_DEVICE_DT_INST_DEFINE(n, kscan_direct_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(n, &kscan_direct_init, PM_DEVICE_DT_INST_GET(n), &kscan_direct_data_##n, \ &kscan_direct_config_##n, POST_KERNEL, CONFIG_KSCAN_INIT_PRIORITY, \ &kscan_direct_api); diff --git a/app/module/drivers/kscan/kscan_gpio_matrix.c b/app/module/drivers/kscan/kscan_gpio_matrix.c index 6e91bf95..3917196e 100644 --- a/app/module/drivers/kscan/kscan_gpio_matrix.c +++ b/app/module/drivers/kscan/kscan_gpio_matrix.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -421,6 +422,28 @@ static int kscan_matrix_init(const struct device *dev) { return 0; } +#if IS_ENABLED(CONFIG_PM_DEVICE) + +static int kscan_matrix_pm_action(const struct device *dev, enum pm_device_action action) { + int ret = 0; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + kscan_matrix_disable(dev); + break; + case PM_DEVICE_ACTION_RESUME: + kscan_matrix_enable(dev); + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} + +#endif // IS_ENABLED(CONFIG_PM_DEVICE) + static const struct kscan_driver_api kscan_matrix_api = { .config = kscan_matrix_configure, .enable_callback = kscan_matrix_enable, @@ -465,7 +488,9 @@ static const struct kscan_driver_api kscan_matrix_api = { .diode_direction = INST_DIODE_DIR(n), \ }; \ \ - DEVICE_DT_INST_DEFINE(n, &kscan_matrix_init, NULL, &kscan_matrix_data_##n, \ + PM_DEVICE_DT_INST_DEFINE(n, kscan_matrix_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(n, &kscan_matrix_init, PM_DEVICE_DT_INST_GET(n), &kscan_matrix_data_##n, \ &kscan_matrix_config_##n, POST_KERNEL, CONFIG_KSCAN_INIT_PRIORITY, \ &kscan_matrix_api); From b19df0cbf053a88a9389bdf463df431e5b7e70a5 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 13 Sep 2023 20:01:02 +0000 Subject: [PATCH 091/127] feat(behaviors): Add soft off behavior. * New soft-off behavior that can be used to force the device into soft-off state with only certain configured wakeup devices. --- app/CMakeLists.txt | 1 + app/Kconfig.behaviors | 6 ++ app/dts/behaviors/soft_off.dtsi | 3 +- .../behaviors/zmk,behavior-soft-off.yaml | 14 ++++ app/src/behaviors/behavior_soft_off.c | 70 +++++++++++++++++++ 5 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml create mode 100644 app/src/behaviors/behavior_soft_off.c diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index ac83091c..bf7cfeef 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -42,6 +42,7 @@ 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) +target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SOFT_OFF app PRIVATE src/behaviors/behavior_soft_off.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) diff --git a/app/Kconfig.behaviors b/app/Kconfig.behaviors index e5e0c4d7..7c30f50e 100644 --- a/app/Kconfig.behaviors +++ b/app/Kconfig.behaviors @@ -22,6 +22,12 @@ config ZMK_BEHAVIOR_MOUSE_KEY_PRESS depends on DT_HAS_ZMK_BEHAVIOR_MOUSE_KEY_PRESS_ENABLED imply ZMK_MOUSE +config ZMK_BEHAVIOR_SOFT_OFF + bool + default y + select ZMK_PM_SOFT_OFF + depends on DT_HAS_ZMK_BEHAVIOR_SOFT_OFF_ENABLED + config ZMK_BEHAVIOR_SENSOR_ROTATE_COMMON bool diff --git a/app/dts/behaviors/soft_off.dtsi b/app/dts/behaviors/soft_off.dtsi index fa6571a1..c68230f3 100644 --- a/app/dts/behaviors/soft_off.dtsi +++ b/app/dts/behaviors/soft_off.dtsi @@ -6,9 +6,8 @@ / { behaviors { - /omit-if-no-ref/ soft_off: behavior_soft_off { + soft_off: soft_off { compatible = "zmk,behavior-soft-off"; - label = "SOFTOFF"; #binding-cells = <0>; }; }; diff --git a/app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml b/app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml new file mode 100644 index 00000000..1467ede4 --- /dev/null +++ b/app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2023 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: Soft-Off Behavior + +compatible: "zmk,behavior-soft-off" + +include: zero_param.yaml + +properties: + hold-time-ms: + type: int + required: false + description: Number of milliseconds the behavior must be held before releasing will actually trigger a soft-off. diff --git a/app/src/behaviors/behavior_soft_off.c b/app/src/behaviors/behavior_soft_off.c new file mode 100644 index 00000000..0f24a644 --- /dev/null +++ b/app/src/behaviors/behavior_soft_off.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_soft_off + +#include +#include +#include + +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +struct behavior_soft_off_config { + uint32_t hold_time_ms; +}; + +struct behavior_soft_off_data { + uint32_t press_start; +}; + +static int behavior_soft_off_init(const struct device *dev) { return 0; }; + +static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + const struct device *dev = zmk_behavior_get_binding(binding->behavior_dev); + struct behavior_soft_off_data *data = dev->data; + +#if IS_ENABLED(CONFIG_ZMK_SPLIT) && !IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) + zmk_pm_soft_off(); +#else + data->press_start = k_uptime_get(); +#endif + + return ZMK_BEHAVIOR_OPAQUE; +} + +static int on_keymap_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + const struct device *dev = zmk_behavior_get_binding(binding->behavior_dev); + struct behavior_soft_off_data *data = dev->data; + const struct behavior_soft_off_config *config = dev->config; + + if (config->hold_time_ms == 0 || (k_uptime_get() - data->press_start) >= config->hold_time_ms) { + zmk_pm_soft_off(); + } + + return ZMK_BEHAVIOR_OPAQUE; +} + +static const struct behavior_driver_api behavior_soft_off_driver_api = { + .binding_pressed = on_keymap_binding_pressed, + .binding_released = on_keymap_binding_released, + .locality = BEHAVIOR_LOCALITY_GLOBAL, +}; + +#define BSO_INST(n) \ + static const struct behavior_soft_off_config bso_config_##n = { \ + .hold_time_ms = DT_INST_PROP_OR(n, hold_time_ms, 0), \ + }; \ + static struct behavior_soft_off_data bso_data_##n = {}; \ + BEHAVIOR_DT_INST_DEFINE(0, behavior_soft_off_init, NULL, &bso_data_##n, &bso_config_##n, \ + APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + &behavior_soft_off_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(BSO_INST) From d3fffb9e8913105bc732eb9cbfbd380a9b98167e Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Sat, 16 Sep 2023 11:50:12 -0700 Subject: [PATCH 092/127] feat(shields): Add soft-off to the nrf52840dk ZMK Uno * Use Button 1 for soft off on the nrf52840 when using the ZMK Uno shield. --- .../boards/nrf52840dk_nrf52840.overlay | 43 ++++++++++++++++++- app/boards/shields/zmk_uno/zmk_uno.dtsi | 2 + 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay index 05c7ed9d..d08105c6 100644 --- a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay +++ b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay @@ -12,6 +12,15 @@ bias-pull-up; }; }; + + qdec_sleep: qdec_sleep { + group1 { + psels = , + ; + bias-pull-up; + low-power-enable; + }; + }; }; // Set up the QDEC hardware based driver and give it the same label as the deleted node. @@ -20,6 +29,38 @@ encoder: &qdec0 { led-pre = <0>; steps = <80>; pinctrl-0 = <&qdec_default>; - pinctrl-1 = <&qdec_default>; + pinctrl-1 = <&qdec_sleep>; pinctrl-names = "default", "sleep"; }; + +/ { + behaviors { + soft_off: soft_off { + compatible = "zmk,behavior-soft-off"; + #binding-cells = <0>; + status = "okay"; + }; + }; + + wakeup_source: wakeup_source { + compatible = "zmk,wakeup-trigger-key"; + status = "okay"; + + trigger = <&button0>; + wakeup-source; + }; + + soft_off_wakers { + compatible = "zmk,soft-off-wakeup-sources"; + status = "okay"; + + wakeup-sources = <&wakeup_source>; + }; + + soft_off_behavior_key { + compatible = "zmk,behavior-key"; + status = "okay"; + bindings = <&soft_off>; + key = <&button0>; + }; +}; \ No newline at end of file diff --git a/app/boards/shields/zmk_uno/zmk_uno.dtsi b/app/boards/shields/zmk_uno/zmk_uno.dtsi index 63deb06a..196ac8b5 100644 --- a/app/boards/shields/zmk_uno/zmk_uno.dtsi +++ b/app/boards/shields/zmk_uno/zmk_uno.dtsi @@ -124,6 +124,7 @@ nice_view_spi: &arduino_spi { kscan_matrix: kscan_matrix { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; @@ -141,6 +142,7 @@ nice_view_spi: &arduino_spi { kscan_direct: kscan_direct { compatible = "zmk,kscan-gpio-direct"; + wakeup-source; status = "disabled"; input-gpios From 860e53b33ac3b09b233a0ec4c6cb0621895fb16c Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Thu, 7 Dec 2023 00:36:02 +0000 Subject: [PATCH 093/127] refactor: Promote new endpoints API * Add ability for external callers to clear the current endpoint. --- app/include/zmk/endpoints.h | 2 ++ app/src/endpoints.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/include/zmk/endpoints.h b/app/include/zmk/endpoints.h index 70240183..f2aff2bc 100644 --- a/app/include/zmk/endpoints.h +++ b/app/include/zmk/endpoints.h @@ -73,3 +73,5 @@ 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) + +void zmk_endpoints_clear_current(void); diff --git a/app/src/endpoints.c b/app/src/endpoints.c index f8452d93..7c9d15a3 100644 --- a/app/src/endpoints.c +++ b/app/src/endpoints.c @@ -340,7 +340,7 @@ static int zmk_endpoints_init(void) { return 0; } -static void disconnect_current_endpoint(void) { +void zmk_endpoints_clear_current(void) { zmk_hid_keyboard_clear(); zmk_hid_consumer_clear(); #if IS_ENABLED(CONFIG_ZMK_MOUSE) @@ -356,7 +356,7 @@ static void update_current_endpoint(void) { if (!zmk_endpoint_instance_eq(new_instance, current_instance)) { // Cancel all current keypresses so keys don't stay held on the old endpoint. - disconnect_current_endpoint(); + zmk_endpoints_clear_current(); current_instance = new_instance; From 0d4d4fb2b5bdfd2b259febe14a9b1dfbf991872d Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Thu, 7 Dec 2023 00:37:31 +0000 Subject: [PATCH 094/127] feat(pm): Clear HID data before soft off. * Make sure the connected host has no held HID usages before we sleep. --- app/src/pm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/pm.c b/app/src/pm.c index af126239..a78b6ae5 100644 --- a/app/src/pm.c +++ b/app/src/pm.c @@ -13,6 +13,8 @@ #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); +#include + #define HAS_WAKERS DT_HAS_COMPAT_STATUS_OKAY(zmk_soft_off_wakeup_sources) #if HAS_WAKERS @@ -29,6 +31,10 @@ int zmk_pm_soft_off(void) { size_t device_count; const struct device *devs; +#if !IS_ENABLED(CONFIG_ZMK_SPLIT) || IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) + zmk_endpoints_clear_current(); +#endif + device_count = z_device_get_all_static(&devs); // There may be some matrix/direct kscan devices that would be used for wakeup From e78249ee067910725cd7fcf447b016ce3cdcf318 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Thu, 7 Dec 2023 04:04:13 +0000 Subject: [PATCH 095/127] fix(bt): Fix BT tests after soft off work. * Move to explicit enable of `ZMK_PM_SOFT_OFF` to turn on the feature and use the behaviors, which matches how other features work, and helps with split and testing schemes. --- app/Kconfig.behaviors | 3 +-- .../shields/zmk_uno/boards/nrf52840dk_nrf52840.conf | 1 + app/dts/behaviors/soft_off.dtsi | 3 ++- docs/docs/config/power.md | 12 ++++++++++++ 4 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.conf diff --git a/app/Kconfig.behaviors b/app/Kconfig.behaviors index 7c30f50e..18fd5c15 100644 --- a/app/Kconfig.behaviors +++ b/app/Kconfig.behaviors @@ -25,8 +25,7 @@ config ZMK_BEHAVIOR_MOUSE_KEY_PRESS config ZMK_BEHAVIOR_SOFT_OFF bool default y - select ZMK_PM_SOFT_OFF - depends on DT_HAS_ZMK_BEHAVIOR_SOFT_OFF_ENABLED + depends on DT_HAS_ZMK_BEHAVIOR_SOFT_OFF_ENABLED && ZMK_PM_SOFT_OFF config ZMK_BEHAVIOR_SENSOR_ROTATE_COMMON bool diff --git a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.conf b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000..ac92c4d8 --- /dev/null +++ b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1 @@ +CONFIG_ZMK_PM_SOFT_OFF=y \ No newline at end of file diff --git a/app/dts/behaviors/soft_off.dtsi b/app/dts/behaviors/soft_off.dtsi index c68230f3..c88e1b51 100644 --- a/app/dts/behaviors/soft_off.dtsi +++ b/app/dts/behaviors/soft_off.dtsi @@ -6,8 +6,9 @@ / { behaviors { - soft_off: soft_off { + /omit-if-no-ref/ soft_off: soft_off { compatible = "zmk,behavior-soft-off"; + label = "SOFTOFF"; #binding-cells = <0>; }; }; diff --git a/docs/docs/config/power.md b/docs/docs/config/power.md index 75e1b26a..396456b2 100644 --- a/docs/docs/config/power.md +++ b/docs/docs/config/power.md @@ -24,6 +24,18 @@ Definition file: [zmk/app/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/ | `CONFIG_ZMK_SLEEP` | bool | Enable deep sleep support | n | | `CONFIG_ZMK_IDLE_SLEEP_TIMEOUT` | int | Milliseconds of inactivity before entering deep sleep | 900000 | +## Soft Off + +The [soft off feature](../features/soft-off.md) allows turning the keyboard on/off from either dedicated hardware of using the [`&soft_off` behavior](../behaviors/soft-off.md) to turn off and a reset button to turn back on again. + +### Kconfig + +Definition file: [zmk/app/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/app/Kconfig) + +| Config | Type | Description | Default | +| ------------------------ | ---- | ------------------------------------------------------------------- | ------- | +| `CONFIG_ZMK_PM_SOFT_OFF` | bool | Enable soft off functionality from the keymap of dedicated hardware | n | + ## External Power Control Driver for enabling or disabling power to peripherals such as displays and lighting. This driver must be configured to use [power management behaviors](../behaviors/power.md). From 96968514e378cd134889637ee3e0c6311e08e13a Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Sat, 9 Dec 2023 17:18:04 -0500 Subject: [PATCH 096/127] fix(docs): Apply suggestions from code review Co-authored-by: Cem Aksoylar --- docs/docs/config/kscan.md | 8 +++++++- docs/docs/config/power.md | 4 ++-- docs/docs/features/soft-off.md | 9 ++++----- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/docs/docs/config/kscan.md b/docs/docs/config/kscan.md index b49529d9..3076edc0 100644 --- a/docs/docs/config/kscan.md +++ b/docs/docs/config/kscan.md @@ -79,6 +79,7 @@ Definition file: [zmk/app/module/dts/bindings/kscan/zmk,kscan-gpio-direct.yaml]( | `debounce-scan-period-ms` | int | Time between reads in milliseconds when any key is pressed. | 1 | | `poll-period-ms` | int | Time between reads in milliseconds when no key is pressed and `CONFIG_ZMK_KSCAN_DIRECT_POLLING` is enabled. | 10 | | `toggle-mode` | bool | Use toggle switch mode. | n | +| `wakeup-source` | bool | Mark this kscan instance as able to wake the keyboard from deep sleep | n | By default, a switch will drain current through the internal pull up/down resistor whenever it is pressed. This is not ideal for a toggle switch, where the switch may be left in the "pressed" state for a long time. Enabling `toggle-mode` will make the driver flip between pull up and down as the switch is toggled to optimize for power. @@ -89,6 +90,7 @@ Assuming the switches connect each GPIO pin to the ground, the [GPIO flags](http ```dts kscan0: kscan { compatible = "zmk,kscan-gpio-direct"; + wakeup-source; input-gpios = <&pro_micro 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)> , <&pro_micro 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)> @@ -123,6 +125,7 @@ Definition file: [zmk/app/module/dts/bindings/kscan/zmk,kscan-gpio-matrix.yaml]( | `debounce-scan-period-ms` | int | Time between reads in milliseconds when any key is pressed. | 1 | | `diode-direction` | string | The direction of the matrix diodes | `"row2col"` | | `poll-period-ms` | int | Time between reads in milliseconds when no key is pressed and `CONFIG_ZMK_KSCAN_MATRIX_POLLING` is enabled. | 10 | +| `wakeup-source` | bool | Mark this kscan instance as able to wake the keyboard from deep sleep | n | The `diode-direction` property must be one of: @@ -137,6 +140,7 @@ The output pins (e.g. columns for `col2row`) should have the flag `GPIO_ACTIVE_H ```dts kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; col-gpios = <&pro_micro 4 GPIO_ACTIVE_HIGH> @@ -177,6 +181,7 @@ Definition file: [zmk/app/module/dts/bindings/kscan/zmk,kscan-gpio-charlieplex.y | `debounce-release-ms` | int | Debounce time for key release in milliseconds. | 5 | | `debounce-scan-period-ms` | int | Time between reads in milliseconds when any key is pressed. | 1 | | `poll-period-ms` | int | Time between reads in milliseconds when no key is pressed and `interrupt-gpois` is not set. | 10 | +| `wakeup-source` | bool | Mark this kscan instance as able to wake the keyboard from deep sleep | n | Define the transform with a [matrix transform](#matrix-transform). The row is always the driven pin, and the column always the receiving pin (input to the controller). For example, in `RC(5,0)` power flows from the 6th pin in `gpios` to the 1st pin in `gpios`. @@ -450,7 +455,8 @@ Note that the entire addressable space does not need to be mapped. }; kscan0: kscan { - compatible = "zmk,kscan-gpio-charlieplex"; + compatible = "zmk,kscan-gpio-charlieplex";k + wakeup-source; interrupt-gpios = <&pro_micro 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN) >; gpios diff --git a/docs/docs/config/power.md b/docs/docs/config/power.md index 396456b2..1a142eb2 100644 --- a/docs/docs/config/power.md +++ b/docs/docs/config/power.md @@ -26,7 +26,7 @@ Definition file: [zmk/app/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/ ## Soft Off -The [soft off feature](../features/soft-off.md) allows turning the keyboard on/off from either dedicated hardware of using the [`&soft_off` behavior](../behaviors/soft-off.md) to turn off and a reset button to turn back on again. +The [soft off feature](../features/soft-off.md) allows turning the keyboard on/off from either dedicated hardware, or using the [`&soft_off` behavior](../behaviors/soft-off.md) to turn off and a reset button to turn back on again. ### Kconfig @@ -34,7 +34,7 @@ Definition file: [zmk/app/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/ | Config | Type | Description | Default | | ------------------------ | ---- | ------------------------------------------------------------------- | ------- | -| `CONFIG_ZMK_PM_SOFT_OFF` | bool | Enable soft off functionality from the keymap of dedicated hardware | n | +| `CONFIG_ZMK_PM_SOFT_OFF` | bool | Enable soft off functionality from the keymap or dedicated hardware | n | ## External Power Control diff --git a/docs/docs/features/soft-off.md b/docs/docs/features/soft-off.md index b0206825..a3a5d7a1 100644 --- a/docs/docs/features/soft-off.md +++ b/docs/docs/features/soft-off.md @@ -20,15 +20,15 @@ Once powered off, the keyboard will only wake up when: ## Soft Off With Existing Designs -For existing designs, using soft off is as simple as placing the [Soft Off Behavior](../behaviors/soft-off.md) in your keymap and then invoking it. For splits, at least for now, you'll need to place it somewhere on each side of your keymap and trigger on both sides, starting from the peripheral side first. +For existing designs, using soft off is as simple as placing the [Soft Off Behavior](../behaviors/soft-off.md) in your keymap and then invoking it. You can then wake up the keyboard by pressing the reset button once, and repeating this for each side for split keyboards. -## Adding Soft On/Off To New Designs +## Adding Dedicated Soft On/Off GPIO Pin To New Designs ### Hardware Design -ZMK's soft on/off requires a dedicated GPIO pin to be used to trigger powering off, and to wake the core from the +ZMK's dedicated soft on/off pin feature requires a dedicated GPIO pin to be used to trigger powering off, and to wake the core from the soft off state when it goes active again later. #### Simple Direct Pin @@ -71,10 +71,9 @@ In this case, we will be creating a dedicated instance of the [Soft Off Behavior ``` / { behaviors { - hw_soft_off: behavior_hw_soft_off { + hw_soft_off: hw_soft_off { compatible = "zmk,behavior-soft-off"; #binding-cells = <0>; - label = "HW_SO"; hold-time-ms = <5000>; }; }; From fceb0351a58622e7a89a649efdb387c1c2ea2df1 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 20 Dec 2023 18:08:40 -0800 Subject: [PATCH 097/127] refactor: Fixes for soft-off based on review. * Better naming for gpio-key behavior triggers. * Tweaks to scanned behavior trigger to avoid bad semaphore use, and reduce chance of issues with slowly scanned matrixes. * Various code cleanups of style issues. --- app/CMakeLists.txt | 6 +- app/Kconfig | 4 +- app/Kconfig.behaviors | 8 +- app/boards/shields/zmk_uno/Kconfig.defconfig | 3 + .../zmk_uno/boards/nrf52840dk_nrf52840.conf | 1 - .../boards/nrf52840dk_nrf52840.overlay | 4 +- app/dts/behaviors/soft_off.dtsi | 1 - ...aml => zmk,gpio-key-behavior-trigger.yaml} | 4 +- ....yaml => zmk,gpio-key-wakeup-trigger.yaml} | 2 +- ...mk,gpio-scanned-key-behavior-trigger.yaml} | 4 +- .../bindings/zmk,soft-off-wakeup-sources.yaml | 4 +- app/module/drivers/kscan/kscan_gpio_direct.c | 7 +- app/module/drivers/kscan/kscan_gpio_matrix.c | 7 +- app/src/behaviors/behavior_soft_off.c | 2 +- ...vior_key.c => gpio_key_behavior_trigger.c} | 100 ++++++++------- app/src/gpio_key_wakeup_trigger.c | 96 ++++++++++++++ ....c => gpio_scanned_key_behavior_trigger.c} | 118 ++++++++---------- app/src/pm.c | 4 +- app/src/wakeup_trigger_key.c | 87 ------------- docs/docs/config/kscan.md | 2 +- docs/docs/features/soft-off.md | 12 +- 21 files changed, 237 insertions(+), 239 deletions(-) delete mode 100644 app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.conf rename app/dts/bindings/{zmk,behavior-key.yaml => zmk,gpio-key-behavior-trigger.yaml} (86%) rename app/dts/bindings/{zmk,wakeup-trigger-key.yaml => zmk,gpio-key-wakeup-trigger.yaml} (90%) rename app/dts/bindings/{zmk,behavior-key-scanned.yaml => zmk,gpio-scanned-key-behavior-trigger.yaml} (86%) rename app/src/{behavior_key.c => gpio_key_behavior_trigger.c} (61%) create mode 100644 app/src/gpio_key_wakeup_trigger.c rename app/src/{behavior_key_scanned.c => gpio_scanned_key_behavior_trigger.c} (57%) delete mode 100644 app/src/wakeup_trigger_key.c diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index bf7cfeef..908800db 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -29,11 +29,11 @@ target_sources(app PRIVATE src/matrix_transform.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) -target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_KEY app PRIVATE src/behavior_key.c) -target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_KEY_SCANNED app PRIVATE src/behavior_key_scanned.c) +target_sources_ifdef(CONFIG_ZMK_GPIO_KEY_BEHAVIOR_TRIGGER app PRIVATE src/gpio_key_behavior_trigger.c) +target_sources_ifdef(CONFIG_ZMK_GPIO_SCANNED_KEY_BEHAVIOR_TRIGGER app PRIVATE src/gpio_scanned_key_behavior_trigger.c) target_sources_ifdef(CONFIG_ZMK_PM_SOFT_OFF app PRIVATE src/pm.c) target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/ext_power_generic.c) -target_sources_ifdef(CONFIG_ZMK_WAKEUP_TRIGGER_KEY app PRIVATE src/wakeup_trigger_key.c) +target_sources_ifdef(CONFIG_ZMK_GPIO_KEY_WAKEUP_TRIGGER app PRIVATE src/gpio_key_wakeup_trigger.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) diff --git a/app/Kconfig b/app/Kconfig index 60a959d4..3ca56793 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -427,10 +427,10 @@ config ZMK_PM_SOFT_OFF bool "Soft-off support" select PM_DEVICE -config ZMK_WAKEUP_TRIGGER_KEY +config ZMK_GPIO_KEY_WAKEUP_TRIGGER bool "Hardware supported wakeup (GPIO)" default y - depends on DT_HAS_ZMK_WAKEUP_TRIGGER_KEY_ENABLED && ZMK_PM_SOFT_OFF + depends on DT_HAS_ZMK_GPIO_KEY_WAKEUP_TRIGGER_ENABLED && ZMK_PM_SOFT_OFF #Power Management endmenu diff --git a/app/Kconfig.behaviors b/app/Kconfig.behaviors index 18fd5c15..ecd06ffb 100644 --- a/app/Kconfig.behaviors +++ b/app/Kconfig.behaviors @@ -1,15 +1,15 @@ # Copyright (c) 2023 The ZMK Contributors # SPDX-License-Identifier: MIT -config ZMK_BEHAVIOR_KEY +config ZMK_GPIO_KEY_BEHAVIOR_TRIGGER bool default y - depends on DT_HAS_ZMK_BEHAVIOR_KEY_ENABLED + depends on DT_HAS_ZMK_GPIO_KEY_BEHAVIOR_TRIGGER_ENABLED -config ZMK_BEHAVIOR_KEY_SCANNED +config ZMK_GPIO_SCANNED_KEY_BEHAVIOR_TRIGGER bool default y - depends on DT_HAS_ZMK_BEHAVIOR_KEY_SCANNED_ENABLED + depends on DT_HAS_ZMK_GPIO_SCANNED_KEY_BEHAVIOR_TRIGGER_ENABLED config ZMK_BEHAVIOR_KEY_TOGGLE bool diff --git a/app/boards/shields/zmk_uno/Kconfig.defconfig b/app/boards/shields/zmk_uno/Kconfig.defconfig index cccca1d2..95602ca7 100644 --- a/app/boards/shields/zmk_uno/Kconfig.defconfig +++ b/app/boards/shields/zmk_uno/Kconfig.defconfig @@ -20,4 +20,7 @@ config ZMK_RGB_UNDERGLOW select WS2812_STRIP select SPI +config ZMK_PM_SOFT_OFF + default y if BOARD_NRF52840DK_NRF52840 + endif diff --git a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.conf b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.conf deleted file mode 100644 index ac92c4d8..00000000 --- a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_ZMK_PM_SOFT_OFF=y \ No newline at end of file diff --git a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay index d08105c6..b068b431 100644 --- a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay +++ b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay @@ -43,7 +43,7 @@ encoder: &qdec0 { }; wakeup_source: wakeup_source { - compatible = "zmk,wakeup-trigger-key"; + compatible = "zmk,gpio-key-wakeup-trigger"; status = "okay"; trigger = <&button0>; @@ -58,7 +58,7 @@ encoder: &qdec0 { }; soft_off_behavior_key { - compatible = "zmk,behavior-key"; + compatible = "zmk,gpio-key-behavior-trigger"; status = "okay"; bindings = <&soft_off>; key = <&button0>; diff --git a/app/dts/behaviors/soft_off.dtsi b/app/dts/behaviors/soft_off.dtsi index c88e1b51..1e58c771 100644 --- a/app/dts/behaviors/soft_off.dtsi +++ b/app/dts/behaviors/soft_off.dtsi @@ -8,7 +8,6 @@ behaviors { /omit-if-no-ref/ soft_off: soft_off { compatible = "zmk,behavior-soft-off"; - label = "SOFTOFF"; #binding-cells = <0>; }; }; diff --git a/app/dts/bindings/zmk,behavior-key.yaml b/app/dts/bindings/zmk,gpio-key-behavior-trigger.yaml similarity index 86% rename from app/dts/bindings/zmk,behavior-key.yaml rename to app/dts/bindings/zmk,gpio-key-behavior-trigger.yaml index ff7a585e..2a1387f0 100644 --- a/app/dts/bindings/zmk,behavior-key.yaml +++ b/app/dts/bindings/zmk,gpio-key-behavior-trigger.yaml @@ -4,7 +4,7 @@ description: | Driver for a dedicated key for invoking a connected behavior. -compatible: "zmk,behavior-key" +compatible: "zmk,gpio-key-behavior-trigger" include: base.yaml @@ -16,7 +16,7 @@ properties: bindings: type: phandle required: true - description: The GPIO key that triggers wake via interrupt + description: The behavior to invoke when the GPIO key is pressed debounce-press-ms: type: int default: 5 diff --git a/app/dts/bindings/zmk,wakeup-trigger-key.yaml b/app/dts/bindings/zmk,gpio-key-wakeup-trigger.yaml similarity index 90% rename from app/dts/bindings/zmk,wakeup-trigger-key.yaml rename to app/dts/bindings/zmk,gpio-key-wakeup-trigger.yaml index fa7636d1..4e16ff33 100644 --- a/app/dts/bindings/zmk,wakeup-trigger-key.yaml +++ b/app/dts/bindings/zmk,gpio-key-wakeup-trigger.yaml @@ -4,7 +4,7 @@ description: | Driver for a dedicated key for waking the device from sleep -compatible: "zmk,wakeup-trigger-key" +compatible: "zmk,gpio-key-wakeup-trigger" include: base.yaml diff --git a/app/dts/bindings/zmk,behavior-key-scanned.yaml b/app/dts/bindings/zmk,gpio-scanned-key-behavior-trigger.yaml similarity index 86% rename from app/dts/bindings/zmk,behavior-key-scanned.yaml rename to app/dts/bindings/zmk,gpio-scanned-key-behavior-trigger.yaml index bdb3abaf..860155dd 100644 --- a/app/dts/bindings/zmk,behavior-key-scanned.yaml +++ b/app/dts/bindings/zmk,gpio-scanned-key-behavior-trigger.yaml @@ -4,7 +4,7 @@ description: | Driver for a dedicated key triggered by matrix scanning for invoking a connected behavior. -compatible: "zmk,behavior-key-scanned" +compatible: "zmk,gpio-scanned-key-behavior-trigger" include: base.yaml @@ -16,7 +16,7 @@ properties: bindings: type: phandle required: true - description: The GPIO key that triggers wake via interrupt + description: The behavior to invoke when the GPIO key is pressed debounce-press-ms: type: int default: 5 diff --git a/app/dts/bindings/zmk,soft-off-wakeup-sources.yaml b/app/dts/bindings/zmk,soft-off-wakeup-sources.yaml index f98039a0..6b55d5d2 100644 --- a/app/dts/bindings/zmk,soft-off-wakeup-sources.yaml +++ b/app/dts/bindings/zmk,soft-off-wakeup-sources.yaml @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT description: | - Description of all possible wakeup-sources from a forces + Description of all possible wakeup-sources from a forced soft-off state. compatible: "zmk,soft-off-wakeup-sources" @@ -11,4 +11,4 @@ properties: wakeup-sources: type: phandles required: true - description: List of wakeup-sources that should be enabled to wake the system from forces soft-off state. + description: List of wakeup-sources that should be enabled to wake the system from forced soft-off state. diff --git a/app/module/drivers/kscan/kscan_gpio_direct.c b/app/module/drivers/kscan/kscan_gpio_direct.c index 2bc35f4c..7cfdb480 100644 --- a/app/module/drivers/kscan/kscan_gpio_direct.c +++ b/app/module/drivers/kscan/kscan_gpio_direct.c @@ -322,8 +322,6 @@ static int kscan_direct_init(const struct device *dev) { #if IS_ENABLED(CONFIG_PM_DEVICE) static int kscan_direct_pm_action(const struct device *dev, enum pm_device_action action) { - int ret = 0; - switch (action) { case PM_DEVICE_ACTION_SUSPEND: kscan_direct_disable(dev); @@ -332,11 +330,8 @@ static int kscan_direct_pm_action(const struct device *dev, enum pm_device_actio kscan_direct_enable(dev); break; default: - ret = -ENOTSUP; - break; + return -ENOTSUP; } - - return ret; } #endif // IS_ENABLED(CONFIG_PM_DEVICE) diff --git a/app/module/drivers/kscan/kscan_gpio_matrix.c b/app/module/drivers/kscan/kscan_gpio_matrix.c index 3917196e..0daf97dc 100644 --- a/app/module/drivers/kscan/kscan_gpio_matrix.c +++ b/app/module/drivers/kscan/kscan_gpio_matrix.c @@ -425,8 +425,6 @@ static int kscan_matrix_init(const struct device *dev) { #if IS_ENABLED(CONFIG_PM_DEVICE) static int kscan_matrix_pm_action(const struct device *dev, enum pm_device_action action) { - int ret = 0; - switch (action) { case PM_DEVICE_ACTION_SUSPEND: kscan_matrix_disable(dev); @@ -435,11 +433,8 @@ static int kscan_matrix_pm_action(const struct device *dev, enum pm_device_actio kscan_matrix_enable(dev); break; default: - ret = -ENOTSUP; - break; + return -ENOTSUP; } - - return ret; } #endif // IS_ENABLED(CONFIG_PM_DEVICE) diff --git a/app/src/behaviors/behavior_soft_off.c b/app/src/behaviors/behavior_soft_off.c index 0f24a644..e6096bb4 100644 --- a/app/src/behaviors/behavior_soft_off.c +++ b/app/src/behaviors/behavior_soft_off.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 The ZMK Contributors + * Copyright (c) 2023 The ZMK Contributors * * SPDX-License-Identifier: MIT */ diff --git a/app/src/behavior_key.c b/app/src/gpio_key_behavior_trigger.c similarity index 61% rename from app/src/behavior_key.c rename to app/src/gpio_key_behavior_trigger.c index 3633ce39..a72f8e48 100644 --- a/app/src/behavior_key.c +++ b/app/src/gpio_key_behavior_trigger.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: MIT */ -#define DT_DRV_COMPAT zmk_behavior_key +#define DT_DRV_COMPAT zmk_gpio_key_behavior_trigger #include #include @@ -19,13 +19,13 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); -struct behavior_key_config { +struct gkbt_config { struct zmk_debounce_config debounce_config; int32_t debounce_scan_period_ms; struct gpio_dt_spec key; }; -struct behavior_key_data { +struct gkbt_data { struct zmk_behavior_binding binding; struct zmk_debounce_state debounce_state; struct gpio_callback key_callback; @@ -34,21 +34,21 @@ struct behavior_key_data { uint32_t read_time; }; -static void bk_enable_interrupt(const struct device *dev) { - const struct behavior_key_config *config = dev->config; +static void gkbt_enable_interrupt(const struct device *dev) { + const struct gkbt_config *config = dev->config; gpio_pin_interrupt_configure_dt(&config->key, GPIO_INT_LEVEL_ACTIVE); } -static void bk_disable_interrupt(const struct device *dev) { - const struct behavior_key_config *config = dev->config; +static void gkbt_disable_interrupt(const struct device *dev) { + const struct gkbt_config *config = dev->config; gpio_pin_interrupt_configure_dt(&config->key, GPIO_INT_DISABLE); } -static void bk_read(const struct device *dev) { - const struct behavior_key_config *config = dev->config; - struct behavior_key_data *data = dev->data; +static void gkbt_read(const struct device *dev) { + const struct gkbt_config *config = dev->config; + struct gkbt_data *data = dev->data; zmk_debounce_update(&data->debounce_state, gpio_pin_get_dt(&config->key), config->debounce_scan_period_ms, &config->debounce_config); @@ -71,65 +71,72 @@ static void bk_read(const struct device *dev) { k_work_reschedule(&data->update_work, K_TIMEOUT_ABS_MS(data->read_time)); } else { - bk_enable_interrupt(dev); + gkbt_enable_interrupt(dev); } } -static void bk_update_work(struct k_work *work) { +static void gkbt_update_work(struct k_work *work) { struct k_work_delayable *dwork = CONTAINER_OF(work, struct k_work_delayable, work); - struct behavior_key_data *data = CONTAINER_OF(dwork, struct behavior_key_data, update_work); - bk_read(data->dev); + struct gkbt_data *data = CONTAINER_OF(dwork, struct gkbt_data, update_work); + gkbt_read(data->dev); } -static void bk_gpio_irq_callback(const struct device *port, struct gpio_callback *cb, - const gpio_port_pins_t pin) { - struct behavior_key_data *data = CONTAINER_OF(cb, struct behavior_key_data, key_callback); +static void gkbt_gpio_irq_callback(const struct device *port, struct gpio_callback *cb, + const gpio_port_pins_t pin) { + struct gkbt_data *data = CONTAINER_OF(cb, struct gkbt_data, key_callback); - bk_disable_interrupt(data->dev); + gkbt_disable_interrupt(data->dev); data->read_time = k_uptime_get(); k_work_reschedule(&data->update_work, K_NO_WAIT); } -static int behavior_key_init(const struct device *dev) { - const struct behavior_key_config *config = dev->config; - struct behavior_key_data *data = dev->data; - - if (!device_is_ready(config->key.port)) { - LOG_ERR("GPIO port is not ready"); - return -ENODEV; - } - - k_work_init_delayable(&data->update_work, bk_update_work); - data->dev = dev; - - gpio_pin_configure_dt(&config->key, GPIO_INPUT); - gpio_init_callback(&data->key_callback, bk_gpio_irq_callback, BIT(config->key.pin)); - gpio_add_callback(config->key.port, &data->key_callback); +static void gkbt_wait_for_key_release(const struct device *dev) { + const struct gkbt_config *config = dev->config; while (gpio_pin_get_dt(&config->key)) { k_sleep(K_MSEC(100)); } +} - bk_enable_interrupt(dev); +static int gkbt_init(const struct device *dev) { + const struct gkbt_config *config = dev->config; + struct gkbt_data *data = dev->data; + + if (!device_is_ready(config->key.port)) { + LOG_ERR("GPIO port %s is not ready", config->key.port->name); + return -ENODEV; + } + + k_work_init_delayable(&data->update_work, gkbt_update_work); + data->dev = dev; + + gpio_pin_configure_dt(&config->key, GPIO_INPUT); + gpio_init_callback(&data->key_callback, gkbt_gpio_irq_callback, BIT(config->key.pin)); + gpio_add_callback(config->key.port, &data->key_callback); + + // Be sure our wakeup key is released before startup continues to avoid wake/sleep loop. + gkbt_wait_for_key_release(dev); + + gkbt_enable_interrupt(dev); return 0; } -static int behavior_key_pm_action(const struct device *dev, enum pm_device_action action) { - const struct behavior_key_config *config = dev->config; - struct behavior_key_data *data = dev->data; +static int gkbt_pm_action(const struct device *dev, enum pm_device_action action) { + const struct gkbt_config *config = dev->config; + struct gkbt_data *data = dev->data; int ret; switch (action) { case PM_DEVICE_ACTION_SUSPEND: - bk_disable_interrupt(dev); + gkbt_disable_interrupt(dev); ret = gpio_remove_callback(config->key.port, &data->key_callback); break; case PM_DEVICE_ACTION_RESUME: ret = gpio_add_callback(config->key.port, &data->key_callback); - bk_enable_interrupt(dev); + gkbt_enable_interrupt(dev); break; default: ret = -ENOTSUP; @@ -139,8 +146,8 @@ static int behavior_key_pm_action(const struct device *dev, enum pm_device_actio return ret; } -#define BK_INST(n) \ - const struct behavior_key_config bk_config_##n = { \ +#define GKBT_INST(n) \ + const struct gkbt_config gkbt_config_##n = { \ .key = GPIO_DT_SPEC_GET(DT_INST_PHANDLE(n, key), gpios), \ .debounce_config = \ { \ @@ -149,11 +156,12 @@ static int behavior_key_pm_action(const struct device *dev, enum pm_device_actio }, \ .debounce_scan_period_ms = DT_INST_PROP(n, debounce_scan_period_ms), \ }; \ - struct behavior_key_data bk_data_##n = { \ + struct gkbt_data gkbt_data_##n = { \ .binding = ZMK_KEYMAP_EXTRACT_BINDING(0, DT_DRV_INST(n)), \ }; \ - PM_DEVICE_DT_INST_DEFINE(n, behavior_key_pm_action); \ - DEVICE_DT_INST_DEFINE(n, behavior_key_init, PM_DEVICE_DT_INST_GET(n), &bk_data_##n, \ - &bk_config_##n, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); + PM_DEVICE_DT_INST_DEFINE(n, gkbt_pm_action); \ + DEVICE_DT_INST_DEFINE(n, gkbt_init, PM_DEVICE_DT_INST_GET(n), &gkbt_data_##n, \ + &gkbt_config_##n, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + NULL); -DT_INST_FOREACH_STATUS_OKAY(BK_INST) +DT_INST_FOREACH_STATUS_OKAY(GKBT_INST) diff --git a/app/src/gpio_key_wakeup_trigger.c b/app/src/gpio_key_wakeup_trigger.c new file mode 100644 index 00000000..ac0c6b22 --- /dev/null +++ b/app/src/gpio_key_wakeup_trigger.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#define DT_DRV_COMPAT zmk_gpio_key_wakeup_trigger + +struct gpio_key_wakeup_trigger_config { + struct gpio_dt_spec trigger; + size_t extra_gpios_count; + struct gpio_dt_spec extra_gpios[]; +}; + +static int zmk_gpio_key_wakeup_trigger_init(const struct device *dev) { +#if IS_ENABLED(CONFIG_PM_DEVICE) + pm_device_init_suspended(dev); + pm_device_wakeup_enable(dev, true); +#endif + + return 0; +} + +#if IS_ENABLED(CONFIG_PM_DEVICE) + +static int gpio_key_wakeup_trigger_pm_resume(const struct device *dev) { + const struct gpio_key_wakeup_trigger_config *config = dev->config; + + int ret = gpio_pin_interrupt_configure_dt(&config->trigger, GPIO_INT_LEVEL_ACTIVE); + if (ret < 0) { + LOG_ERR("Failed to configure wakeup trigger key GPIO pin interrupt (%d)", ret); + goto exit; + } + + for (int i = 0; i < config->extra_gpios_count; i++) { + ret = gpio_pin_configure_dt(&config->extra_gpios[i], GPIO_OUTPUT_ACTIVE); + if (ret < 0) { + LOG_WRN("Failed to set extra GPIO pin active for waker (%d)", ret); + goto exit; + } + } + +exit: + return ret; +} + +static int gpio_key_wakeup_trigger_pm_suspend(const struct device *dev) { + const struct gpio_key_wakeup_trigger_config *config = dev->config; + + int ret = gpio_pin_interrupt_configure_dt(&config->trigger, GPIO_INT_DISABLE); + if (ret < 0) { + LOG_ERR("Failed to configure wakeup trigger key GPIO pin interrupt (%d)", ret); + } + + return ret; +} + +static int gpio_key_wakeup_trigger_pm_action(const struct device *dev, + enum pm_device_action action) { + switch (action) { + case PM_DEVICE_ACTION_RESUME: + return gpio_key_wakeup_trigger_pm_resume(dev); + case PM_DEVICE_ACTION_SUSPEND: + return gpio_key_wakeup_trigger_pm_suspend(dev); + default: + return -ENOTSUP; + } +} + +#endif // IS_ENABLED(CONFIG_PM_DEVICE) + +#define WAKEUP_TRIGGER_EXTRA_GPIO_SPEC(idx, n) \ + GPIO_DT_SPEC_GET_BY_IDX(DT_DRV_INST(n), extra_gpios, idx) + +#define GPIO_KEY_WAKEUP_TRIGGER_INST(n) \ + const struct gpio_key_wakeup_trigger_config wtk_cfg_##n = { \ + .trigger = GPIO_DT_SPEC_GET(DT_INST_PROP(n, trigger), gpios), \ + .extra_gpios = {LISTIFY(DT_PROP_LEN_OR(DT_DRV_INST(n), extra_gpios, 0), \ + WAKEUP_TRIGGER_EXTRA_GPIO_SPEC, (, ), n)}, \ + .extra_gpios_count = DT_PROP_LEN_OR(DT_DRV_INST(n), extra_gpios, 0), \ + }; \ + PM_DEVICE_DT_INST_DEFINE(n, gpio_key_wakeup_trigger_pm_action); \ + DEVICE_DT_INST_DEFINE(n, zmk_gpio_key_wakeup_trigger_init, PM_DEVICE_DT_INST_GET(n), NULL, \ + &wtk_cfg_##n, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_KEY_WAKEUP_TRIGGER_INST) diff --git a/app/src/behavior_key_scanned.c b/app/src/gpio_scanned_key_behavior_trigger.c similarity index 57% rename from app/src/behavior_key_scanned.c rename to app/src/gpio_scanned_key_behavior_trigger.c index c961b292..d27b162b 100644 --- a/app/src/behavior_key_scanned.c +++ b/app/src/gpio_scanned_key_behavior_trigger.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: MIT */ -#define DT_DRV_COMPAT zmk_behavior_key_scanned +#define DT_DRV_COMPAT zmk_gpio_scanned_key_behavior_trigger #include #include @@ -19,45 +19,41 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); -struct behavior_key_scanned_config { +struct gskbt_config { struct zmk_debounce_config debounce_config; int32_t debounce_scan_period_ms; struct gpio_dt_spec key; }; -struct behavior_key_scanned_data { +struct gskbt_data { struct zmk_behavior_binding binding; struct zmk_debounce_state debounce_state; struct gpio_callback key_callback; const struct device *dev; struct k_work_delayable update_work; + struct k_work gpio_trigger_work; uint32_t read_time; + uint32_t trigger_time; bool pin_active; bool active_scan_detected; - struct k_sem sem; }; -static void bks_enable_interrupt(const struct device *dev, bool active_scanning) { - const struct behavior_key_scanned_config *config = dev->config; +static void gskbt_enable_interrupt(const struct device *dev, bool active_scanning) { + const struct gskbt_config *config = dev->config; gpio_pin_interrupt_configure_dt(&config->key, active_scanning ? GPIO_INT_EDGE_TO_ACTIVE : GPIO_INT_LEVEL_ACTIVE); } -static void bks_disable_interrupt(const struct device *dev) { - const struct behavior_key_scanned_config *config = dev->config; +static void gskbt_disable_interrupt(const struct device *dev) { + const struct gskbt_config *config = dev->config; gpio_pin_interrupt_configure_dt(&config->key, GPIO_INT_DISABLE); } -static void bks_read(const struct device *dev) { - const struct behavior_key_scanned_config *config = dev->config; - struct behavior_key_scanned_data *data = dev->data; - - if (k_sem_take(&data->sem, K_NO_WAIT) < 0) { - // k_work_reschedule(&data->update_work, K_NO_WAIT); - return; - } +static void gskbt_read(const struct device *dev) { + const struct gskbt_config *config = dev->config; + struct gskbt_data *data = dev->data; zmk_debounce_update(&data->debounce_state, data->active_scan_detected, config->debounce_scan_period_ms, &config->debounce_config); @@ -81,89 +77,83 @@ static void bks_read(const struct device *dev) { k_work_schedule(&data->update_work, K_TIMEOUT_ABS_MS(data->read_time)); } else { - bks_enable_interrupt(dev, false); + gskbt_enable_interrupt(dev, false); } - - k_sem_give(&data->sem); } -static void bks_update_work(struct k_work *work) { +static void gskbt_update_work(struct k_work *work) { struct k_work_delayable *dwork = CONTAINER_OF(work, struct k_work_delayable, work); - struct behavior_key_scanned_data *data = - CONTAINER_OF(dwork, struct behavior_key_scanned_data, update_work); - bks_read(data->dev); + struct gskbt_data *data = CONTAINER_OF(dwork, struct gskbt_data, update_work); + gskbt_read(data->dev); } -static void bks_gpio_irq_callback(const struct device *port, struct gpio_callback *cb, - const gpio_port_pins_t pin) { - struct behavior_key_scanned_data *data = - CONTAINER_OF(cb, struct behavior_key_scanned_data, key_callback); - const struct behavior_key_scanned_config *config = data->dev->config; +static void gskbt_gpio_interrupt_work(struct k_work *work) { + struct gskbt_data *data = CONTAINER_OF(work, struct gskbt_data, gpio_trigger_work); - uint32_t time = k_uptime_get(); - - if (k_sem_take(&data->sem, K_MSEC(10)) < 0) { - LOG_ERR("FAILED TO TAKE THE SEMAPHORE"); - // Do more? - return; - } - - data->active_scan_detected = true; - data->read_time = time; + const struct gskbt_config *config = data->dev->config; if (!zmk_debounce_is_active(&data->debounce_state)) { - // When we get that very first interrupt, we need to schedule the update checks to fall in - // between each of the real scans, so we can do our checks for state *after* each scan has + // When we get that very first interrupt, we need to schedule the update checks right before + // the next real scan, so we can do our checks for state *after* each scan has // occurred. + data->read_time = data->trigger_time; k_work_reschedule(&data->update_work, - K_TIMEOUT_ABS_MS(time + (config->debounce_scan_period_ms / 2))); - - bks_enable_interrupt(data->dev, true); + K_TIMEOUT_ABS_MS(data->read_time + config->debounce_scan_period_ms - 1)); } - - k_sem_give(&data->sem); } -static int behavior_key_scanned_init(const struct device *dev) { - const struct behavior_key_scanned_config *config = dev->config; - struct behavior_key_scanned_data *data = dev->data; +static void gskbt_gpio_irq_callback(const struct device *port, struct gpio_callback *cb, + const gpio_port_pins_t pin) { + struct gskbt_data *data = CONTAINER_OF(cb, struct gskbt_data, key_callback); + + // LOG_DBG("IRQ"); + data->active_scan_detected = true; + data->trigger_time = k_uptime_get(); + gskbt_enable_interrupt(data->dev, true); + k_work_submit(&data->gpio_trigger_work); +} + +static int gskbt_init(const struct device *dev) { + const struct gskbt_config *config = dev->config; + struct gskbt_data *data = dev->data; if (!device_is_ready(config->key.port)) { LOG_ERR("GPIO port is not ready"); return -ENODEV; } - k_work_init_delayable(&data->update_work, bks_update_work); - k_sem_init(&data->sem, 1, 1); + k_work_init_delayable(&data->update_work, gskbt_update_work); + k_work_init(&data->gpio_trigger_work, gskbt_gpio_interrupt_work); + data->dev = dev; gpio_pin_configure_dt(&config->key, GPIO_INPUT); - gpio_init_callback(&data->key_callback, bks_gpio_irq_callback, BIT(config->key.pin)); + gpio_init_callback(&data->key_callback, gskbt_gpio_irq_callback, BIT(config->key.pin)); gpio_add_callback(config->key.port, &data->key_callback); while (gpio_pin_get_dt(&config->key)) { k_sleep(K_MSEC(100)); } - bks_enable_interrupt(dev, false); + gskbt_enable_interrupt(dev, false); return 0; } -static int behavior_key_scanned_pm_action(const struct device *dev, enum pm_device_action action) { - const struct behavior_key_scanned_config *config = dev->config; - struct behavior_key_scanned_data *data = dev->data; +static int gskbt_pm_action(const struct device *dev, enum pm_device_action action) { + const struct gskbt_config *config = dev->config; + struct gskbt_data *data = dev->data; int ret; switch (action) { case PM_DEVICE_ACTION_SUSPEND: - bks_disable_interrupt(dev); + gskbt_disable_interrupt(dev); ret = gpio_remove_callback(config->key.port, &data->key_callback); break; case PM_DEVICE_ACTION_RESUME: ret = gpio_add_callback(config->key.port, &data->key_callback); - bks_enable_interrupt(dev, false); + gskbt_enable_interrupt(dev, false); break; default: ret = -ENOTSUP; @@ -173,8 +163,8 @@ static int behavior_key_scanned_pm_action(const struct device *dev, enum pm_devi return ret; } -#define BK_INST(n) \ - const struct behavior_key_scanned_config bks_config_##n = { \ +#define GSKBT_INST(n) \ + const struct gskbt_config gskbt_config_##n = { \ .key = GPIO_DT_SPEC_GET(DT_INST_PHANDLE(n, key), gpios), \ .debounce_config = \ { \ @@ -183,12 +173,12 @@ static int behavior_key_scanned_pm_action(const struct device *dev, enum pm_devi }, \ .debounce_scan_period_ms = DT_INST_PROP(n, debounce_scan_period_ms), \ }; \ - struct behavior_key_scanned_data bks_data_##n = { \ + struct gskbt_data gskbt_data_##n = { \ .binding = ZMK_KEYMAP_EXTRACT_BINDING(0, DT_DRV_INST(n)), \ }; \ - PM_DEVICE_DT_INST_DEFINE(n, behavior_key_scanned_pm_action); \ - DEVICE_DT_INST_DEFINE(n, behavior_key_scanned_init, PM_DEVICE_DT_INST_GET(n), &bks_data_##n, \ - &bks_config_##n, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + PM_DEVICE_DT_INST_DEFINE(n, gskbt_pm_action); \ + DEVICE_DT_INST_DEFINE(n, gskbt_init, PM_DEVICE_DT_INST_GET(n), &gskbt_data_##n, \ + &gskbt_config_##n, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ NULL); -DT_INST_FOREACH_STATUS_OKAY(BK_INST) +DT_INST_FOREACH_STATUS_OKAY(GSKBT_INST) diff --git a/app/src/pm.c b/app/src/pm.c index a78b6ae5..41d72eee 100644 --- a/app/src/pm.c +++ b/app/src/pm.c @@ -41,10 +41,10 @@ int zmk_pm_soft_off(void) { // from normal "inactive goes to sleep" behavior, so disable them as wakeup devices // and then suspend them so we're ready to take over setting up our system // and then putting it into an off state. + LOG_DBG("soft-on-off pressed cb: suspend devices"); for (int i = 0; i < device_count; i++) { const struct device *dev = &devs[i]; - LOG_DBG("soft-on-off pressed cb: suspend device"); if (pm_device_wakeup_is_enabled(dev)) { pm_device_wakeup_enable(dev, false); } @@ -60,6 +60,6 @@ int zmk_pm_soft_off(void) { } #endif // HAS_WAKERS - LOG_DBG("soft-on-off interrupt: go to sleep"); + LOG_DBG("soft-off: go to sleep"); return pm_state_force(0U, &(struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0}); } diff --git a/app/src/wakeup_trigger_key.c b/app/src/wakeup_trigger_key.c deleted file mode 100644 index 0cc4f250..00000000 --- a/app/src/wakeup_trigger_key.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2023 The ZMK Contributors - * - * SPDX-License-Identifier: MIT - */ - -#include -#include -#include -#include -#include - -#include - -LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); - -#define DT_DRV_COMPAT zmk_wakeup_trigger_key - -struct wakeup_trigger_key_config { - struct gpio_dt_spec trigger; - size_t extra_gpios_count; - struct gpio_dt_spec extra_gpios[]; -}; - -static int zmk_wakeup_trigger_key_init(const struct device *dev) { -#if IS_ENABLED(CONFIG_PM_DEVICE) - pm_device_init_suspended(dev); - pm_device_wakeup_enable(dev, true); -#endif - - return 0; -} - -#if IS_ENABLED(CONFIG_PM_DEVICE) - -static int wakeup_trigger_key_pm_action(const struct device *dev, enum pm_device_action action) { - const struct wakeup_trigger_key_config *config = dev->config; - int ret = 0; - - switch (action) { - case PM_DEVICE_ACTION_RESUME: - ret = gpio_pin_interrupt_configure_dt(&config->trigger, GPIO_INT_LEVEL_ACTIVE); - if (ret < 0) { - LOG_ERR("Failed to configure wakeup trigger key GPIO pin interrupt (%d)", ret); - return ret; - } - - for (int i = 0; i < config->extra_gpios_count; i++) { - ret = gpio_pin_configure_dt(&config->extra_gpios[i], GPIO_OUTPUT_ACTIVE); - if (ret < 0) { - LOG_WRN("Failed to set extra GPIO pin active for waker (%d)", ret); - } - } - break; - case PM_DEVICE_ACTION_SUSPEND: - - ret = gpio_pin_interrupt_configure_dt(&config->trigger, GPIO_INT_DISABLE); - if (ret < 0) { - LOG_ERR("Failed to configure wakeup trigger key GPIO pin interrupt (%d)", ret); - return ret; - } - break; - default: - ret = -ENOTSUP; - break; - } - - return ret; -} - -#endif // IS_ENABLED(CONFIG_PM_DEVICE) - -#define WAKEUP_TRIGGER_EXTRA_GPIO_SPEC(idx, n) \ - GPIO_DT_SPEC_GET_BY_IDX(DT_DRV_INST(n), extra_gpios, idx) - -#define WAKEUP_TRIGGER_KEY_INST(n) \ - const struct wakeup_trigger_key_config wtk_cfg_##n = { \ - .trigger = GPIO_DT_SPEC_GET(DT_INST_PROP(n, trigger), gpios), \ - .extra_gpios = {LISTIFY(DT_PROP_LEN_OR(DT_DRV_INST(n), extra_gpios, 0), \ - WAKEUP_TRIGGER_EXTRA_GPIO_SPEC, (, ), n)}, \ - .extra_gpios_count = DT_PROP_LEN_OR(DT_DRV_INST(n), extra_gpios, 0), \ - }; \ - PM_DEVICE_DT_INST_DEFINE(n, wakeup_trigger_key_pm_action); \ - DEVICE_DT_INST_DEFINE(n, zmk_wakeup_trigger_key_init, PM_DEVICE_DT_INST_GET(n), NULL, \ - &wtk_cfg_##n, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); - -DT_INST_FOREACH_STATUS_OKAY(WAKEUP_TRIGGER_KEY_INST) diff --git a/docs/docs/config/kscan.md b/docs/docs/config/kscan.md index 3076edc0..4a3954f9 100644 --- a/docs/docs/config/kscan.md +++ b/docs/docs/config/kscan.md @@ -455,7 +455,7 @@ Note that the entire addressable space does not need to be mapped. }; kscan0: kscan { - compatible = "zmk,kscan-gpio-charlieplex";k + compatible = "zmk,kscan-gpio-charlieplex"; wakeup-source; interrupt-gpios = <&pro_micro 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN) >; diff --git a/docs/docs/features/soft-off.md b/docs/docs/features/soft-off.md index a3a5d7a1..6b6b5cf4 100644 --- a/docs/docs/features/soft-off.md +++ b/docs/docs/features/soft-off.md @@ -79,7 +79,7 @@ In this case, we will be creating a dedicated instance of the [Soft Off Behavior }; soft_off_behavior_key { - compatible = "zmk,behavior-key"; + compatible = "zmk,gpio-key-behavior-trigger"; bindings = <&hw_soft_off>; key = <&wakeup_key>; }; @@ -88,7 +88,7 @@ In this case, we will be creating a dedicated instance of the [Soft Off Behavior Here are the properties for the behavior key node: -- The `compatible` property for the node must be `zmk,behavior-key`. +- The `compatible` property for the node must be `zmk,gpio-key-behavior-trigger`. - The `bindings` property is a phandle to the soft off behavior defined above. - The `key` property is a phandle to the GPIO key defined earlier. @@ -97,7 +97,7 @@ If you have set up your on/off to be controlled by a matrix-integrated combo, th ``` / { soft_off_behavior_key { - compatible = "zmk,behavior-key-scanned"; + compatible = "zmk,gpio-scanned-key-behavior-trigger"; status = "okay"; bindings = <&hw_soft_off>; key = <&wakeup_key>; @@ -105,7 +105,7 @@ If you have set up your on/off to be controlled by a matrix-integrated combo, th }; ``` -Note that the only difference from the `soft_off_behavior_key` definition for GPIO keys above is the `compatible` value of `zmk,behavior-key-scanned`. +Note that the only difference from the `soft_off_behavior_key` definition for GPIO keys above is the `compatible` value of `zmk,gpio-scanned-key-behavior-trigger`. #### Wakeup Sources @@ -131,7 +131,7 @@ Next, we need to add another device which will be enabled only when the keyboard ``` / { wakeup_source: wakeup_source { - compatible = "zmk,wakeup-trigger-key"; + compatible = "zmk,gpio-key-wakeup-trigger"; trigger = <&wakeup_key>; wakeup-source; @@ -141,7 +141,7 @@ Next, we need to add another device which will be enabled only when the keyboard Here are the properties for the node: -- The `compatible` property for the node must be `zmk,wakeup-trigger-key`. +- The `compatible` property for the node must be `zmk,gpio-key-wakeup-trigger`. - The `trigger` property is a phandle to the GPIO key defined earlier. - The `wakeup-source` property signals to Zephyr this device should not be suspended during the shutdown procedure. - An optional `output-gpios` property contains a list of GPIO pins (including the appropriate flags) to set active before going into power off, if needed to ensure the GPIO pin will trigger properly to wake the keyboard. This is only needed for matrix integrated combos. For those keyboards, the list should include the matrix output needs needed so the combo hardware is properly "driven" when the keyboard is off. From 5ebe924e941ba00e81d1c66ad2333e6a73826754 Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Fri, 29 Dec 2023 15:03:14 -0800 Subject: [PATCH 098/127] chore: Various soft-off review fixes * Code style to avoid goto. * Enable pm.c compilation via dedicated Kconfig flag. * Comment wakeup trigger PM behavior. --- app/CMakeLists.txt | 2 +- app/Kconfig | 4 ++++ app/module/drivers/kscan/kscan_gpio_direct.c | 6 ++---- app/module/drivers/kscan/kscan_gpio_matrix.c | 6 ++---- app/src/gpio_key_wakeup_trigger.c | 16 +++++++++++++--- app/src/pm.c | 4 ++++ 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 908800db..a56a63b3 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -31,7 +31,7 @@ target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/wpm.c) target_sources(app PRIVATE src/event_manager.c) target_sources_ifdef(CONFIG_ZMK_GPIO_KEY_BEHAVIOR_TRIGGER app PRIVATE src/gpio_key_behavior_trigger.c) target_sources_ifdef(CONFIG_ZMK_GPIO_SCANNED_KEY_BEHAVIOR_TRIGGER app PRIVATE src/gpio_scanned_key_behavior_trigger.c) -target_sources_ifdef(CONFIG_ZMK_PM_SOFT_OFF app PRIVATE src/pm.c) +target_sources_ifdef(CONFIG_ZMK_PM app PRIVATE src/pm.c) target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/ext_power_generic.c) target_sources_ifdef(CONFIG_ZMK_GPIO_KEY_WAKEUP_TRIGGER app PRIVATE src/gpio_key_wakeup_trigger.c) target_sources(app PRIVATE src/events/activity_state_changed.c) diff --git a/app/Kconfig b/app/Kconfig index 3ca56793..df84d97d 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -423,8 +423,12 @@ config ZMK_EXT_POWER bool "Enable support to control external power output" default y +config ZMK_PM + bool + config ZMK_PM_SOFT_OFF bool "Soft-off support" + select ZMK_PM select PM_DEVICE config ZMK_GPIO_KEY_WAKEUP_TRIGGER diff --git a/app/module/drivers/kscan/kscan_gpio_direct.c b/app/module/drivers/kscan/kscan_gpio_direct.c index 7cfdb480..a10190da 100644 --- a/app/module/drivers/kscan/kscan_gpio_direct.c +++ b/app/module/drivers/kscan/kscan_gpio_direct.c @@ -324,11 +324,9 @@ static int kscan_direct_init(const struct device *dev) { static int kscan_direct_pm_action(const struct device *dev, enum pm_device_action action) { switch (action) { case PM_DEVICE_ACTION_SUSPEND: - kscan_direct_disable(dev); - break; + return kscan_direct_disable(dev); case PM_DEVICE_ACTION_RESUME: - kscan_direct_enable(dev); - break; + return kscan_direct_enable(dev); default: return -ENOTSUP; } diff --git a/app/module/drivers/kscan/kscan_gpio_matrix.c b/app/module/drivers/kscan/kscan_gpio_matrix.c index 0daf97dc..8a3c39f2 100644 --- a/app/module/drivers/kscan/kscan_gpio_matrix.c +++ b/app/module/drivers/kscan/kscan_gpio_matrix.c @@ -427,11 +427,9 @@ static int kscan_matrix_init(const struct device *dev) { static int kscan_matrix_pm_action(const struct device *dev, enum pm_device_action action) { switch (action) { case PM_DEVICE_ACTION_SUSPEND: - kscan_matrix_disable(dev); - break; + return kscan_matrix_disable(dev); case PM_DEVICE_ACTION_RESUME: - kscan_matrix_enable(dev); - break; + return kscan_matrix_enable(dev); default: return -ENOTSUP; } diff --git a/app/src/gpio_key_wakeup_trigger.c b/app/src/gpio_key_wakeup_trigger.c index ac0c6b22..308c4973 100644 --- a/app/src/gpio_key_wakeup_trigger.c +++ b/app/src/gpio_key_wakeup_trigger.c @@ -39,18 +39,17 @@ static int gpio_key_wakeup_trigger_pm_resume(const struct device *dev) { int ret = gpio_pin_interrupt_configure_dt(&config->trigger, GPIO_INT_LEVEL_ACTIVE); if (ret < 0) { LOG_ERR("Failed to configure wakeup trigger key GPIO pin interrupt (%d)", ret); - goto exit; + return ret; } for (int i = 0; i < config->extra_gpios_count; i++) { ret = gpio_pin_configure_dt(&config->extra_gpios[i], GPIO_OUTPUT_ACTIVE); if (ret < 0) { LOG_WRN("Failed to set extra GPIO pin active for waker (%d)", ret); - goto exit; + return ret; } } -exit: return ret; } @@ -62,9 +61,20 @@ static int gpio_key_wakeup_trigger_pm_suspend(const struct device *dev) { LOG_ERR("Failed to configure wakeup trigger key GPIO pin interrupt (%d)", ret); } + for (int i = 0; i < config->extra_gpios_count; i++) { + ret = gpio_pin_configure_dt(&config->extra_gpios[i], GPIO_DISCONNECTED); + if (ret < 0) { + LOG_WRN("Failed to set extra GPIO pin disconnected for waker (%d)", ret); + return ret; + } + } + return ret; } +// The waker is "backwards", in as much as it is designed to be resumed/enabled immediately +// before a soft-off state is entered, so it can wake the device from that state later. +// So this waker correctly resumes and is ready to wake the device later. static int gpio_key_wakeup_trigger_pm_action(const struct device *dev, enum pm_device_action action) { switch (action) { diff --git a/app/src/pm.c b/app/src/pm.c index 41d72eee..a4599ac8 100644 --- a/app/src/pm.c +++ b/app/src/pm.c @@ -15,6 +15,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include +#if IS_ENABLED(CONFIG_ZMK_PM_SOFT_OFF) + #define HAS_WAKERS DT_HAS_COMPAT_STATUS_OKAY(zmk_soft_off_wakeup_sources) #if HAS_WAKERS @@ -63,3 +65,5 @@ int zmk_pm_soft_off(void) { LOG_DBG("soft-off: go to sleep"); return pm_state_force(0U, &(struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0}); } + +#endif // IS_ENABLED(CONFIG_ZMK_PM_SOFT_OFF) \ No newline at end of file From 933fdcd36400ea9d2f73284ff5936e0c6cefe879 Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Fri, 29 Dec 2023 16:28:22 -0800 Subject: [PATCH 099/127] refactor(pm): Remove scanned behavior trigger. * Remove the painful scanned behavior trigger for now, future enhancement will restore this high level functionality using kscan directly. --- app/CMakeLists.txt | 1 - app/Kconfig.behaviors | 5 - ...zmk,gpio-scanned-key-behavior-trigger.yaml | 31 --- app/src/gpio_scanned_key_behavior_trigger.c | 184 ------------------ docs/docs/features/soft-off.md | 17 +- 5 files changed, 2 insertions(+), 236 deletions(-) delete mode 100644 app/dts/bindings/zmk,gpio-scanned-key-behavior-trigger.yaml delete mode 100644 app/src/gpio_scanned_key_behavior_trigger.c diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index a56a63b3..4ee9135d 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -30,7 +30,6 @@ 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) target_sources_ifdef(CONFIG_ZMK_GPIO_KEY_BEHAVIOR_TRIGGER app PRIVATE src/gpio_key_behavior_trigger.c) -target_sources_ifdef(CONFIG_ZMK_GPIO_SCANNED_KEY_BEHAVIOR_TRIGGER app PRIVATE src/gpio_scanned_key_behavior_trigger.c) target_sources_ifdef(CONFIG_ZMK_PM app PRIVATE src/pm.c) target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/ext_power_generic.c) target_sources_ifdef(CONFIG_ZMK_GPIO_KEY_WAKEUP_TRIGGER app PRIVATE src/gpio_key_wakeup_trigger.c) diff --git a/app/Kconfig.behaviors b/app/Kconfig.behaviors index ecd06ffb..6abdbddd 100644 --- a/app/Kconfig.behaviors +++ b/app/Kconfig.behaviors @@ -6,11 +6,6 @@ config ZMK_GPIO_KEY_BEHAVIOR_TRIGGER default y depends on DT_HAS_ZMK_GPIO_KEY_BEHAVIOR_TRIGGER_ENABLED -config ZMK_GPIO_SCANNED_KEY_BEHAVIOR_TRIGGER - bool - default y - depends on DT_HAS_ZMK_GPIO_SCANNED_KEY_BEHAVIOR_TRIGGER_ENABLED - config ZMK_BEHAVIOR_KEY_TOGGLE bool default y diff --git a/app/dts/bindings/zmk,gpio-scanned-key-behavior-trigger.yaml b/app/dts/bindings/zmk,gpio-scanned-key-behavior-trigger.yaml deleted file mode 100644 index 860155dd..00000000 --- a/app/dts/bindings/zmk,gpio-scanned-key-behavior-trigger.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2023 The ZMK Contributors -# SPDX-License-Identifier: MIT - -description: | - Driver for a dedicated key triggered by matrix scanning for invoking a connected behavior. - -compatible: "zmk,gpio-scanned-key-behavior-trigger" - -include: base.yaml - -properties: - key: - type: phandle - required: true - description: The GPIO key that triggers wake via interrupt - bindings: - type: phandle - required: true - description: The behavior to invoke when the GPIO key is pressed - debounce-press-ms: - type: int - default: 5 - description: Debounce time for key press in milliseconds. Use 0 for eager debouncing. - debounce-release-ms: - type: int - default: 5 - description: Debounce time for key release in milliseconds. - debounce-scan-period-ms: - type: int - default: 1 - description: Time between reads in milliseconds when any key is pressed. diff --git a/app/src/gpio_scanned_key_behavior_trigger.c b/app/src/gpio_scanned_key_behavior_trigger.c deleted file mode 100644 index d27b162b..00000000 --- a/app/src/gpio_scanned_key_behavior_trigger.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2023 The ZMK Contributors - * - * SPDX-License-Identifier: MIT - */ - -#define DT_DRV_COMPAT zmk_gpio_scanned_key_behavior_trigger - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); - -struct gskbt_config { - struct zmk_debounce_config debounce_config; - int32_t debounce_scan_period_ms; - struct gpio_dt_spec key; -}; - -struct gskbt_data { - struct zmk_behavior_binding binding; - struct zmk_debounce_state debounce_state; - struct gpio_callback key_callback; - const struct device *dev; - struct k_work_delayable update_work; - struct k_work gpio_trigger_work; - uint32_t read_time; - uint32_t trigger_time; - bool pin_active; - bool active_scan_detected; -}; - -static void gskbt_enable_interrupt(const struct device *dev, bool active_scanning) { - const struct gskbt_config *config = dev->config; - - gpio_pin_interrupt_configure_dt(&config->key, active_scanning ? GPIO_INT_EDGE_TO_ACTIVE - : GPIO_INT_LEVEL_ACTIVE); -} - -static void gskbt_disable_interrupt(const struct device *dev) { - const struct gskbt_config *config = dev->config; - - gpio_pin_interrupt_configure_dt(&config->key, GPIO_INT_DISABLE); -} - -static void gskbt_read(const struct device *dev) { - const struct gskbt_config *config = dev->config; - struct gskbt_data *data = dev->data; - - zmk_debounce_update(&data->debounce_state, data->active_scan_detected, - config->debounce_scan_period_ms, &config->debounce_config); - - if (zmk_debounce_get_changed(&data->debounce_state)) { - const bool pressed = zmk_debounce_is_pressed(&data->debounce_state); - - struct zmk_behavior_binding_event event = {.position = INT32_MAX, - .timestamp = k_uptime_get()}; - - if (pressed) { - behavior_keymap_binding_pressed(&data->binding, event); - } else { - behavior_keymap_binding_released(&data->binding, event); - } - } - - if (zmk_debounce_is_active(&data->debounce_state)) { - data->active_scan_detected = false; - data->read_time += config->debounce_scan_period_ms; - - k_work_schedule(&data->update_work, K_TIMEOUT_ABS_MS(data->read_time)); - } else { - gskbt_enable_interrupt(dev, false); - } -} - -static void gskbt_update_work(struct k_work *work) { - struct k_work_delayable *dwork = CONTAINER_OF(work, struct k_work_delayable, work); - struct gskbt_data *data = CONTAINER_OF(dwork, struct gskbt_data, update_work); - gskbt_read(data->dev); -} - -static void gskbt_gpio_interrupt_work(struct k_work *work) { - struct gskbt_data *data = CONTAINER_OF(work, struct gskbt_data, gpio_trigger_work); - - const struct gskbt_config *config = data->dev->config; - - if (!zmk_debounce_is_active(&data->debounce_state)) { - // When we get that very first interrupt, we need to schedule the update checks right before - // the next real scan, so we can do our checks for state *after* each scan has - // occurred. - data->read_time = data->trigger_time; - k_work_reschedule(&data->update_work, - K_TIMEOUT_ABS_MS(data->read_time + config->debounce_scan_period_ms - 1)); - } -} - -static void gskbt_gpio_irq_callback(const struct device *port, struct gpio_callback *cb, - const gpio_port_pins_t pin) { - struct gskbt_data *data = CONTAINER_OF(cb, struct gskbt_data, key_callback); - - // LOG_DBG("IRQ"); - data->active_scan_detected = true; - data->trigger_time = k_uptime_get(); - gskbt_enable_interrupt(data->dev, true); - k_work_submit(&data->gpio_trigger_work); -} - -static int gskbt_init(const struct device *dev) { - const struct gskbt_config *config = dev->config; - struct gskbt_data *data = dev->data; - - if (!device_is_ready(config->key.port)) { - LOG_ERR("GPIO port is not ready"); - return -ENODEV; - } - - k_work_init_delayable(&data->update_work, gskbt_update_work); - k_work_init(&data->gpio_trigger_work, gskbt_gpio_interrupt_work); - - data->dev = dev; - - gpio_pin_configure_dt(&config->key, GPIO_INPUT); - gpio_init_callback(&data->key_callback, gskbt_gpio_irq_callback, BIT(config->key.pin)); - gpio_add_callback(config->key.port, &data->key_callback); - - while (gpio_pin_get_dt(&config->key)) { - k_sleep(K_MSEC(100)); - } - - gskbt_enable_interrupt(dev, false); - - return 0; -} - -static int gskbt_pm_action(const struct device *dev, enum pm_device_action action) { - const struct gskbt_config *config = dev->config; - struct gskbt_data *data = dev->data; - - int ret; - - switch (action) { - case PM_DEVICE_ACTION_SUSPEND: - gskbt_disable_interrupt(dev); - ret = gpio_remove_callback(config->key.port, &data->key_callback); - break; - case PM_DEVICE_ACTION_RESUME: - ret = gpio_add_callback(config->key.port, &data->key_callback); - gskbt_enable_interrupt(dev, false); - break; - default: - ret = -ENOTSUP; - break; - } - - return ret; -} - -#define GSKBT_INST(n) \ - const struct gskbt_config gskbt_config_##n = { \ - .key = GPIO_DT_SPEC_GET(DT_INST_PHANDLE(n, key), gpios), \ - .debounce_config = \ - { \ - .debounce_press_ms = DT_INST_PROP(n, debounce_press_ms), \ - .debounce_release_ms = DT_INST_PROP(n, debounce_release_ms), \ - }, \ - .debounce_scan_period_ms = DT_INST_PROP(n, debounce_scan_period_ms), \ - }; \ - struct gskbt_data gskbt_data_##n = { \ - .binding = ZMK_KEYMAP_EXTRACT_BINDING(0, DT_DRV_INST(n)), \ - }; \ - PM_DEVICE_DT_INST_DEFINE(n, gskbt_pm_action); \ - DEVICE_DT_INST_DEFINE(n, gskbt_init, PM_DEVICE_DT_INST_GET(n), &gskbt_data_##n, \ - &gskbt_config_##n, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ - NULL); - -DT_INST_FOREACH_STATUS_OKAY(GSKBT_INST) diff --git a/docs/docs/features/soft-off.md b/docs/docs/features/soft-off.md index 6b6b5cf4..370a3880 100644 --- a/docs/docs/features/soft-off.md +++ b/docs/docs/features/soft-off.md @@ -37,7 +37,7 @@ The simplest way to achieve this is with a push button between a GPIO pin and gr #### Matrix-Integrated Hardware Combo -Another, more complicated option is to tie two of the switch outputs in the matrix together through an AND gate and connect that to the dedicated GPIO pin. This way you can use a key combination in your existing keyboard matrix to trigger soft on/off. To make this work best, the two switches used should both be driven by the same matrix input pin so that both will be active simultaneously on the AND gate inputs. The alternative is to use a combination of diodes and capacitors to ensure both pins are active/high at the same time even if scanning sets them high at different times. +Another, more complicated option is to tie two of the switch outputs in the matrix together through an AND gate and connect that to the dedicated GPIO pin. This way you can use a key combination in your existing keyboard matrix to trigger soft on/off. To make this work best, the two switches used should both be driven by the same matrix input pin so that both will be active simultaneously on the AND gate inputs. The alternative is to use a combination of diodes and capacitors to ensure both pins are active/high at the same time even if scanning sets them high at different times. Support for this mode will be coming soon. ### Firmware Changes @@ -92,20 +92,7 @@ Here are the properties for the behavior key node: - The `bindings` property is a phandle to the soft off behavior defined above. - The `key` property is a phandle to the GPIO key defined earlier. -If you have set up your on/off to be controlled by a matrix-integrated combo, the behavior key needs use a different driver that will handle detecting the pressed state when the pin is toggled by the other matrix kscan driver: - -``` -/ { - soft_off_behavior_key { - compatible = "zmk,gpio-scanned-key-behavior-trigger"; - status = "okay"; - bindings = <&hw_soft_off>; - key = <&wakeup_key>; - }; -}; -``` - -Note that the only difference from the `soft_off_behavior_key` definition for GPIO keys above is the `compatible` value of `zmk,gpio-scanned-key-behavior-trigger`. +If you have set up your on/off to be controlled by a matrix-integrated combo, the behavior key will need to be integrated into your existing kscan setup. Full details to come when this is supported. #### Wakeup Sources From e78b25a445b5bfc4b0c9b979d68964729c3e8fa1 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Sun, 31 Dec 2023 00:34:20 +0000 Subject: [PATCH 100/127] feat(kscan): Direct kscan driver can use gpio-keys. * Allow specifying direct kscan driver pins using gpio-key list as an alternative. --- app/module/drivers/kscan/kscan_gpio_direct.c | 11 +++++++++-- .../dts/bindings/kscan/zmk,kscan-gpio-direct.yaml | 6 +++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/module/drivers/kscan/kscan_gpio_direct.c b/app/module/drivers/kscan/kscan_gpio_direct.c index a10190da..e05eb2f3 100644 --- a/app/module/drivers/kscan/kscan_gpio_direct.c +++ b/app/module/drivers/kscan/kscan_gpio_direct.c @@ -42,9 +42,14 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #define COND_POLL_OR_INTERRUPTS(pollcode, intcode) \ COND_CODE_1(CONFIG_ZMK_KSCAN_DIRECT_POLLING, pollcode, intcode) -#define INST_INPUTS_LEN(n) DT_INST_PROP_LEN(n, input_gpios) +#define INST_INPUTS_LEN(n) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, input_gpios), (DT_INST_PROP_LEN(n, input_gpios)), \ + (DT_INST_PROP_LEN(n, input_keys))) + #define KSCAN_DIRECT_INPUT_CFG_INIT(idx, inst_idx) \ KSCAN_GPIO_GET_BY_IDX(DT_DRV_INST(inst_idx), input_gpios, idx) +#define KSCAN_KEY_DIRECT_INPUT_CFG_INIT(idx, inst_idx) \ + KSCAN_GPIO_GET_BY_IDX(DT_INST_PROP_BY_IDX(inst_idx, input_keys, idx), gpios, 0) struct kscan_direct_irq_callback { const struct device *dev; @@ -347,7 +352,9 @@ static const struct kscan_driver_api kscan_direct_api = { "ZMK_KSCAN_DEBOUNCE_RELEASE_MS or debounce-release-ms is too large"); \ \ static struct kscan_gpio kscan_direct_inputs_##n[] = { \ - LISTIFY(INST_INPUTS_LEN(n), KSCAN_DIRECT_INPUT_CFG_INIT, (, ), n)}; \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, input_gpios), \ + (LISTIFY(INST_INPUTS_LEN(n), KSCAN_DIRECT_INPUT_CFG_INIT, (, ), n)), \ + (LISTIFY(INST_INPUTS_LEN(n), KSCAN_KEY_DIRECT_INPUT_CFG_INIT, (, ), n)))}; \ \ static struct zmk_debounce_state kscan_direct_state_##n[INST_INPUTS_LEN(n)]; \ \ diff --git a/app/module/dts/bindings/kscan/zmk,kscan-gpio-direct.yaml b/app/module/dts/bindings/kscan/zmk,kscan-gpio-direct.yaml index f477b591..4953d5cf 100644 --- a/app/module/dts/bindings/kscan/zmk,kscan-gpio-direct.yaml +++ b/app/module/dts/bindings/kscan/zmk,kscan-gpio-direct.yaml @@ -10,7 +10,11 @@ include: kscan.yaml properties: input-gpios: type: phandle-array - required: true + required: false + input-keys: + type: phandles + required: false + description: List of gpio-key references debounce-period: type: int required: false From a0ad1d4c9402fbfe5e3dee8996057150a3f0f209 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Sat, 30 Dec 2023 16:38:52 -0800 Subject: [PATCH 101/127] refactor: Add kscan sideband behavior driver * Instead of gpio key behavior trigger, add new kscan driver that decorates/wraps a given kscan driver and will invoke basic system behavior assigned to a given row + column, without the need for keymap mapping in the matrix transform, bypassing keymaps entirely. --- app/CMakeLists.txt | 2 +- app/Kconfig | 6 + app/Kconfig.behaviors | 5 - .../boards/nrf52840dk_nrf52840.overlay | 19 +- .../kscan/zmk,kscan-sideband-behaviors.yaml | 29 +++ .../zmk,gpio-key-behavior-trigger.yaml | 31 ---- app/src/gpio_key_behavior_trigger.c | 167 ------------------ app/src/kscan_sideband_behaviors.c | 142 +++++++++++++++ 8 files changed, 192 insertions(+), 209 deletions(-) create mode 100644 app/dts/bindings/kscan/zmk,kscan-sideband-behaviors.yaml delete mode 100644 app/dts/bindings/zmk,gpio-key-behavior-trigger.yaml delete mode 100644 app/src/gpio_key_behavior_trigger.c create mode 100644 app/src/kscan_sideband_behaviors.c diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 4ee9135d..2abf943f 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -25,11 +25,11 @@ target_sources(app PRIVATE src/stdlib.c) target_sources(app PRIVATE src/activity.c) target_sources(app PRIVATE src/behavior.c) target_sources(app PRIVATE src/kscan.c) +target_sources_ifdef(CONFIG_ZMK_KSCAN_SIDEBAND_BEHAVIORS app PRIVATE src/kscan_sideband_behaviors.c) target_sources(app PRIVATE src/matrix_transform.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) -target_sources_ifdef(CONFIG_ZMK_GPIO_KEY_BEHAVIOR_TRIGGER app PRIVATE src/gpio_key_behavior_trigger.c) target_sources_ifdef(CONFIG_ZMK_PM app PRIVATE src/pm.c) target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/ext_power_generic.c) target_sources_ifdef(CONFIG_ZMK_GPIO_KEY_WAKEUP_TRIGGER app PRIVATE src/gpio_key_wakeup_trigger.c) diff --git a/app/Kconfig b/app/Kconfig index df84d97d..15c31375 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -512,6 +512,12 @@ config ZMK_KSCAN_EVENT_QUEUE_SIZE endif # ZMK_KSCAN +config ZMK_KSCAN_SIDEBAND_BEHAVIORS + bool + default y + depends on DT_HAS_ZMK_KSCAN_SIDEBAND_BEHAVIORS_ENABLED + select KSCAN + menu "Logging" config ZMK_LOGGING_MINIMAL diff --git a/app/Kconfig.behaviors b/app/Kconfig.behaviors index 6abdbddd..c9754bf7 100644 --- a/app/Kconfig.behaviors +++ b/app/Kconfig.behaviors @@ -1,11 +1,6 @@ # Copyright (c) 2023 The ZMK Contributors # SPDX-License-Identifier: MIT -config ZMK_GPIO_KEY_BEHAVIOR_TRIGGER - bool - default y - depends on DT_HAS_ZMK_GPIO_KEY_BEHAVIOR_TRIGGER_ENABLED - config ZMK_BEHAVIOR_KEY_TOGGLE bool default y diff --git a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay index b068b431..47b67dc0 100644 --- a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay +++ b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay @@ -57,10 +57,19 @@ encoder: &qdec0 { wakeup-sources = <&wakeup_source>; }; - soft_off_behavior_key { - compatible = "zmk,gpio-key-behavior-trigger"; - status = "okay"; - bindings = <&soft_off>; - key = <&button0>; + soft_off_direct_kscan: soft_off_direct_kscan { + compatible = "zmk,kscan-gpio-direct"; + input-keys = <&button0>; }; + + soft_off_sideband_behaviors { + compatible = "zmk,kscan-sideband-behaviors"; + kscan = <&soft_off_direct_kscan>; + soft_off { + row = <0>; + column = <0>; + bindings = <&soft_off>; + }; + }; + }; \ No newline at end of file diff --git a/app/dts/bindings/kscan/zmk,kscan-sideband-behaviors.yaml b/app/dts/bindings/kscan/zmk,kscan-sideband-behaviors.yaml new file mode 100644 index 00000000..7289b9e1 --- /dev/null +++ b/app/dts/bindings/kscan/zmk,kscan-sideband-behaviors.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2023, The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: | + kscan sideband behavior runner. Only basic system behavior should be used, + since no keymap processing occurs when using them. + +compatible: "zmk,kscan-sideband-behaviors" + +include: [kscan.yaml] + +properties: + kscan: + type: phandle + required: true + +child-binding: + description: "A sideband behavior tied to a row/column pair" + + properties: + row: + type: int + required: true + column: + type: int + required: true + bindings: + type: phandle-array + required: true diff --git a/app/dts/bindings/zmk,gpio-key-behavior-trigger.yaml b/app/dts/bindings/zmk,gpio-key-behavior-trigger.yaml deleted file mode 100644 index 2a1387f0..00000000 --- a/app/dts/bindings/zmk,gpio-key-behavior-trigger.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2023 The ZMK Contributors -# SPDX-License-Identifier: MIT - -description: | - Driver for a dedicated key for invoking a connected behavior. - -compatible: "zmk,gpio-key-behavior-trigger" - -include: base.yaml - -properties: - key: - type: phandle - required: true - description: The GPIO key that triggers wake via interrupt - bindings: - type: phandle - required: true - description: The behavior to invoke when the GPIO key is pressed - debounce-press-ms: - type: int - default: 5 - description: Debounce time for key press in milliseconds. Use 0 for eager debouncing. - debounce-release-ms: - type: int - default: 5 - description: Debounce time for key release in milliseconds. - debounce-scan-period-ms: - type: int - default: 1 - description: Time between reads in milliseconds when any key is pressed. diff --git a/app/src/gpio_key_behavior_trigger.c b/app/src/gpio_key_behavior_trigger.c deleted file mode 100644 index a72f8e48..00000000 --- a/app/src/gpio_key_behavior_trigger.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2023 The ZMK Contributors - * - * SPDX-License-Identifier: MIT - */ - -#define DT_DRV_COMPAT zmk_gpio_key_behavior_trigger - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); - -struct gkbt_config { - struct zmk_debounce_config debounce_config; - int32_t debounce_scan_period_ms; - struct gpio_dt_spec key; -}; - -struct gkbt_data { - struct zmk_behavior_binding binding; - struct zmk_debounce_state debounce_state; - struct gpio_callback key_callback; - const struct device *dev; - struct k_work_delayable update_work; - uint32_t read_time; -}; - -static void gkbt_enable_interrupt(const struct device *dev) { - const struct gkbt_config *config = dev->config; - - gpio_pin_interrupt_configure_dt(&config->key, GPIO_INT_LEVEL_ACTIVE); -} - -static void gkbt_disable_interrupt(const struct device *dev) { - const struct gkbt_config *config = dev->config; - - gpio_pin_interrupt_configure_dt(&config->key, GPIO_INT_DISABLE); -} - -static void gkbt_read(const struct device *dev) { - const struct gkbt_config *config = dev->config; - struct gkbt_data *data = dev->data; - - zmk_debounce_update(&data->debounce_state, gpio_pin_get_dt(&config->key), - config->debounce_scan_period_ms, &config->debounce_config); - - if (zmk_debounce_get_changed(&data->debounce_state)) { - const bool pressed = zmk_debounce_is_pressed(&data->debounce_state); - - struct zmk_behavior_binding_event event = {.position = INT32_MAX, - .timestamp = k_uptime_get()}; - - if (pressed) { - behavior_keymap_binding_pressed(&data->binding, event); - } else { - behavior_keymap_binding_released(&data->binding, event); - } - } - - if (zmk_debounce_is_active(&data->debounce_state)) { - data->read_time += config->debounce_scan_period_ms; - - k_work_reschedule(&data->update_work, K_TIMEOUT_ABS_MS(data->read_time)); - } else { - gkbt_enable_interrupt(dev); - } -} - -static void gkbt_update_work(struct k_work *work) { - struct k_work_delayable *dwork = CONTAINER_OF(work, struct k_work_delayable, work); - struct gkbt_data *data = CONTAINER_OF(dwork, struct gkbt_data, update_work); - gkbt_read(data->dev); -} - -static void gkbt_gpio_irq_callback(const struct device *port, struct gpio_callback *cb, - const gpio_port_pins_t pin) { - struct gkbt_data *data = CONTAINER_OF(cb, struct gkbt_data, key_callback); - - gkbt_disable_interrupt(data->dev); - - data->read_time = k_uptime_get(); - k_work_reschedule(&data->update_work, K_NO_WAIT); -} - -static void gkbt_wait_for_key_release(const struct device *dev) { - const struct gkbt_config *config = dev->config; - - while (gpio_pin_get_dt(&config->key)) { - k_sleep(K_MSEC(100)); - } -} - -static int gkbt_init(const struct device *dev) { - const struct gkbt_config *config = dev->config; - struct gkbt_data *data = dev->data; - - if (!device_is_ready(config->key.port)) { - LOG_ERR("GPIO port %s is not ready", config->key.port->name); - return -ENODEV; - } - - k_work_init_delayable(&data->update_work, gkbt_update_work); - data->dev = dev; - - gpio_pin_configure_dt(&config->key, GPIO_INPUT); - gpio_init_callback(&data->key_callback, gkbt_gpio_irq_callback, BIT(config->key.pin)); - gpio_add_callback(config->key.port, &data->key_callback); - - // Be sure our wakeup key is released before startup continues to avoid wake/sleep loop. - gkbt_wait_for_key_release(dev); - - gkbt_enable_interrupt(dev); - - return 0; -} - -static int gkbt_pm_action(const struct device *dev, enum pm_device_action action) { - const struct gkbt_config *config = dev->config; - struct gkbt_data *data = dev->data; - - int ret; - - switch (action) { - case PM_DEVICE_ACTION_SUSPEND: - gkbt_disable_interrupt(dev); - ret = gpio_remove_callback(config->key.port, &data->key_callback); - break; - case PM_DEVICE_ACTION_RESUME: - ret = gpio_add_callback(config->key.port, &data->key_callback); - gkbt_enable_interrupt(dev); - break; - default: - ret = -ENOTSUP; - break; - } - - return ret; -} - -#define GKBT_INST(n) \ - const struct gkbt_config gkbt_config_##n = { \ - .key = GPIO_DT_SPEC_GET(DT_INST_PHANDLE(n, key), gpios), \ - .debounce_config = \ - { \ - .debounce_press_ms = DT_INST_PROP(n, debounce_press_ms), \ - .debounce_release_ms = DT_INST_PROP(n, debounce_release_ms), \ - }, \ - .debounce_scan_period_ms = DT_INST_PROP(n, debounce_scan_period_ms), \ - }; \ - struct gkbt_data gkbt_data_##n = { \ - .binding = ZMK_KEYMAP_EXTRACT_BINDING(0, DT_DRV_INST(n)), \ - }; \ - PM_DEVICE_DT_INST_DEFINE(n, gkbt_pm_action); \ - DEVICE_DT_INST_DEFINE(n, gkbt_init, PM_DEVICE_DT_INST_GET(n), &gkbt_data_##n, \ - &gkbt_config_##n, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ - NULL); - -DT_INST_FOREACH_STATUS_OKAY(GKBT_INST) diff --git a/app/src/kscan_sideband_behaviors.c b/app/src/kscan_sideband_behaviors.c new file mode 100644 index 00000000..3a03a293 --- /dev/null +++ b/app/src/kscan_sideband_behaviors.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_kscan_sideband_behaviors + +#include +#include +#include +#include +#include + +#include +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +struct ksbb_entry { + uint8_t row; + uint8_t column; + struct zmk_behavior_binding binding; +}; + +struct ksbb_config { + const struct device *kscan; + struct ksbb_entry *entries; + size_t entries_len; +}; + +struct ksbb_data { + kscan_callback_t callback; + bool enabled; +}; + +#define GET_KSBB_DEV(n) DEVICE_DT_GET(DT_DRV_INST(n)), + +// The kscan callback has no context with it, so we keep a static array of all possible +// KSBBs to check when a kscan callback from the "wrapped" inner kscan fires. +static const struct device *ksbbs[DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)] = { + DT_INST_FOREACH_STATUS_OKAY(GET_KSBB_DEV)}; + +void ksbb_inner_kscan_callback(const struct device *dev, uint32_t row, uint32_t column, + bool pressed) { + for (int i = 0; i < ARRAY_SIZE(ksbbs); i++) { + const struct device *ksbb = ksbbs[i]; + const struct ksbb_config *cfg = ksbb->config; + struct ksbb_data *data = ksbb->data; + + if (cfg->kscan != dev) { + continue; + } + + for (int e = 0; e < cfg->entries_len; e++) { + struct ksbb_entry *entry = &cfg->entries[e]; + if (entry->row == row && entry->column == column) { + struct zmk_behavior_binding_event event = {.position = INT32_MAX, + .timestamp = k_uptime_get()}; + + if (pressed) { + behavior_keymap_binding_pressed(&entry->binding, event); + } else { + behavior_keymap_binding_released(&entry->binding, event); + } + return; + } + } + + if (data->enabled && data->callback) { + data->callback(ksbb, row, column, pressed); + } + } +} + +static int ksbb_configure(const struct device *dev, kscan_callback_t callback) { + struct ksbb_data *data = dev->data; + + if (!callback) { + return -EINVAL; + } + + data->callback = callback; + return 0; +} + +static int ksbb_enable(const struct device *dev) { + struct ksbb_data *data = dev->data; + data->enabled = true; + + return 0; +} + +static int ksbb_disable(const struct device *dev) { + struct ksbb_data *data = dev->data; + data->enabled = false; + + return 0; +} + +static int ksbb_init(const struct device *dev) { + const struct ksbb_config *config = dev->config; + + if (!device_is_ready(config->kscan)) { + LOG_ERR("kscan %s is not ready", config->kscan->name); + return -ENODEV; + } + + kscan_config(config->kscan, &ksbb_inner_kscan_callback); + kscan_enable_callback(config->kscan); + + return 0; +} + +static const struct kscan_driver_api ksbb_api = { + .config = ksbb_configure, + .enable_callback = ksbb_enable, + .disable_callback = ksbb_disable, +}; + +#define JUST_ONE(_id) 1 + +#define ENTRY(e) \ + { \ + .row = DT_PROP(e, row), .column = DT_PROP(e, column), \ + .binding = ZMK_KEYMAP_EXTRACT_BINDING(0, e), \ + } + +#define KSBB_INST(n) \ + static struct ksbb_entry entries_##n[] = { \ + DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(n, ENTRY, (, ))}; \ + const struct ksbb_config ksbb_config_##n = { \ + .kscan = DEVICE_DT_GET(DT_INST_PHANDLE(n, kscan)), \ + .entries = entries_##n, \ + .entries_len = DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(n, JUST_ONE, (+)), \ + }; \ + struct ksbb_data ksbb_data_##n = {}; \ + DEVICE_DT_INST_DEFINE(n, ksbb_init, NULL, &ksbb_data_##n, &ksbb_config_##n, APPLICATION, \ + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &ksbb_api); + +DT_INST_FOREACH_STATUS_OKAY(KSBB_INST) From c3144055e8534169bf1a6d798b1ee712f6c1d002 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Sun, 31 Dec 2023 00:57:00 +0000 Subject: [PATCH 102/127] refactor(boards): Move ZMK Uno 1P3T slider to sideband * Invoke output selection from the slider on the ZMK Uno via sideband behavior setup, to simplify keymap. --- app/boards/shields/zmk_uno/zmk_uno.dtsi | 36 +---------------- app/boards/shields/zmk_uno/zmk_uno.keymap | 21 +--------- app/boards/shields/zmk_uno/zmk_uno.overlay | 40 +++++++++++++++++++ app/boards/shields/zmk_uno/zmk_uno_split.dtsi | 10 ++--- .../shields/zmk_uno/zmk_uno_split.keymap | 18 --------- 5 files changed, 46 insertions(+), 79 deletions(-) diff --git a/app/boards/shields/zmk_uno/zmk_uno.dtsi b/app/boards/shields/zmk_uno/zmk_uno.dtsi index 196ac8b5..e8ba79d6 100644 --- a/app/boards/shields/zmk_uno/zmk_uno.dtsi +++ b/app/boards/shields/zmk_uno/zmk_uno.dtsi @@ -40,7 +40,7 @@ nice_view_spi: &arduino_spi { / { chosen { - zmk,kscan = &kscan_matrix_comp; + zmk,kscan = &kscan_matrix; zmk,backlight = &backlight; zmk,underglow = &led_strip; zmk,matrix-transform = &matrix_transform; @@ -74,7 +74,6 @@ nice_view_spi: &arduino_spi { map = < RC(0,0) RC(0,1) RC(1,0) RC(1,1) - RC(2,0) RC(2,1) RC(2,2) >; }; @@ -86,42 +85,9 @@ nice_view_spi: &arduino_spi { map = < RC(0,0) RC(0,1) RC(0,2) RC(0,3) - RC(1,0) RC(1,1) RC(1,2) >; }; - - kscan_matrix_comp: kscan_matrix_comp { - compatible = "zmk,kscan-composite"; - rows = <1>; - columns = <7>; - - matrix { - kscan = <&kscan_matrix>; - }; - - toggle { - kscan = <&kscan_sp3t_toggle>; - row-offset = <2>; - }; - - }; - - kscan_direct_comp: kscan_direct_comp { - compatible = "zmk,kscan-composite"; - status = "disabled"; - - matrix { - kscan = <&kscan_direct>; - }; - - toggle { - kscan = <&kscan_sp3t_toggle>; - row-offset = <1>; - }; - - }; - kscan_matrix: kscan_matrix { compatible = "zmk,kscan-gpio-matrix"; wakeup-source; diff --git a/app/boards/shields/zmk_uno/zmk_uno.keymap b/app/boards/shields/zmk_uno/zmk_uno.keymap index 0e0fc795..e416ff5e 100644 --- a/app/boards/shields/zmk_uno/zmk_uno.keymap +++ b/app/boards/shields/zmk_uno/zmk_uno.keymap @@ -9,42 +9,25 @@ #include #include #include -#include #include // Uncomment the following block if using the "Direct Wire" jumper to switch the matrix to a direct wire. /* :REMOVE ME -&kscan_direct_comp { status = "okay"; }; &kscan_direct { status = "okay"; }; -&kscan_matrix_comp { status = "disabled"; }; &kscan_matrix { status = "disabled"; }; / { chosen { zmk,matrix-transform = &direct_matrix_transform; - zmk,kscan = &kscan_direct_comp; + zmk,kscan = &kscan_direct; }; }; REMOVE ME: */ - / { - macros { - ZMK_MACRO(ble_zero, - wait-ms = <1>; - tap-ms = <1>; - bindings = <&out OUT_BLE &bt BT_SEL 0>; - ) - ZMK_MACRO(ble_one, - wait-ms = <1>; - tap-ms = <1>; - bindings = <&out OUT_BLE &bt BT_SEL 1>; - ) - }; - keymap { compatible = "zmk,keymap"; @@ -52,8 +35,6 @@ REMOVE ME: */ bindings = < &kp A &bl BL_TOG &rgb_ug RGB_EFF &bt BT_CLR - - &out OUT_USB &ble_zero &ble_one >; sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; diff --git a/app/boards/shields/zmk_uno/zmk_uno.overlay b/app/boards/shields/zmk_uno/zmk_uno.overlay index 4999c82c..c86f6e5c 100644 --- a/app/boards/shields/zmk_uno/zmk_uno.overlay +++ b/app/boards/shields/zmk_uno/zmk_uno.overlay @@ -6,6 +6,10 @@ #include "zmk_uno.dtsi" +#include +#include +#include + / { chosen { zmk,matrix-transform = &matrix_transform; @@ -19,4 +23,40 @@ }; }; + macros { + ZMK_MACRO(ble_zero, + wait-ms = <1>; + tap-ms = <1>; + bindings = <&out OUT_BLE &bt BT_SEL 0>; + ) + ZMK_MACRO(ble_one, + wait-ms = <1>; + tap-ms = <1>; + bindings = <&out OUT_BLE &bt BT_SEL 1>; + ) + }; + + endpoint_sideband_behaviors { + compatible = "zmk,kscan-sideband-behaviors"; + kscan = <&kscan_sp3t_toggle>; + + usb { + row = <0>; + column = <0>; + bindings = <&out OUT_USB>; + }; + + ble_zero { + row = <0>; + column = <1>; + bindings = <&ble_zero>; + }; + + ble_one { + row = <0>; + column = <2>; + bindings = <&ble_one>; + }; + }; + }; diff --git a/app/boards/shields/zmk_uno/zmk_uno_split.dtsi b/app/boards/shields/zmk_uno/zmk_uno_split.dtsi index 516213bd..dac6fc3e 100644 --- a/app/boards/shields/zmk_uno/zmk_uno_split.dtsi +++ b/app/boards/shields/zmk_uno/zmk_uno_split.dtsi @@ -17,16 +17,15 @@ split_matrix_transform: split_matrix_transform { compatible = "zmk,matrix-transform"; - rows = <3>; - columns = <4>; + rows = <4>; + columns = <2>; map = < RC(0,0) RC(0,1) RC(1,0) RC(1,1) - RC(2,0) RC(2,1) RC(2,2) + RC(3,0) RC(3,1) RC(4,0) RC(4,1) - RC(5,0) RC(5,1) RC(5,2) >; }; @@ -38,10 +37,9 @@ map = < RC(0,0) RC(0,1) RC(0,2) RC(0,3) - RC(1,0) RC(1,1) RC(1,2) + RC(2,0) RC(2,1) RC(2,2) RC(2,3) - RC(3,0) RC(3,1) RC(3,2) >; }; diff --git a/app/boards/shields/zmk_uno/zmk_uno_split.keymap b/app/boards/shields/zmk_uno/zmk_uno_split.keymap index 05f0ffb0..1e46042a 100644 --- a/app/boards/shields/zmk_uno/zmk_uno_split.keymap +++ b/app/boards/shields/zmk_uno/zmk_uno_split.keymap @@ -16,9 +16,7 @@ /* :REMOVE ME -&kscan_direct_comp { status = "okay"; }; &kscan_direct { status = "okay"; }; -&kscan_matrix_comp { status = "disabled"; }; &kscan_matrix { status = "disabled"; }; / { @@ -30,20 +28,7 @@ REMOVE ME: */ - / { - macros { - ZMK_MACRO(ble_zero, - wait-ms = <1>; - tap-ms = <1>; - bindings = <&out OUT_BLE &bt BT_SEL 0>; - ) - ZMK_MACRO(ble_one, - wait-ms = <1>; - tap-ms = <1>; - bindings = <&out OUT_BLE &bt BT_SEL 1>; - ) - }; keymap { compatible = "zmk,keymap"; @@ -53,11 +38,8 @@ REMOVE ME: */ &kp A &bl BL_TOG &rgb_ug RGB_EFF &bt BT_CLR - &out OUT_USB &ble_zero &ble_one - &kp C &kp D &kp E &kp F - &none &none &none >; sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>; From 09111f1cf36099690bf96091b46214c421b1fb3b Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Sun, 31 Dec 2023 06:36:52 +0000 Subject: [PATCH 103/127] fix: Sleep after clearing endpoints to wait for send. * Add a small sleep to allow other threads to send data for the endpoint clearing before sleep. --- app/src/pm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/pm.c b/app/src/pm.c index a4599ac8..8525046f 100644 --- a/app/src/pm.c +++ b/app/src/pm.c @@ -35,6 +35,8 @@ int zmk_pm_soft_off(void) { #if !IS_ENABLED(CONFIG_ZMK_SPLIT) || IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) zmk_endpoints_clear_current(); + // Need to sleep to give any other threads a chance so submit endpoint data. + k_sleep(K_MSEC(100)); #endif device_count = z_device_get_all_static(&devs); From 4198fac90f4f35e7464cb3793632f81601bbf1d5 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 3 Jan 2024 11:11:24 -0800 Subject: [PATCH 104/127] fix(pm): Fix deep sleep with sideband behaviors. * Properly implement the PM hook needed for sideband behavior kscan device to have wakeup source enabled on it. --- .../kscan/zmk,kscan-sideband-behaviors.yaml | 2 +- app/src/kscan.c | 5 ++-- app/src/kscan_sideband_behaviors.c | 29 +++++++++++++++++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/app/dts/bindings/kscan/zmk,kscan-sideband-behaviors.yaml b/app/dts/bindings/kscan/zmk,kscan-sideband-behaviors.yaml index 7289b9e1..57b54a60 100644 --- a/app/dts/bindings/kscan/zmk,kscan-sideband-behaviors.yaml +++ b/app/dts/bindings/kscan/zmk,kscan-sideband-behaviors.yaml @@ -7,7 +7,7 @@ description: | compatible: "zmk,kscan-sideband-behaviors" -include: [kscan.yaml] +include: kscan.yaml properties: kscan: diff --git a/app/src/kscan.c b/app/src/kscan.c index c04ce2d8..5c7a5535 100644 --- a/app/src/kscan.c +++ b/app/src/kscan.c @@ -74,13 +74,14 @@ int zmk_kscan_init(const struct device *dev) { k_work_init(&msg_processor.work, zmk_kscan_process_msgq); - kscan_config(dev, zmk_kscan_callback); - kscan_enable_callback(dev); #if IS_ENABLED(CONFIG_PM_DEVICE) if (pm_device_wakeup_is_capable(dev)) { pm_device_wakeup_enable(dev, true); } #endif // IS_ENABLED(CONFIG_PM_DEVICE) + kscan_config(dev, zmk_kscan_callback); + kscan_enable_callback(dev); + return 0; } diff --git a/app/src/kscan_sideband_behaviors.c b/app/src/kscan_sideband_behaviors.c index 3a03a293..cff28e49 100644 --- a/app/src/kscan_sideband_behaviors.c +++ b/app/src/kscan_sideband_behaviors.c @@ -75,6 +75,7 @@ void ksbb_inner_kscan_callback(const struct device *dev, uint32_t row, uint32_t } static int ksbb_configure(const struct device *dev, kscan_callback_t callback) { + const struct ksbb_config *cfg = dev->config; struct ksbb_data *data = dev->data; if (!callback) { @@ -82,6 +83,13 @@ static int ksbb_configure(const struct device *dev, kscan_callback_t callback) { } data->callback = callback; + +#if IS_ENABLED(CONFIG_PM_DEVICE) + if (pm_device_wakeup_is_enabled(dev) && pm_device_wakeup_is_capable(cfg->kscan)) { + pm_device_wakeup_enable(cfg->kscan, true); + } +#endif // IS_ENABLED(CONFIG_PM_DEVICE) + return 0; } @@ -119,6 +127,21 @@ static const struct kscan_driver_api ksbb_api = { .disable_callback = ksbb_disable, }; +#if IS_ENABLED(CONFIG_PM_DEVICE) + +static int ksbb_pm_action(const struct device *dev, enum pm_device_action action) { + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + return ksbb_disable(dev); + case PM_DEVICE_ACTION_RESUME: + return ksbb_disable(dev); + default: + return -ENOTSUP; + } +} + +#endif // IS_ENABLED(CONFIG_PM_DEVICE) + #define JUST_ONE(_id) 1 #define ENTRY(e) \ @@ -136,7 +159,9 @@ static const struct kscan_driver_api ksbb_api = { .entries_len = DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(n, JUST_ONE, (+)), \ }; \ struct ksbb_data ksbb_data_##n = {}; \ - DEVICE_DT_INST_DEFINE(n, ksbb_init, NULL, &ksbb_data_##n, &ksbb_config_##n, APPLICATION, \ - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &ksbb_api); + PM_DEVICE_DT_INST_DEFINE(n, ksbb_pm_action); \ + DEVICE_DT_INST_DEFINE(n, ksbb_init, PM_DEVICE_DT_INST_GET(n), &ksbb_data_##n, \ + &ksbb_config_##n, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + &ksbb_api); DT_INST_FOREACH_STATUS_OKAY(KSBB_INST) From 5d960a758f6067ae82eccb01d8508114b2a98c6a Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 22 Jan 2024 13:39:08 -0800 Subject: [PATCH 105/127] fix: Cleanups of sideband and direct kscan from review. * Add dedicated init priority for the sideband kscan. * Refactor sideband code for clarity. * Tweaks to direct kscan for clarity. * Make sideband behavior row optional for brevity. * Allow overriding ZMK Uno sideband behaviors. --- app/Kconfig | 9 +++ app/boards/shields/zmk_uno/zmk_uno.keymap | 22 +++--- app/boards/shields/zmk_uno/zmk_uno.overlay | 9 +-- .../shields/zmk_uno/zmk_uno_split.keymap | 21 +++--- .../kscan/zmk,kscan-sideband-behaviors.yaml | 7 +- app/module/drivers/kscan/kscan_gpio_direct.c | 4 +- app/src/kscan_sideband_behaviors.c | 67 ++++++++++++------- 7 files changed, 78 insertions(+), 61 deletions(-) diff --git a/app/Kconfig b/app/Kconfig index 15c31375..a719875e 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -518,6 +518,15 @@ config ZMK_KSCAN_SIDEBAND_BEHAVIORS depends on DT_HAS_ZMK_KSCAN_SIDEBAND_BEHAVIORS_ENABLED select KSCAN +if ZMK_KSCAN_SIDEBAND_BEHAVIORS + +config ZMK_KSCAN_SIDEBAND_BEHAVIORS_INIT_PRIORITY + int "Keyboard scan sideband behaviors driver init priority" + # The default kscan init priority is 90, so be sure we are lower. + default 95 + +endif # ZMK_KSCAN_SIDEBAND_BEHAVIORS + menu "Logging" config ZMK_LOGGING_MINIMAL diff --git a/app/boards/shields/zmk_uno/zmk_uno.keymap b/app/boards/shields/zmk_uno/zmk_uno.keymap index e416ff5e..a7f6a267 100644 --- a/app/boards/shields/zmk_uno/zmk_uno.keymap +++ b/app/boards/shields/zmk_uno/zmk_uno.keymap @@ -11,21 +11,17 @@ #include #include -// Uncomment the following block if using the "Direct Wire" jumper to switch the matrix to a direct wire. +// Uncomment the following lines if using the "Direct Wire" jumper to switch the matrix to a direct wire. -/* :REMOVE ME +// &kscan_direct { status = "okay"; }; +// &kscan_matrix { status = "disabled"; }; -&kscan_direct { status = "okay"; }; -&kscan_matrix { status = "disabled"; }; - -/ { - chosen { - zmk,matrix-transform = &direct_matrix_transform; - zmk,kscan = &kscan_direct; - }; -}; - -REMOVE ME: */ +// / { +// chosen { +// zmk,matrix-transform = &direct_matrix_transform; +// zmk,kscan = &kscan_direct; +// }; +// }; / { keymap { diff --git a/app/boards/shields/zmk_uno/zmk_uno.overlay b/app/boards/shields/zmk_uno/zmk_uno.overlay index c86f6e5c..3d105abf 100644 --- a/app/boards/shields/zmk_uno/zmk_uno.overlay +++ b/app/boards/shields/zmk_uno/zmk_uno.overlay @@ -40,20 +40,17 @@ compatible = "zmk,kscan-sideband-behaviors"; kscan = <&kscan_sp3t_toggle>; - usb { - row = <0>; + first_toggle_sideband: first_toggle_sideband { column = <0>; bindings = <&out OUT_USB>; }; - ble_zero { - row = <0>; + second_toggle_sideband: second_toggle_sideband { column = <1>; bindings = <&ble_zero>; }; - ble_one { - row = <0>; + third_toggle_sideband: third_toggle_sideband { column = <2>; bindings = <&ble_one>; }; diff --git a/app/boards/shields/zmk_uno/zmk_uno_split.keymap b/app/boards/shields/zmk_uno/zmk_uno_split.keymap index 1e46042a..37672a7d 100644 --- a/app/boards/shields/zmk_uno/zmk_uno_split.keymap +++ b/app/boards/shields/zmk_uno/zmk_uno_split.keymap @@ -12,21 +12,18 @@ #include #include -// Uncomment the following block if using the "Direct Wire" jumper to switch the matrix to a direct wire. +// Uncomment the following lines if using the "Direct Wire" jumper to switch the matrix to a direct wire. -/* :REMOVE ME -&kscan_direct { status = "okay"; }; -&kscan_matrix { status = "disabled"; }; +// &kscan_direct { status = "okay"; }; +// &kscan_matrix { status = "disabled"; }; -/ { - chosen { - zmk,matrix-transform = &split_direct_matrix_transform; - zmk,kscan = &kscan_direct_comp; - }; -}; - -REMOVE ME: */ +// / { +// chosen { +// zmk,matrix-transform = &split_direct_matrix_transform; +// zmk,kscan = &kscan_direct_comp; +// }; +// }; / { diff --git a/app/dts/bindings/kscan/zmk,kscan-sideband-behaviors.yaml b/app/dts/bindings/kscan/zmk,kscan-sideband-behaviors.yaml index 57b54a60..f3ed180d 100644 --- a/app/dts/bindings/kscan/zmk,kscan-sideband-behaviors.yaml +++ b/app/dts/bindings/kscan/zmk,kscan-sideband-behaviors.yaml @@ -2,8 +2,9 @@ # SPDX-License-Identifier: MIT description: | - kscan sideband behavior runner. Only basic system behavior should be used, - since no keymap processing occurs when using them. + kscan sideband behavior runner. Only basic system behaviors should be used, + since no keymap processing occurs when using them. Primarily, that means avoiding + using tap-holds, sticky keys, etc. as sideband behaviors. compatible: "zmk,kscan-sideband-behaviors" @@ -20,7 +21,7 @@ child-binding: properties: row: type: int - required: true + default: 0 column: type: int required: true diff --git a/app/module/drivers/kscan/kscan_gpio_direct.c b/app/module/drivers/kscan/kscan_gpio_direct.c index e05eb2f3..fa24e69e 100644 --- a/app/module/drivers/kscan/kscan_gpio_direct.c +++ b/app/module/drivers/kscan/kscan_gpio_direct.c @@ -46,7 +46,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); COND_CODE_1(DT_INST_NODE_HAS_PROP(n, input_gpios), (DT_INST_PROP_LEN(n, input_gpios)), \ (DT_INST_PROP_LEN(n, input_keys))) -#define KSCAN_DIRECT_INPUT_CFG_INIT(idx, inst_idx) \ +#define KSCAN_GPIO_DIRECT_INPUT_CFG_INIT(idx, inst_idx) \ KSCAN_GPIO_GET_BY_IDX(DT_DRV_INST(inst_idx), input_gpios, idx) #define KSCAN_KEY_DIRECT_INPUT_CFG_INIT(idx, inst_idx) \ KSCAN_GPIO_GET_BY_IDX(DT_INST_PROP_BY_IDX(inst_idx, input_keys, idx), gpios, 0) @@ -353,7 +353,7 @@ static const struct kscan_driver_api kscan_direct_api = { \ static struct kscan_gpio kscan_direct_inputs_##n[] = { \ COND_CODE_1(DT_INST_NODE_HAS_PROP(n, input_gpios), \ - (LISTIFY(INST_INPUTS_LEN(n), KSCAN_DIRECT_INPUT_CFG_INIT, (, ), n)), \ + (LISTIFY(INST_INPUTS_LEN(n), KSCAN_GPIO_DIRECT_INPUT_CFG_INIT, (, ), n)), \ (LISTIFY(INST_INPUTS_LEN(n), KSCAN_KEY_DIRECT_INPUT_CFG_INIT, (, ), n)))}; \ \ static struct zmk_debounce_state kscan_direct_state_##n[INST_INPUTS_LEN(n)]; \ diff --git a/app/src/kscan_sideband_behaviors.c b/app/src/kscan_sideband_behaviors.c index cff28e49..5b8a30a8 100644 --- a/app/src/kscan_sideband_behaviors.c +++ b/app/src/kscan_sideband_behaviors.c @@ -19,9 +19,9 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); struct ksbb_entry { + struct zmk_behavior_binding binding; uint8_t row; uint8_t column; - struct zmk_behavior_binding binding; }; struct ksbb_config { @@ -39,32 +39,53 @@ struct ksbb_data { // The kscan callback has no context with it, so we keep a static array of all possible // KSBBs to check when a kscan callback from the "wrapped" inner kscan fires. -static const struct device *ksbbs[DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)] = { - DT_INST_FOREACH_STATUS_OKAY(GET_KSBB_DEV)}; +static const struct device *ksbbs[] = {DT_INST_FOREACH_STATUS_OKAY(GET_KSBB_DEV)}; -void ksbb_inner_kscan_callback(const struct device *dev, uint32_t row, uint32_t column, - bool pressed) { +int find_ksbb_for_inner(const struct device *inner_dev, const struct device **ksbb_dev) { for (int i = 0; i < ARRAY_SIZE(ksbbs); i++) { const struct device *ksbb = ksbbs[i]; const struct ksbb_config *cfg = ksbb->config; - struct ksbb_data *data = ksbb->data; - if (cfg->kscan != dev) { - continue; + if (cfg->kscan == inner_dev) { + *ksbb_dev = ksbb; + return 0; } + } - for (int e = 0; e < cfg->entries_len; e++) { - struct ksbb_entry *entry = &cfg->entries[e]; - if (entry->row == row && entry->column == column) { - struct zmk_behavior_binding_event event = {.position = INT32_MAX, - .timestamp = k_uptime_get()}; + return -ENODEV; +} - if (pressed) { - behavior_keymap_binding_pressed(&entry->binding, event); - } else { - behavior_keymap_binding_released(&entry->binding, event); - } - return; +int find_sideband_behavior(const struct device *dev, uint32_t row, uint32_t column, + struct ksbb_entry **entry) { + const struct ksbb_config *cfg = dev->config; + + for (int e = 0; e < cfg->entries_len; e++) { + struct ksbb_entry *candidate = &cfg->entries[e]; + + if (candidate->row == row && candidate->column == column) { + *entry = candidate; + return 0; + } + } + + return -ENODEV; +} + +void ksbb_inner_kscan_callback(const struct device *dev, uint32_t row, uint32_t column, + bool pressed) { + struct ksbb_entry *entry = NULL; + const struct device *ksbb = NULL; + + if (find_ksbb_for_inner(dev, &ksbb) >= 0) { + struct ksbb_data *data = ksbb->data; + if (find_sideband_behavior(ksbb, row, column, &entry) >= 0) { + struct zmk_behavior_binding_event event = {.position = INT32_MAX, + .timestamp = k_uptime_get()}; + + if (pressed) { + behavior_keymap_binding_pressed(&entry->binding, event); + } else { + behavior_keymap_binding_released(&entry->binding, event); } } @@ -78,10 +99,6 @@ static int ksbb_configure(const struct device *dev, kscan_callback_t callback) { const struct ksbb_config *cfg = dev->config; struct ksbb_data *data = dev->data; - if (!callback) { - return -EINVAL; - } - data->callback = callback; #if IS_ENABLED(CONFIG_PM_DEVICE) @@ -161,7 +178,7 @@ static int ksbb_pm_action(const struct device *dev, enum pm_device_action action struct ksbb_data ksbb_data_##n = {}; \ PM_DEVICE_DT_INST_DEFINE(n, ksbb_pm_action); \ DEVICE_DT_INST_DEFINE(n, ksbb_init, PM_DEVICE_DT_INST_GET(n), &ksbb_data_##n, \ - &ksbb_config_##n, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ - &ksbb_api); + &ksbb_config_##n, POST_KERNEL, \ + CONFIG_ZMK_KSCAN_SIDEBAND_BEHAVIORS_INIT_PRIORITY, &ksbb_api); DT_INST_FOREACH_STATUS_OKAY(KSBB_INST) From bd21f41412eaff5822a17efa86ce1dadf831cbcc Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 26 Jan 2024 01:48:46 -0800 Subject: [PATCH 106/127] refactor: Fixes for review feedback. --- app/Kconfig | 2 +- app/src/kscan_sideband_behaviors.c | 29 ++++++++++++----------------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/app/Kconfig b/app/Kconfig index a719875e..28d3c22a 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -522,7 +522,7 @@ if ZMK_KSCAN_SIDEBAND_BEHAVIORS config ZMK_KSCAN_SIDEBAND_BEHAVIORS_INIT_PRIORITY int "Keyboard scan sideband behaviors driver init priority" - # The default kscan init priority is 90, so be sure we are lower. + # The default kscan init priority is 90, so be sure we are initialized later. default 95 endif # ZMK_KSCAN_SIDEBAND_BEHAVIORS diff --git a/app/src/kscan_sideband_behaviors.c b/app/src/kscan_sideband_behaviors.c index 5b8a30a8..7a9922af 100644 --- a/app/src/kscan_sideband_behaviors.c +++ b/app/src/kscan_sideband_behaviors.c @@ -41,44 +41,41 @@ struct ksbb_data { // KSBBs to check when a kscan callback from the "wrapped" inner kscan fires. static const struct device *ksbbs[] = {DT_INST_FOREACH_STATUS_OKAY(GET_KSBB_DEV)}; -int find_ksbb_for_inner(const struct device *inner_dev, const struct device **ksbb_dev) { +const struct device *find_ksbb_for_inner(const struct device *inner_dev) { for (int i = 0; i < ARRAY_SIZE(ksbbs); i++) { const struct device *ksbb = ksbbs[i]; const struct ksbb_config *cfg = ksbb->config; if (cfg->kscan == inner_dev) { - *ksbb_dev = ksbb; - return 0; + return ksbb; } } - return -ENODEV; + return NULL; } -int find_sideband_behavior(const struct device *dev, uint32_t row, uint32_t column, - struct ksbb_entry **entry) { +struct ksbb_entry *find_sideband_behavior(const struct device *dev, uint32_t row, uint32_t column) { const struct ksbb_config *cfg = dev->config; for (int e = 0; e < cfg->entries_len; e++) { struct ksbb_entry *candidate = &cfg->entries[e]; if (candidate->row == row && candidate->column == column) { - *entry = candidate; - return 0; + return candidate; } } - return -ENODEV; + return NULL; } void ksbb_inner_kscan_callback(const struct device *dev, uint32_t row, uint32_t column, bool pressed) { - struct ksbb_entry *entry = NULL; - const struct device *ksbb = NULL; - - if (find_ksbb_for_inner(dev, &ksbb) >= 0) { + const struct device *ksbb = find_ksbb_for_inner(dev); + if (ksbb) { struct ksbb_data *data = ksbb->data; - if (find_sideband_behavior(ksbb, row, column, &entry) >= 0) { + + struct ksbb_entry *entry = find_sideband_behavior(ksbb, row, column); + if (entry) { struct zmk_behavior_binding_event event = {.position = INT32_MAX, .timestamp = k_uptime_get()}; @@ -159,8 +156,6 @@ static int ksbb_pm_action(const struct device *dev, enum pm_device_action action #endif // IS_ENABLED(CONFIG_PM_DEVICE) -#define JUST_ONE(_id) 1 - #define ENTRY(e) \ { \ .row = DT_PROP(e, row), .column = DT_PROP(e, column), \ @@ -173,7 +168,7 @@ static int ksbb_pm_action(const struct device *dev, enum pm_device_action action const struct ksbb_config ksbb_config_##n = { \ .kscan = DEVICE_DT_GET(DT_INST_PHANDLE(n, kscan)), \ .entries = entries_##n, \ - .entries_len = DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(n, JUST_ONE, (+)), \ + .entries_len = ARRAY_SIZE(entries_##n), \ }; \ struct ksbb_data ksbb_data_##n = {}; \ PM_DEVICE_DT_INST_DEFINE(n, ksbb_pm_action); \ From 8d54e287f019baa44540c8d8120eac594a630b03 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 19 Feb 2024 02:18:23 -0800 Subject: [PATCH 107/127] fix: Adjustments for Zephyr 3.5. --- app/Kconfig | 6 +++ app/include/zmk/pm.h | 3 ++ app/src/activity.c | 61 +----------------------- app/src/behaviors/behavior_soft_off.c | 2 +- app/src/pm.c | 68 ++++++++++++++++++++++++++- 5 files changed, 79 insertions(+), 61 deletions(-) diff --git a/app/Kconfig b/app/Kconfig index 28d3c22a..5068e91f 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -405,6 +405,7 @@ config ZMK_SLEEP bool "Enable deep sleep support" depends on HAS_POWEROFF select POWEROFF + select ZMK_PM_DEVICE_SUSPEND_RESUME imply USB if ZMK_SLEEP @@ -426,10 +427,15 @@ config ZMK_EXT_POWER config ZMK_PM bool +config ZMK_PM_DEVICE_SUSPEND_RESUME + bool + select ZMK_PM + config ZMK_PM_SOFT_OFF bool "Soft-off support" select ZMK_PM select PM_DEVICE + select ZMK_PM_DEVICE_SUSPEND_RESUME config ZMK_GPIO_KEY_WAKEUP_TRIGGER bool "Hardware supported wakeup (GPIO)" diff --git a/app/include/zmk/pm.h b/app/include/zmk/pm.h index dff217af..a733856d 100644 --- a/app/include/zmk/pm.h +++ b/app/include/zmk/pm.h @@ -6,4 +6,7 @@ #pragma once +int zmk_pm_suspend_devices(void); +void zmk_pm_resume_devices(void); + int zmk_pm_soft_off(void); \ No newline at end of file diff --git a/app/src/activity.c b/app/src/activity.c index 8f421f85..454e91e5 100644 --- a/app/src/activity.c +++ b/app/src/activity.c @@ -7,8 +7,6 @@ #include #include #include -#include -#include #include #include @@ -20,69 +18,14 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include +#include + #include #if IS_ENABLED(CONFIG_USB_DEVICE_STACK) #include #endif -// Reimplement some of the device work from Zephyr PM to work with the new `sys_poweroff` API. -// TODO: Tweak this to smarter runtime PM of subsystems on sleep. - -#ifdef CONFIG_PM_DEVICE -TYPE_SECTION_START_EXTERN(const struct device *, zmk_pm_device_slots); - -#if !defined(CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE) -/* Number of devices successfully suspended. */ -static size_t zmk_num_susp; - -static int zmk_pm_suspend_devices(void) { - const struct device *devs; - size_t devc; - - devc = z_device_get_all_static(&devs); - - zmk_num_susp = 0; - - for (const struct device *dev = devs + devc - 1; dev >= devs; dev--) { - int ret; - - /* - * Ignore uninitialized devices, busy devices, wake up sources, and - * devices with runtime PM enabled. - */ - if (!device_is_ready(dev) || pm_device_is_busy(dev) || pm_device_state_is_locked(dev) || - pm_device_wakeup_is_enabled(dev) || pm_device_runtime_is_enabled(dev)) { - continue; - } - - ret = pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND); - /* ignore devices not supporting or already at the given state */ - if ((ret == -ENOSYS) || (ret == -ENOTSUP) || (ret == -EALREADY)) { - continue; - } else if (ret < 0) { - LOG_ERR("Device %s did not enter %s state (%d)", dev->name, - pm_device_state_str(PM_DEVICE_STATE_SUSPENDED), ret); - return ret; - } - - TYPE_SECTION_START(zmk_pm_device_slots)[zmk_num_susp] = dev; - zmk_num_susp++; - } - - return 0; -} - -static void zmk_pm_resume_devices(void) { - for (int i = (zmk_num_susp - 1); i >= 0; i--) { - pm_device_action_run(TYPE_SECTION_START(zmk_pm_device_slots)[i], PM_DEVICE_ACTION_RESUME); - } - - zmk_num_susp = 0; -} -#endif /* !CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE */ -#endif /* CONFIG_PM_DEVICE */ - bool is_usb_power_present(void) { #if IS_ENABLED(CONFIG_USB_DEVICE_STACK) return zmk_usb_is_powered(); diff --git a/app/src/behaviors/behavior_soft_off.c b/app/src/behaviors/behavior_soft_off.c index e6096bb4..878a2fc5 100644 --- a/app/src/behaviors/behavior_soft_off.c +++ b/app/src/behaviors/behavior_soft_off.c @@ -64,7 +64,7 @@ static const struct behavior_driver_api behavior_soft_off_driver_api = { }; \ static struct behavior_soft_off_data bso_data_##n = {}; \ BEHAVIOR_DT_INST_DEFINE(0, behavior_soft_off_init, NULL, &bso_data_##n, &bso_config_##n, \ - APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ &behavior_soft_off_driver_api); DT_INST_FOREACH_STATUS_OKAY(BSO_INST) diff --git a/app/src/pm.c b/app/src/pm.c index 8525046f..4f151875 100644 --- a/app/src/pm.c +++ b/app/src/pm.c @@ -8,13 +8,72 @@ #include #include #include +#include #include +#include #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include +// Reimplement some of the device work from Zephyr PM to work with the new `sys_poweroff` API. +// TODO: Tweak this to smarter runtime PM of subsystems on sleep. + +#ifdef CONFIG_ZMK_PM_DEVICE_SUSPEND_RESUME +TYPE_SECTION_START_EXTERN(const struct device *, zmk_pm_device_slots); + +#if !defined(CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE) +/* Number of devices successfully suspended. */ +static size_t zmk_num_susp; + +int zmk_pm_suspend_devices(void) { + const struct device *devs; + size_t devc; + + devc = z_device_get_all_static(&devs); + + zmk_num_susp = 0; + + for (const struct device *dev = devs + devc - 1; dev >= devs; dev--) { + int ret; + + /* + * Ignore uninitialized devices, busy devices, wake up sources, and + * devices with runtime PM enabled. + */ + if (!device_is_ready(dev) || pm_device_is_busy(dev) || pm_device_state_is_locked(dev) || + pm_device_wakeup_is_enabled(dev) || pm_device_runtime_is_enabled(dev)) { + continue; + } + + ret = pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND); + /* ignore devices not supporting or already at the given state */ + if ((ret == -ENOSYS) || (ret == -ENOTSUP) || (ret == -EALREADY)) { + continue; + } else if (ret < 0) { + LOG_ERR("Device %s did not enter %s state (%d)", dev->name, + pm_device_state_str(PM_DEVICE_STATE_SUSPENDED), ret); + return ret; + } + + TYPE_SECTION_START(zmk_pm_device_slots)[zmk_num_susp] = dev; + zmk_num_susp++; + } + + return 0; +} + +void zmk_pm_resume_devices(void) { + for (int i = (zmk_num_susp - 1); i >= 0; i--) { + pm_device_action_run(TYPE_SECTION_START(zmk_pm_device_slots)[i], PM_DEVICE_ACTION_RESUME); + } + + zmk_num_susp = 0; +} +#endif /* !CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE */ +#endif /* CONFIG_ZMK_PM_DEVICE_SUSPEND_RESUME */ + #if IS_ENABLED(CONFIG_ZMK_PM_SOFT_OFF) #define HAS_WAKERS DT_HAS_COMPAT_STATUS_OKAY(zmk_soft_off_wakeup_sources) @@ -64,8 +123,15 @@ int zmk_pm_soft_off(void) { } #endif // HAS_WAKERS + int err = zmk_pm_suspend_devices(); + if (err < 0) { + zmk_pm_resume_devices(); + return err; + } + LOG_DBG("soft-off: go to sleep"); - return pm_state_force(0U, &(struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0}); + sys_poweroff(); + return 0; } #endif // IS_ENABLED(CONFIG_ZMK_PM_SOFT_OFF) \ No newline at end of file From cac999b1d6f09cb9f11fbdb832bed64b888baef5 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Tue, 20 Feb 2024 07:59:26 +0000 Subject: [PATCH 108/127] feat: Updated soft-off docs. * Document new sideband behavior kscan driver for integrated soft-off support. --- docs/docs/features/soft-off.md | 207 +++++++++++++++++++++++++-------- 1 file changed, 156 insertions(+), 51 deletions(-) diff --git a/docs/docs/features/soft-off.md b/docs/docs/features/soft-off.md index 370a3880..ff47e7f1 100644 --- a/docs/docs/features/soft-off.md +++ b/docs/docs/features/soft-off.md @@ -37,11 +37,28 @@ The simplest way to achieve this is with a push button between a GPIO pin and gr #### Matrix-Integrated Hardware Combo -Another, more complicated option is to tie two of the switch outputs in the matrix together through an AND gate and connect that to the dedicated GPIO pin. This way you can use a key combination in your existing keyboard matrix to trigger soft on/off. To make this work best, the two switches used should both be driven by the same matrix input pin so that both will be active simultaneously on the AND gate inputs. The alternative is to use a combination of diodes and capacitors to ensure both pins are active/high at the same time even if scanning sets them high at different times. Support for this mode will be coming soon. +Another, more complicated option is to tie two of the switch outputs in the matrix together through an AND gate and connect that to the dedicated GPIO pin. This way you can use a key combination in your existing keyboard matrix to trigger soft on/off. To make this work best, the two switches used should both be driven by the same matrix input pin so that both will be active simultaneously on the AND gate inputs. The alternative is to connect the switch to two MOSFETs that trigger both the regular matrix connect and the connect to the AND gate to ensure both pins are active/high at the same time even if scanning sets them high at different times. ### Firmware Changes -Several items work together to make both triggering soft off properly, and setting up the device to _wake_ from soft off work as expected. +Several items work together to make both triggering soft off properly, and setting up the device to _wake_ from soft off work as expected. In addition, some small changes are needed to keep the regular idle deep sleep functionality working. + +#### Wakeup Sources + +Zephyr has general support for the concept of a device as a "wakeup source", which ZMK has not previously used. Adding soft off requires properly updating the existing `kscan` devices with the `wakeup-source` property to ensure they will still work to wake the device from regular inactive deep sleep, e.g.: + +``` +/ { + kscan0: kscan_0 { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + diode-direction = "col2row"; + wakeup-source; + + ... + }; +}; +``` #### GPIO Key @@ -62,55 +79,6 @@ GPIO keys are defined using child nodes under the `gpio-keys` compatible node. E - The `gpios` property should be a phandle-array with a fully defined GPIO pin and with the correct pull up/down and active high/low flags set. In the above example the soft on/off would be triggered by pulling the specified pin low, typically by pressing a switch that has the other leg connected to ground. -#### Behavior Key - -Next, we will create a new "behavior key". Behavior keys are an easy way to tie a keymap behavior to a GPIO key outside of the normal keymap processing. They do _not_ do the normal keymap processing, so they are only suitable for use with basic behaviors, not complicated macros, hold-taps, etc. - -In this case, we will be creating a dedicated instance of the [Soft Off Behavior](../behaviors/soft-off.md) that will be used only for our hardware on/off button, then binding it to our key: - -``` -/ { - behaviors { - hw_soft_off: hw_soft_off { - compatible = "zmk,behavior-soft-off"; - #binding-cells = <0>; - hold-time-ms = <5000>; - }; - }; - - soft_off_behavior_key { - compatible = "zmk,gpio-key-behavior-trigger"; - bindings = <&hw_soft_off>; - key = <&wakeup_key>; - }; -}; -``` - -Here are the properties for the behavior key node: - -- The `compatible` property for the node must be `zmk,gpio-key-behavior-trigger`. -- The `bindings` property is a phandle to the soft off behavior defined above. -- The `key` property is a phandle to the GPIO key defined earlier. - -If you have set up your on/off to be controlled by a matrix-integrated combo, the behavior key will need to be integrated into your existing kscan setup. Full details to come when this is supported. - -#### Wakeup Sources - -Zephyr has general support for the concept of a device as a "wakeup source", which ZMK has not previously used. Adding soft off requires properly updating the existing `kscan` devices with the `wakeup-source` property, e.g.: - -``` -/ { - kscan0: kscan_0 { - compatible = "zmk,kscan-gpio-matrix"; - label = "KSCAN"; - diode-direction = "col2row"; - wakeup-source; - - ... - }; -}; -``` - #### Soft Off Waker Next, we need to add another device which will be enabled only when the keyboard is going into soft off state, and will configure the previously declared GPIO key with the correct interrupt configuration to wake the device from soft off once it is pressed. @@ -148,3 +116,140 @@ Here are the properties for the node: - The `compatible` property for the node must be `zmk,soft-off-wakeup-sources`. - The `wakeup-sources` property is a [phandle array](../config/index.md#devicetree-property-types) pointing to all the devices that should be enabled during the shutdown process to be sure they can later wake the keyboard. + +#### Soft Off Behavior Instance + +To use the [soft off behavior](../behaviors/soft-off.md) outside of a keymap, add an instance of the behavior to your `.overlay`/`.dts` file: + +``` +/ { + behaviors { + hw_soft_off: hw_soft_off { + compatible = "zmk,behavior-soft-off"; + #binding-cells = <0>; + hold-time-ms = <5000>; + }; + }; +}; +``` + +#### KScan Sideband Behavior + +The kscan sideband behavior driver will be used to trigger the [soft off behavior](../behaviors/soft-off.md) "out of band" from the normal keymap processing. To do so, it will decorate/wrap an underlying kscan driver. What kscan driver will vary for simple direct pin vs. matrix-integrated hardware combo. + +##### Simple Direct Pin + +With a simple direct pin setup, the The [direct kscan](../config/kscan.md) driver can be used with a GPIO key, to make a small "side matrix": + +``` + soft_off_direct_scan: soft_off_direct_scan { + compatible = "zmk,kscan-gpio-direct"; + input-keys = <&wakeup_key>; + }; +``` + +With that in place, the kscan sideband behavior will wrap the new driver: + +``` +/ { + side_band_behavior_triggers: side_band_behavior_triggers { + compatible = "zmk,kscan-sideband-behaviors"; + + kscan = <&soft_off_direct_scan>; + wakeup-source; + + soft_off { + column = <0>; + row = <0>; + bindings = <&hw_soft_off>; + }; + }; +}; +``` + +##### Matrix-Integrated Hardware Combo + +For this case, you will supplement the existing kscan matrix, by adding the additional pin as another entry in +the `row-gpios`/`col-gpios` for whichever pins are used to read the matrix state. For example, for an existing matrix like: + +``` + kscan: kscan { + compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + label = "KSCAN"; + debounce-press-ms = <1>; + debounce-release-ms = <5>; + + diode-direction = "col2row"; + + col-gpios + = <&gpio0 12 (GPIO_ACTIVE_HIGH)> + , <&gpio1 9 (GPIO_ACTIVE_HIGH)> + ; + row-gpios + = <&gpio0 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio0 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + }; +``` + +you would add another row value: + +``` + kscan: kscan { + compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + label = "KSCAN"; + debounce-press-ms = <1>; + debounce-release-ms = <5>; + + diode-direction = "col2row"; + + col-gpios + = <&gpio0 12 (GPIO_ACTIVE_HIGH)> + , <&gpio1 9 (GPIO_ACTIVE_HIGH)> + ; + row-gpios + = <&gpio0 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio0 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio0 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + }; +``` + +With that in place, you would decorate the kscan driver: + +``` + side_band_behavior_triggers: side_band_behavior_triggers { + compatible = "zmk,kscan-sideband-behaviors"; + wakeup-source; + kscan = <&kscan>; + soft_off { + column = <0>; + row = <3>; + bindings = <&hw_soft_off>; + }; + }; +``` + +Critically, the `column` and `row` values would correspond to the location of the added entry. + +Lastly, which is critical, you would update the `zmk,kscan` chosen value to point to the new kscan instance: + +``` + chosen { + ... + zmk,kscan = &side_band_behavior_triggers; + ... + }; +``` + +Here are the properties for the kscan sideband behaviors node: + +- The `compatible` property for the node must be `zmk,kscan-sideband-behaviors`. +- The `kscan` property is a phandle to the inner kscan instance that will have press/release events intercepted. + +The child nodes allow setting up the behaviors to invoke directly for a certain row and column: + +- The `row` and `column` properties set the values to intercept and trigger the behavior for. +- The `bindings` property references the behavior that should be triggered when the matching row and column event triggers. From bb94a7aafeb3d3d2f4165f58a654e79f8f6e6c9f Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Tue, 20 Feb 2024 00:10:15 -0800 Subject: [PATCH 109/127] fix: Fixes for building soft off without deep sleep. --- app/CMakeLists.txt | 2 +- app/Kconfig | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 2abf943f..2744f53d 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -8,7 +8,7 @@ set(ZEPHYR_EXTRA_MODULES "${ZMK_EXTRA_MODULES};${CMAKE_CURRENT_SOURCE_DIR}/modul find_package(Zephyr REQUIRED HINTS ../zephyr) project(zmk) -if(CONFIG_ZMK_SLEEP) +if(CONFIG_ZMK_PM_DEVICE_SUSPEND_RESUME) zephyr_linker_sources(SECTIONS include/linker/zmk-pm-devices.ld) endif() diff --git a/app/Kconfig b/app/Kconfig index 5068e91f..8f2fe837 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -433,9 +433,11 @@ config ZMK_PM_DEVICE_SUSPEND_RESUME config ZMK_PM_SOFT_OFF bool "Soft-off support" + depends on HAS_POWEROFF select ZMK_PM select PM_DEVICE select ZMK_PM_DEVICE_SUSPEND_RESUME + select POWEROFF config ZMK_GPIO_KEY_WAKEUP_TRIGGER bool "Hardware supported wakeup (GPIO)" From fa9ea9ea8b171a86765b5b08bed31922e9b2af76 Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Fri, 15 Mar 2024 20:22:54 -0400 Subject: [PATCH 110/127] fix(docs): Fix soft off waker prop name, headers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use the correct property for extra GPIOs to make active for the waker before going into soft off state. * Change header depth for easier navigation of the soft off feature page. Co-authored-by: Pablo Martínez <58857054+elpekenin@users.noreply.github.com> --- docs/docs/features/soft-off.md | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/docs/docs/features/soft-off.md b/docs/docs/features/soft-off.md index ff47e7f1..20a5bbe4 100644 --- a/docs/docs/features/soft-off.md +++ b/docs/docs/features/soft-off.md @@ -24,26 +24,24 @@ For existing designs, using soft off is as simple as placing the [Soft Off Behav You can then wake up the keyboard by pressing the reset button once, and repeating this for each side for split keyboards. -## Adding Dedicated Soft On/Off GPIO Pin To New Designs - -### Hardware Design +## Hardware Changes For New Designs ZMK's dedicated soft on/off pin feature requires a dedicated GPIO pin to be used to trigger powering off, and to wake the core from the soft off state when it goes active again later. -#### Simple Direct Pin +### Simple Direct Pin The simplest way to achieve this is with a push button between a GPIO pin and ground. -#### Matrix-Integrated Hardware Combo +### Matrix-Integrated Hardware Combo Another, more complicated option is to tie two of the switch outputs in the matrix together through an AND gate and connect that to the dedicated GPIO pin. This way you can use a key combination in your existing keyboard matrix to trigger soft on/off. To make this work best, the two switches used should both be driven by the same matrix input pin so that both will be active simultaneously on the AND gate inputs. The alternative is to connect the switch to two MOSFETs that trigger both the regular matrix connect and the connect to the AND gate to ensure both pins are active/high at the same time even if scanning sets them high at different times. -### Firmware Changes +## Firmware Changes For New Designs Several items work together to make both triggering soft off properly, and setting up the device to _wake_ from soft off work as expected. In addition, some small changes are needed to keep the regular idle deep sleep functionality working. -#### Wakeup Sources +### Wakeup Sources Zephyr has general support for the concept of a device as a "wakeup source", which ZMK has not previously used. Adding soft off requires properly updating the existing `kscan` devices with the `wakeup-source` property to ensure they will still work to wake the device from regular inactive deep sleep, e.g.: @@ -60,7 +58,7 @@ Zephyr has general support for the concept of a device as a "wakeup source", whi }; ``` -#### GPIO Key +### GPIO Key Zephyr's basic GPIO Key concept is used to configure the GPIO pin that will be used for both triggering soft off and waking the device later. Here is an example for a keyboard with a dedicated on/off push button that is a direct wire between the GPIO pin and ground: @@ -79,7 +77,7 @@ GPIO keys are defined using child nodes under the `gpio-keys` compatible node. E - The `gpios` property should be a phandle-array with a fully defined GPIO pin and with the correct pull up/down and active high/low flags set. In the above example the soft on/off would be triggered by pulling the specified pin low, typically by pressing a switch that has the other leg connected to ground. -#### Soft Off Waker +### Soft Off Waker Next, we need to add another device which will be enabled only when the keyboard is going into soft off state, and will configure the previously declared GPIO key with the correct interrupt configuration to wake the device from soft off once it is pressed. @@ -99,7 +97,7 @@ Here are the properties for the node: - The `compatible` property for the node must be `zmk,gpio-key-wakeup-trigger`. - The `trigger` property is a phandle to the GPIO key defined earlier. - The `wakeup-source` property signals to Zephyr this device should not be suspended during the shutdown procedure. -- An optional `output-gpios` property contains a list of GPIO pins (including the appropriate flags) to set active before going into power off, if needed to ensure the GPIO pin will trigger properly to wake the keyboard. This is only needed for matrix integrated combos. For those keyboards, the list should include the matrix output needs needed so the combo hardware is properly "driven" when the keyboard is off. +- An optional `extra-gpios` property contains a list of GPIO pins (including the appropriate flags) to set active before going into power off, if needed to ensure the GPIO pin will trigger properly to wake the keyboard. This is only needed for matrix integrated combos. For those keyboards, the list should include the matrix output needs needed so the combo hardware is properly "driven" when the keyboard is off. Once that is declared, we will list it in an additional configuration section so that the ZMK soft off process knows it needs to enable this device as part of the soft off processing: @@ -117,7 +115,7 @@ Here are the properties for the node: - The `compatible` property for the node must be `zmk,soft-off-wakeup-sources`. - The `wakeup-sources` property is a [phandle array](../config/index.md#devicetree-property-types) pointing to all the devices that should be enabled during the shutdown process to be sure they can later wake the keyboard. -#### Soft Off Behavior Instance +### Soft Off Behavior Instance To use the [soft off behavior](../behaviors/soft-off.md) outside of a keymap, add an instance of the behavior to your `.overlay`/`.dts` file: @@ -133,11 +131,11 @@ To use the [soft off behavior](../behaviors/soft-off.md) outside of a keymap, ad }; ``` -#### KScan Sideband Behavior +### KScan Sideband Behavior The kscan sideband behavior driver will be used to trigger the [soft off behavior](../behaviors/soft-off.md) "out of band" from the normal keymap processing. To do so, it will decorate/wrap an underlying kscan driver. What kscan driver will vary for simple direct pin vs. matrix-integrated hardware combo. -##### Simple Direct Pin +#### Simple Direct Pin With a simple direct pin setup, the The [direct kscan](../config/kscan.md) driver can be used with a GPIO key, to make a small "side matrix": @@ -167,7 +165,7 @@ With that in place, the kscan sideband behavior will wrap the new driver: }; ``` -##### Matrix-Integrated Hardware Combo +#### Matrix-Integrated Hardware Combo For this case, you will supplement the existing kscan matrix, by adding the additional pin as another entry in the `row-gpios`/`col-gpios` for whichever pins are used to read the matrix state. For example, for an existing matrix like: From 2df6dcd973776c0c0d1047d13178a72b5c0b6ca7 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Sat, 16 Mar 2024 14:15:52 -0700 Subject: [PATCH 111/127] feat(behaviors): More logging in soft off. --- app/src/behaviors/behavior_soft_off.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/behaviors/behavior_soft_off.c b/app/src/behaviors/behavior_soft_off.c index 878a2fc5..8b8ba4f9 100644 --- a/app/src/behaviors/behavior_soft_off.c +++ b/app/src/behaviors/behavior_soft_off.c @@ -45,8 +45,18 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding, struct behavior_soft_off_data *data = dev->data; const struct behavior_soft_off_config *config = dev->config; - if (config->hold_time_ms == 0 || (k_uptime_get() - data->press_start) >= config->hold_time_ms) { + if (config->hold_time_ms == 0) { + LOG_DBG("No hold time set, triggering soft off"); zmk_pm_soft_off(); + } else { + uint32_t hold_time = k_uptime_get() - data->press_start; + + if (hold_time > config->hold_time_ms) { + zmk_pm_soft_off(); + } else { + LOG_INF("Not triggering soft off: held for %d and hold time is %d", hold_time, + config->hold_time_ms); + } } return ZMK_BEHAVIOR_OPAQUE; From d0e0ecb4e3d11b5303c1dc5c857ff1f75c1d0aaa Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 25 Mar 2024 01:47:11 -0700 Subject: [PATCH 112/127] refactor: Use kscan directly to wake when we can. * When adding a dedicated GPIO pin for soft off/on, use the direct kscan as the waker, instead of adding an additional node. --- .../boards/nrf52840dk_nrf52840.overlay | 22 ++--- docs/docs/features/soft-off.md | 95 +++++++++++-------- 2 files changed, 63 insertions(+), 54 deletions(-) diff --git a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay index 47b67dc0..b9c68e5a 100644 --- a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay +++ b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay @@ -42,24 +42,10 @@ encoder: &qdec0 { }; }; - wakeup_source: wakeup_source { - compatible = "zmk,gpio-key-wakeup-trigger"; - status = "okay"; - - trigger = <&button0>; - wakeup-source; - }; - - soft_off_wakers { - compatible = "zmk,soft-off-wakeup-sources"; - status = "okay"; - - wakeup-sources = <&wakeup_source>; - }; - soft_off_direct_kscan: soft_off_direct_kscan { compatible = "zmk,kscan-gpio-direct"; input-keys = <&button0>; + wakeup-source; }; soft_off_sideband_behaviors { @@ -72,4 +58,10 @@ encoder: &qdec0 { }; }; + soft_off_wakers { + compatible = "zmk,soft-off-wakeup-sources"; + status = "okay"; + + wakeup-sources = <&soft_off_direct_kscan>; + }; }; \ No newline at end of file diff --git a/docs/docs/features/soft-off.md b/docs/docs/features/soft-off.md index 20a5bbe4..b08e1643 100644 --- a/docs/docs/features/soft-off.md +++ b/docs/docs/features/soft-off.md @@ -66,7 +66,7 @@ Zephyr's basic GPIO Key concept is used to configure the GPIO pin that will be u / { keys { compatible = "gpio-keys"; - wakeup_key: wakeup_key { + soft_off_key: soft_off_key { gpios = <&gpio0 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; }; }; @@ -77,44 +77,6 @@ GPIO keys are defined using child nodes under the `gpio-keys` compatible node. E - The `gpios` property should be a phandle-array with a fully defined GPIO pin and with the correct pull up/down and active high/low flags set. In the above example the soft on/off would be triggered by pulling the specified pin low, typically by pressing a switch that has the other leg connected to ground. -### Soft Off Waker - -Next, we need to add another device which will be enabled only when the keyboard is going into soft off state, and will configure the previously declared GPIO key with the correct interrupt configuration to wake the device from soft off once it is pressed. - -``` -/ { - wakeup_source: wakeup_source { - compatible = "zmk,gpio-key-wakeup-trigger"; - - trigger = <&wakeup_key>; - wakeup-source; - }; -}; -``` - -Here are the properties for the node: - -- The `compatible` property for the node must be `zmk,gpio-key-wakeup-trigger`. -- The `trigger` property is a phandle to the GPIO key defined earlier. -- The `wakeup-source` property signals to Zephyr this device should not be suspended during the shutdown procedure. -- An optional `extra-gpios` property contains a list of GPIO pins (including the appropriate flags) to set active before going into power off, if needed to ensure the GPIO pin will trigger properly to wake the keyboard. This is only needed for matrix integrated combos. For those keyboards, the list should include the matrix output needs needed so the combo hardware is properly "driven" when the keyboard is off. - -Once that is declared, we will list it in an additional configuration section so that the ZMK soft off process knows it needs to enable this device as part of the soft off processing: - -``` -/ { - soft_off_wakers { - compatible = "zmk,soft-off-wakeup-sources"; - wakeup-sources = <&wakeup_source>; - }; -}; -``` - -Here are the properties for the node: - -- The `compatible` property for the node must be `zmk,soft-off-wakeup-sources`. -- The `wakeup-sources` property is a [phandle array](../config/index.md#devicetree-property-types) pointing to all the devices that should be enabled during the shutdown process to be sure they can later wake the keyboard. - ### Soft Off Behavior Instance To use the [soft off behavior](../behaviors/soft-off.md) outside of a keymap, add an instance of the behavior to your `.overlay`/`.dts` file: @@ -143,6 +105,7 @@ With a simple direct pin setup, the The [direct kscan](../config/kscan.md) drive soft_off_direct_scan: soft_off_direct_scan { compatible = "zmk,kscan-gpio-direct"; input-keys = <&wakeup_key>; + wakeup-source; }; ``` @@ -165,6 +128,22 @@ With that in place, the kscan sideband behavior will wrap the new driver: }; ``` +Finally, we will list the kscan instance in an additional configuration section so that the ZMK soft off process knows it needs to enable this device as part of the soft off processing so it can _also_ wake the keyboard from soft off when pressed: + +``` +/ { + soft_off_wakers { + compatible = "zmk,soft-off-wakeup-sources"; + wakeup-sources = <&soft_off_direct_scan>; + }; +}; +``` + +Here are the properties for the node: + +- The `compatible` property for the node must be `zmk,soft-off-wakeup-sources`. +- The `wakeup-sources` property is a [phandle array](../config/index.md#devicetree-property-types) pointing to all the devices that should be enabled during the shutdown process to be sure they can later wake the keyboard. + #### Matrix-Integrated Hardware Combo For this case, you will supplement the existing kscan matrix, by adding the additional pin as another entry in @@ -251,3 +230,41 @@ The child nodes allow setting up the behaviors to invoke directly for a certain - The `row` and `column` properties set the values to intercept and trigger the behavior for. - The `bindings` property references the behavior that should be triggered when the matching row and column event triggers. + +### Soft Off Waker + +Next, we need to add another device which will be enabled only when the keyboard is going into soft off state, and will configure the previously declared GPIO key with the correct interrupt configuration to wake the device from soft off once it is pressed. + +``` +/ { + wakeup_source: wakeup_source { + compatible = "zmk,gpio-key-wakeup-trigger"; + + trigger = <&wakeup_key>; + wakeup-source; + }; +}; +``` + +Here are the properties for the node: + +- The `compatible` property for the node must be `zmk,gpio-key-wakeup-trigger`. +- The `trigger` property is a phandle to the GPIO key defined earlier. +- The `wakeup-source` property signals to Zephyr this device should not be suspended during the shutdown procedure. +- An optional `extra-gpios` property contains a list of GPIO pins (including the appropriate flags) to set active before going into power off, if needed to ensure the GPIO pin will trigger properly to wake the keyboard. This is only needed for matrix integrated combos. For those keyboards, the list should include the matrix output needs needed so the combo hardware is properly "driven" when the keyboard is off. + +Once that is declared, we will list it in an additional configuration section so that the ZMK soft off process knows it needs to enable this device as part of the soft off processing: + +``` +/ { + soft_off_wakers { + compatible = "zmk,soft-off-wakeup-sources"; + wakeup-sources = <&wakeup_source>; + }; +}; +``` + +Here are the properties for the node: + +- The `compatible` property for the node must be `zmk,soft-off-wakeup-sources`. +- The `wakeup-sources` property is a [phandle array](../config/index.md#devicetree-property-types) pointing to all the devices that should be enabled during the shutdown process to be sure they can later wake the keyboard. From 41d81801ed11a1dca918c9c0088351856e4e1808 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 25 Mar 2024 09:37:14 +0000 Subject: [PATCH 113/127] fix(pm): Use Zephyr created device slots. * Avoid overwriting random memory by using iterable section created by Zephyr PM. --- app/CMakeLists.txt | 4 ---- app/include/linker/zmk-pm-devices.ld | 9 --------- app/src/pm.c | 6 +++--- 3 files changed, 3 insertions(+), 16 deletions(-) delete mode 100644 app/include/linker/zmk-pm-devices.ld diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 2744f53d..0b681ea9 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -8,10 +8,6 @@ set(ZEPHYR_EXTRA_MODULES "${ZMK_EXTRA_MODULES};${CMAKE_CURRENT_SOURCE_DIR}/modul find_package(Zephyr REQUIRED HINTS ../zephyr) project(zmk) -if(CONFIG_ZMK_PM_DEVICE_SUSPEND_RESUME) - zephyr_linker_sources(SECTIONS include/linker/zmk-pm-devices.ld) -endif() - zephyr_linker_sources(SECTIONS include/linker/zmk-behaviors.ld) zephyr_linker_sources(RODATA include/linker/zmk-events.ld) diff --git a/app/include/linker/zmk-pm-devices.ld b/app/include/linker/zmk-pm-devices.ld deleted file mode 100644 index 93ec5025..00000000 --- a/app/include/linker/zmk-pm-devices.ld +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2023 The ZMK Contributors - * - * SPDX-License-Identifier: MIT - */ - -#include - -ITERABLE_SECTION_RAM(zmk_pm_device_slots, 4) diff --git a/app/src/pm.c b/app/src/pm.c index 4f151875..447eb351 100644 --- a/app/src/pm.c +++ b/app/src/pm.c @@ -21,7 +21,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); // TODO: Tweak this to smarter runtime PM of subsystems on sleep. #ifdef CONFIG_ZMK_PM_DEVICE_SUSPEND_RESUME -TYPE_SECTION_START_EXTERN(const struct device *, zmk_pm_device_slots); +TYPE_SECTION_START_EXTERN(const struct device *, pm_device_slots); #if !defined(CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE) /* Number of devices successfully suspended. */ @@ -57,7 +57,7 @@ int zmk_pm_suspend_devices(void) { return ret; } - TYPE_SECTION_START(zmk_pm_device_slots)[zmk_num_susp] = dev; + TYPE_SECTION_START(pm_device_slots)[zmk_num_susp] = dev; zmk_num_susp++; } @@ -66,7 +66,7 @@ int zmk_pm_suspend_devices(void) { void zmk_pm_resume_devices(void) { for (int i = (zmk_num_susp - 1); i >= 0; i--) { - pm_device_action_run(TYPE_SECTION_START(zmk_pm_device_slots)[i], PM_DEVICE_ACTION_RESUME); + pm_device_action_run(TYPE_SECTION_START(pm_device_slots)[i], PM_DEVICE_ACTION_RESUME); } zmk_num_susp = 0; From 7e7110d85f0fe24948b319382bed723e38f5336c Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 25 Mar 2024 02:39:54 -0700 Subject: [PATCH 114/127] fix(pm): Fixes for dedicated on/off on peripherals. * Add new flag to differentiate soft off on peripherals that is invoked by split GATT svc and dedicated additional ones tied to GPIO pin. --- .../zmk_uno/boards/nrf52840dk_nrf52840.overlay | 5 ++--- app/dts/behaviors/soft_off.dtsi | 3 ++- .../behaviors/zmk,behavior-soft-off.yaml | 3 +++ app/src/behaviors/behavior_soft_off.c | 17 ++++++++++++----- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay index b9c68e5a..d798eca7 100644 --- a/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay +++ b/app/boards/shields/zmk_uno/boards/nrf52840dk_nrf52840.overlay @@ -35,10 +35,9 @@ encoder: &qdec0 { / { behaviors { - soft_off: soft_off { + hw_soft_off: hw_soft_off { compatible = "zmk,behavior-soft-off"; #binding-cells = <0>; - status = "okay"; }; }; @@ -54,7 +53,7 @@ encoder: &qdec0 { soft_off { row = <0>; column = <0>; - bindings = <&soft_off>; + bindings = <&hw_soft_off>; }; }; diff --git a/app/dts/behaviors/soft_off.dtsi b/app/dts/behaviors/soft_off.dtsi index 1e58c771..63c04b1d 100644 --- a/app/dts/behaviors/soft_off.dtsi +++ b/app/dts/behaviors/soft_off.dtsi @@ -6,9 +6,10 @@ / { behaviors { - /omit-if-no-ref/ soft_off: soft_off { + /omit-if-no-ref/ soft_off: keymap_soft_off { compatible = "zmk,behavior-soft-off"; #binding-cells = <0>; + split-peripheral-off-on-press; }; }; }; diff --git a/app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml b/app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml index 1467ede4..865e656f 100644 --- a/app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml +++ b/app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml @@ -12,3 +12,6 @@ properties: type: int required: false description: Number of milliseconds the behavior must be held before releasing will actually trigger a soft-off. + split-peripheral-off-on-press: + type: boolean + description: When built for a split peripheral, turn off on press, not release diff --git a/app/src/behaviors/behavior_soft_off.c b/app/src/behaviors/behavior_soft_off.c index 8b8ba4f9..3a4ae424 100644 --- a/app/src/behaviors/behavior_soft_off.c +++ b/app/src/behaviors/behavior_soft_off.c @@ -16,6 +16,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); struct behavior_soft_off_config { + bool split_peripheral_turn_off_on_press; uint32_t hold_time_ms; }; @@ -23,18 +24,22 @@ struct behavior_soft_off_data { uint32_t press_start; }; +#define IS_SPLIT_PERIPHERAL \ + (IS_ENABLED(CONFIG_ZMK_SPLIT) && !IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)) + static int behavior_soft_off_init(const struct device *dev) { return 0; }; static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { const struct device *dev = zmk_behavior_get_binding(binding->behavior_dev); struct behavior_soft_off_data *data = dev->data; + const struct behavior_soft_off_config *config = dev->config; -#if IS_ENABLED(CONFIG_ZMK_SPLIT) && !IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) - zmk_pm_soft_off(); -#else - data->press_start = k_uptime_get(); -#endif + if (IS_SPLIT_PERIPHERAL && config->split_peripheral_turn_off_on_press) { + zmk_pm_soft_off(); + } else { + data->press_start = k_uptime_get(); + } return ZMK_BEHAVIOR_OPAQUE; } @@ -71,6 +76,8 @@ static const struct behavior_driver_api behavior_soft_off_driver_api = { #define BSO_INST(n) \ static const struct behavior_soft_off_config bso_config_##n = { \ .hold_time_ms = DT_INST_PROP_OR(n, hold_time_ms, 0), \ + .split_peripheral_turn_off_on_press = \ + DT_INST_PROP_OR(n, split_peripheral_off_on_press, false), \ }; \ static struct behavior_soft_off_data bso_data_##n = {}; \ BEHAVIOR_DT_INST_DEFINE(0, behavior_soft_off_init, NULL, &bso_data_##n, &bso_config_##n, \ From 29c0cdb3abce98708f5961e01d96eefc9efb7d42 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 25 Mar 2024 09:41:33 +0000 Subject: [PATCH 115/127] fix(shields): Fix for direct use with ZMK Uno split. --- app/boards/shields/zmk_uno/zmk_uno_split.keymap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/boards/shields/zmk_uno/zmk_uno_split.keymap b/app/boards/shields/zmk_uno/zmk_uno_split.keymap index 37672a7d..0e50a283 100644 --- a/app/boards/shields/zmk_uno/zmk_uno_split.keymap +++ b/app/boards/shields/zmk_uno/zmk_uno_split.keymap @@ -21,7 +21,7 @@ // / { // chosen { // zmk,matrix-transform = &split_direct_matrix_transform; -// zmk,kscan = &kscan_direct_comp; +// zmk,kscan = &kscan_direct; // }; // }; From e66f068fb5d53f3e6071359970021d04a338c176 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 27 Mar 2024 20:35:40 -0700 Subject: [PATCH 116/127] fix(docs): Minor soft-off docs tweaks from review. --- docs/docs/behaviors/soft-off.md | 2 ++ docs/docs/config/kscan.md | 2 +- docs/docs/features/soft-off.md | 8 ++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/docs/behaviors/soft-off.md b/docs/docs/behaviors/soft-off.md index 05374004..14b5f36a 100644 --- a/docs/docs/behaviors/soft-off.md +++ b/docs/docs/behaviors/soft-off.md @@ -7,6 +7,8 @@ sidebar_label: Soft Off The soft off behavior is used to force the keyboard into an off state. Depending on the specific keyboard hardware, the keyboard can be turned back on again either with a dedicated on/off button that is available, or using the reset button found on the device. +Refer to the [soft off config](../config/power.md#soft-off) for details on enabling soft off in order to use this behavior. + For more information, see the [Soft Off Feature](../features/soft-off.md) page. ### Behavior Binding diff --git a/docs/docs/config/kscan.md b/docs/docs/config/kscan.md index 4a3954f9..3aa1b378 100644 --- a/docs/docs/config/kscan.md +++ b/docs/docs/config/kscan.md @@ -73,7 +73,7 @@ Definition file: [zmk/app/module/dts/bindings/kscan/zmk,kscan-gpio-direct.yaml]( | Property | Type | Description | Default | | ------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------- | ------- | -| `input-gpios` | GPIO array | Input GPIOs (one per key) | | +| `input-gpios` | GPIO array | Input GPIOs (one per key). Can be either direct GPIO pin or `gpio-key` references. | | | `debounce-press-ms` | int | Debounce time for key press in milliseconds. Use 0 for eager debouncing. | 5 | | `debounce-release-ms` | int | Debounce time for key release in milliseconds. | 5 | | `debounce-scan-period-ms` | int | Time between reads in milliseconds when any key is pressed. | 1 | diff --git a/docs/docs/features/soft-off.md b/docs/docs/features/soft-off.md index b08e1643..bd631f1b 100644 --- a/docs/docs/features/soft-off.md +++ b/docs/docs/features/soft-off.md @@ -18,6 +18,10 @@ Once powered off, the keyboard will only wake up when: - You press the same button/sequence that you pressed to power off the keyboard, or - You press a reset button found on the keyboard. +## Config + +Refer to the [soft off config](../config/power.md#soft-off) for details on enabling soft off. + ## Soft Off With Existing Designs For existing designs, using soft off is as simple as placing the [Soft Off Behavior](../behaviors/soft-off.md) in your keymap and then invoking it. @@ -104,7 +108,7 @@ With a simple direct pin setup, the The [direct kscan](../config/kscan.md) drive ``` soft_off_direct_scan: soft_off_direct_scan { compatible = "zmk,kscan-gpio-direct"; - input-keys = <&wakeup_key>; + input-keys = <&on_off_key>; wakeup-source; }; ``` @@ -240,7 +244,7 @@ Next, we need to add another device which will be enabled only when the keyboard wakeup_source: wakeup_source { compatible = "zmk,gpio-key-wakeup-trigger"; - trigger = <&wakeup_key>; + trigger = <&on_off_key>; wakeup-source; }; }; From f9bb18b67631288a7ee8046e796775e34b61c0f6 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Thu, 28 Mar 2024 04:14:02 +0000 Subject: [PATCH 117/127] fix(docs): Add `&soft_off` to behaviors index. --- docs/docs/behaviors/index.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs/behaviors/index.mdx b/docs/docs/behaviors/index.mdx index 32f4b29a..4a05f565 100644 --- a/docs/docs/behaviors/index.mdx +++ b/docs/docs/behaviors/index.mdx @@ -70,6 +70,7 @@ Below is a summary of pre-defined behavior bindings and user-definable behaviors | Binding | Behavior | Description | | ------------ | --------------------------------------------- | --------------------------------------------------------------- | | `&ext_power` | [Power management](power.md#behavior-binding) | Allows enabling or disabling the VCC power output to save power | +| `&soft_off` | [Soft off](soft-off.md#behavior-binding) | Turns the keyboard off. | ## User-defined behaviors From 34910787ff68d7e977a2f74b4bc51ef8f99d2cb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 23 Mar 2024 06:44:29 +0000 Subject: [PATCH 118/127] chore(deps): bump webpack-dev-middleware from 5.3.3 to 5.3.4 in /docs Bumps [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) from 5.3.3 to 5.3.4. - [Release notes](https://github.com/webpack/webpack-dev-middleware/releases) - [Changelog](https://github.com/webpack/webpack-dev-middleware/blob/v5.3.4/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack-dev-middleware/compare/v5.3.3...v5.3.4) --- updated-dependencies: - dependency-name: webpack-dev-middleware dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 16525e7c..b0b7e4f6 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -21538,9 +21538,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", - "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.3", From 25bb126a11736545401e351a68649b7626763963 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 17:16:57 +0000 Subject: [PATCH 119/127] chore(deps): bump express from 4.18.2 to 4.19.2 in /docs Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2) --- updated-dependencies: - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/package-lock.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index b0b7e4f6..afdc8248 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -4809,12 +4809,12 @@ } }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -4822,7 +4822,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -5542,9 +5542,9 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -9042,16 +9042,16 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -17802,9 +17802,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", From 18b86b7720201dde045fddb42965cd64d1082a9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 17:23:05 +0000 Subject: [PATCH 120/127] chore(deps): bump follow-redirects from 1.15.5 to 1.15.6 in /docs Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.5 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.5...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index afdc8248..379360a9 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9387,9 +9387,9 @@ "devOptional": true }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", From d672b0c70512aa9c880c76f34dd448f9cffe4ae6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 17:32:02 +0000 Subject: [PATCH 121/127] chore(deps): bump react-toastify from 7.0.4 to 10.0.5 in /docs Bumps [react-toastify](https://github.com/fkhadra/react-toastify) from 7.0.4 to 10.0.5. - [Release notes](https://github.com/fkhadra/react-toastify/releases) - [Commits](https://github.com/fkhadra/react-toastify/compare/v7.0.4...v10.0.5) --- updated-dependencies: - dependency-name: react-toastify dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- docs/package-lock.json | 22 +++++++--------------- docs/package.json | 2 +- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 379360a9..3c76a963 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -20,7 +20,7 @@ "react-async": "^10.0.1", "react-copy-to-clipboard": "^5.0.3", "react-dom": "^18.0.0", - "react-toastify": "^7.0.4", + "react-toastify": "^10.0.5", "web-tree-sitter": "^0.20.8" }, "devDependencies": { @@ -18049,23 +18049,15 @@ } }, "node_modules/react-toastify": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-7.0.4.tgz", - "integrity": "sha512-Rol7+Cn39hZp5hQ/k6CbMNE2CKYV9E5OQdC/hBLtIQU2xz7DdAm7xil4NITQTHR6zEbE5RVFbpgSwTD7xRGLeQ==", + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz", + "integrity": "sha512-mNKt2jBXJg4O7pSdbNUfDdTsK9FIdikfsIE/yUCxbAEXl4HMyJaivrVFcn3Elvt5xvCQYhUZm+hqTIu1UXM3Pw==", "dependencies": { - "clsx": "^1.1.1" + "clsx": "^2.1.0" }, "peerDependencies": { - "react": ">=16", - "react-dom": ">=16" - } - }, - "node_modules/react-toastify/node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "engines": { - "node": ">=6" + "react": ">=18", + "react-dom": ">=18" } }, "node_modules/read-package-json-fast": { diff --git a/docs/package.json b/docs/package.json index 7f468cb5..a0801763 100644 --- a/docs/package.json +++ b/docs/package.json @@ -27,7 +27,7 @@ "react-async": "^10.0.1", "react-copy-to-clipboard": "^5.0.3", "react-dom": "^18.0.0", - "react-toastify": "^7.0.4", + "react-toastify": "^10.0.5", "web-tree-sitter": "^0.20.8" }, "browserslist": { From fff1cbecdcc75302b6280a469ed31687cfc79776 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 29 Mar 2024 18:15:06 +0000 Subject: [PATCH 122/127] fix: Add wakeup-source; to kscan nodes for ZMK_SLEEP. * ZMK_SLEEP also enables PM_DEVICE, so be sure to mark kscan nodes as wakeup sources so they can wake keyboards from sleep. --- app/boards/arm/adv360pro/adv360pro_left.dts | 1 + app/boards/arm/adv360pro/adv360pro_right.dts | 1 + app/boards/arm/bt60/bt60_v1.dts | 2 ++ app/boards/arm/bt60/bt60_v1_hs.dts | 2 ++ app/boards/arm/ckp/ckp.dtsi | 2 ++ app/boards/arm/corneish_zen/corneish_zen_v1_left.dts | 1 + app/boards/arm/corneish_zen/corneish_zen_v1_right.dts | 1 + app/boards/arm/corneish_zen/corneish_zen_v2_left.dts | 1 + app/boards/arm/corneish_zen/corneish_zen_v2_right.dts | 1 + app/boards/arm/glove80/glove80.dtsi | 2 ++ app/boards/arm/nice60/nice60.dts | 1 + app/boards/arm/s40nc/s40nc.dts | 1 + app/boards/shields/a_dux/a_dux.dtsi | 2 ++ app/boards/shields/bat43/bat43.overlay | 1 + app/boards/shields/bfo9000/bfo9000.dtsi | 1 + app/boards/shields/boardsource3x4/boardsource3x4.overlay | 2 ++ app/boards/shields/boardsource5x12/boardsource5x12.overlay | 2 ++ app/boards/shields/chalice/chalice.overlay | 2 ++ app/boards/shields/clog/clog.dtsi | 1 + app/boards/shields/contra/contra.overlay | 2 ++ app/boards/shields/corne/corne.dtsi | 1 + app/boards/shields/cradio/cradio.dtsi | 2 ++ app/boards/shields/crbn/crbn.overlay | 2 ++ app/boards/shields/eek/eek.overlay | 2 ++ app/boards/shields/elephant42/elephant42.dtsi | 1 + app/boards/shields/ergodash/ergodash.dtsi | 1 + app/boards/shields/eternal_keypad/eternal_keypad.dtsi | 1 + app/boards/shields/fourier/fourier.dtsi | 1 + app/boards/shields/helix/helix.dtsi | 1 + app/boards/shields/hummingbird/hummingbird.overlay | 2 ++ app/boards/shields/iris/iris.dtsi | 1 + app/boards/shields/jian/jian.dtsi | 1 + app/boards/shields/jiran/jiran.dtsi | 1 + app/boards/shields/jorne/jorne.dtsi | 1 + app/boards/shields/knob_goblin/knob_goblin.overlay | 2 ++ app/boards/shields/kyria/kyria_common.dtsi | 1 + app/boards/shields/leeloo/leeloo_common.dtsi | 1 + app/boards/shields/leeloo_micro/leeloo_micro.dtsi | 1 + app/boards/shields/lily58/lily58.dtsi | 1 + app/boards/shields/lotus58/lotus58.dtsi | 1 + app/boards/shields/m60/m60.overlay | 1 + app/boards/shields/microdox/microdox.dtsi | 1 + app/boards/shields/microdox/microdox_v2.dtsi | 1 + app/boards/shields/murphpad/murphpad.overlay | 1 + app/boards/shields/naked60/naked60.overlay | 1 + app/boards/shields/osprette/osprette.overlay | 1 + app/boards/shields/pancake/pancake.overlay | 1 + app/boards/shields/qaz/qaz.overlay | 1 + app/boards/shields/quefrency/quefrency_left.overlay | 2 ++ app/boards/shields/quefrency/quefrency_right.overlay | 2 ++ app/boards/shields/redox/redox.dtsi | 1 + app/boards/shields/reviung34/reviung34.overlay | 2 ++ app/boards/shields/reviung41/reviung41.overlay | 2 ++ app/boards/shields/reviung5/reviung5.overlay | 1 + app/boards/shields/reviung53/reviung53.overlay | 2 ++ app/boards/shields/romac/romac.overlay | 1 + app/boards/shields/romac_plus/romac_plus.overlay | 1 + app/boards/shields/sofle/sofle.dtsi | 1 + .../splitkb_aurora_corne/splitkb_aurora_corne_left.overlay | 2 ++ .../splitkb_aurora_corne/splitkb_aurora_corne_right.overlay | 2 ++ .../splitkb_aurora_helix/splitkb_aurora_helix_left.overlay | 2 ++ .../splitkb_aurora_helix/splitkb_aurora_helix_right.overlay | 2 ++ .../splitkb_aurora_lily58/splitkb_aurora_lily58_left.overlay | 2 ++ .../splitkb_aurora_lily58/splitkb_aurora_lily58_right.overlay | 2 ++ .../splitkb_aurora_sofle/splitkb_aurora_sofle_left.overlay | 2 ++ .../splitkb_aurora_sofle/splitkb_aurora_sofle_right.overlay | 2 ++ .../splitkb_aurora_sweep/splitkb_aurora_sweep_left.overlay | 2 ++ .../splitkb_aurora_sweep/splitkb_aurora_sweep_right.overlay | 1 + app/boards/shields/splitreus62/splitreus62.dtsi | 1 + app/boards/shields/tg4x/tg4x.overlay | 1 + app/boards/shields/two_percent_milk/two_percent_milk.overlay | 1 + app/boards/shields/waterfowl/waterfowl.dtsi | 1 + app/boards/shields/zodiark/zodiark.dtsi | 1 + 73 files changed, 101 insertions(+) diff --git a/app/boards/arm/adv360pro/adv360pro_left.dts b/app/boards/arm/adv360pro/adv360pro_left.dts index 6ef5f590..459a2232 100644 --- a/app/boards/arm/adv360pro/adv360pro_left.dts +++ b/app/boards/arm/adv360pro/adv360pro_left.dts @@ -10,6 +10,7 @@ /{ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/arm/adv360pro/adv360pro_right.dts b/app/boards/arm/adv360pro/adv360pro_right.dts index 97d846f8..748cc42a 100644 --- a/app/boards/arm/adv360pro/adv360pro_right.dts +++ b/app/boards/arm/adv360pro/adv360pro_right.dts @@ -10,6 +10,7 @@ /{ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/arm/bt60/bt60_v1.dts b/app/boards/arm/bt60/bt60_v1.dts index 53d4e77b..315d8cce 100644 --- a/app/boards/arm/bt60/bt60_v1.dts +++ b/app/boards/arm/bt60/bt60_v1.dts @@ -81,6 +81,8 @@ kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; col-gpios diff --git a/app/boards/arm/bt60/bt60_v1_hs.dts b/app/boards/arm/bt60/bt60_v1_hs.dts index 57b47554..27e38286 100644 --- a/app/boards/arm/bt60/bt60_v1_hs.dts +++ b/app/boards/arm/bt60/bt60_v1_hs.dts @@ -30,6 +30,8 @@ kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; col-gpios diff --git a/app/boards/arm/ckp/ckp.dtsi b/app/boards/arm/ckp/ckp.dtsi index 6bbbbdd7..4142622a 100644 --- a/app/boards/arm/ckp/ckp.dtsi +++ b/app/boards/arm/ckp/ckp.dtsi @@ -34,6 +34,8 @@ kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; col-gpios diff --git a/app/boards/arm/corneish_zen/corneish_zen_v1_left.dts b/app/boards/arm/corneish_zen/corneish_zen_v1_left.dts index 6683b1b2..2c77f01c 100644 --- a/app/boards/arm/corneish_zen/corneish_zen_v1_left.dts +++ b/app/boards/arm/corneish_zen/corneish_zen_v1_left.dts @@ -15,6 +15,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/arm/corneish_zen/corneish_zen_v1_right.dts b/app/boards/arm/corneish_zen/corneish_zen_v1_right.dts index 492c79fa..536e46ea 100644 --- a/app/boards/arm/corneish_zen/corneish_zen_v1_right.dts +++ b/app/boards/arm/corneish_zen/corneish_zen_v1_right.dts @@ -15,6 +15,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/arm/corneish_zen/corneish_zen_v2_left.dts b/app/boards/arm/corneish_zen/corneish_zen_v2_left.dts index dacb24c3..42839b61 100644 --- a/app/boards/arm/corneish_zen/corneish_zen_v2_left.dts +++ b/app/boards/arm/corneish_zen/corneish_zen_v2_left.dts @@ -15,6 +15,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/arm/corneish_zen/corneish_zen_v2_right.dts b/app/boards/arm/corneish_zen/corneish_zen_v2_right.dts index f1baea42..b47d122f 100644 --- a/app/boards/arm/corneish_zen/corneish_zen_v2_right.dts +++ b/app/boards/arm/corneish_zen/corneish_zen_v2_right.dts @@ -15,6 +15,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/arm/glove80/glove80.dtsi b/app/boards/arm/glove80/glove80.dtsi index 0078fe62..4803488b 100644 --- a/app/boards/arm/glove80/glove80.dtsi +++ b/app/boards/arm/glove80/glove80.dtsi @@ -34,6 +34,8 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; debounce-press-ms = <4>; debounce-release-ms = <20>; diff --git a/app/boards/arm/nice60/nice60.dts b/app/boards/arm/nice60/nice60.dts index 7397cffa..d1b9f992 100644 --- a/app/boards/arm/nice60/nice60.dts +++ b/app/boards/arm/nice60/nice60.dts @@ -42,6 +42,7 @@ RC(4,0) RC(4,1) RC(4,2) RC(4,5) R kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/arm/s40nc/s40nc.dts b/app/boards/arm/s40nc/s40nc.dts index a04f42e1..a2eb89ea 100644 --- a/app/boards/arm/s40nc/s40nc.dts +++ b/app/boards/arm/s40nc/s40nc.dts @@ -37,6 +37,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/a_dux/a_dux.dtsi b/app/boards/shields/a_dux/a_dux.dtsi index caeae8db..46aa8fda 100644 --- a/app/boards/shields/a_dux/a_dux.dtsi +++ b/app/boards/shields/a_dux/a_dux.dtsi @@ -27,6 +27,8 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-direct"; + wakeup-source; + input-gpios = <&pro_micro 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, <&pro_micro 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, diff --git a/app/boards/shields/bat43/bat43.overlay b/app/boards/shields/bat43/bat43.overlay index 600dccec..89c2428d 100644 --- a/app/boards/shields/bat43/bat43.overlay +++ b/app/boards/shields/bat43/bat43.overlay @@ -28,6 +28,7 @@ RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(6,0) RC(6,1) RC(6,2) kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; col-gpios diff --git a/app/boards/shields/bfo9000/bfo9000.dtsi b/app/boards/shields/bfo9000/bfo9000.dtsi index ea9283ad..11080671 100644 --- a/app/boards/shields/bfo9000/bfo9000.dtsi +++ b/app/boards/shields/bfo9000/bfo9000.dtsi @@ -28,6 +28,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/boardsource3x4/boardsource3x4.overlay b/app/boards/shields/boardsource3x4/boardsource3x4.overlay index 389f5b7a..0d63214d 100644 --- a/app/boards/shields/boardsource3x4/boardsource3x4.overlay +++ b/app/boards/shields/boardsource3x4/boardsource3x4.overlay @@ -13,6 +13,8 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/boardsource5x12/boardsource5x12.overlay b/app/boards/shields/boardsource5x12/boardsource5x12.overlay index 9a721d0c..15ae7b68 100644 --- a/app/boards/shields/boardsource5x12/boardsource5x12.overlay +++ b/app/boards/shields/boardsource5x12/boardsource5x12.overlay @@ -13,6 +13,8 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/chalice/chalice.overlay b/app/boards/shields/chalice/chalice.overlay index 92dfe356..8631d735 100644 --- a/app/boards/shields/chalice/chalice.overlay +++ b/app/boards/shields/chalice/chalice.overlay @@ -44,6 +44,8 @@ kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; col-gpios diff --git a/app/boards/shields/clog/clog.dtsi b/app/boards/shields/clog/clog.dtsi index feea830c..883aaa29 100644 --- a/app/boards/shields/clog/clog.dtsi +++ b/app/boards/shields/clog/clog.dtsi @@ -26,6 +26,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-direct"; + wakeup-source; input-gpios = <&pro_micro 18 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)> diff --git a/app/boards/shields/contra/contra.overlay b/app/boards/shields/contra/contra.overlay index 0ac042d6..45cc3088 100644 --- a/app/boards/shields/contra/contra.overlay +++ b/app/boards/shields/contra/contra.overlay @@ -11,6 +11,8 @@ kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; col-gpios diff --git a/app/boards/shields/corne/corne.dtsi b/app/boards/shields/corne/corne.dtsi index f6d41e33..e1edcce8 100644 --- a/app/boards/shields/corne/corne.dtsi +++ b/app/boards/shields/corne/corne.dtsi @@ -47,6 +47,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 kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/cradio/cradio.dtsi b/app/boards/shields/cradio/cradio.dtsi index 4f8a09d7..b510c636 100644 --- a/app/boards/shields/cradio/cradio.dtsi +++ b/app/boards/shields/cradio/cradio.dtsi @@ -27,6 +27,8 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-direct"; + wakeup-source; + input-gpios = <&pro_micro 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)> , <&pro_micro 18 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)> diff --git a/app/boards/shields/crbn/crbn.overlay b/app/boards/shields/crbn/crbn.overlay index af5910d6..c6a2b87c 100644 --- a/app/boards/shields/crbn/crbn.overlay +++ b/app/boards/shields/crbn/crbn.overlay @@ -13,6 +13,8 @@ kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; col-gpios diff --git a/app/boards/shields/eek/eek.overlay b/app/boards/shields/eek/eek.overlay index e9e734ac..28aab7ef 100644 --- a/app/boards/shields/eek/eek.overlay +++ b/app/boards/shields/eek/eek.overlay @@ -26,6 +26,8 @@ kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; col-gpios diff --git a/app/boards/shields/elephant42/elephant42.dtsi b/app/boards/shields/elephant42/elephant42.dtsi index 22a72708..d72aa9a8 100644 --- a/app/boards/shields/elephant42/elephant42.dtsi +++ b/app/boards/shields/elephant42/elephant42.dtsi @@ -26,6 +26,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) kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/ergodash/ergodash.dtsi b/app/boards/shields/ergodash/ergodash.dtsi index 2e41ca30..b6ef7fc4 100644 --- a/app/boards/shields/ergodash/ergodash.dtsi +++ b/app/boards/shields/ergodash/ergodash.dtsi @@ -35,6 +35,7 @@ RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,4) RC(4,5) RC(4,6) RC(4,13) RC(4,12 kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; diff --git a/app/boards/shields/eternal_keypad/eternal_keypad.dtsi b/app/boards/shields/eternal_keypad/eternal_keypad.dtsi index 3144f986..1274e3dd 100644 --- a/app/boards/shields/eternal_keypad/eternal_keypad.dtsi +++ b/app/boards/shields/eternal_keypad/eternal_keypad.dtsi @@ -14,6 +14,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; diff --git a/app/boards/shields/fourier/fourier.dtsi b/app/boards/shields/fourier/fourier.dtsi index 3b309b8d..f486e0a4 100644 --- a/app/boards/shields/fourier/fourier.dtsi +++ b/app/boards/shields/fourier/fourier.dtsi @@ -30,6 +30,7 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) /**/ RC(3,6) RC(3,9 kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/helix/helix.dtsi b/app/boards/shields/helix/helix.dtsi index df80f4ca..8566ffc6 100644 --- a/app/boards/shields/helix/helix.dtsi +++ b/app/boards/shields/helix/helix.dtsi @@ -32,6 +32,7 @@ RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,4) RC(4,5) RC(4,6) RC(4,7) RC(4,8) RC(4,9 kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/hummingbird/hummingbird.overlay b/app/boards/shields/hummingbird/hummingbird.overlay index 871728a2..2474d089 100644 --- a/app/boards/shields/hummingbird/hummingbird.overlay +++ b/app/boards/shields/hummingbird/hummingbird.overlay @@ -29,6 +29,8 @@ kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "row2col"; col-gpios diff --git a/app/boards/shields/iris/iris.dtsi b/app/boards/shields/iris/iris.dtsi index c979214c..8ddbd359 100644 --- a/app/boards/shields/iris/iris.dtsi +++ b/app/boards/shields/iris/iris.dtsi @@ -32,6 +32,7 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(4,2) RC(4,9) RC(3,6) RC(3,7) kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/jian/jian.dtsi b/app/boards/shields/jian/jian.dtsi index c5ae1b9e..439bf93c 100644 --- a/app/boards/shields/jian/jian.dtsi +++ b/app/boards/shields/jian/jian.dtsi @@ -62,6 +62,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/jiran/jiran.dtsi b/app/boards/shields/jiran/jiran.dtsi index b6633b65..517cbe5f 100644 --- a/app/boards/shields/jiran/jiran.dtsi +++ b/app/boards/shields/jiran/jiran.dtsi @@ -67,6 +67,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/jorne/jorne.dtsi b/app/boards/shields/jorne/jorne.dtsi index a2d804b9..e7b81e5f 100644 --- a/app/boards/shields/jorne/jorne.dtsi +++ b/app/boards/shields/jorne/jorne.dtsi @@ -63,6 +63,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 kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/knob_goblin/knob_goblin.overlay b/app/boards/shields/knob_goblin/knob_goblin.overlay index 49306ddf..c42482db 100644 --- a/app/boards/shields/knob_goblin/knob_goblin.overlay +++ b/app/boards/shields/knob_goblin/knob_goblin.overlay @@ -14,6 +14,8 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/kyria/kyria_common.dtsi b/app/boards/shields/kyria/kyria_common.dtsi index 23058f37..f662fa1c 100644 --- a/app/boards/shields/kyria/kyria_common.dtsi +++ b/app/boards/shields/kyria/kyria_common.dtsi @@ -15,6 +15,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; }; diff --git a/app/boards/shields/leeloo/leeloo_common.dtsi b/app/boards/shields/leeloo/leeloo_common.dtsi index df4f228e..8ae5b064 100644 --- a/app/boards/shields/leeloo/leeloo_common.dtsi +++ b/app/boards/shields/leeloo/leeloo_common.dtsi @@ -32,6 +32,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) kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; diff --git a/app/boards/shields/leeloo_micro/leeloo_micro.dtsi b/app/boards/shields/leeloo_micro/leeloo_micro.dtsi index bc314205..f2339653 100644 --- a/app/boards/shields/leeloo_micro/leeloo_micro.dtsi +++ b/app/boards/shields/leeloo_micro/leeloo_micro.dtsi @@ -31,6 +31,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) kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; diff --git a/app/boards/shields/lily58/lily58.dtsi b/app/boards/shields/lily58/lily58.dtsi index 1a326d62..c82b197c 100644 --- a/app/boards/shields/lily58/lily58.dtsi +++ b/app/boards/shields/lily58/lily58.dtsi @@ -33,6 +33,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) kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/lotus58/lotus58.dtsi b/app/boards/shields/lotus58/lotus58.dtsi index afa311d9..e4595930 100644 --- a/app/boards/shields/lotus58/lotus58.dtsi +++ b/app/boards/shields/lotus58/lotus58.dtsi @@ -33,6 +33,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 kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/m60/m60.overlay b/app/boards/shields/m60/m60.overlay index 22eed44f..c479233c 100644 --- a/app/boards/shields/m60/m60.overlay +++ b/app/boards/shields/m60/m60.overlay @@ -14,6 +14,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/microdox/microdox.dtsi b/app/boards/shields/microdox/microdox.dtsi index 4869cfea..65c670f0 100644 --- a/app/boards/shields/microdox/microdox.dtsi +++ b/app/boards/shields/microdox/microdox.dtsi @@ -9,6 +9,7 @@ / { kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios = <&pro_micro 16 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> diff --git a/app/boards/shields/microdox/microdox_v2.dtsi b/app/boards/shields/microdox/microdox_v2.dtsi index 6eb7efa5..95aaf79d 100644 --- a/app/boards/shields/microdox/microdox_v2.dtsi +++ b/app/boards/shields/microdox/microdox_v2.dtsi @@ -9,6 +9,7 @@ / { kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; }; }; diff --git a/app/boards/shields/murphpad/murphpad.overlay b/app/boards/shields/murphpad/murphpad.overlay index a8234968..e2c9117f 100644 --- a/app/boards/shields/murphpad/murphpad.overlay +++ b/app/boards/shields/murphpad/murphpad.overlay @@ -14,6 +14,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/naked60/naked60.overlay b/app/boards/shields/naked60/naked60.overlay index 843c867f..4e36bc76 100644 --- a/app/boards/shields/naked60/naked60.overlay +++ b/app/boards/shields/naked60/naked60.overlay @@ -11,6 +11,7 @@ kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; col-gpios diff --git a/app/boards/shields/osprette/osprette.overlay b/app/boards/shields/osprette/osprette.overlay index af2e5625..ed893f47 100644 --- a/app/boards/shields/osprette/osprette.overlay +++ b/app/boards/shields/osprette/osprette.overlay @@ -26,6 +26,7 @@ RC(0,0) RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(1,6) RC(1,7) RC(1,8) kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "row2col"; col-gpios diff --git a/app/boards/shields/pancake/pancake.overlay b/app/boards/shields/pancake/pancake.overlay index 0ceb2d5c..0538bf71 100644 --- a/app/boards/shields/pancake/pancake.overlay +++ b/app/boards/shields/pancake/pancake.overlay @@ -11,6 +11,7 @@ kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; col-gpios diff --git a/app/boards/shields/qaz/qaz.overlay b/app/boards/shields/qaz/qaz.overlay index d0ec5b3a..5c76b98f 100644 --- a/app/boards/shields/qaz/qaz.overlay +++ b/app/boards/shields/qaz/qaz.overlay @@ -27,6 +27,7 @@ kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; col-gpios diff --git a/app/boards/shields/quefrency/quefrency_left.overlay b/app/boards/shields/quefrency/quefrency_left.overlay index cf795841..a40d47c1 100644 --- a/app/boards/shields/quefrency/quefrency_left.overlay +++ b/app/boards/shields/quefrency/quefrency_left.overlay @@ -12,6 +12,8 @@ */ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; diff --git a/app/boards/shields/quefrency/quefrency_right.overlay b/app/boards/shields/quefrency/quefrency_right.overlay index 446a614a..ebb9f844 100644 --- a/app/boards/shields/quefrency/quefrency_right.overlay +++ b/app/boards/shields/quefrency/quefrency_right.overlay @@ -17,6 +17,8 @@ */ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; diff --git a/app/boards/shields/redox/redox.dtsi b/app/boards/shields/redox/redox.dtsi index 505a5c69..098be434 100644 --- a/app/boards/shields/redox/redox.dtsi +++ b/app/boards/shields/redox/redox.dtsi @@ -32,6 +32,7 @@ RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,4) RC(4,5) RC(4,6) RC(4,7) RC(4,8) kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/reviung34/reviung34.overlay b/app/boards/shields/reviung34/reviung34.overlay index 6ec9813d..0f58b99d 100644 --- a/app/boards/shields/reviung34/reviung34.overlay +++ b/app/boards/shields/reviung34/reviung34.overlay @@ -38,6 +38,8 @@ 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(3,7) kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; col-gpios diff --git a/app/boards/shields/reviung41/reviung41.overlay b/app/boards/shields/reviung41/reviung41.overlay index 079fd36b..f8503fc3 100644 --- a/app/boards/shields/reviung41/reviung41.overlay +++ b/app/boards/shields/reviung41/reviung41.overlay @@ -27,6 +27,8 @@ RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(5,0) RC(5,1) RC(5,2) RC(5,3) kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; col-gpios diff --git a/app/boards/shields/reviung5/reviung5.overlay b/app/boards/shields/reviung5/reviung5.overlay index 0382145c..0abd3a06 100644 --- a/app/boards/shields/reviung5/reviung5.overlay +++ b/app/boards/shields/reviung5/reviung5.overlay @@ -22,6 +22,7 @@ kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; col-gpios diff --git a/app/boards/shields/reviung53/reviung53.overlay b/app/boards/shields/reviung53/reviung53.overlay index d6037aec..fa784478 100644 --- a/app/boards/shields/reviung53/reviung53.overlay +++ b/app/boards/shields/reviung53/reviung53.overlay @@ -28,6 +28,8 @@ RC(6,0) RC(6,1) RC(6,2) RC(6,3) RC(6,4) RC(6,5) kscan0: kscan_0 { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; col-gpios diff --git a/app/boards/shields/romac/romac.overlay b/app/boards/shields/romac/romac.overlay index 3d99e51b..8c11a8ac 100644 --- a/app/boards/shields/romac/romac.overlay +++ b/app/boards/shields/romac/romac.overlay @@ -13,6 +13,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/romac_plus/romac_plus.overlay b/app/boards/shields/romac_plus/romac_plus.overlay index 229b4a2c..39e123c0 100644 --- a/app/boards/shields/romac_plus/romac_plus.overlay +++ b/app/boards/shields/romac_plus/romac_plus.overlay @@ -13,6 +13,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; diff --git a/app/boards/shields/sofle/sofle.dtsi b/app/boards/shields/sofle/sofle.dtsi index f88339d7..ef89e4a5 100644 --- a/app/boards/shields/sofle/sofle.dtsi +++ b/app/boards/shields/sofle/sofle.dtsi @@ -33,6 +33,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) kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne_left.overlay b/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne_left.overlay index df930cd2..ec40a016 100644 --- a/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne_left.overlay +++ b/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne_left.overlay @@ -13,6 +13,8 @@ kscan: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne_right.overlay b/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne_right.overlay index 3823cdfb..7341f072 100644 --- a/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne_right.overlay +++ b/app/boards/shields/splitkb_aurora_corne/splitkb_aurora_corne_right.overlay @@ -13,6 +13,8 @@ kscan: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix_left.overlay b/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix_left.overlay index 59d82553..61b663e6 100644 --- a/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix_left.overlay +++ b/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix_left.overlay @@ -13,6 +13,8 @@ kscan: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix_right.overlay b/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix_right.overlay index 95cea9ec..5aee19bd 100644 --- a/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix_right.overlay +++ b/app/boards/shields/splitkb_aurora_helix/splitkb_aurora_helix_right.overlay @@ -13,6 +13,8 @@ kscan: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58_left.overlay b/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58_left.overlay index fc38bbcb..8d56890f 100644 --- a/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58_left.overlay +++ b/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58_left.overlay @@ -13,6 +13,8 @@ kscan: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "row2col"; row-gpios diff --git a/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58_right.overlay b/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58_right.overlay index c9a96491..6b719020 100644 --- a/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58_right.overlay +++ b/app/boards/shields/splitkb_aurora_lily58/splitkb_aurora_lily58_right.overlay @@ -13,6 +13,8 @@ kscan: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "row2col"; row-gpios diff --git a/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle_left.overlay b/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle_left.overlay index 024c9e75..2a3f485d 100644 --- a/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle_left.overlay +++ b/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle_left.overlay @@ -13,6 +13,8 @@ kscan: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle_right.overlay b/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle_right.overlay index 58df0026..6eb0d113 100644 --- a/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle_right.overlay +++ b/app/boards/shields/splitkb_aurora_sofle/splitkb_aurora_sofle_right.overlay @@ -13,6 +13,8 @@ kscan: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep_left.overlay b/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep_left.overlay index 4a1bec90..9c1fd975 100644 --- a/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep_left.overlay +++ b/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep_left.overlay @@ -13,6 +13,8 @@ kscan: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; + diode-direction = "row2col"; row-gpios diff --git a/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep_right.overlay b/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep_right.overlay index c3655477..b280b42d 100644 --- a/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep_right.overlay +++ b/app/boards/shields/splitkb_aurora_sweep/splitkb_aurora_sweep_right.overlay @@ -13,6 +13,7 @@ kscan: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "row2col"; row-gpios diff --git a/app/boards/shields/splitreus62/splitreus62.dtsi b/app/boards/shields/splitreus62/splitreus62.dtsi index d80f8731..1a4f3af1 100644 --- a/app/boards/shields/splitreus62/splitreus62.dtsi +++ b/app/boards/shields/splitreus62/splitreus62.dtsi @@ -34,6 +34,7 @@ RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,4) RC(4,5) RC(4,6) RC(4,7) kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "row2col"; row-gpios diff --git a/app/boards/shields/tg4x/tg4x.overlay b/app/boards/shields/tg4x/tg4x.overlay index 07a0635d..ac05e810 100644 --- a/app/boards/shields/tg4x/tg4x.overlay +++ b/app/boards/shields/tg4x/tg4x.overlay @@ -9,6 +9,7 @@ / { kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; diff --git a/app/boards/shields/two_percent_milk/two_percent_milk.overlay b/app/boards/shields/two_percent_milk/two_percent_milk.overlay index 474150ef..7647f551 100644 --- a/app/boards/shields/two_percent_milk/two_percent_milk.overlay +++ b/app/boards/shields/two_percent_milk/two_percent_milk.overlay @@ -11,6 +11,7 @@ kscan0: kscan { compatible = "zmk,kscan-gpio-direct"; + wakeup-source; input-gpios = <&pro_micro 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)> diff --git a/app/boards/shields/waterfowl/waterfowl.dtsi b/app/boards/shields/waterfowl/waterfowl.dtsi index d46910a3..2329ca78 100644 --- a/app/boards/shields/waterfowl/waterfowl.dtsi +++ b/app/boards/shields/waterfowl/waterfowl.dtsi @@ -31,6 +31,7 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios diff --git a/app/boards/shields/zodiark/zodiark.dtsi b/app/boards/shields/zodiark/zodiark.dtsi index 3151f31c..aa68e20d 100644 --- a/app/boards/shields/zodiark/zodiark.dtsi +++ b/app/boards/shields/zodiark/zodiark.dtsi @@ -33,6 +33,7 @@ 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 kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; + wakeup-source; diode-direction = "col2row"; row-gpios From 4bef4e98f52c3ea57630a3cd1e0e2d078d67758b Mon Sep 17 00:00:00 2001 From: zhiayang <500236+zhiayang@users.noreply.github.com> Date: Sat, 30 Mar 2024 19:12:37 -0400 Subject: [PATCH 123/127] feat(boards): Support board revisions in setup scripts. * Make setup.sh/ps1 prompt for board revision for boards that have revisions --- docs/src/templates/setup.ps1.mustache | 29 ++++++++++++++++++++++ docs/src/templates/setup.sh.mustache | 35 +++++++++++++++++++++++++++ schema/hardware-metadata.schema.json | 15 +++++++++++- 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/docs/src/templates/setup.ps1.mustache b/docs/src/templates/setup.ps1.mustache index 90f9cdcf..b8ecc293 100644 --- a/docs/src/templates/setup.ps1.mustache +++ b/docs/src/templates/setup.ps1.mustache @@ -131,6 +131,19 @@ if ($keyboard_type -eq "shield") { {{/boards}} } + $boards_revisions = [ordered]@{ + {{#boards}} + {{id}} = @({{#revisions}} + "{{.}}"{{/revisions}}); + {{/boards}} + } + + $boards_default_revision=[ordered]@{ + {{#boards}} + {{id}} = "{{{default_revision}}}"; + {{/boards}} + } + Write-Host "$title" Write-Host "" Write-Host "MCU Board Selection:" @@ -145,6 +158,22 @@ if ($keyboard_type -eq "shield") { $shields = $keyboard_siblings $board = $($($boards.keys)[$choice]) $boards = ( $board ) + + if ($($($boards_revisions.values)[$choice]).count -gt 0) { + $valid_revisions = $($($boards_revisions.values)[$choice]) + $revision_choices = @() + $valid_revisions + + for ($i = 0; $i -lt $valid_revisions.count; $i += 1) { + if ($valid_revisions[$i] -eq $($($boards_default_revision.values)[$choice])) { + $revision_choices[$i] += " (default)" + } + } + + $revision_choice = Get-Choice-From-Options -Options $revision_choices -Prompt $prompt + $board = $board + "@" + $valid_revisions[$revision_choice] + $boards = ( $board ) + } + } else { $boards = ( $keyboard_siblings ) $shields = @( ) diff --git a/docs/src/templates/setup.sh.mustache b/docs/src/templates/setup.sh.mustache index c711dbc5..dd7a7a2d 100644 --- a/docs/src/templates/setup.sh.mustache +++ b/docs/src/templates/setup.sh.mustache @@ -122,6 +122,9 @@ if [ "$keyboard_shield" == "y" ]; then board_ids=({{#boards}}"{{id}}" {{/boards}}) boards_usb_only=({{#boards}}"{{#usb_only}}y{{/usb_only}}{{^usb_only}}n{{/usb_only}}" {{/boards}}) + boards_revisions=({{#boards}}"{{#revisions}}{{.}} {{/revisions}}" {{/boards}}) + boards_default_revision=({{#boards}}"{{{default_revision}}}" {{/boards}}) + echo "" echo "MCU Board Selection:" PS3="$prompt " @@ -151,6 +154,38 @@ if [ "$keyboard_shield" == "y" ]; then esac done + + if [ -n "${boards_revisions[$board_index]}" ]; then + read -a _valid_revisions <<< "${boards_revisions[$board_index]}" + + _rev_choices=("${_valid_revisions[@]}") + for (( _i=0; _i<${#_valid_revisions}; _i++ )); do + if [ "${boards_default_revision[board_index]}" = "${_valid_revisions[_i]}" ]; then + _rev_choices[_i]+=" (default)" + fi + done + + echo "" + echo "MCU Board Revision:" + select opt in "${_rev_choices[@]}" "Quit"; do + case "$REPLY" in + ''|*[!0-9]*) echo "Invalid option. Try another one."; continue;; + + $(( ${#_valid_revisions[@]}+1 )) ) echo "Goodbye!"; exit 1;; + *) + if [ $REPLY -gt $(( ${#_valid_revisions[@]}+1 )) ] || [ $REPLY -lt 0 ]; then + echo "Invalid option. Try another one." + continue + fi + + _rev_index=$(( $REPLY-1 )) + board="${board_ids[$board_index]}@${_valid_revisions[_rev_index]}" + boards=( "${board}" ) + break + ;; + esac + done + fi else board=${keyboard} boards=$keyboard_siblings diff --git a/schema/hardware-metadata.schema.json b/schema/hardware-metadata.schema.json index 4c2bdf3b..9710c792 100644 --- a/schema/hardware-metadata.schema.json +++ b/schema/hardware-metadata.schema.json @@ -16,7 +16,11 @@ "$defs": { "id": { "type": "string", - "pattern": "^[a-z0-9_]+$" + "pattern": "^[a-z0-9_]+(@([A-Z]|[0-9]+|([0-9]+(\\.[0-9]+){1,2})))?$" + }, + "revision": { + "type": "string", + "pattern": "[A-Z]|[0-9]+|([0-9]+(\\.[0-9]+){1,2})" }, "keyboard_siblings": { "type": "array", @@ -202,6 +206,15 @@ }, "exposes": { "$ref": "#/$defs/interconnects" + }, + "revisions": { + "type": "array", + "items": { + "$ref": "#/$defs/revision" + } + }, + "default_revision": { + "$ref": "#/$defs/revision" } } }, From e65a1227d8cddc2edc2e5da2276f992d8a91ed49 Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Fri, 29 Mar 2024 14:41:18 -0700 Subject: [PATCH 124/127] fix(docs): Correct property types for behavior bindings --- docs/docs/config/behaviors.md | 52 +++++++++++++++++------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/docs/docs/config/behaviors.md b/docs/docs/config/behaviors.md index 1a5b899a..06e87850 100644 --- a/docs/docs/config/behaviors.md +++ b/docs/docs/config/behaviors.md @@ -57,18 +57,18 @@ Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml](htt Applies to: `compatible = "zmk,behavior-hold-tap"` -| Property | Type | Description | Default | -| ----------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------- | ------------------ | -| `#binding-cells` | int | Must be `<2>` | | -| `bindings` | phandle array | A list of two behaviors (without parameters): one for hold and one for tap | | -| `flavor` | string | Adjusts how the behavior chooses between hold and tap | `"hold-preferred"` | -| `tapping-term-ms` | int | How long in milliseconds the key must be held to trigger a hold | | -| `quick-tap-ms` | int | Tap twice within this period (in milliseconds) to trigger a tap, even when held | -1 (disabled) | -| `require-prior-idle-ms` | int | Triggers a tap immediately if any non-modifier key was pressed within `require-prior-idle-ms` of the hold-tap. | -1 (disabled) | -| `retro-tap` | bool | Triggers the tap behavior on release if no other key was pressed during a hold | false | -| `hold-while-undecided` | bool | Triggers the hold behavior immediately on press and releases before a tap | false | -| `hold-while-undecided-linger` | bool | Continues to hold the hold behavior until after the tap is released | false | -| `hold-trigger-key-positions` | array | If set, pressing the hold-tap and then any key position _not_ in the list triggers a tap. | | +| Property | Type | Description | Default | +| ----------------------------- | -------- | -------------------------------------------------------------------------------------------------------------- | ------------------ | +| `#binding-cells` | int | Must be `<2>` | | +| `bindings` | phandles | A list of two behaviors (without parameters): one for hold and one for tap | | +| `flavor` | string | Adjusts how the behavior chooses between hold and tap | `"hold-preferred"` | +| `tapping-term-ms` | int | How long in milliseconds the key must be held to trigger a hold | | +| `quick-tap-ms` | int | Tap twice within this period (in milliseconds) to trigger a tap, even when held | -1 (disabled) | +| `require-prior-idle-ms` | int | Triggers a tap immediately if any non-modifier key was pressed within `require-prior-idle-ms` of the hold-tap. | -1 (disabled) | +| `retro-tap` | bool | Triggers the tap behavior on release if no other key was pressed during a hold | false | +| `hold-while-undecided` | bool | Triggers the hold behavior immediately on press and releases before a tap | false | +| `hold-while-undecided-linger` | bool | Continues to hold the hold behavior until after the tap is released | false | +| `hold-trigger-key-positions` | array | If set, pressing the hold-tap and then any key position _not_ in the list triggers a tap. | | This behavior forwards the first parameter it receives to the parameter of the first behavior specified in `bindings`, and second parameter to the parameter of the second behavior. @@ -203,12 +203,12 @@ Definition files: - [zmk/app/dts/bindings/behaviors/zmk,behavior-sensor-rotate.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-sensor-rotate.yaml) - [zmk/app/dts/bindings/behaviors/zmk,behavior-sensor-rotate-var.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-sensor-rotate-var.yaml) -| Property | Type | Description | Default | -| ----------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `compatible` | string | Sensor rotation type, **must be _one_ of**:
  • `"zmk,behavior-sensor-rotate"`
  • `"zmk,behavior-sensor-rotate-var"`
| | -| `#sensor-binding-cells` | int | Must be
  • `<0>` if `compatible = "zmk,behavior-sensor-rotate"`
  • `<2>` if `compatible = "zmk,behavior-sensor-rotate-var"`
| | -| `bindings` | phandle array | A list of two behaviors to trigger for each rotation direction, must include parameters for `"zmk,behavior-sensor-rotate"` and exclude them for `"zmk,behavior-sensor-rotate-var"` | | -| `tap-ms` | int | The tap duration (between press and release events) in milliseconds for behaviors in `bindings` | 5 | +| Property | Type | Description | Default | +| ----------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `compatible` | string | Sensor rotation type, **must be _one_ of**:
  • `"zmk,behavior-sensor-rotate"`
  • `"zmk,behavior-sensor-rotate-var"`
| | +| `#sensor-binding-cells` | int | Must be
  • `<0>` if `compatible = "zmk,behavior-sensor-rotate"`
  • `<2>` if `compatible = "zmk,behavior-sensor-rotate-var"`
| | +| `bindings` | phandles for `"zmk,behavior-sensor-rotate"`, phandle array for `"zmk,behavior-sensor-rotate-var"` | A list of two behaviors to trigger for each rotation direction, must include parameters for `"zmk,behavior-sensor-rotate"` and exclude them for `"zmk,behavior-sensor-rotate-var"` | | +| `tap-ms` | int | The tap duration (between press and release events) in milliseconds for behaviors in `bindings` | 5 | With `compatible = "zmk,behavior-sensor-rotate-var"`, this behavior forwards the first parameter it receives to the parameter of the first behavior specified in `bindings`, and second parameter to the parameter of the second behavior. @@ -224,14 +224,14 @@ Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-sticky-key.yaml](h Applies to: `compatible = "zmk,behavior-sticky-key"` -| Property | Type | Description | Default | -| ------------------ | ------------- | ------------------------------------------------------------------------ | ------- | -| `#binding-cells` | int | Must be `<1>` | | -| `bindings` | phandle array | A behavior (without parameters) to trigger | | -| `release-after-ms` | int | Releases the key after this many milliseconds if no other key is pressed | 1000 | -| `quick-release` | bool | Release the sticky key on the next key press instead of release | false | -| `lazy` | bool | Wait until the next key press to activate the sticky key behavior | false | -| `ignore-modifiers` | bool | If enabled, pressing a modifier key does not cancel the sticky key | true | +| Property | Type | Description | Default | +| ------------------ | -------- | ------------------------------------------------------------------------ | ------- | +| `#binding-cells` | int | Must be `<1>` | | +| `bindings` | phandles | A behavior (without parameters) to trigger | | +| `release-after-ms` | int | Releases the key after this many milliseconds if no other key is pressed | 1000 | +| `quick-release` | bool | Release the sticky key on the next key press instead of release | false | +| `lazy` | bool | Wait until the next key press to activate the sticky key behavior | false | +| `ignore-modifiers` | bool | If enabled, pressing a modifier key does not cancel the sticky key | true | This behavior forwards the one parameter it receives to the parameter of the behavior specified in `bindings`. From eb5a6fcfe19b32df13488d2ec751f90cb9fa3362 Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Fri, 29 Mar 2024 14:44:00 -0700 Subject: [PATCH 125/127] refactor(docs): Split DT props table for sensor rotate variants --- docs/docs/config/behaviors.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/docs/config/behaviors.md b/docs/docs/config/behaviors.md index 06e87850..28abdf27 100644 --- a/docs/docs/config/behaviors.md +++ b/docs/docs/config/behaviors.md @@ -203,12 +203,21 @@ Definition files: - [zmk/app/dts/bindings/behaviors/zmk,behavior-sensor-rotate.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-sensor-rotate.yaml) - [zmk/app/dts/bindings/behaviors/zmk,behavior-sensor-rotate-var.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/behaviors/zmk%2Cbehavior-sensor-rotate-var.yaml) -| Property | Type | Description | Default | -| ----------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `compatible` | string | Sensor rotation type, **must be _one_ of**:
  • `"zmk,behavior-sensor-rotate"`
  • `"zmk,behavior-sensor-rotate-var"`
| | -| `#sensor-binding-cells` | int | Must be
  • `<0>` if `compatible = "zmk,behavior-sensor-rotate"`
  • `<2>` if `compatible = "zmk,behavior-sensor-rotate-var"`
| | -| `bindings` | phandles for `"zmk,behavior-sensor-rotate"`, phandle array for `"zmk,behavior-sensor-rotate-var"` | A list of two behaviors to trigger for each rotation direction, must include parameters for `"zmk,behavior-sensor-rotate"` and exclude them for `"zmk,behavior-sensor-rotate-var"` | | -| `tap-ms` | int | The tap duration (between press and release events) in milliseconds for behaviors in `bindings` | 5 | +Applies to: `compatible = "zmk,behavior-sensor-rotate"` + +| Property | Type | Description | Default | +| ----------------------- | -------- | ------------------------------------------------------------------------------------------------------ | ------- | +| `#sensor-binding-cells` | int | Must be `<0>` | | +| `bindings` | phandles | A list of two behaviors to trigger for each rotation direction, must _include_ any behavior parameters | | +| `tap-ms` | int | The tap duration (between press and release events) in milliseconds for behaviors in `bindings` | 5 | + +Applies to: `compatible = "zmk,behavior-sensor-rotate-var"` + +| Property | Type | Description | Default | +| ----------------------- | ------------- | ------------------------------------------------------------------------------------------------------ | ------- | +| `#sensor-binding-cells` | int | Must be `<2>` | | +| `bindings` | phandle array | A list of two behaviors to trigger for each rotation direction, must _exclude_ any behavior parameters | | +| `tap-ms` | int | The tap duration (between press and release events) in milliseconds for behaviors in `bindings` | 5 | With `compatible = "zmk,behavior-sensor-rotate-var"`, this behavior forwards the first parameter it receives to the parameter of the first behavior specified in `bindings`, and second parameter to the parameter of the second behavior. From e7d6519534231525e6173635061ab8e8bda5a997 Mon Sep 17 00:00:00 2001 From: Tobias Arndt Date: Sat, 30 Mar 2024 18:24:11 -0700 Subject: [PATCH 126/127] fix(docs): Fix and note GPIO flags for charlieplex config --- docs/docs/config/kscan.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/docs/config/kscan.md b/docs/docs/config/kscan.md index 3aa1b378..e6e8bb62 100644 --- a/docs/docs/config/kscan.md +++ b/docs/docs/config/kscan.md @@ -187,6 +187,8 @@ Define the transform with a [matrix transform](#matrix-transform). The row is al For example, in `RC(5,0)` power flows from the 6th pin in `gpios` to the 1st pin in `gpios`. Exclude all positions where the row and column are the same as these pairs will never be triggered, since no pin can be both input and output at the same time. +The [GPIO flags](https://docs.zephyrproject.org/3.5.0/hardware/peripherals/gpio.html#api-reference) for the elements in `gpios` should be `GPIO_ACTIVE_HIGH`, and interrupt pins set in `interrupt-gpios` should have the flags `(GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)`. + ## Composite Driver Keyboard scan driver which combines multiple other keyboard scan drivers. @@ -460,11 +462,11 @@ Note that the entire addressable space does not need to be mapped. interrupt-gpios = <&pro_micro 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN) >; gpios - = <&pro_micro 16 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN) > - , <&pro_micro 17 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN) > - , <&pro_micro 18 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN) > - , <&pro_micro 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN) > - , <&pro_micro 20 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN) > + = <&pro_micro 16 GPIO_ACTIVE_HIGH> + , <&pro_micro 17 GPIO_ACTIVE_HIGH> + , <&pro_micro 18 GPIO_ACTIVE_HIGH> + , <&pro_micro 19 GPIO_ACTIVE_HIGH> + , <&pro_micro 20 GPIO_ACTIVE_HIGH> ; // addressable space is 5x5, (minus paired values) }; From fe509c466f818471c677b069094d1e84e33ccf2e Mon Sep 17 00:00:00 2001 From: Tobias Arndt Date: Sat, 30 Mar 2024 18:24:51 -0700 Subject: [PATCH 127/127] fix(kscan): Enable charlieplex interrupts for single compatible device Fixes #2201 --- app/module/drivers/kscan/kscan_gpio_charlieplex.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/module/drivers/kscan/kscan_gpio_charlieplex.c b/app/module/drivers/kscan/kscan_gpio_charlieplex.c index a4867aa3..3ecbcd6a 100644 --- a/app/module/drivers/kscan/kscan_gpio_charlieplex.c +++ b/app/module/drivers/kscan/kscan_gpio_charlieplex.c @@ -47,14 +47,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #define USES_POLLING DT_INST_FOREACH_STATUS_OKAY(WITHOUT_INTR) > 0 #define USES_INTERRUPT DT_INST_FOREACH_STATUS_OKAY(WITH_INTR) > 0 -#if USES_POLLING && USES_INTERRUPT -#define USES_POLL_AND_INTR 1 -#else -#define USES_POLL_AND_INTR 0 -#endif - #define COND_ANY_POLLING(code) COND_CODE_1(USES_POLLING, code, ()) -#define COND_POLL_AND_INTR(code) COND_CODE_1(USES_POLL_AND_INTR, code, ()) #define COND_THIS_INTERRUPT(n, code) COND_CODE_1(INST_INTR_DEFINED(n), code, ()) #define KSCAN_INTR_CFG_INIT(inst_idx) GPIO_DT_SPEC_GET(DT_DRV_INST(inst_idx), interrupt_gpios) @@ -410,7 +403,7 @@ static const struct kscan_driver_api kscan_charlieplex_api = { }, \ .debounce_scan_period_ms = DT_INST_PROP(n, debounce_scan_period_ms), \ COND_ANY_POLLING((.poll_period_ms = DT_INST_PROP(n, poll_period_ms), )) \ - COND_POLL_AND_INTR((.use_interrupt = INST_INTR_DEFINED(n), )) \ + COND_THIS_INTERRUPT(n, (.use_interrupt = INST_INTR_DEFINED(n), )) \ COND_THIS_INTERRUPT(n, (.interrupt = KSCAN_INTR_CFG_INIT(n), ))}; \ \ DEVICE_DT_INST_DEFINE(n, &kscan_charlieplex_init, NULL, &kscan_charlieplex_data_##n, \