diff options
Diffstat (limited to 'docs')
32 files changed, 1253 insertions, 139 deletions
diff --git a/docs/blog/2020-09-21-zmk-sotf-2.md b/docs/blog/2020-09-21-zmk-sotf-2.md new file mode 100644 index 0000000..82278ad --- /dev/null +++ b/docs/blog/2020-09-21-zmk-sotf-2.md @@ -0,0 +1,106 @@ +--- +title: ZMK State Of The Firmware \#2 +author: Pete Johanson +author_title: Project Creator +author_url: https://gitlab.com/petejohanson +author_image_url: https://www.gravatar.com/avatar/2001ceff7e9dc753cf96fcb2e6f41110 +tags: [SOTF, keyboards, firmware, oss, ble] +--- + +Welcome to the second ZMK "State Of The Firmware" (SOTF)! + +This update will cover all the major activity since [SOTF #1](/blog/2020/08/12/zmk-sotf-1), preparations for the upcoming +Hacktoberfest activity, and a current open call for community feedback on a ZMK mascot. + +## Recent Activity + +So much going on in ZMK! + +- Added a new generic [Hold Tap behavior](https://zmkfirmware.dev/docs/behavior/hold-tap) + in [#146](https://github.com/zmkfirmware/zmk/pull/146) which now powers mod-tap, layer-tap, etc. - [okke-formsma] +- [BLE profile/connection management](https://zmkfirmware.dev/docs/behavior/bluetooth) + in [#133](https://github.com/zmkfirmware/zmk/pull/133) - [petejohanson] +- Integration tests were added to automate testing of behaviors in [#131](https://github.com/zmkfirmware/zmk/pull/131) by [BrainWart] & [petejohanson] +- [Toggle layer behavior](https://zmkfirmware.dev/docs/behavior/layers#toggle-layer), e.g. `&tog LOWER`, in + [#98](https://github.com/zmkfirmware/zmk/pull/98) - [BrainWart] +- Key fix for dropped press/release over HID [#93](https://github.com/zmkfirmware/zmk/pull/93)/[#96](https://github.com/zmkfirmware/zmk/pull/96) - [careyk007](https://github.com/careyk007) & [petejohanson] +- Code formatting standardized using `clang-format` in [#183](https://github.com/zmkfirmware/zmk/pull/183) - [petejohanson] +- [Bootloader reset behavior](https://zmkfirmware.dev/docs/behavior/reset#bootloader-reset), e.g. `&bootloader`, in [#116](https://github.com/zmkfirmware/zmk/pull/116) - [petejohanson] +- Various bug fixes and documentation + +## New Shields + +- QAZ in [#130](https://github.com/zmkfirmware/zmk/pull/130) - [tominabox1](https://github.com/tominabox1) +- Iris in [#151](https://github.com/zmkfirmware/zmk/pull/151) - [kurtis-lew](https://github.com/kurtis-lew) +- RoMac 2.1 in [#122](https://github.com/zmkfirmware/zmk/pull/122) - [bmcgavin](https://github.com/bmcgavin) +- Sofle in [#118](https://github.com/zmkfirmware/zmk/pull/118) - [CrossR](https://github.com/CrossR) +- splitreus62 in [#92](https://github.com/zmkfirmware/zmk/pull/92) - [Na-Cly](https://github.com/Na-Cly) + +## New Boards + +- DZ60RGB rev1 in [#166](https://github.com/zmkfirmware/zmk/pull/166) - [Nicell] +- nrfMicro in [#101](https://github.com/zmkfirmware/zmk/pull/101) - [okke-formsma] +- BlueMicro840 [#91](https://github.com/zmkfirmware/zmk/pull/91) - [Na-Cly](https://github.com/Na-Cly) + +## Hacktoberfest Preparation + +[Hacktoberfest](https://hacktoberfest.digitalocean.com/) is a yearly celebration of open source, +which encourages participation in OSS, especially from new contributors. + +The ZMK contributors have been busy preparing for folks to join in on the fun by contributing to +ZMK! + +- There is now a basic [Contributing Guide](https://github.com/zmkfirmware/zmk/blob/main/CONTRIBUTING.md) to help newcomers get oriented, and get up to speed. +- The [`Hacktoberfest`](https://github.com/zmkfirmware/zmk/issues?q=is%3Aissue+is%3Aopen+label%3AHacktoberfest) + issue label will help participants discover good issues to work on. + (The existing [`good first issue`](https://github.com/zmkfirmware/zmk/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label also helps with this) + +We're looking forward to the launch of Hacktoberfest! + +## Mascot Selection Feedback + +The ZMK project would like to settle on a mascot! We're soliciting community feedback as part of +the process before a final mascot is selected. + +The current mascots up for consideration are: + +- Griffin +- Peregrine Falcon +- Zapata Wren +- Zorro (south american fox) + +If you're interested in helping with the decision, head over to [Issue #195](https://github.com/zmkfirmware/zmk/issues/195) and add a reaction! + +## Coming Soon! + +There still lots of activity in ZMK, and plenty of exciting upcoming changes. + +- Improved modifier infrastructure, including "shifted keycodes" - [okke-formsma] +- Battery percentage reporting over BLE - [Nicell] +- Complete defines for HID keycodes/usage IDs - [innovaker](https://github.com/innovaker) +- Additional core BLE connection/bond management work - [petejohanson] +- Improved power management - [petejohanson], [Nicell] +- One shot mod/layer behaviors - [okke-formsma] + +## Statistics + +Some statistics of interest for ZMK: + +- GitHub + - 115 Closed PRs + - 64 Stars + - 48 Forks +- Discord Chat + - 186 total registered +- Website (last 30 days) + - 7.4K page views + - 474 new users + +## Thanks! + +Thanks again to the numerous contributors and users who have made working on ZMK such a pleasure! + +[okke-formsma]: https://github.com/okke-formsma +[nicell]: https://github.com/Nicell +[petejohanson]: https://github.com/petejohanson +[brainwart]: https://github.com/BrainWart diff --git a/docs/docs/assets/dev-setup/vscode_devcontainer.png b/docs/docs/assets/dev-setup/vscode_devcontainer.png Binary files differnew file mode 100644 index 0000000..e5c22b0 --- /dev/null +++ b/docs/docs/assets/dev-setup/vscode_devcontainer.png diff --git a/docs/docs/assets/pro-micro/pro-micro-pins-labelled.jpg b/docs/docs/assets/pro-micro/pro-micro-pins-labelled.jpg Binary files differnew file mode 100644 index 0000000..f72d407 --- /dev/null +++ b/docs/docs/assets/pro-micro/pro-micro-pins-labelled.jpg diff --git a/docs/docs/assets/troubleshooting/filetransfer/linux.png b/docs/docs/assets/troubleshooting/filetransfer/linux.png Binary files differnew file mode 100644 index 0000000..c192dfa --- /dev/null +++ b/docs/docs/assets/troubleshooting/filetransfer/linux.png diff --git a/docs/docs/assets/troubleshooting/filetransfer/mac.png b/docs/docs/assets/troubleshooting/filetransfer/mac.png Binary files differnew file mode 100644 index 0000000..f28ca8d --- /dev/null +++ b/docs/docs/assets/troubleshooting/filetransfer/mac.png diff --git a/docs/docs/assets/troubleshooting/filetransfer/windows.png b/docs/docs/assets/troubleshooting/filetransfer/windows.png Binary files differnew file mode 100644 index 0000000..91cb8a6 --- /dev/null +++ b/docs/docs/assets/troubleshooting/filetransfer/windows.png diff --git a/docs/docs/assets/troubleshooting/keymaps/errorscreen.png b/docs/docs/assets/troubleshooting/keymaps/errorscreen.png Binary files differnew file mode 100644 index 0000000..73b5b58 --- /dev/null +++ b/docs/docs/assets/troubleshooting/keymaps/errorscreen.png diff --git a/docs/docs/assets/troubleshooting/keymaps/healthyEDIT.png b/docs/docs/assets/troubleshooting/keymaps/healthyEDIT.png Binary files differnew file mode 100644 index 0000000..50d2c73 --- /dev/null +++ b/docs/docs/assets/troubleshooting/keymaps/healthyEDIT.png diff --git a/docs/docs/assets/troubleshooting/keymaps/unhealthyEDIT.png b/docs/docs/assets/troubleshooting/keymaps/unhealthyEDIT.png Binary files differnew file mode 100644 index 0000000..3fd8dc7 --- /dev/null +++ b/docs/docs/assets/troubleshooting/keymaps/unhealthyEDIT.png diff --git a/docs/docs/behavior/bluetooth.md b/docs/docs/behavior/bluetooth.md new file mode 100644 index 0000000..be0fb23 --- /dev/null +++ b/docs/docs/behavior/bluetooth.md @@ -0,0 +1,76 @@ +--- +title: Bluetooth Behavior +sidebar_label: Bluetooth +--- + +## Summary + +The bluetooth behavior allows management of various settings and states related to the bluetooth connection(s) +between the keyboard and the host. By default, ZMK supports five "profiles" for selecting which bonded host +computer/laptop/keyboard should receive the keyboard input; many of the commands here operation on those profiles. + +## Bluetooth Command Defines + +Bluetooth command defines are provided through the [`dt-bindings/zmk/bt.h`](https://github.com/zmkfirmware/zmk/blob/main/app/include/dt-bindings/zmk/bt.h) header, +which is added at the top of the keymap file: + +``` +#include <dt-bindings/zmk/bt.h> +``` + +This will allow you to reference the actions defined in this header such as `BT_CLR_CMD`. + +Here is a table describing the command for each define: + +| Define | Action | +| ------------ | ---------------------------------------------------------------------------------------------- | +| `BT_CLR_CMD` | Clear bond information between the keyboard and host for the selected profile. | +| `BT_NXT_CMD` | Switch to the next profile, cycling through to the first one when the end is reached. | +| `BT_PRV_CMD` | Switch to the previous profile, cycling through to the last one when the beginning is reached. | +| `BT_SEL_CMD` | Select the 0-indexed profile by number. | + +Because at least one bluetooth commands takes an additional parameter, it is recommended to use +the following aliases in your keymap to avoid having to specify an ignored second parameter: + +| Define | Action | +| -------- | -------------------------------------------------------------------------------- | +| `BT_CLR` | Alias for `BT_CLR_CMD 0` to clear the current profile's bond to the current host | +| `BT_NXT` | Alias for `BT_NXT_CMD 0` to select the next profile | +| `BT_PRV` | Alias for `BT_PRV_CMD 0` to select the previous profile | +| `BT_SEL` | Alias for `BT_SEL_CMD` to select the given profile, e.g. `&bt BT_SEL 1` | + +## Bluetooth Behavior + +The bluetooth behavior completes an bluetooth action given on press. + +### Behavior Binding + +- Reference: `&bt` +- Parameter #1: The bluetooth command define, e.g. `BT_CLR_CMD` +- Parameter #2: (Reserved for future bluetooth command types) + +### Examples + +1. Behavior binding to clear the paired host for the selected profile: + + ``` + &bt BT_CLR + ``` + +1. Behavior binding to select the next profile: + + ``` + &bt BT_NXT + ``` + +1. Behavior binding to select the previous profile: + + ``` + &bt BT_PRV + ``` + +1. Behavior binding to select the 2nd profile (passed parameters are [zero based](https://en.wikipedia.org/wiki/Zero-based_numbering)): + + ``` + &bt BT_SEL 1 + ``` diff --git a/docs/docs/behavior/hold-tap.md b/docs/docs/behavior/hold-tap.md index fa68538..9f8f5fa 100644 --- a/docs/docs/behavior/hold-tap.md +++ b/docs/docs/behavior/hold-tap.md @@ -22,7 +22,11 @@ We call this the 'hold-preferred' flavor of hold-taps. While this flavor may wor  -### Configuration +### Basic usage +For basic usage, please see [mod-tap](./mod-tap.md) and [layer-tap](./layers.md) pages. + + +### Advanced Configuration A code example which configures a mod-tap setting that works with homerow mods: ``` @@ -58,5 +62,5 @@ If this config does not work for you, try the flavor "tap-preferred" and a short If you want to use a tap-hold with a keycode from a different code page, you have to define another behavior with another "bindings" parameter.For example, if you want to use SHIFT and volume up, define the bindings like `bindings = <&kp>, <&cp>;`. Only single-argument behaviors are supported at the moment. -#### Note -Astute readers may notice similarities between the possible behaviors in ZMK and other firmware, such as QMK. The hold-preferred flavor works similar to the `HOLD_ON_OTHER_KEY_PRESS` setting. The 'balanced' flavor is similar to the `PERMISSIVE_HOLD` setting, and the `tap-preferred` flavor is similar to `IGNORE_MOD_TAP_INTERRUPT`.
\ No newline at end of file +#### Comparison to QMK +The hold-preferred flavor works similar to the `HOLD_ON_OTHER_KEY_PRESS` setting in QMK. The 'balanced' flavor is similar to the `PERMISSIVE_HOLD` setting, and the `tap-preferred` flavor is similar to `IGNORE_MOD_TAP_INTERRUPT`.
\ No newline at end of file diff --git a/docs/docs/behavior/key-press.md b/docs/docs/behavior/key-press.md index f58225d..d427f9d 100644 --- a/docs/docs/behavior/key-press.md +++ b/docs/docs/behavior/key-press.md @@ -27,6 +27,11 @@ There is an [open issue](https://github.com/zmkfirmware/zmk/issues/21) to provid complete set of defines for the full keypad and consumer usage pages in the future for ZMK. ::: +### Improperly defined keymap - `dtlib.DTError: <board>.dts.pre.tmp:<line number>` + +When compiling firmware from a keymap, it may be common to encounter an error in the form of a`dtlib.DTError: <board>.dts.pre.tmp:<line number>`. +For instructions to resolve such an error, click [here](../troubleshooting###Improperly-defined-keymap) + ## Keypad Key Press The "keypad key press" behavior sends standard keypad keycodes on press/release. @@ -59,4 +64,4 @@ Example: ``` &cp M_PREV -``` +```
\ No newline at end of file diff --git a/docs/docs/behavior/layers.md b/docs/docs/behavior/layers.md index da7f07f..c769388 100644 --- a/docs/docs/behavior/layers.md +++ b/docs/docs/behavior/layers.md @@ -26,7 +26,7 @@ This allows you to use those defines, e.g. `LOWER` later in your keymap. ## Momentary Layer -The "momentary layer" behavior allows you to enable a layer while a certain key is pressed. Immediately upon +The "momentary layer" behavior enables a layer while a certain key is pressed. Immediately upon activation of the key, the layer is enabled, and immediately open release of the key, the layer is disabled again. @@ -41,9 +41,25 @@ Example: &mo LOWER ``` +## Layer-tap + +The "layer-tap" behavior enables a layer when a key is held, and output another key when the key is only tapped for a short time. For more information on the inner workings of layer-tap, see [hold-tap](./hold-tap.md). + +### Behavior Binding +- Reference: `<` +- Parameter: The layer number to enable when held, e.g. `1` +- Parameter: The keycode to send when tapped, e.g. `A` + +Example: + +``` +< LOWER SPC +``` + + ## Toggle Layer -The "toggle layer" behavior allows you to enable a layer until the layer is manually disabled. +The "toggle layer" behavior enables a layer until the layer is manually disabled. ### Behavior Binding diff --git a/docs/docs/behavior/mod-tap.md b/docs/docs/behavior/mod-tap.md index dcac492..068928a 100644 --- a/docs/docs/behavior/mod-tap.md +++ b/docs/docs/behavior/mod-tap.md @@ -31,8 +31,8 @@ You can configure a different tapping term in your keymap: ``` &mt { - tapping_term_ms: <400>; -} + tapping_term_ms = <400>; +}; / { keymap { diff --git a/docs/docs/behavior/power.md b/docs/docs/behavior/power.md new file mode 100644 index 0000000..6b8237b --- /dev/null +++ b/docs/docs/behavior/power.md @@ -0,0 +1,64 @@ +--- +title: Power Management Behaviors +sidebar_label: Power Management +--- + +## Summary + +These page contains some of the power management behaviors currently supported by ZMK. + +## External Power Control + +The External power control behavior allows enabling or disabling the VCC power output +to save power. Some of the LEDs will consume power even in OFF state. To preserve +battery life in this scenario, some controller boards have support to disable the +external power completely. + +The following boards currently support this feature: +- nRFMicro +- nice!nano + +## External Power Control Command Defines + +External power control command defines are provided through the [`dt-bindings/zmk/ext_power.h`](https://github.com/zmkfirmware/zmk/blob/main/app/include/dt-bindings/zmk/ext_power.h) header, +which is added at the top of the keymap file: + +``` +#include <dt-bindings/zmk/ext_power.h> +``` + +This will allow you to reference the actions defined in this header such as `EXT_POWER_OFF_CMD`. + +Here is a table describing the command for each define: + +| Define | Action | Alias | +| ------------ | -------------------------------------- | -------- | +| `EXT_POWER_OFF_CMD` | Disable the external power. | `EP_OFF` | +| `EXT_POWER_ON_CMD` | Enable the external power. | `EP_ON` | +| `EXT_POWER_TOGGLE_CMD` | Toggle the external power. | `EP_TOG` | + +### Behavior Binding + +- Reference: `&ext_power` +- Parameter#1: Command, e.g `EP_ON` + +### Example: + +1. Behavior binding to enable the external power + + ``` + &ext_power EP_ON + ``` + +1. Behavior binding to disable the external power + + ``` + &ext_power EP_OFF + ``` + +1. Behavior binding to toggle the external power + + ``` + &ext_power EP_TOG + ``` + diff --git a/docs/docs/bond-reset.md b/docs/docs/bond-reset.md index 1ba79ee..504fd72 100644 --- a/docs/docs/bond-reset.md +++ b/docs/docs/bond-reset.md @@ -1,7 +1,7 @@ --- id: bond-reset -title: Reset BLE Connections -sidebar_label: BLE Reset +title: Reset BLE Connections (DEPRECATED) +sidebar_label: BLE Reset (DEPRECATED) --- Known as a 'bond reset', each keyboard has a special key combination independent of the user defined key map which will diff --git a/docs/docs/customization.md b/docs/docs/customization.md index 0bb1794..261c40d 100644 --- a/docs/docs/customization.md +++ b/docs/docs/customization.md @@ -1,10 +1,21 @@ --- id: customization -title: Customizing ZMK +title: Customizing ZMK/`zmk-config` folders sidebar_label: Customizing ZMK --- After verifying you can successfully flash the default firmware, you will probably want to begin customizing your keymap and other keyboard options. +[In the initial setup tutorial](user-setup), you created a Github repository called `zmk-config`. This repository is a discrete filesystem which works +with the main `zmk` firmware repository to build your desired firmware. The main advantage of a discrete configuration folder is ensuring that the +working components of ZMK are kept separate from your personal keyboard settings, reducing the amount of file manipulation in the configuration process. +This makes flashing ZMK to your keyboard much easier, especially because you don't need to keep an up-to-date copy of zmk on your computer at all times. + +On default `zmk-config` folder should contain two files: +* `<shield>.conf` +* `<shield>`.keymap + +However, your config folder can also be modified to include a `boards/` directory for keymaps and configurations for multiple boards/shields +outside of the default keyboard setting definitions. ## Configuration Changes @@ -26,8 +37,23 @@ GitHub Actions job to build your firmware which you can download once it complet If you need to, a review of [Learn The Basics Of Git In Under 10 Minutes](https://www.freecodecamp.org/news/learn-the-basics-of-git-in-under-10-minutes-da548267cc91/) will help you get these steps right. ::: +## Building from a local `zmk` fork using `zmk-config` + +[As outlined here](dev-build-flash), firmware comes in the form of .uf2 files, which can be built locally using the command `west build`. Normally, +`west build` will default to using the in-tree .keymap and .conf files found in your local copy of the `zmk` repository. However, you can append the command, `-DZMK_CONFIG="C:/the/absolute/path/config"` to `west build` in order to use the contents of your `zmk-config` folder instead of the +default keyboard settings. + **Notice that this path should point to the folder labelled `config` within your `zmk-config` folder.** + + +For instance, building kyria firmware from a user `myUser`'s `zmk-config` folder on Windows 10 may look something like this: + +``` +west build -b nice_nano -- -DSHIELD=kyria_left -DZMK_CONFIG="C:/Users/myUser/Documents/Github/zmk-config/config" +``` + ## Flashing Your Changes For normal keyboards, follow the same flashing instructions as before to flash your updated firmware. For split keyboards, only the central (left) side will need to be reflashed if you are just updating your keymap. +More troubleshooting information for split keyboards can be found [here](troubleshooting#split-keyboard-halves-unable-to-pair). diff --git a/docs/docs/dev-boards-shields-keymaps.md b/docs/docs/dev-boards-shields-keymaps.md index cfe5252..9ed5a32 100644 --- a/docs/docs/dev-boards-shields-keymaps.md +++ b/docs/docs/dev-boards-shields-keymaps.md @@ -35,6 +35,8 @@ in the `app/boards/${arch}/${board_name}` directory, e.g. `app/boards/arm/planck ## Pro Micro Compatible Keyboard + + For keyboards that require a (usually Pro Micro compatible) add-on board to operate, the ZMK integration pieces are places in the _shield_ definition for that keyboard, allowing users to swap in different Pro Micro compatible boards (e.g. Proton-C, or nice!nano) and build a firmware the matches their actual diff --git a/docs/docs/dev-build.md b/docs/docs/dev-build.md index 816468e..83ed8cb 100644 --- a/docs/docs/dev-build.md +++ b/docs/docs/dev-build.md @@ -84,6 +84,19 @@ west build -d build/right -b nice_nano -- -DSHIELD=kyria_right ``` This produces `left` and `right` subfolders under the `build` directory and two separate .uf2 files. For future work on a specific half, use the `-d` parameter again to ensure you are building into the correct location. +### Building from `zmk-config` Folder + +Instead of building .uf2 files using the default keymap and config files, you can build directly from your [`zmk-config` folder](user-setup#github-repo) by adding +`-DZMK_CONFIG="C:/the/absolute/path/config"` to your `west build` command. **Notice that this path should point to the folder labelled `config` within your `zmk-config` folder.** + + +For instance, building kyria firmware from a user `myUser`'s `zmk-config` folder on Windows 10 may look something like this: + +``` +west build -b nice_nano -- -DSHIELD=kyria_left -DZMK_CONFIG="C:/Users/myUser/Documents/Github/zmk-config/config" +``` + + ## Flashing Once built, the previously supplied parameters will be remembered so you can run the following to flash your diff --git a/docs/docs/dev-clean-room.md b/docs/docs/dev-clean-room.md index c11171c..2f301ec 100644 --- a/docs/docs/dev-clean-room.md +++ b/docs/docs/dev-clean-room.md @@ -6,7 +6,7 @@ sidebar_label: Clean Room :::warning -Anyone wanting to contribute code to ZMK _must_ read this, and adhere to the steps outlines in order to not violate any licenses/copyright of other projects +Anyone wanting to contribute code to ZMK _MUST_ read this, and adhere to the steps outlines in order to not violate any licenses/copyright of other projects ::: @@ -22,8 +22,8 @@ or duplicating any of the GPL code found in those other projects, even though th Contributors to ZMK must adhere to the following standard. -- Implementations of features for ZMK _MUST_ not reuse any existing code from any projects not licensed with the MIT license. -- Contributors _MUST_ not study or refer to any GPL licensed source code while working on ZMK. +- Implementations of features for ZMK _MUST NOT_ reuse any existing code from any projects not licensed with the MIT license. +- Contributors _MUST NOT_ study or refer to any GPL licensed source code while working on ZMK. - Contributors _MAY_ read the documentation from other GPL licensed projects, to gain a broad understanding of the behavior of certain features in order to implement equivalent features for ZMK. - Contributors _MAY_ refer to the [QMK Configurator](https://config.qmk.fm/) to inspect existing layouts/keymaps for keyboards, and re-implement them for ZMK. diff --git a/docs/docs/dev-guide-new-shield.md b/docs/docs/dev-guide-new-shield.md index 8556623..9f7b23c 100644 --- a/docs/docs/dev-guide-new-shield.md +++ b/docs/docs/dev-guide-new-shield.md @@ -3,6 +3,9 @@ id: dev-guide-new-shield title: New Keyboard Shield --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + ## Overview This guide will walk through the steps necessary to add ZMK support for a keyboard the uses a (Pro Micro compatible) addon MCU board to provide the microprocessor. @@ -13,9 +16,15 @@ The high level steps are: - Add the shield overlay file to define the [KSCAN driver]() for detecting key press/release. - (Optional) Add the matrix transform for mapping KSCAN row/column values to sane key positions. This is needed for non-rectangular keyboards, or where the underlying row/column pin arrangement does not map one to one with logical locations on the keyboard. - Add a default keymap, which users can override in their own configs as needed. +- Add support for features such as encoders, OLED displays, or RGB underglow. +- Update build.yml It may be helpful to review the upstream [shields documentation](https://docs.zephyrproject.org/2.3.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. +::: + ## New Shield Directory Shields for Zephyr applications go into the `boards/shields/` directory; since ZMK's Zephyr application lives in the `app/` subdirectory of the repository, that means the new shield directory should be: @@ -40,6 +49,16 @@ config SHIELD_MY_BOARD This will make sure the new configuration `SHIELD_MY_BOARD` is set to true whenever `my_board` is added as a shield in your build. + +**For split boards**, you will need to add configurations for the left and right sides. +``` +config SHIELD_MY_BOARD_LEFT + def_bool $(shields_list_contains,my_board_left) + +config SHIELD_MY_BOARD_RIGHT + def_bool $(shields_list_contains,my_board_right) +``` + ### Kconfig.defconfig The `Kconfig.defconfig` file is where overrides for various configuration settings @@ -58,7 +77,40 @@ config ZMK_KEYBOARD_NAME endif ``` -## Shield Overlay + +Similarly to defining the halves of a split board in `Kconfig.shield` it is important to set the `ZMK_KEYBOARD_NAME` for each half of a split keyboard. + +``` +if SHIELD_MY_BOARD_LEFT + +config ZMK_KEYBOARD_NAME + default "My Awesome Keyboard Left" + +endif + +if SHIELD_MY_BOARD_RIGHT + +config ZMK_KEYBOARD_NAME + default "My Awesome Keyboard Right" + +endif +``` + +## Shield Overlays + + + + +ZMK uses the green color coded pin names to generate devicetree node references. For example, to refer to the node `D0` in the devicetree files, use `&pro_micro_d 0` or to refer to `A1`, use `&pro_micro_a 1`. + +<Tabs +defaultValue="unibody" +values={[ +{label: 'Unibody Shields', value: 'unibody'}, +{label: 'Split Shields', value: 'split'}, +]}> + +<TabItem value="unibody"> The `<shield_name>.overlay` is the devicetree description of the keyboard shield that is merged with the primary board devicetree description before the build. For ZMK, this file at a minimum should include the [chosen]() node named `zmk,kscan` that references a KSCAN driver instance. For a simple 3x3 macropad matrix, this might look something like: @@ -89,6 +141,146 @@ this might look something like: }; ``` +</TabItem> + +<TabItem value="split"> + +### .dtsi files and Shield Overlays (Split Shields) + +Unlike unibody keyboards, split keyboards have a core .dtsi file with shield overlays for each half of the keyboard. +It is preferred to define only the `col-gpios` or `row-gpios` in the common shield .dtsi, depending on the `diode-direction` value. +For `col2row` directed boards like the iris, the shared .dtsi file may look like this: + +``` +#include <dt-bindings/zmk/matrix-transform.h> + +/ { + chosen { + zmk,kscan = &kscan0; + zmk,matrix_transform = &default_transform; + }; + + default_transform: keymap_transform_0 { + compatible = "zmk,matrix-transform"; + columns = <16>; + rows = <4>; +// | SW6 | SW5 | SW4 | SW3 | SW2 | SW1 | | SW1 | SW2 | SW3 | SW4 | SW5 | SW6 | +// | SW12 | SW11 | SW10 | SW9 | SW8 | SW7 | | SW7 | SW8 | SW9 | SW10 | SW11 | SW12 | +// | SW18 | SW17 | SW16 | SW15 | SW14 | SW13 | | SW13 | SW14 | SW15 | SW16 | SW17 | SW18 | +// | SW24 | SW23 | SW22 | SW21 | SW20 | SW19 | SW25 | | SW25 | SW19 | SW20 | SW21 | SW22 | SW23 | SW24 | +// | SW29 | SW28 | SW27 | SW26 | | SW26 | SW27 | SW28 | SW29 | + map = < +RC(0,0) RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7) RC(0,8) RC(0,9) RC(0,10) RC(0,11) +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) RC(1,9) RC(1,10) RC(1,11) +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) RC(2,10) RC(2,11) +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) RC(3,8) RC(3,9) RC(3,10) RC(3,11) + 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"; + label = "KSCAN"; + + diode-direction = "col2row"; + row-gpios + = <&pro_micro_d 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // Row A from the schematic file + , <&pro_micro_d 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // Row B from the schematic file + , <&pro_micro_d 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // Row C from the schematic file + , <&pro_micro_d 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // Row D from the schematic file + , <&pro_micro_d 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // Row E from the schematic file + ; + + }; +``` + +:::note +Notice that in addition to the common `row-gpios` that are declared in the kscan, the [matrix transform](#optional-matrix-transform) is defined in the .dtsi. +::: + +The missing `col-gpios` would be defined in your `<boardname>_left.overlay` and `<boardname>_right.overlay` files. +Keep in mind that the mirrored position of the GPIOs means that the `col-gpios` will appear reversed when the .overlay files are compared to one another. +Furthermore, the column offset for the [matrix transform](#optional-matrix-transform) should be added to the right half of the keyboard's overlay +because the keyboard's switch matrix is read from left to right, top to bottom. +This is exemplified with the iris .overlay files. + +``` +// iris_left.overlay + +#include "iris.dtsi" // Notice that the main dtsi files are included in the overlay. + +&kscan0 { + col-gpios + = <&pro_micro_a 1 GPIO_ACTIVE_HIGH> // col1 in the schematic + , <&pro_micro_a 0 GPIO_ACTIVE_HIGH> // col2 in the schematic + , <&pro_micro_d 15 GPIO_ACTIVE_HIGH> // col3 in the schematic + , <&pro_micro_d 14 GPIO_ACTIVE_HIGH> // col4 in the schematic + , <&pro_micro_d 16 GPIO_ACTIVE_HIGH> // col5 in the schematic + , <&pro_micro_d 10 GPIO_ACTIVE_HIGH> // col6 in the schematic + ; +}; +``` + +``` +// iris_right.overlay + +#include "iris.dtsi" + +&default_transform { // The matrix transform for this board is 6 columns over because the left half is 6 columns wide according to the matrix. + col-offset = <6>; +}; + +&kscan0 { + col-gpios + = <&pro_micro_d 10 GPIO_ACTIVE_HIGH> // col6 in the schematic + , <&pro_micro_d 16 GPIO_ACTIVE_HIGH> // col5 in the schematic + , <&pro_micro_d 14 GPIO_ACTIVE_HIGH> // col4 in the schematic + , <&pro_micro_d 15 GPIO_ACTIVE_HIGH> // col3 in the schematic + , <&pro_micro_a 0 GPIO_ACTIVE_HIGH> // col2 in the schematic + , <&pro_micro_a 1 GPIO_ACTIVE_HIGH> // col1 in the schematic + ; +}; + +``` + +### .conf files (Split Shields) + +While unibody boards only have one .conf file that applies configuration characteristics to the entire keyboard, +split keyboards are unique in that they contain multiple .conf files with different scopes. +For example, a split board called `my_awesome_split_board` would have the following files: + +* `my_awesome_split_board.conf` - Configuration elements affect both halves +* `my_awesome_split_board_left.conf` - Configuration elements only affect left half +* `my_awesome_split_board_right.conf` - Configuration elements only affect right half + +For proper communication between keyboard halves and that between the central half and the computer, +the **the central and peripheral halves of the keyboard must be defined**. This can be seen below. + +``` +// Central Half (Usually the left side: my_awesome_split_board_left.conf) + +CONFIG_ZMK_SPLIT=y +CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL=y +``` + +``` +// Peripheral Half (Usually the right side: my_awesome_split_board_right.conf) + +CONFIG_ZMK_SPLIT=y +CONFIG_ZMK_SPLIT_BLE_ROLE_Peripheral=y +``` + +Using the .conf file that affects both halves of a split board would be for adding features like deep-sleep or rotary encoders. + +``` +// my_awesome_split_board.conf + +CONFIG_ZMK_SLEEP=y +``` + +</TabItem> +</Tabs> + ## (Optional) Matrix Transform Internally ZMK translates all row/column events into "key position" events to maintain a consistent model that works no matter what any possible GPIO matrix may look like for a certain keyboard. This is particularly helpful when: @@ -195,6 +387,91 @@ Further documentation on behaviors and bindings is forthcoming, but a summary of - `trans` is the "transparent" behavior, useful to be place in higher layers above `mo` bindings to be sure the key release is handled by the lower layer. No binding arguments are required. - `mt` is the "mod-tap" behavior, and takes two binding arguments, the modifier to use if held, and the keycode to send if tapped. +## Adding Features + +### Encoders + +EC11 encoder support can be added to your board or shield by adding the appropriate lines to your board/shield's configuration (.conf), device tree (.dtsi), overlay (.overlay), and keymap (.keymap) files. + +<Tabs +defaultValue="conf" +values={[ +{label: '.conf', value: 'conf'}, +{label: '.dtsi', value: 'dtsi'}, +{label: '.overlay', value: 'overlay'}, +{label: '.keymap', value: 'keymap'}, +]}> +<TabItem value="conf"> + +In your configuration file you will need to add the following lines so that the encoders can be enabled/disabled: + +``` +# Uncomment to enable encoder +# CONFIG_EC11=y +# CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y +``` + +These should be commented by default for encoders that are optional/can be swapped with switches, but can be uncommented if encoders are part of the default design. + +:::note +If building locally for split boards, you may need to add these lines to the specific half's configuration file as well as the combined configuration file. +::: + +</TabItem> +<TabItem value = "dtsi"> +In your device tree file you will need to add the following lines to define the encoder sensor: + + +``` +left_encoder: encoder_left { + compatible = "alps,ec11"; + label = "LEFT_ENCODER"; + a-gpios = <PIN_A (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + b-gpios = <PIN_B (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + resolution = <4>; + }; +``` +Here you will have to replace PIN_A and PIN_B with the appropriate pins that your PCB utilizes for the encoder(s). For keyboards that use the Pro Micro or any of the Pro Micro replacements, Sparkfun's [Pro Micro Hookup Guide](https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/hardware-overview-pro-micro) has a pinout diagram that can be useful to determine the right pins. Reference either the blue numbers labeled "Arduino" (digital pins) or the green numbers labeled "Analog" (analog pins). For pins that are labeled as both digital and analog, refer to your specific board's .dtsi file to determine how you should refer to that pin. + +Add additional encoders as necessary by duplicating the above lines, replacing `left` with whatever you would like to call your encoder, and updating the pins. Note that support for peripheral (right) side sensors over BLE is still in progress. + +Once you have defined the encoder sensors, you will have to add them to the list of sensors: + +``` +sensors { + compatible = "zmk,keymap-sensors"; + sensors = <&left_encoder &right_encoder>; + }; +``` + +In this example, a left_encoder and right_encoder are both added. Additional encoders can be added with spaces separating each, and the order they are added here determines the order in which you define their behavior in your keymap. + +</TabItem> +<TabItem value = "overlay"> +Add the following lines to your overlay file(s) to enable the encoder: + +``` +&left_encoder { + status = "okay"; +}; +``` + +:::note +For split keyboards, make sure to add left hand encoders to the left .overlay file and right hand encoders to the right .overlay file. +::: + +</TabItem> +<TabItem value = "keymap"> +Add the following line to your keymap file to add default encoder behavior bindings: + +``` +sensor-bindings = <&inc_dec_cp M_VOLU M_VOLD>; +``` +Add additional bindings as necessary to match the default number of encoders on your board. See the [Encoders](/docs/feature/encoders) and [Keymap](/docs/feature/keymaps) feature documentation for more details. + +</TabItem> +</Tabs> + ## Testing Once you've fully created the new keyboard shield definition, @@ -209,3 +486,41 @@ and then flash with: ``` west flash ``` + +:::note +Further testing your keyboard shield without altering the root keymap file can be done with the use of `-DZMK_CONFIG` in your `west build` command, +shown [here](dev-build-flash#building-from-zmk-config-folder) +::: + +## Updating `build.yml` + +Before publishing your shield to the public via a PR, navigate to `build.yml` found in `.github/workflows` and add your shield to the appropriate list. An example edit to `build.yml` is shown below. + +``` +jobs: + build: + runs-on: ubuntu-latest + name: Build Test + strategy: + matrix: + board: [proton_c, nice_nano, bluemicro840_v1, nrfmicro_13] + shield: + - corne_left + - corne_right + - kyria_left + - kyria_right + - lily58_left + - lily58_right + - iris_left + - iris_right + - romac + - <MY_BOARD> + - <MY_SPLIT_BOARD_left> + - <MY_SPLIT_BOARD_right> + include: + - board: proton_c + shield: clueboard_california +``` +:::note +Notice that both the left and right halves of a split board need to be added to the list of shields for proper error checking. +:::note diff --git a/docs/docs/dev-setup.md b/docs/docs/dev-setup.md index 1d7d703..521d5d0 100644 --- a/docs/docs/dev-setup.md +++ b/docs/docs/dev-setup.md @@ -12,16 +12,17 @@ groupId="operating-systems" defaultValue="debian" values={[ {label: 'Debian/Ubuntu', value: 'debian'}, -{label: 'Raspberry OS', value: 'raspberryos'}, -{label: 'Fedora', value: 'fedora'}, {label: 'Windows', value: 'win'}, {label: 'macOS', value: 'mac'}, +{label: 'Raspberry OS', value: 'raspberryos'}, +{label: 'Fedora', value: 'fedora'}, +{label: 'VS Code & Docker', value: 'docker'}, ] }>{props.children}</Tabs>); ## Prerequisites -A unix-like environment with the following base packages installed: +ZMK requires the following base packages to first be installed: - Git - Python 3 @@ -34,6 +35,7 @@ A unix-like environment with the following base packages installed: <OsTabs> <TabItem value="debian"> + On Debian and Ubuntu, we'll use `apt` to install our base dependencies: First, if you haven't updated recently, or if this is a new install, @@ -74,7 +76,8 @@ or download and install CMake version 3.13.1 or newer manually. ::: </TabItem> <TabItem value="raspberryos"> -On Raspberry OS, we'll use apt to install our base dependencies: + +On Raspberry OS, we'll use `apt` to install our base dependencies: First, if you haven't updated recently, or if this is a new install, you should update to get the latest package information: @@ -165,6 +168,10 @@ Chocolatey is recommended and used for the following instructions. You can manua choco install ninja gperf python git ``` +It is recommended to install `dfu-util` to avoid any later confusion while flashing devices. You can do this by running this command with chocolatey: +``` shell +choco install dfu-util +``` </TabItem> <TabItem value="mac"> @@ -173,10 +180,24 @@ Chocolatey is recommended and used for the following instructions. You can manua Homebrew is required to install the system dependencies. If you haven't done so, visit [Homebrew](https://brew.sh/) for instructions. Once installed, use it to install the base dependencies: ``` -brew install cmake ninja python3 ccache dtc git wget +brew install cmake ninja python3 ccache dtc git wget dfu-util ``` </TabItem> +<TabItem value="docker"> + +This setup leverages the same [image which is used by the GitHub action](https://github.com/zmkfirmware/zephyr-west-action) for local development. Beyond the benefits of [dev/prod parity](https://12factor.net/dev-prod-parity), this approach is also the easiest to set up. No toolchain or dependencies are necessary when using Docker; the container image you'll be using already has the toolchain installed and set up to use. + + +1. Install [Docker Desktop](https://www.docker.com/products/docker-desktop) for your operating system. +2. Install [VS Code](https://code.visualstudio.com/) +3. Install the [Remote - Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) + +:::info +The docker container includes `west` and the compilation toolchain. If you're using docker and VS Code, you can skip right to [Source Code](#source-code). +::: + +</TabItem> </OsTabs> ## Setup @@ -185,14 +206,40 @@ brew install cmake ninja python3 ccache dtc git wget `west` is the [Zephyr™ meta-tool](https://docs.zephyrproject.org/2.3.0/guides/west/index.html) used to configure and build Zephyr™ applications. -West can be installed by using the `pip` python package manager. +West can be installed by using the `pip` python package manager. The [Zephyr™ instructions](https://docs.zephyrproject.org/latest/guides/west/install.html#installing-west) are summarized here: + +<Tabs +defaultValue="linux" +values={[ +{label: 'Linux', value: 'linux'}, +{label: 'Windows', value: 'win'}, +]}> +<TabItem value = 'linux'> ```sh pip3 install --user -U west ``` -:::danger pip user packages -If you haven't done so yet, you may need to add the Python Pip user package directory to your `PATH` otherwise your computer will not be able to find the `west` command. +</TabItem> +<TabItem value = 'win'> + +In `cmd.exe` as **Administrator**: + +```sh +pip3 install -U west +``` + +:::note +**For Windows, do not use the `--user` argument** that Linux uses otherwise `west` will be installed in a different location and the below instructions for adding Python `pip` will no longer apply. +::: + +Once `west` is installed, close Command Prompt and open a new session as a **user** for the remainder of the instructions. + +</TabItem> +</Tabs> + +:::danger `pip` user packages +If you haven't done so yet, you may need to add the Python `pip` package directory to your `PATH` otherwise your computer will not be able to find the `west` command. ::: <Tabs @@ -213,7 +260,8 @@ source ~/.bashrc <TabItem value = 'win'> 1. See the [Environment Variables](#environment-variables) section on how to get to the Environment Variables page. -3. Click "Edit..." and then "New" to add the directory where your west.exe is located. By default this should be something like `C:\Python38\Scripts`. +2. Under "System variables" select the "Path" variable. Click "Edit..." and then "New" to add the directory where your `west.exe` is located. By default this should be `C:\Python##\Scripts` where ## is your Python version number. +3. Close Command Prompt and open a new session for the changes to take effect, or run `refreshenv`. </TabItem> </Tabs> @@ -279,7 +327,7 @@ The installation will prompt with several questions about installation location, #### GNU ARM Embedded -Since the Zephyr™ SDK is not available for Windows, we recommending following the steps to install the [GNU ARM Embedded](https://docs.zephyrproject.org/2.3.0/getting_started/toolchain_3rd_party_x_compilers.html#gnu-arm-embedded). +Since the Zephyr™ SDK is not available for Windows, we recommending following the [Zephyr documentation](https://docs.zephyrproject.org/2.3.0/getting_started/toolchain_3rd_party_x_compilers.html#gnu-arm-embedded) to install a GNU ARM Embedded build. Note the warnings regarding installing the toolchain into a path with spaces, and make sure to follow the steps to add the environment variables which are also summarized with screenshots in the [Environment Variables](#environment-variables) section below. </TabItem> <TabItem value="mac"> @@ -308,7 +356,7 @@ The transient instructions must be run to build firmware using the current shell ### Source Code -Next, you'll need to clone the ZMK source repository if you haven't already: +Next, you'll need to clone the ZMK source repository if you haven't already. Navigate to the folder you would like to place your `zmk` directory in and run the following command: ``` git clone https://github.com/zmkfirmware/zmk.git @@ -320,12 +368,63 @@ Since ZMK is built as a Zephyr™ application, the next step is to use `west` to initialize and update your workspace. The ZMK Zephyr™ application is in the `app/` source directory: + #### Step into the repository +<OsTabs> +<TabItem value="debian"> + +```sh +cd zmk +``` + +</TabItem> +<TabItem value="raspberryos"> + +```sh +cd zmk +``` + +</TabItem> +<TabItem value="fedora"> + +```sh +cd zmk +``` + +</TabItem> +<TabItem value="mac"> + ```sh cd zmk ``` +</TabItem> +<TabItem value="win"> + +```sh +cd zmk +``` + +</TabItem> + +<TabItem value="docker"> + +Open the `zmk` checkout folder in VS Code. The repository includes a configuration for containerized development, so an alert will pop up: + + + +Click `Reopen in Container` in order to reopen the VS Code with the running container. + +The first time you do this on your machine, it will pull the docker image down from the registry and build the container. Subsequent launches are much faster! + +:::caution +All subsequent steps must be performed from the VS Code terminal _inside_ the container. +::: + +</TabItem> +</OsTabs> + #### Initialize West ```sh @@ -344,6 +443,17 @@ section again for links to how to do this west update ``` +:::tip +This step pulls down quite a bit of tooling. Go grab a cup of coffee, it can take 10-15 minutes even on a good internet connection! +::: + +:::info +If you're using Docker, you're done with setup! You must restart the container at this point. The easiest way to do so is to close the VS Code window, verify that the container has stopped in Docker Dashboard, and reopen the container with VS Code. + +Once your container is restarted, proceed to [Building and Flashing](./dev-build.md). +::: + + #### Export Zephyr™ Core ```sh @@ -358,12 +468,17 @@ pip3 install --user -r zephyr/scripts/requirements-base.txt ### Environment Variables -#### For GNU ARM Embedded on Windows +<Tabs +defaultValue="win" +values={[ +{label: 'Windows', value: 'win'}, +{label: 'Other OS', value: 'other'}, +]}> +<TabItem value = 'win'> -On Windows, you will have to set two environment variables for ZMK to build properly: `ZEPHYR_TOOLCHAIN_VARIANT` and `GNUARMEMB_TOOLCHAIN_PATH`. +#### For GNU ARM Embedded on Windows -<details> -<summary> Steps to Update Environment Variables </summary> +On Windows, only two environment variables need to be set for ZMK to build properly: `ZEPHYR_TOOLCHAIN_VARIANT` and `GNUARMEMB_TOOLCHAIN_PATH`. 1. Open Start Menu and type 'env' to find the 'Edit the system environment variables' option. Open it. @@ -381,11 +496,15 @@ On Windows, you will have to set two environment variables for ZMK to build prop  -5. Create another variable with variable name 'GNUARMEMB_TOOLCHAIN_PATH' and value set to wherever you installed your toolchain. Click OK to save. +5. Create another variable with variable name 'GNUARMEMB_TOOLCHAIN_PATH' and value set to wherever you installed your toolchain. **Make sure this path does not contain any spaces.** If it does, rename the folder and update here. Click OK to save.  -</details> +6. Close Command Prompt and reopen, or run `refreshenv` to apply the changes. + +</TabItem> + +<TabItem value = 'other'> #### For Zephyr @@ -396,48 +515,10 @@ We suggest two main [options](https://docs.zephyrproject.org/2.3.0/guides/env_va To load the Zephyr environment properly for just one transient shell, run the following from your ZMK checkout directory: -<OsTabs> -<TabItem value="debian"> - -``` -source zephyr/zephyr-env.sh -``` - -</TabItem> - -<TabItem value="raspberryos"> - -``` -source zephyr/zephyr-env.sh -``` - -</TabItem> - -<TabItem value="fedora"> - -``` -source zephyr/zephyr-env.sh -``` - -</TabItem> - -<TabItem value="mac"> - ``` source zephyr/zephyr-env.sh ``` -</TabItem> - -<TabItem value="win"> - -``` -source zephyr/zephyr-env.cmd -``` - -</TabItem> -</OsTabs> - ##### All Shells To load the environment variables for your shell every time, @@ -469,3 +550,7 @@ cat ~/.zephyrrc >> ~/.zshrc </TabItem> </Tabs> + +</TabItem> + +</Tabs> diff --git a/docs/docs/faq.md b/docs/docs/faq.md index 2ab158d..d8bbd71 100644 --- a/docs/docs/faq.md +++ b/docs/docs/faq.md @@ -76,7 +76,7 @@ Please note, many keyboards only have a single PCB which includes the “brains ### What bootloader does ZMK use? -ZMK isn’t designed for any particular bootloader, and supports flashing different boards with different flash utilities (e.g. OpenOCD, nrfjprog, etc.). So if you have any difficulties, please let us know on [Discord](https://discord.gg/VJnx9kr)! +ZMK isn’t designed for any particular bootloader, and supports flashing different boards with different flash utilities (e.g. OpenOCD, nrfjprog, etc.). So if you have any difficulties, please let us know on [Discord](https://zmkfirmware.dev/community/discord/invite)! ### Can I contribute? @@ -84,11 +84,11 @@ Of course! Please use the developer [documentation](/docs) to get started! ### I have an idea! What should I do? -Please join us on [Discord](https://discord.gg/VJnx9kr) and discuss it with us! +Please join us on [Discord](https://zmkfirmware.dev/community/discord/invite) and discuss it with us! ### I want to add a new keyboard! What should I do? -The exact process for the management of all the possible hardware is still being finalized, but any developer looking to contribute new keyboard definitions should chat with us on [Discord](https://discord.gg/VJnx9kr) to get started. +The exact process for the management of all the possible hardware is still being finalized, but any developer looking to contribute new keyboard definitions should chat with us on [Discord](https://zmkfirmware.dev/community/discord/invite) to get started. ### Does ZMK have a Code of Conduct? diff --git a/docs/docs/feature/encoders.md b/docs/docs/feature/encoders.md index 16537ad..9caccc2 100644 --- a/docs/docs/feature/encoders.md +++ b/docs/docs/feature/encoders.md @@ -3,4 +3,42 @@ title: Encoders sidebar_label: Encoders --- -TODO: Documentation on encoders. +Existing support for encoders in ZMK is focused around the five pin EC11 rotary encoder with push button design used in the majority of current keyboard and macropad designs. + +## Enabling EC11 Encoders + +To enable encoders for boards that have existing encoder support, uncomment the `EC11_CONFIG=y` and `CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y` lines in your board's .conf file in your `zmk-config/config` folder. Save and push your changes, then download and flash the new firmware. + +## Customizing EC11 Encoder Behavior + +Encoder behavior in ZMK is configured in two different locations as the push button and rotation behaviors are handled in two separate ways. + +### Push Button + +Keyboards and macropads with encoder support will typically take the two EC11 pins responsible for the push button and include them as part of the matrix for the keys. To configure what is sent by the push button, find the encoder's position in the keyboard matrix and assign it a behavior the same as you would any other key. + +### Rotation + +Rotation is handled separately as a type of sensor. The behavior for this is set in `sensor-bindings`, which is defined in each keymap layer in the following format: + +``` +sensor-bindings = <BINDING CW_KEY CCW_KEY>; +``` + +- `BINDING` is one of two rotation bindings that are currently defined, `&inc_dec_cp` for consumer key presses or `&inc_dec_kp` for normal key presses (see [Key Press](/docs/behavior/key-press) for the difference between the two). +- `CW_KEY` is the keycode activated by a clockwise turn. +- `CCW_KEY` is the keycode activated by a counter-clockwise turn. + +Additional encoders can be configured by adding more `BINDING CW_KEY CCW_KEY` sets immediately after the first. + +As an example, a complete `sensor-bindings` for a Kyria with two encoders could look like: + +``` +sensor-bindings = <&inc_dec_cp M_VOLU M_VOLD &inc_dec_kp PGUP PGDN>; +``` + +Here, the left encoder is configured to control volume up and down while the right encoder sends either Page Up or Page Down. + +## Adding Encoder Support + +See the [New Keyboard Shield](/docs/dev-guide-new-shield#encoders) documentation for how to add or modify additional encoders to your shield. diff --git a/docs/docs/feature/keymaps.md b/docs/docs/feature/keymaps.md index d991925..56fc2cc 100644 --- a/docs/docs/feature/keymaps.md +++ b/docs/docs/feature/keymaps.md @@ -55,7 +55,7 @@ in the stack _also_ get the event. ## Behavior Bindings Binding a behavior at a certain key position may include up to two extra parameters that are used to -alter the behavior when that specific key position is activated/deactived. For example, when binding +alter the behavior when that specific key position is activated/deactivated. For example, when binding the "key press" (`kp`) behavior at a certain key position, you must specific _which_ keycode should be used for that key position. diff --git a/docs/docs/hardware.md b/docs/docs/hardware.md index 299d1f5..fe229df 100644 --- a/docs/docs/hardware.md +++ b/docs/docs/hardware.md @@ -16,7 +16,7 @@ That being said, there are currently only a few specific [boards](/docs/faq#what ## Boards -- [nice!nano](https://docs.nicekeyboards.com/#/nice!nano/) (`nice_nano`) +- [nice!nano](https://nicekeyboards.com/products/nice-nano-v1-0) (`nice_nano`) - [nrfMicro](https://github.com/joric/nrfmicro) (`nrfmicro_13`, `nrfmicro_11`, `nrfmicro_11_flipped`) - [BlueMicro840](https://store.jpconstantineau.com/#/group/bluemicro) (`bluemicro840_v1`) - [QMK Proton-C](https://qmk.fm/proton-c/) (`proton_c`) @@ -26,6 +26,11 @@ That being said, there are currently only a few specific [boards](/docs/faq#what - [Kyria](https://splitkb.com/products/kyria-pcb-kit) (`kyria_left` and `kyria_right`) - [Corne](https://github.com/foostan/crkbd) (`corne_left` and `corne_right`) - [Lily58](https://github.com/kata0510/Lily58) (`lily58_left` and `lily58_right`) +- [Sofle](https://github.com/josefadamcik/SofleKeyboard) (`sofle_left` and `sofle_right`) +- [Splitreus62](https://github.com/Na-Cly/splitreus62) (`splitreus62_left` and `splitreus62_right`) +- [RoMac+ v4](https://www.littlekeyboards.com/products/romac) (`romac_plus`) +- [RoMac v2](https://mechboards.co.uk/shop/kits/romac-macro-pad/) (`romac`) +- [QAZ](https://www.cbkbd.com/product/qaz-keyboard-kit) (`qaz`) ## Other Hardware diff --git a/docs/docs/intro.md b/docs/docs/intro.md index 29045f7..60fe0d2 100644 --- a/docs/docs/intro.md +++ b/docs/docs/intro.md @@ -5,34 +5,41 @@ sidebar_label: Introduction --- ZMK Firmware is an open source (MIT) keyboard -firmware built on the [Zephyr™ Project](https://zephyrproject.com/) Real Time Operating System (RTOS). - -The goal is to provider a powerful, featureful keyboard firmware that is free -of licensing issues that prevent upstream BLE support as a first-class -feature. +firmware built on the [Zephyr™ Project](https://zephyrproject.org/) Real Time Operating System (RTOS). ZMK's goal is to provide a modern, wireless, and powerful firmware free of licensing issues. ## Features -At this point, ZMK is _missing_ more features than it has. Currently, the mostly working bits -include: - -- HID Over GATT (HOG) - This is the official term for BLE HID devices -- Keymaps and layers with basic keycodes -- Some initial work on one "behavior", Mod-Tap -- Basic HID over USB -- Basic consumer (media) keycodes. -- Basic OLED display logic -- Basic Split support -- Encoders - -## Missing Features - -- One Shot -- Layer Tap -- Complete split support -- Battery reporting -- Low power mode -- Shell over BLE +ZMK is currently missing some features found in other popular firmware. This table compares the features supported by ZMK, BlueMicro and QMK: + + +| **Feature** | ZMK | BlueMicro | QMK | +|--------------------------------------------------------------------------------------------------------|:-----------:|:------------:|:-----------:| +| Low Latency BLE Support | ✅ | ✅ | | +| Multi-Device BLE Support | ✅ | | | +| USB Connectivity | ✅ | | ✅ | +| User Configuration Repositories | ✅ | | | +| Split Keyboard Support | ✅ | ✅ | ✅ | +| [Keymaps and Layers](behavior/layers) | ✅ | ✅ | ✅ | +| [Hold-Tap](behavior/hold-tap) (which includes [Mod-Tap](behavior/mod-tap) and [Layer-Tap](behavior/layers/#layer-tap)) | ✅ | ✅ | ✅ | +| [Basic Keycodes](behavior/key-press) | ✅ | ✅ | ✅ | +| [Basic consumer (Media) Keycodes](behavior/key-press#consumer-key-press) | ✅ | ✅ | ✅ | +| [Encoders](feature/encoders)[^1] | ✅ | | ✅ | +| [OLED Display Support](feature/displays)[^2] | 🚧 | 🚧 | ✅ | +| [RGB Underglow](feature/underglow) | ✅ | ✅ | ✅ | +| One Shot Keys | 🚧 | ✅ | ✅ | +| Combo Keys | 🚧 | | ✅ | +| Macros | 🚧 | ✅ | ✅ | +| Mouse Keys | | ✅ | ✅ | +| Low Active Power Usage | ✅ | | | +| [Low Power Sleep States](https://github.com/zmkfirmware/zmk/pull/211) | 🚧 | ✅ | | +| [Low Power Mode (VCC Shutoff)](https://github.com/zmkfirmware/zmk/pull/242) | 🚧 | | | +| [Battery Reporting](https://github.com/zmkfirmware/zmk/issues/47) | 🚧 | ✅ | | +| Shell over BLE | | | | +| Realtime Keymap Updating | 💡 | | ✅ | +| AVR/8 Bit | | | ✅ | +| [Wide Range of ARM Chips Supported](https://docs.zephyrproject.org/latest/boards/index.html) | ✅ | | | +[^2]: Encoders are not currently supported on peripheral side splits. +[^1]: OLEDs are currently proof of concept in ZMK. ## Code Of Conduct diff --git a/docs/docs/troubleshooting.md b/docs/docs/troubleshooting.md new file mode 100644 index 0000000..36682e7 --- /dev/null +++ b/docs/docs/troubleshooting.md @@ -0,0 +1,82 @@ +--- +id: troubleshooting +title: Troubleshooting +sidebar_title: Troubleshooting +--- +### Summary + +The following page provides suggestions for common errors that may occur during firmware compilation. If the information provided is insufficient to resolve the issue, feel free to seek out help from the [ZMK Discord](https://zmkfirmware.dev/community/discord/invite). + +### File Transfer Error + +Variations of the warnings shown below occur when flashing the `<firmware>.uf2` onto the microcontroller. This is because the microcontroller resets itself before the OS receives confirmation that the file transfer is complete. Errors like this are normal and can generally be ignored. Verification of a functional board can be done by attempting to pair your newly flashed keyboard to your computer via Bluetooth or plugging in a USB cable if `ZMK_USB` is enabled in your Kconfig.defconfig. + +|  | +| :-------------------------------------------------------------------------------: | +| An example of the file transfer error on Windows 10 | + +|  | +| :-------------------------------------------------------------------------------: | +| An example of the file transfer error on Linux | + +|  | +| :-------------------------------------------------------------------------------: | +| An example of the file transfer error on MacOS | + + +### CMake Error + +``` +CMake Warning at C:/zmk/zephyr/subsys/usb/CMakeLists.txt:28 (message): + CONFIG_USB_DEVICE_VID has default value 0x2FE3. + + This value is only for testing and MUST be configured for USB products. + + +CMake Warning at C:/zmk/zephyr/subsys/usb/CMakeLists.txt:34 (message): + CONFIG_USB_DEVICE_PID has default value 0x100. + + This value is only for testing and MUST be configured for USB products. +``` + +CMake Warnings shown above during `west build` are normal occurrences. They should not negatively affect the firmware's ability to function as normal. + +On the other hand, 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. +For more information, click [here](../docs/dev-setup#environment-variables). + + +### dtlib.DTError + +An error along the lines of `dtlib.DTError: <board>.dts.pre.tmp:<line number>` during firmware compilation indicates an issue within the `<shield>.keymap` file. +This can be verified by checking the file in question, found in `mkdir/app/build`. + +|  | +| :-------------------------------------------------------------------------------: | +| An example of the dtlib.DTError when compiling an iris with the nice!nano while the keymap is not properly defined | + +After opening the `<board>.dts.pre.tmp:<line number>` and scrolling down to the referenced line, one can locate errors within their shield's keymap by checking if the referenced keycodes were properly converted into the correct [USB HID Usage ID](https://www.usb.org/document-library/hid-usage-tables-12). + +|  | +| :-------------------------------------------------------------------------------: | +| An incorrectly defined keymap unable to compile. As shown in red, `&kp SPAC` is not a valid reference to the [USB HID Usage ID](https://www.usb.org/document-library/hid-usage-tables-12) used for "Keyboard Spacebar" | + +|  | +| :-------------------------------------------------------------------------------: | +| A properly defined keymap with successful compilation. As shown in red, the corrected keycode (`&kp SPC`) references the proper Usage ID defined in the [USB HID Usage Tables](https://www.usb.org/document-library/hid-usage-tables-12)| + +### Split Keyboard Halves Unable to Pair + +Previously, pairing split keyboard halves involved a **BLE Reset** via a combination of held keys that removed all bluetooth profile information from the keyboard. +Since then, a much simpler procedure of performing a bluetooth reset for split keyboards has come about, without the need for any file modification: + +**New Procedure:** + +1. Log into Github and download the "settings clear" UF2 image from the [latest build in Github Actions](https://github.com/zmkfirmware/zmk/actions?query=workflow%3ABuild+branch%3Amain) +1. Put each half of the split keyboard into bootloader mode +1. Flash one of the halves of the split with the "settings clear" UF2 image from step 1. Immediately after flashing "settings clear" to the chosen half, immediately put it into bootloader mode +to avoid accidental bonding between the halves. +1. Repeat step 3 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.
\ No newline at end of file diff --git a/docs/docs/user-setup.md b/docs/docs/user-setup.md index 2aade82..2785096 100644 --- a/docs/docs/user-setup.md +++ b/docs/docs/user-setup.md @@ -63,6 +63,7 @@ defaultValue="curl" values={[ {label: 'Using curl', value: 'curl'}, {label: 'Using wget', value: 'wget'}, +{label: 'Using PowerShell', value: 'PowerShell'}, ]}> <TabItem value="curl"> @@ -78,6 +79,12 @@ bash -c "$(wget https://zmkfirmware.dev/setup.sh -O -)" ``` </TabItem> +<TabItem value="PowerShell"> + +``` +iex ((New-Object System.Net.WebClient).DownloadString('https://zmkfirmware.dev/setup.ps1'))" +``` +</TabItem> </Tabs> ### MCU Board Selection diff --git a/docs/sidebars.js b/docs/sidebars.js index 53c5cf3..12b4a6e 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -1,6 +1,13 @@ module.exports = { someSidebar: { - "Getting Started": ["intro", "hardware", "faq", "user-setup","customization", "bond-reset"], + "Getting Started": [ + "intro", + "hardware", + "faq", + "user-setup", + "customization", + "troubleshooting" + ], Features: [ "feature/keymaps", "feature/displays", @@ -11,9 +18,12 @@ module.exports = { "behavior/key-press", "behavior/layers", "behavior/misc", + "behavior/hold-tap", "behavior/mod-tap", "behavior/reset", + "behavior/bluetooth", "behavior/lighting", + "behavior/power", ], Development: [ "dev-clean-room", @@ -23,6 +33,8 @@ module.exports = { "dev-posix-board", "dev-tests", ], - "Dev Guides": ["dev-guide-new-shield", "dev-guide-usb-logging"], + "Dev Guides": [ + "dev-guide-new-shield", + "dev-guide-usb-logging"], }, }; diff --git a/docs/static/setup.ps1 b/docs/static/setup.ps1 new file mode 100644 index 0000000..5ebd376 --- /dev/null +++ b/docs/static/setup.ps1 @@ -0,0 +1,206 @@ +# Copyright (c) 2020 The ZMK Contributors
+#
+# SPDX-License-Identifier: MIT
+
+$ErrorActionPreference = "Stop"
+
+function Get-Choice-From-Options {
+ param(
+ [String[]] $Options,
+ [String] $Prompt
+ )
+
+ while ($true) {
+ for ($i = 0; $i -lt $Options.length; $i++) {
+ Write-Host "$($i + 1)) $($Options[$i])"
+ }
+
+ Write-Host "$($Options.length + 1)) Quit"
+ $selection = Read-Host $Prompt
+
+ if ($selection -eq $Options.length + 1) {
+ Write-Host "Goodbye!"
+ exit 1
+ }
+ elseif ($selection -le $Options.length) {
+ $choice = $($selection - 1)
+ break
+ }
+ else {
+ Write-Host "Invalid Option. Try another one."
+ }
+ }
+
+ return $choice
+}
+
+function Test-Git-Config {
+ param(
+ [String] $Option,
+ [String] $ErrMsg
+ )
+
+ git config $Option | Out-Null
+
+ if ($lastExitCode -ne 0) {
+ Write-Host $ErrMsg
+ exit 1
+ }
+}
+
+try {
+ git | Out-Null
+}
+catch [System.Management.Automation.CommandNotFoundException] {
+ Write-Host "Git is not installed, and is required for this script!"
+ exit 1
+}
+
+Test-Git-Config -Option "user.name" -ErrMsg "Git username not set!`nRun: git config --global user.name 'My Name'"
+Test-Git-Config -Option "user.email" -ErrMsg "Git email not set!`nRun: git config --global user.email 'example@myemail.com'"
+
+$permission = (Get-Acl $pwd).Access |
+?{$_.IdentityReference -match $env:UserName `
+ -and $_.FileSystemRights -match "FullControl" `
+ -or $_.FileSystemRights -match "Write" } |
+
+ Select IdentityReference,FileSystemRights
+
+If (-Not $permission){
+ Write-Host "Sorry, you do not have write permissions in this directory."
+ Write-Host "Please try running this script again from a directory that you do have write permissions for."
+ exit 1
+}
+
+$repo_path = "https://github.com/zmkfirmware/zmk-config-split-template.git"
+
+$title = "ZMK Config Setup:"
+$prompt = "Pick an MCU board"
+$options = "nice!nano", "QMK Proton-C", "BlueMicro840 (v1)", "makerdiary nRF52840 M.2"
+$boards = "nice_nano", "proton_c", "bluemicro840_v1", "nrf52840_m2"
+
+Write-Host "$title"
+Write-Host ""
+Write-Host "MCU Board Selection:"
+
+$choice = Get-Choice-From-Options -Options $options -Prompt $prompt
+$board = $($boards[$choice])
+
+Write-Host ""
+Write-Host "Keyboard Shield Selection:"
+$prompt = "Pick a keyboard"
+
+# TODO: Add support for "Other" and linking to docs on adding custom shields in user config repos.
+$options = "Kyria", "Lily58", "Corne", "Splitreus62", "Sofle", "Iris", "RoMac", "RoMac+", "makerdiary M60", "Microdox", "TG4X", "QAZ"
+$names = "kyria", "lily58", "corne", "splitreus62", "sofle", "iris", "romac", "romac_plus", "m60", "microdox", "tg4x", "qaz"
+$splits = "y", "y", "y", "y", "y", "y", "n", "n", "n", "y", "n", "n"
+
+$choice = Get-Choice-From-Options -Options $options -Prompt $prompt
+$shield_title = $($options[$choice])
+$shield = $($names[$choice])
+$split = $($splits[$choice])
+
+if ($split -eq "n") {
+ $repo_path = "https://github.com/zmkfirmware/zmk-config-template.git"
+}
+
+$copy_keymap = Read-Host "Copy in the stock keymap for customisation? [Yn]"
+
+if ($copy_keymap -eq "" -or $copy_keymap -eq "Y" -or $copy_keymap -eq "y") {
+ $copy_keymap = "yes"
+}
+
+$github_user = Read-Host "GitHub Username (leave empty to skip GitHub repo creation)"
+
+if ($github_user -ne "") {
+ $repo_name = Read-Host "GitHub Repo Name [zmk-config]"
+
+ if ($repo_name -eq "") {
+ $repo_name = "zmk-config"
+ }
+
+ $github_repo = Read-Host "GitHub Repo [https://github.com/$github_user/$repo_name.git]"
+
+ if ($github_repo -eq "") {
+ $github_repo = "https://github.com/$github_user/$repo_name.git"
+ }
+}
+else {
+ $repo_name = "zmk-config"
+ $github_repo = ""
+}
+
+Write-Host ""
+Write-Host "Preparing a user config for:"
+Write-Host "* MCU Board: ${board}"
+Write-Host "* Shield: ${shield}"
+
+if ($copy_keymap -eq "yes") {
+ Write-Host "* Copy Keymap?: Yes"
+}
+else {
+ Write-Host "* Copy Keymap?: No"
+}
+
+if ($github_repo -ne "") {
+ Write-Host "* GitHub Repo to Push (please create this in GH first!): $github_repo"
+}
+
+Write-Host ""
+$do_it = Read-Host "Continue? [Yn]"
+
+if ($do_it -ne "" -and $do_it -ne "Y" -and $do_it -ne "y") {
+ Write-Host "Aborting..."
+ exit 1
+}
+
+git clone --single-branch "$repo_path" "$repo_name"
+Set-Location "$repo_name"
+
+Push-Location config
+
+Invoke-RestMethod -Uri "https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/shields/${shield}/${shield}.conf" -OutFile "${shield}.conf"
+
+if ($copy_keymap -eq "yes") {
+ Invoke-RestMethod -Uri "https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/shields/${shield}/${shield}.keymap" -OutFile "${shield}.keymap"
+}
+
+Pop-Location
+
+$build_file = (Get-Content .github/workflows/build.yml).replace("BOARD_NAME", $board)
+$build_file = $build_file.replace("SHIELD_NAME", $shield)
+$build_file = $build_file.replace("KEYBOARD_TITLE", $shield_title)
+
+if ($board -eq "proton_c") {
+ $build_file = $build_file.replace("uf2", "hex")
+}
+
+Set-Content -Path .github/workflows/build.yml -Value $build_file
+
+Remove-Item -Recurse -Force .git
+git init .
+git add .
+git commit -m "Initial User Config."
+
+if ($github_repo -ne "") {
+ git remote add origin "$github_repo"
+
+ git push --set-upstream origin $(git symbolic-ref --short HEAD)
+
+ # If push failed, assume that the origin was incorrect and give instructions on fixing.
+ if ($lastExitCode -ne 0) {
+ Write-Host "Remote repository $github_repo not found..."
+ Write-Host "Check GitHub URL, and try adding again."
+ Write-Host "Run the following: "
+ Write-Host " git remote rm origin"
+ Write-Host " git remote add origin FIXED_URL"
+ Write-Host " git push --set-upstream origin $(git symbolic-ref --short HEAD)"
+ Write-Host "Once pushed, your firmware should be availalbe from GitHub Actions at: $actions"
+ exit 1
+ }
+
+ if ($github_repo -imatch "https") {
+ $actions = "$($github_repo.substring(0, $github_repo.length - 4))/actions"
+ Write-Host "Your firmware should be availalbe from GitHub Actions shortly: $actions"
+ }
+}
diff --git a/docs/static/setup.sh b/docs/static/setup.sh index 70defdf..e45a7ed 100644 --- a/docs/static/setup.sh +++ b/docs/static/setup.sh @@ -1,49 +1,69 @@ -#!/bin/sh +#!/bin/bash + +# Copyright (c) 2020 The ZMK Contributors +# +# SPDX-License-Identifier: MIT set -e -repo_path="https://github.com/zmkfirmware/zmk-config-split-template.git" -title="ZMK Config Setup:" +check_exists() { + command_to_run=$1 + error_message=$2 + + if ! eval "$command_to_run" &> /dev/null; then + printf "%s\n" "$error_message" + exit 1 + fi +} +check_exists "command -v git" "git is not installed, and is required for this script!" +check_exists "command -v curl" "curl is not installed, and is required for this script!" -# TODO: Check for git being installed -# TODO: Check for curl being installed -# TODO: Check for user.name and user.email git configs being set +check_exists "git config user.name" "Git username not set!\nRun: git config --global user.name 'My Name'" +check_exists "git config user.email" "Git email not set!\nRun: git config --global user.email 'example@myemail.com'" + +# Check to see if the user has write permissions in this directory to prevent a cryptic error later on +if [ ! -w `pwd` ]; then + echo 'Sorry, you do not have write permissions in this directory.'; + echo 'Please try running this script again from a directory that you do have write permissions for.'; + exit 1 +fi + +repo_path="https://github.com/zmkfirmware/zmk-config-split-template.git" +title="ZMK Config Setup:" prompt="Pick an MCU board:" -options=("nice!nano" "QMK Proton-C" "BlueMicro840 (v1)") +options=("nice!nano" "QMK Proton-C" "BlueMicro840 (v1)" "makerdiary nRF52840 M.2") echo "$title" echo "" echo "MCU Board Selection:" PS3="$prompt " -select opt in "${options[@]}" "Quit"; do +select opt in "${options[@]}" "Quit"; do case "$REPLY" in 1 ) board="nice_nano"; break;; 2 ) board="proton_c"; break;; 3 ) board="bluemicro840_v1"; break;; + 3 ) board="nrf52840_m2"; break;; - $(( ${#options[@]}+1 )) ) echo "Goodbye!"; exit;; - *) echo "Invalid option. Try another one.";continue;; + $(( ${#options[@]}+1 )) ) echo "Goodbye!"; exit 1;; + *) echo "Invalid option. Try another one."; continue;; esac done -#read -p "Is this board a complete keyboard [yN]: " complete -#echo "$complete" - echo "" echo "Keyboard Shield Selection:" prompt="Pick an keyboard:" -options=("Kyria" "Lily58" "Corne" "Splitreus62" "Sofle" "Iris") +options=("Kyria" "Lily58" "Corne" "Splitreus62" "Sofle" "Iris" "RoMac" "RoMac+" "makerdiary M60" "Microdox" "TG4X" "QAZ") PS3="$prompt " # TODO: Add support for "Other" and linking to docs on adding custom shields in user config repos. -# select opt in "${options[@]}" "Other" "Quit"; do -select opt in "${options[@]}" "Quit"; do +# select opt in "${options[@]}" "Other" "Quit"; do +select opt in "${options[@]}" "Quit"; do case "$REPLY" in @@ -53,50 +73,62 @@ select opt in "${options[@]}" "Quit"; do 4 ) shield_title="Splitreus62" shield="splitreus62"; split="y"; break;; 5 ) shield_title="Sofle" shield="sofle"; split="y"; break;; 6 ) shield_title="Iris" shield="iris"; split="y"; break;; + 7 ) shield_title="RoMac" shield="romac"; split="n"; break;; + 8 ) shield_title="RoMac+" shield="romac_plus"; split="n"; break;; + 9 ) shield_title="M60" shield="m60"; split="n"; break;; + 10 ) shield_title="Microdox" shield="microdox"; split="y"; break;; + 11 ) shield_title="TG4X" shield="tg4x"; split="n"; break;; + 12 ) shield_title="QAZ" shield="qaz"; split="n"; break;; # Add link to docs on adding your own custom shield in your ZMK config! - # $(( ${#options[@]}+1 )) ) echo "Other!"; break;; - $(( ${#options[@]}+1 )) ) echo "Goodbye!"; exit;; + # $(( ${#options[@]}+1 )) ) echo "Other!"; break;; + $(( ${#options[@]}+1 )) ) echo "Goodbye!"; exit 1;; *) echo "Invalid option. Try another one.";continue;; esac done -read -e -p "Copy in the stock keymap for customization? [Yn]: " copy_keymap +if [ "$split" == "n" ]; then + repo_path="https://github.com/zmkfirmware/zmk-config-template.git" +fi + +read -r -e -p "Copy in the stock keymap for customization? [Yn]: " copy_keymap if [ -z "$copy_keymap" ] || [ "$copy_keymap" == "Y" ] || [ "$copy_keymap" == "y" ]; then copy_keymap="yes"; fi -read -e -p "GitHub Username (leave empty to skip GitHub repo creation): " github_user +read -r -e -p "GitHub Username (leave empty to skip GitHub repo creation): " github_user if [ -n "$github_user" ]; then - read -p "GitHub Repo Name [zmk-config]: " repo_name - if [ -z "$repo_name" ]; then repo_name="zmk-config"; fi + read -r -p "GitHub Repo Name [zmk-config]: " repo_name + if [ -z "$repo_name" ]; then repo_name="zmk-config"; fi - read -p "GitHub Repo [https://github.com/${github_user}/${repo_name}.git]: " github_repo + read -r -p "GitHub Repo [https://github.com/${github_user}/${repo_name}.git]: " github_repo - if [ -z "$github_repo" ]; then github_repo="https://github.com/${github_user}/${repo_name}.git"; fi + if [ -z "$github_repo" ]; then github_repo="https://github.com/${github_user}/${repo_name}.git"; fi else - repo_name="zmk-config" + repo_name="zmk-config" fi echo "" echo "Preparing a user config for:" echo "* MCU Board: ${board}" echo "* Shield: ${shield}" + if [ "$copy_keymap" == "yes" ]; then echo "* Copy Keymap?: ✓" else echo "* Copy Keymap?: ❌" fi + if [ -n "$github_repo" ]; then - echo "* GitHub Repo To Push (please create this in GH first!): ${github_repo}" + echo "* GitHub Repo To Push (please create this in GH first!): ${github_repo}" fi echo "" -read -p "Continue? [Yn]: " do_it +read -r -p "Continue? [Yn]: " do_it if [ -n "$do_it" ] && [ "$do_it" != "y" ] && [ "$do_it" != "Y" ]; then - echo "Aborting..." - exit + echo "Aborting..." + exit 1 fi git clone --single-branch $repo_path ${repo_name} @@ -113,10 +145,10 @@ fi popd sed -i'.orig' \ - -e "s/BOARD_NAME/$board/" \ - -e "s/SHIELD_NAME/$shield/" \ - -e "s/KEYBOARD_TITLE/$shield_title/" \ - .github/workflows/build.yml + -e "s/BOARD_NAME/$board/" \ + -e "s/SHIELD_NAME/$shield/" \ + -e "s/KEYBOARD_TITLE/$shield_title/" \ + .github/workflows/build.yml if [ "$board" == "proton_c" ]; then # Proton-C board still fa @@ -131,11 +163,24 @@ git add . git commit -m "Initial User Config." if [ -n "$github_repo" ]; then - git remote add origin "$github_repo" - git push --set-upstream origin $(git symbolic-ref --short HEAD) + git remote add origin "$github_repo" + git push --set-upstream origin "$(git symbolic-ref --short HEAD)" + push_return_code=$? + + # If push failed, assume that the origin was incorrect and give instructions on fixing. + if [ ${push_return_code} -ne 0 ]; then + echo "Remote repository $github_repo not found..." + echo "Check GitHub URL, and try adding again." + echo "Run the following: " + echo " git remote rm origin" + echo " git remote add origin FIXED_URL" + echo " git push --set-upstream origin $(git symbolic-ref --short HEAD)" + echo "Once pushed, your firmware should be availalbe from GitHub Actions at: ${github_repo%.git}/actions" + exit 1 + fi # TODO: Support determing the actions URL when non-https:// repo URL is used. if [ "${github_repo}" != "${github_repo#https://}" ]; then - echo "Your firmware should be available from the GitHub Actions shortly: ${github_url%.git}/actions" + echo "Your firmware should be available from GitHub Actions shortly: ${github_repo%.git}/actions" fi fi |