diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..a6ee435 --- /dev/null +++ b/.envrc @@ -0,0 +1,5 @@ +# shellcheck shell=bash +if ! has nix_direnv_version || ! nix_direnv_version 3.0.6; then + source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.6/direnvrc" "sha256-RYcUJaRMf8oF5LznDrlCXbkOQrywm0HDv1VjYGaJGdM=" +fi +use flake diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..9922df0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + commit-message: + prefix: "ci" diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..bdedac6 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,26 @@ +name: build + +on: + pull_request: + push: + branches: + - main + workflow_dispatch: + +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: DeterminateSystems/nix-installer-action@v14 + + - run: nix -vL --show-trace flake check + + - run: nix -vL --show-trace build + + - uses: actions/upload-artifact@v4 + with: + name: zmk_firmware + path: result diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e0e90f4 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + workflow_dispatch: + +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: DeterminateSystems/nix-installer-action@v11 + + - run: nix -vL --show-trace flake check + + - run: nix -vL --show-trace build + + - uses: actions/upload-artifact@v4 + with: + name: zmk_firmware + path: result diff --git a/.github/workflows/deps.yml b/.github/workflows/deps.yml new file mode 100644 index 0000000..b1ba83b --- /dev/null +++ b/.github/workflows/deps.yml @@ -0,0 +1,44 @@ +name: Dependencies + +on: + schedule: + - cron: '0 0 * * 0' + workflow_dispatch: + +permissions: + pull-requests: write + contents: write + +jobs: + update: + name: Update + runs-on: ubuntu-latest + permissions: + actions: write + contents: write + pull-requests: write + steps: + - uses: actions/checkout@v4 + + - uses: DeterminateSystems/nix-installer-action@v12 + + - run: nix -vL run --show-trace .#update + + - id: create-pr + uses: peter-evans/create-pull-request@v6 + with: + branch: update_zmk_config_deps + delete-branch: true + committer: 'github-actions[bot] ' + author: 'github-actions[bot] ' + commit-message: 'config,nix: update deps' + title: 'config,nix: update deps' + labels: 'dependencies' + body: | + Automated bump of ZMK dependencies + + - uses: benc-uk/workflow-dispatch@v1 + if: ${{ contains(fromJSON('["created", "updated"]'), steps.create-pr.outputs.pull-request-operation) }} + with: + workflow: ci.yml + ref: refs/heads/update_zmk_config_deps diff --git a/.github/workflows/flake.yml b/.github/workflows/flake.yml new file mode 100644 index 0000000..5aef002 --- /dev/null +++ b/.github/workflows/flake.yml @@ -0,0 +1,32 @@ +name: Flake + +on: + schedule: + - cron: '0 0 * * 0' + workflow_dispatch: + +jobs: + update: + name: Update + runs-on: ubuntu-latest + permissions: + actions: write + contents: write + pull-requests: write + steps: + - uses: actions/checkout@v4 + + - uses: DeterminateSystems/nix-installer-action@v11 + + - id: update-flake-lock + uses: DeterminateSystems/update-flake-lock@v21 + with: + commit-msg: 'flake: update inputs' + pr-title: 'flake: update inputs' + pr-labels: 'dependencies' + + - uses: benc-uk/workflow-dispatch@v1 + if: ${{ contains(fromJSON('["created", "updated"]'), steps.update-flake-lock.outputs.pull-request-operation) }} + with: + workflow: ci.yml + ref: refs/heads/update_flake_lock_action diff --git a/config/cradio.conf b/config/cradio.conf deleted file mode 100644 index 9b40be0..0000000 --- a/config/cradio.conf +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_ZMK_SLEEP=y -CONFIG_ZMK_IDLE_TIMEOUT=30000 -CONFIG_ZMK_IDLE_SLEEP_TIMEOUT=900000 diff --git a/config/cradio.keymap b/config/cradio.keymap deleted file mode 100644 index ef1130b..0000000 --- a/config/cradio.keymap +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2020 The ZMK Contributors - * - * SPDX-License-Identifier: MIT - */ - -#include -#include -#include -#include -#include -#include - -#define COLEMAK 0 -#define NAV 1 -#define NUM 2 -#define SYM 3 -#define FUN 4 - -/* krita base */ -#define KRB 5 - -/* play */ -#define PLAY 6 - - -&mt { - flavor = "tap-preferred"; - tapping_term_ms = <200>; - quick_tap_ms = <75>; -}; - - -/ { - - combos { - compatible = "zmk,combos"; - combo_caps_word { - timeout-ms = <100>; - key-positions = <20 29>; - bindings = <&caps_word>; - }; - combo_esc { - timeout-ms = <150>; - key-positions = <12 13 16 17>; - bindings = <&kp ESC>; - }; - - // ( - combo_lpar { - timeout-ms = <150>; - key-positions = <4 14>; - bindings = <&kp LPAR>; - }; - - // ) - combo_rpar { - timeout-ms = <150>; - key-positions = <5 15>; - bindings = <&kp RPAR>; - }; - - // { - combo_lcurly { - timeout-ms = <150>; - key-positions = <3 13>; - bindings = <&kp LBRC>; - }; - // } - combo_rcurly { - timeout-ms = <150>; - key-positions = <6 16>; - bindings = <&kp RBRC>; - }; - - // [ - combo_lsquare { - timeout-ms = <150>; - key-positions = <13 23>; - bindings = <&kp LBKT>; - }; - - // ] - combo_rsquare { - timeout-ms = <150>; - key-positions = <16 26>; - bindings = <&kp RBKT>; - }; - - // < - combo_less_than { - timeout-ms = <150>; - key-positions = <14 24>; - bindings = <&kp LT>; - }; - - // > - combo_greater_than { - timeout-ms = <150>; - key-positions = <15 25>; - bindings = <&kp GT>; - }; - - combo_minus { - timeout-ms = <150>; - key-positions = <2 3 6 7>; - bindings = <&kp MINUS>; - }; - combo_under { - timeout-ms = <150>; - key-positions = <22 23 26 27>; - bindings = <&kp UNDER>; - }; - combo_ble { - timeout-ms = <20>; - key-positions = <0 1>; - bindings = <&out OUT_BLE>; - }; - combo_krita { - timeout-ms = <100>; - key-positions = <0 10 20>; - bindings = <&tog KRB>; - }; - combo_draw { - timeout-ms = <100>; - key-positions = <9 19 29>; - bindings = <&tog PLAY>; - }; - }; - - keymap { - compatible = "zmk,keymap"; - default_layer { - bindings = < - &kp Q &kp W &kp F &kp P &kp G &kp J &kp L &kp U &kp Y &kp SCLN - &kp A &kp R < FUN S < NAV T &kp D &kp H < SYM N < NUM E &kp I &kp O - &kp Z &kp X &kp C &kp V &kp B &kp K &kp M &kp CMMA &kp DOT &kp FSLH - &mt LALT TAB &mt LGUI SPC &mt LSHIFT RET &mt LCTRL BSPC - >; - }; - - nav_layer { - bindings = < - &bt BT_CLR &trans &trans &bootloader &sys_reset &trans &kp LBRC &kp RBRC &kp LPAR &kp RPAR - &bt BT_SEL 0 &trans &trans &trans &trans &kp LEFT &kp DOWN &kp UP &kp RIGHT &trans - &bt BT_SEL 1 &trans &trans &trans &trans &trans &kp LBKT &kp RBKT &trans &trans - &trans &trans &trans &kp BSPC - >; - }; - - num_layer { - bindings = < - &trans &kp F7 &kp F8 &kp F9 &trans &trans &trans &trans &trans &trans - &kp SQT &kp F4 &kp F5 &kp F6 &kp EQUAL &trans &trans &trans &trans &trans - &kp GRAVE &kp F1 &kp F2 &kp F3 &kp BSLH &trans &trans &trans &trans &trans - &trans &trans &trans &trans - >; - }; - - sym_layer { - bindings = < - &kp LS(Q) &kp LS(Z) &kp STAR &kp AMPS &trans &sys_reset &bootloader &trans &trans &trans - &kp DQT &kp CARET &kp PRCNT &kp DLLR &kp KP_PLUS &trans &trans &trans &trans &trans - &kp TILDE &kp HASH &kp AT &kp EXCL &kp PIPE &trans &trans &trans &trans &trans - &kp LPAR &kp RPAR &trans &trans - >; - }; - - fun_layer { - bindings = < - &trans &trans &trans &trans &trans &trans &kp N7 &kp N8 &kp N9 &trans - &trans &trans &trans &trans &trans &kp BSPC &kp N4 &kp N5 &kp N6 &trans - &trans &trans &trans &trans &trans &trans &kp N1 &kp N2 &kp N3 &trans - &trans &trans &trans &kp N0 - >; - }; - - krita_base_layer { - bindings = < - &kp M &trans &kp BSLH &kp LBKT &kp RBKT &trans &trans &trans &trans &trans - &trans &trans &kp F &kp I &kp O &trans &trans &trans &trans &trans - &kp LC(S) &trans &kp P &kp K &kp L &trans &trans &trans &trans &trans - &kp LS(LC(Z)) &kp LC(Z) &trans &trans - >; - }; - - draw { - bindings = < - &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P - &kp N1 &kp S &kp N3 &mt LCTRL F &kp G &kp H &mt LCTRL J &mt RSHIFT K &mt LALT L &mt LGUI SCLN - &kp Z &kp X &kp C &kp V &kp B &kp M &kp LEFT &kp DOWN &kp RIGHT &trans - &kp R &kp U &kp RET &kp BSPC - >; - }; - }; -}; diff --git a/config/urchin.conf b/config/urchin.conf new file mode 100644 index 0000000..f3676e4 --- /dev/null +++ b/config/urchin.conf @@ -0,0 +1,23 @@ +# increase bluetooth signal power +CONFIG_BT_CTLR_TX_PWR_PLUS_8=y + +# enable deep sleep support +CONFIG_ZMK_SLEEP=y + +# the keyboard disconnects from bluetooth. +# uses very little power, but it may take +# a few seconds to reconnect after waking. +# 1.800.000 ms = 30 minutes +CONFIG_ZMK_IDLE_SLEEP_TIMEOUT=1800000 + +# "Eager Debouncing" +# Trying to lower the input lag. +# CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS=1 +# CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS=5 + +# --- DISPLAY SETTINGS --- + +# disable the WPM widget +CONFIG_ZMK_WIDGET_WPM_STATUS=n +# display battery as n% +CONFIG_ZMK_WIDGET_BATTERY_STATUS_SHOW_PERCENTAGE=y diff --git a/config/urchin.keymap b/config/urchin.keymap new file mode 100644 index 0000000..056752f --- /dev/null +++ b/config/urchin.keymap @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2020 duckyb + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include + +// Layer definitions +#define BASE 0 +#define SYM 1 +#define EXT 2 +#define FNC 3 +#define SYM2 4 +#define ACCENT 5 +#define SETTINGS 6 +// ----------------- + +&sk { + // don't release mods on other mods presses + ignore-modifiers; +}; + + +/ { + behaviors { + // Enables holding the first mod-tap key + // by performing a tap-release-hold sequence. + // To use it: "&qt KEYCODE1 KEYCODE2" + qt: quick_tap { + compatible = "zmk,behavior-hold-tap"; + label = "QUICK_TAP"; + #binding-cells = <2>; + flavor = "hold-preferred"; + tapping-term-ms = <200>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + }; + }; + + macros { + // sometimes my device thinks a modifier is being held down + // pressing all modifiers fixes it. + unstick: unstick { + label = "ZM_unstick"; + compatible = "zmk,behavior-macro"; + #binding-cells = <0>; + bindings = <&kp LSHIFT &kp RSHIFT &kp LCTRL &kp RCTRL &kp LALT &kp RALT &kp LGUI &kp RGUI>; + }; + }; + + combos { + compatible = "zmk,combos"; + // Escape key + combo_esc { + timeout-ms = <150>; + key-positions = <12 13 16 17>; + bindings = <&kp ESC>; + }; + + // IMPORTED FROM ZMK // + // both right thumb keys + combo_accent { + timeout-ms = <200>; + key-positions = <32 33>; + bindings = <&mo ACCENT>; + }; + // internal-left & external-right thumb keys + combo_sym2 { + timeout-ms = <200>; + key-positions = <31 33>; + bindings = <&mo SYM2>; + }; + // both left thumb keys + combo_settings { + timeout-ms = <200>; + key-positions = <30 31>; + bindings = <&mo SETTINGS>; + }; + // left index & middle fingers (home-row) + // hold control & space for Adobe workflow + combo_ctrl_space { + timeout-ms = <200>; + key-positions = <12 13>; + bindings = <&kp LC(SPACE)>; + layers = ; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp SQT &kp CMMA &kp DOT &kp P &kp Y &kp F &kp G &kp C &kp R &kp L &kp A &kp O < FUN E < NAV U &kp I &kp D < SYM H < NUM T &kp N &kp S + &kp SCLN &kp Q &kp J &kp K &kp X &kp B &kp M &kp W &kp V &kp Z &mt LALT TAB &mt LGUI SPC &mt LSHIFT RET &mt LCTRL BSPC + >; + }; + + nav_layer { + bindings = < + &bt BT_CLR &trans &trans &bootloader &sys_reset &trans &kp LBRC &kp RBRC &kp LPAR &kp RPAR + &bt BT_SEL 0 &trans &trans &trans &trans &kp LEFT &kp DOWN &kp UP &kp RIGHT &trans + &bt BT_SEL 1 &trans &trans &trans &trans &trans &kp LBKT &kp RBKT &IT_LESS &IT_GREAT + &trans &trans &trans &kp BSPC + >; + }; + + num_layer { + bindings = < + &trans &kp F7 &kp F8 &kp F9 &trans &trans &trans &trans &trans &trans + &kp DQT &kp F4 &kp F5 &kp F6 &kp EQUAL &trans &trans &trans &trans &trans + &kp GRAVE &kp F1 &kp F2 &kp F3 &kp BSLH &trans &trans &trans &trans &trans + &trans &trans &trans &trans + >; + }; + + sym_layer { + label = "Sym."; + bindings = < + &kp LS(Q) &kp LS(Z) &kp STAR &kp AMPS &trans &sys_reset &bootloader &trans &trans &trans + &kp DQT &kp CARET &kp PRCNT &kp DLLR &kp KP_PLUS &trans &trans &trans &trans &trans + &kp TILDE &kp HASH &kp AT &kp EXCL &kp PIPE &trans &trans &trans &trans &trans + &kp LPAR &kp RPAR &trans &trans + >; + }; + + + // Numbers and high frequency symbols + sym_layer { + label = "Sym."; + bindings = < + &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 + &kp IT_LESS &kp IT_USD &kp IT_LPAR &kp IT_LBRC &kp IT_LBKT &kp IT_EQL &kp IT_QUES &kp IT_SQUOT &kp IT_MINUS &kp IT_AST + &kp IT_GREAT &kp IT_PERC &kp IT_RPAR &kp IT_RBRC &kp IT_RBKT &kp IT_AT &kp IT_EXCL &kp IT_DQUOT &kp IT_PLUS &kp IT_FSLH + &mo FNC &mo SYM2 &trans &trans + >; + }; + + // Main modifiers and arrow keys + ext_layer { + label = "Mods"; + bindings = < + &kp ESC &kp C_PREV &kp C_PP &kp C_NEXT &kp C_PAUSE &kp PG_UP &kp HOME &kp UP &kp END &kp CAPS + &sk LALT &sk LGUI &sk LSHIFT &sk LCTRL &kp RALT &kp PG_DN &kp LEFT &kp DOWN &kp RIGHT &kp DEL + &kp LC(Z) &kp LC(X) &kp LC(C) &kp TAB &kp LC(V) &kp LC(BSPC) &kp BSPC &trans &trans &trans + &trans &kp LCTRL &kp ENTER &mo FNC + >; + }; + + // Low frequency symbols. + symbols_2_layer { + label = "Sym.2"; + bindings = < + &kp IT_CARET &kp IT_UNDER &kp IT_PND &kp IT_EUR &kp IT_HASH &none &none &none &none &none + &kp IT_BKTK &kp IT_TILDE &kp IT_BSLH &kp IT_PIPE &kp IT_AND &none &none &none &none &none + &none &none &kp IT_SECT &kp IT_CCED &kp IT_DEG &none &none &none &none &none + &none &none &none &none + >; + }; + }; +}; diff --git a/config/west.yml b/config/west.yml index 379d291..faff268 100644 --- a/config/west.yml +++ b/config/west.yml @@ -1,11 +1,18 @@ manifest: remotes: + # zmk official - name: zmkfirmware url-base: https://github.com/zmkfirmware + # kyek / duckyb + - name: duckyb + url-base: https://github.com/duckyb projects: - name: zmk remote: zmkfirmware revision: main import: app/west.yml + - name: urchin-zmk-module + remote: duckyb + revision: self: path: config diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..d8c85b9 --- /dev/null +++ b/flake.lock @@ -0,0 +1,48 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1726871744, + "narHash": "sha256-V5LpfdHyQkUF7RfOaDPrZDP+oqz88lTJrMT1+stXNwo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a1d92660c6b3b7c26fb883500a80ea9d33321be2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "zmk-nix": "zmk-nix" + } + }, + "zmk-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1726965294, + "narHash": "sha256-GVXPzSVtcdEqeRIYhW8vLoDP2l97ElGcjP8eEpd6BWo=", + "owner": "lilyinstarlight", + "repo": "zmk-nix", + "rev": "58b3bb81f0823a071d9688c552b5ed7d1d5ecfaa", + "type": "github" + }, + "original": { + "owner": "lilyinstarlight", + "repo": "zmk-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..c903ee4 --- /dev/null +++ b/flake.nix @@ -0,0 +1,52 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + zmk-nix = { + url = "github:lilyinstarlight/zmk-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, zmk-nix }: + let + forAllSystems = + nixpkgs.lib.genAttrs (nixpkgs.lib.attrNames zmk-nix.packages); + in { + packages = forAllSystems (system: rec { + default = firmware; + + firmware = zmk-nix.legacyPackages.${system}.buildSplitKeyboard { + name = "firmware"; + + src = nixpkgs.lib.sourceFilesBySuffices self [ + ".conf" + ".keymap" + ".dtsi" + ".yml" + ".shield" + ".overlay" + ".defconfig" + ]; + + board = "nice_nano_v2"; + shield = "urchin_%PART%"; + + zephyrDepsHash = + "sha256-TBGBB8VowUxdvlBGY4jprgKg6fjmb712ennqr88TyZE="; + + meta = { + description = "ZMK firmware"; + license = nixpkgs.lib.licenses.mit; + platforms = nixpkgs.lib.platforms.all; + }; + }; + + flash = zmk-nix.packages.${system}.flash.override { inherit firmware; }; + update = zmk-nix.packages.${system}.update; + }); + + devShells = forAllSystems + (system: { default = zmk-nix.devShells.${system}.default; }); + }; +}