Merge remote-tracking branch 'upstream/main' into CrossR/Sofle
62
.github/workflows/test.yml
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
name: Test
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
integration_test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Integration Tests
|
||||||
|
steps:
|
||||||
|
# To use this repository's private action,
|
||||||
|
# you must check out the repository
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Cache west modules
|
||||||
|
timeout-minutes: 2
|
||||||
|
continue-on-error: true
|
||||||
|
uses: actions/cache@v2
|
||||||
|
env:
|
||||||
|
cache-name: cache-zephyr-modules
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
modules/
|
||||||
|
tools/
|
||||||
|
zephyr/
|
||||||
|
bootloader/
|
||||||
|
key: 2-${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('app/west.yml') }}
|
||||||
|
restore-keys: |
|
||||||
|
2-${{ runner.os }}-build-${{ env.cache-name }}-
|
||||||
|
2-${{ runner.os }}-build-
|
||||||
|
2-${{ runner.os }}-
|
||||||
|
- name: West Init
|
||||||
|
uses: "docker://zmkfirmware/zephyr-west-action-arm:latest"
|
||||||
|
id: west-init
|
||||||
|
with:
|
||||||
|
args: 'init "-l app"'
|
||||||
|
- name: West Update
|
||||||
|
uses: "docker://zmkfirmware/zephyr-west-action-arm:latest"
|
||||||
|
id: west-update
|
||||||
|
with:
|
||||||
|
args: "update"
|
||||||
|
- name: West Config Zephyr Base
|
||||||
|
uses: "docker://zmkfirmware/zephyr-west-action-arm:latest"
|
||||||
|
id: west-config
|
||||||
|
with:
|
||||||
|
args: 'config "--global zephyr.base-prefer configfile"'
|
||||||
|
- name: West Zephyr Export
|
||||||
|
uses: "docker://zmkfirmware/zephyr-west-action-arm:latest"
|
||||||
|
id: west-zephyr-export
|
||||||
|
with:
|
||||||
|
args: "zephyr-export"
|
||||||
|
- name: Test All
|
||||||
|
uses: "docker://zmkfirmware/zephyr-west-action-arm:latest"
|
||||||
|
id: west-build
|
||||||
|
with:
|
||||||
|
entrypoint: /bin/bash
|
||||||
|
args: '-c "cd app && ./run-test.sh all"'
|
||||||
|
- name: Archive Build
|
||||||
|
if: ${{ always() }}
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: "log-files"
|
||||||
|
path: app/build/**/*.log
|
|
@ -56,3 +56,5 @@ target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/rgb_underglow.c)
|
||||||
target_sources(app PRIVATE src/endpoints.c)
|
target_sources(app PRIVATE src/endpoints.c)
|
||||||
target_sources(app PRIVATE src/hid_listener.c)
|
target_sources(app PRIVATE src/hid_listener.c)
|
||||||
target_sources(app PRIVATE src/main.c)
|
target_sources(app PRIVATE src/main.c)
|
||||||
|
|
||||||
|
zephyr_cc_option(-Wfatal-errors)
|
|
@ -1,2 +1,6 @@
|
||||||
|
# Uncomment to enable encoder
|
||||||
|
# CONFIG_EC11=y
|
||||||
|
# CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y
|
||||||
|
|
||||||
# Uncomment the following line to enable the Lily58 OLED Display
|
# Uncomment the following line to enable the Lily58 OLED Display
|
||||||
# CONFIG_ZMK_DISPLAY=y
|
# CONFIG_ZMK_DISPLAY=y
|
||||||
|
|
|
@ -45,6 +45,19 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(4,5) RC(4,6) RC(3,6) RC(3,7)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
left_encoder: encoder_left {
|
||||||
|
compatible = "alps,ec11";
|
||||||
|
label = "LEFT_ENCODER";
|
||||||
|
a-gpios = <&pro_micro_a 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>;
|
||||||
|
b-gpios = <&pro_micro_a 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>;
|
||||||
|
resolution = <4>;
|
||||||
|
};
|
||||||
|
|
||||||
|
sensors {
|
||||||
|
compatible = "zmk,keymap-sensors";
|
||||||
|
sensors = <&left_encoder>;
|
||||||
|
};
|
||||||
|
|
||||||
bt_unpair_combo: bt_unpair_combo {
|
bt_unpair_combo: bt_unpair_combo {
|
||||||
compatible = "zmk,bt-unpair-combo";
|
compatible = "zmk,bt-unpair-combo";
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
&kp LSFT &kp Z &kp X &kp C &kp V &kp B &kp LBKT &kp RBKT &kp N &kp M &kp CMMA &kp DOT &kp FSLH &kp RSFT
|
&kp LSFT &kp Z &kp X &kp C &kp V &kp B &kp LBKT &kp RBKT &kp N &kp M &kp CMMA &kp DOT &kp FSLH &kp RSFT
|
||||||
&kp LALT &kp LGUI &mo 1 &kp SPC &kp RET &mo 2 &kp BKSP &kp RGUI
|
&kp LALT &kp LGUI &mo 1 &kp SPC &kp RET &mo 2 &kp BKSP &kp RGUI
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
sensor-bindings = <&inc_dec_cp M_VOLU M_VOLD>;
|
||||||
};
|
};
|
||||||
|
|
||||||
lower_layer {
|
lower_layer {
|
||||||
|
@ -35,6 +37,8 @@
|
||||||
&trans &trans &trans &trans &trans &trans &trans &trans &trans &kp MINUS &kp KPLS &kp LCUR &kp RCUR &kp PIPE
|
&trans &trans &trans &trans &trans &trans &trans &trans &trans &kp MINUS &kp KPLS &kp LCUR &kp RCUR &kp PIPE
|
||||||
&trans &trans &trans &trans &trans &trans &trans &trans
|
&trans &trans &trans &trans &trans &trans &trans &trans
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
sensor-bindings = <&inc_dec_cp M_VOLU M_VOLD>;
|
||||||
};
|
};
|
||||||
|
|
||||||
raise_layer {
|
raise_layer {
|
||||||
|
@ -51,6 +55,8 @@
|
||||||
&kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &trans &trans &kp KPLS &kp MINUS &kp EQL &kp LBKT &kp RBKT &kp BSLH
|
&kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &trans &trans &kp KPLS &kp MINUS &kp EQL &kp LBKT &kp RBKT &kp BSLH
|
||||||
&trans &trans &trans &trans &trans &trans &trans &trans
|
&trans &trans &trans &trans &trans &trans &trans &trans
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
sensor-bindings = <&inc_dec_cp M_VOLU M_VOLD>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,2 +1,6 @@
|
||||||
|
# Uncomment to enable encoder
|
||||||
|
# CONFIG_EC11=y
|
||||||
|
# CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y
|
||||||
|
|
||||||
CONFIG_ZMK_SPLIT=y
|
CONFIG_ZMK_SPLIT=y
|
||||||
CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL=y
|
CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL=y
|
|
@ -17,6 +17,10 @@
|
||||||
;
|
;
|
||||||
};
|
};
|
||||||
|
|
||||||
&bt_unpair_combo {
|
&left_encoder {
|
||||||
key-positions = <0 42>;
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&bt_unpair_combo {
|
||||||
|
key-positions = <0 53>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,5 +22,5 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
&bt_unpair_combo {
|
&bt_unpair_combo {
|
||||||
key-positions = <11 43>;
|
key-positions = <11 54>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -156,7 +156,6 @@ static int kscan_gpio_read(struct device *dev)
|
||||||
struct kscan_gpio_data *data = dev->driver_data;
|
struct kscan_gpio_data *data = dev->driver_data;
|
||||||
const struct kscan_gpio_config *cfg = dev->config_info;
|
const struct kscan_gpio_config *cfg = dev->config_info;
|
||||||
u32_t read_state = data->pin_state;
|
u32_t read_state = data->pin_state;
|
||||||
LOG_DBG("Scanning the pins for updated state");
|
|
||||||
for (int i = 0; i < cfg->num_of_inputs; i++)
|
for (int i = 0; i < cfg->num_of_inputs; i++)
|
||||||
{
|
{
|
||||||
struct device *in_dev = kscan_gpio_input_devices(dev)[i];
|
struct device *in_dev = kscan_gpio_input_devices(dev)[i];
|
||||||
|
@ -165,8 +164,9 @@ static int kscan_gpio_read(struct device *dev)
|
||||||
}
|
}
|
||||||
for (int i = 0; i < cfg->num_of_inputs; i++)
|
for (int i = 0; i < cfg->num_of_inputs; i++)
|
||||||
{
|
{
|
||||||
|
bool prev_pressed = BIT(i) & data->pin_state;
|
||||||
bool pressed = BIT(i) & read_state;
|
bool pressed = BIT(i) & read_state;
|
||||||
if (pressed != (BIT(i) & data->pin_state))
|
if (pressed != prev_pressed)
|
||||||
{
|
{
|
||||||
LOG_DBG("Sending event at %d,%d state %s",
|
LOG_DBG("Sending event at %d,%d state %s",
|
||||||
0, i, (pressed ? "on" : "off"));
|
0, i, (pressed ? "on" : "off"));
|
||||||
|
|
|
@ -51,10 +51,10 @@ static u8_t zmk_keymap_layer_default = 0;
|
||||||
|
|
||||||
// State
|
// State
|
||||||
|
|
||||||
// When a behavior handles a key position "down" event, we record that layer
|
// When a behavior handles a key position "down" event, we record the layer state
|
||||||
// here so that even if that layer is deactivated before the "up", event, we
|
// here so that even if that layer is deactivated before the "up", event, we
|
||||||
// still send the release event to the behavior in that layer also.
|
// still send the release event to the behavior in that layer also.
|
||||||
static u8_t zmk_keymap_active_behavior_layer[ZMK_KEYMAP_LEN];
|
static u32_t zmk_keymap_active_behavior_layer[ZMK_KEYMAP_LEN];
|
||||||
|
|
||||||
static struct zmk_behavior_binding zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_KEYMAP_LEN] = {
|
static struct zmk_behavior_binding zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_KEYMAP_LEN] = {
|
||||||
DT_INST_FOREACH_CHILD(0, TRANSFORMED_LAYER)
|
DT_INST_FOREACH_CHILD(0, TRANSFORMED_LAYER)
|
||||||
|
@ -101,22 +101,16 @@ int zmk_keymap_layer_toggle(u8_t layer)
|
||||||
return zmk_keymap_layer_activate(layer);
|
return zmk_keymap_layer_activate(layer);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool is_active_position(u32_t position, u8_t layer)
|
bool is_active_layer(u8_t layer, u32_t layer_state)
|
||||||
{
|
{
|
||||||
return (zmk_keymap_layer_state & BIT(layer)) == BIT(layer)
|
return (layer_state & BIT(layer)) == BIT(layer)
|
||||||
|| layer == zmk_keymap_layer_default
|
|| layer == zmk_keymap_layer_default;
|
||||||
|| zmk_keymap_active_behavior_layer[position] == layer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_keymap_position_state_changed(u32_t position, bool pressed)
|
int zmk_keymap_apply_position_state(int layer, u32_t position, bool pressed)
|
||||||
{
|
{
|
||||||
for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= zmk_keymap_layer_default; layer--)
|
|
||||||
{
|
|
||||||
if (is_active_position(position, layer))
|
|
||||||
{
|
|
||||||
struct zmk_behavior_binding *binding = &zmk_keymap[layer][position];
|
struct zmk_behavior_binding *binding = &zmk_keymap[layer][position];
|
||||||
struct device *behavior;
|
struct device *behavior;
|
||||||
int ret;
|
|
||||||
|
|
||||||
LOG_DBG("layer: %d position: %d, binding name: %s", layer, position, log_strdup(binding->behavior_dev));
|
LOG_DBG("layer: %d position: %d, binding name: %s", layer, position, log_strdup(binding->behavior_dev));
|
||||||
|
|
||||||
|
@ -124,24 +118,34 @@ int zmk_keymap_position_state_changed(u32_t position, bool pressed)
|
||||||
|
|
||||||
if (!behavior) {
|
if (!behavior) {
|
||||||
LOG_DBG("No behavior assigned to %d on layer %d", position, layer);
|
LOG_DBG("No behavior assigned to %d on layer %d", position, layer);
|
||||||
continue;
|
return 1;
|
||||||
}
|
|
||||||
if (pressed) {
|
|
||||||
ret = behavior_keymap_binding_pressed(behavior, position, binding->param1, binding->param2);
|
|
||||||
} else {
|
|
||||||
ret = behavior_keymap_binding_released(behavior, position, binding->param1, binding->param2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pressed) {
|
||||||
|
return behavior_keymap_binding_pressed(behavior, position, binding->param1, binding->param2);
|
||||||
|
} else {
|
||||||
|
return behavior_keymap_binding_released(behavior, position, binding->param1, binding->param2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmk_keymap_position_state_changed(u32_t position, bool pressed)
|
||||||
|
{
|
||||||
|
for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= zmk_keymap_layer_default; layer--)
|
||||||
|
{
|
||||||
|
u32_t layer_state = pressed ? zmk_keymap_layer_state : zmk_keymap_active_behavior_layer[position];
|
||||||
|
if (is_active_layer(layer, layer_state))
|
||||||
|
{
|
||||||
|
int ret = zmk_keymap_apply_position_state(layer, position, pressed);
|
||||||
|
|
||||||
|
zmk_keymap_active_behavior_layer[position] = zmk_keymap_layer_state;
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
LOG_DBG("behavior processing to continue to next layer");
|
LOG_DBG("behavior processing to continue to next layer");
|
||||||
continue;
|
continue;
|
||||||
} else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
LOG_DBG("Behavior returned error: %d", ret);
|
LOG_DBG("Behavior returned error: %d", ret);
|
||||||
zmk_keymap_active_behavior_layer[position] = 0;
|
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
zmk_keymap_active_behavior_layer[position] = pressed ? layer : 0;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
0
docs/docs/assets/bond-clearing/debug.log
Normal file
BIN
docs/docs/assets/bond-clearing/lily58.jpg
Normal file
After Width: | Height: | Size: 2.4 MiB |
BIN
docs/docs/assets/env-var/env_var.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
docs/docs/assets/env-var/gnuarmemb.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
docs/docs/assets/env-var/new_variable.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
docs/docs/assets/env-var/start_menu.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
docs/docs/assets/env-var/zephyr_toolchain.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
docs/docs/assets/usb-logging/com.jpg
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
docs/docs/assets/usb-logging/putty.jpg
Normal file
After Width: | Height: | Size: 157 KiB |
|
@ -8,7 +8,7 @@ sidebar_label: Key Press
|
||||||
The most basic of behaviors, is the ability to send certain keycode presses and releases in response to activating
|
The most basic of behaviors, is the ability to send certain keycode presses and releases in response to activating
|
||||||
a certain key.
|
a certain key.
|
||||||
|
|
||||||
For reference on keycode values, see the [USB HID Usage Tables](https://www.usb.org/document-library/hid-usage-tables-12).
|
For reference on keycode values, see pages 83-89 of the [USB HID Usage Tables](https://www.usb.org/document-library/hid-usage-tables-12).
|
||||||
|
|
||||||
## Keycode Defines
|
## Keycode Defines
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ title: Reset BLE Connections
|
||||||
sidebar_label: BLE Reset
|
sidebar_label: BLE Reset
|
||||||
---
|
---
|
||||||
|
|
||||||
Known as a 'bond reset', a special key combination, that is not related to the user defined key map, which
|
Known as a 'bond reset', each keyboard has a special key combination independent of the user defined key map which will
|
||||||
clears all wireless connection configurations. The keys must be held for 3 to 5 seconds after the device is
|
clear all wireless connection configurations. The keys must be held for 3 to 5 seconds after the device is
|
||||||
reset.
|
reset.
|
||||||
|
|
||||||
:::warning
|
:::warning
|
||||||
|
@ -13,15 +13,19 @@ Currently, ZMK only supports a single BLE host. If you remove the keyboard from
|
||||||
list, you will need to clear the bonds.
|
list, you will need to clear the bonds.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### Split Keyboards
|
## Split Keyboards
|
||||||
|
|
||||||
Split keyboards will need to be cleared on both halves. For best results try to reset them at the same time.
|
Split keyboards will need to be cleared on both halves. For best results try to reset them at the same time.
|
||||||
|
|
||||||
|
|
||||||
## Kyria
|
### Kyria
|
||||||
|
|
||||||
![Kyria bond-reset combo](assets/bond-clearing/kyria.jpg)
|
![Kyria bond-reset combo](assets/bond-clearing/kyria.jpg)
|
||||||
|
|
||||||
## Corne
|
### Corne
|
||||||
|
|
||||||
![Corne bond-reset combo](assets/bond-clearing/corne.jpg)
|
![Corne bond-reset combo](assets/bond-clearing/corne.jpg)
|
||||||
|
|
||||||
|
### Lily58
|
||||||
|
|
||||||
|
![Lily58 bond-reset combo](assets/bond-clearing/lily58.jpg)
|
33
docs/docs/customization.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
id: customization
|
||||||
|
title: Customizing ZMK
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Configuration Changes
|
||||||
|
|
||||||
|
The setup script creates a `config/<shield>.conf` file that allows you to add additional configuration options to
|
||||||
|
control what features and options are built into your firmware. Opening that file with your text editor will allow you to see the
|
||||||
|
various config settings that can be commented/uncommented to modify how your firmware is built.
|
||||||
|
|
||||||
|
## Keymap
|
||||||
|
|
||||||
|
Once you have the basic user config completed, you can find the keymap file in `config/<shield>.keymap` and customize from there.
|
||||||
|
Refer to the [Keymap](/docs/feature/keymaps) documentation to learn more.
|
||||||
|
|
||||||
|
## Publishing
|
||||||
|
|
||||||
|
After making any changes you want, you should commit the changes and then push them to GitHub. That will trigger a new
|
||||||
|
GitHub Actions job to build your firmware which you can download once it completes.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
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.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 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.
|
96
docs/docs/dev-build.md
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
---
|
||||||
|
id: dev-build-flash
|
||||||
|
title: Building and Flashing
|
||||||
|
sidebar_label: Building and Flashing
|
||||||
|
---
|
||||||
|
|
||||||
|
import Tabs from '@theme/Tabs';
|
||||||
|
import TabItem from '@theme/TabItem';
|
||||||
|
|
||||||
|
export const OsTabs = (props) => (<Tabs
|
||||||
|
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'},
|
||||||
|
]
|
||||||
|
}>{props.children}</Tabs>);
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
From here on, building and flashing ZMK should all be done from the `app/` subdirectory of the ZMK checkout:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd app
|
||||||
|
```
|
||||||
|
|
||||||
|
To build for your particular keyboard, the behaviour varies slightly depending on if you are building for a keyboard with
|
||||||
|
an onboard MCU, or one that uses an MCU board addon.
|
||||||
|
|
||||||
|
### Keyboard (Shield) + MCU Board
|
||||||
|
|
||||||
|
ZMK treats keyboards that take an MCU addon board as [shields](https://docs.zephyrproject.org/2.3.0/guides/porting/shields.html), and treats the smaller MCU board as the true [board](https://docs.zephyrproject.org/2.3.0/guides/porting/board_porting.html)
|
||||||
|
|
||||||
|
Given the following:
|
||||||
|
|
||||||
|
- MCU Board: Proton-C
|
||||||
|
- Keyboard PCB: kyria_left
|
||||||
|
- Keymap: default
|
||||||
|
|
||||||
|
You can build ZMK with the following:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
west build -b proton_c -- -DSHIELD=kyria_left
|
||||||
|
```
|
||||||
|
|
||||||
|
### Keyboard With Onboard MCU
|
||||||
|
|
||||||
|
Keyboards with onboard MCU chips are simply treated as the [board](https://docs.zephyrproject.org/2.3.0/guides/porting/board_porting.html) as far as Zephyr™ is concerned.
|
||||||
|
|
||||||
|
Given the following:
|
||||||
|
|
||||||
|
- Keyboard: Planck (rev6)
|
||||||
|
- Keymap: default
|
||||||
|
|
||||||
|
you can build ZMK with the following:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
west build -b planck_rev6
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pristine Building
|
||||||
|
When building for a new board and/or shield after having built one previously, you may need to enable the pristine build option. This option removes all existing files in the build directory before regenerating them, and can be enabled by adding either --pristine or -p to the command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
west build -p -b proton_c -- -DSHIELD=kyria_left
|
||||||
|
```
|
||||||
|
### Building For Split Keyboards
|
||||||
|
|
||||||
|
:::note
|
||||||
|
For split keyboards, you will have to build and flash each side separately the first time you install ZMK.
|
||||||
|
:::
|
||||||
|
|
||||||
|
By default, the `build` command outputs a single .uf2 file named `zmk.uf2` so building left and then right immediately after will overwrite your left firmware. In addition, you will need to pristine build each side to ensure the correct files are used. To avoid having to pristine build every time and separate the left and right build files, we recommend setting up separate build directories for each half. You can do this by using the `-d` parameter and first building left into `build/left`:
|
||||||
|
|
||||||
|
```
|
||||||
|
west build -d build/left -b nice_nano -- -DSHIELD=kyria_left
|
||||||
|
```
|
||||||
|
and then building right into `build/right`:
|
||||||
|
```
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Flashing
|
||||||
|
|
||||||
|
Once built, the previously supplied parameters will be remembered so you can run the following to flash your
|
||||||
|
board with it in bootloader mode:
|
||||||
|
|
||||||
|
```
|
||||||
|
west flash
|
||||||
|
```
|
||||||
|
|
||||||
|
For boards that have drag and drop .uf2 flashing capability, the .uf2 file to flash can be found in `build/zephyr` (or `build/left|right/zephyr` if you followed the instructions for splits) and is by default named `zmk.uf2`.
|
|
@ -3,6 +3,9 @@ id: dev-guide-usb-logging
|
||||||
title: USB Logging
|
title: USB Logging
|
||||||
---
|
---
|
||||||
|
|
||||||
|
import Tabs from '@theme/Tabs';
|
||||||
|
import TabItem from '@theme/TabItem';
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
If you are developing ZMK on a device that does not have a built in UART for debugging and log/console output,
|
If you are developing ZMK on a device that does not have a built in UART for debugging and log/console output,
|
||||||
|
@ -11,7 +14,7 @@ messages to that device instead.
|
||||||
|
|
||||||
## Kconfig
|
## Kconfig
|
||||||
|
|
||||||
The following KConfig values need to be set, either by copy and paste into the `app/prj.conf` file, or by running
|
The following KConfig values need to be set, either by copy and pasting into the `app/prj.conf` file, or by running
|
||||||
`west build -t menuconfig` and manually enabling the various settings in that UI.
|
`west build -t menuconfig` and manually enabling the various settings in that UI.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -42,12 +45,32 @@ CONFIG_USB_UART_DTR_WAIT=n
|
||||||
|
|
||||||
## Viewing Logs
|
## Viewing Logs
|
||||||
|
|
||||||
After flashing the updated ZMK image, the board should expose a USB CDC ACM device, that you can connect to and view the logs.
|
After flashing the updated ZMK image, the board should expose a USB CDC ACM device that you can connect to and view the logs.
|
||||||
|
|
||||||
|
<Tabs
|
||||||
|
defaultValue="linux"
|
||||||
|
values={[
|
||||||
|
{label: 'Linux', value: 'linux'},
|
||||||
|
{label: 'Windows', value: 'win'},
|
||||||
|
]}>
|
||||||
|
<TabItem value="linux">
|
||||||
|
|
||||||
On Linux, this should be a device like `/dev/ttyACM0` and you can connect with `minicom` or `tio` as usual, e.g.:
|
On Linux, this should be a device like `/dev/ttyACM0` and you can connect with `minicom` or `tio` as usual, e.g.:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo tio /dev/ttyACM0
|
sudo tio /dev/ttyACM0
|
||||||
```
|
```
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="win">
|
||||||
|
|
||||||
|
On Windows, you can use [PuTTY](https://www.putty.org/). Once installed, use Device Manager to figure out which COM port your controller is communicating on (listed under 'Ports (COM & LPT)') and specify that as the 'Serial line' in PuTTY.
|
||||||
|
|
||||||
|
![Controller COM port](./assets/usb-logging/com.jpg)
|
||||||
|
|
||||||
|
![PuTTY settings](assets/usb-logging/putty.jpg)
|
||||||
|
|
||||||
|
If you already have the Ardunio IDE installed you can also use its built-in Serial Monitor.
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
From there, you should see the various log messages from ZMK and Zephyr, depending on which systems you have set to what log levels.
|
From there, you should see the various log messages from ZMK and Zephyr, depending on which systems you have set to what log levels.
|
||||||
|
|
|
@ -181,7 +181,7 @@ brew install cmake ninja python3 ccache dtc git wget
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
### West Build Command
|
### West Installation
|
||||||
|
|
||||||
`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` is the [Zephyr™ meta-tool](https://docs.zephyrproject.org/2.3.0/guides/west/index.html) used to configure and build Zephyr™ applications.
|
||||||
|
|
||||||
|
@ -192,14 +192,31 @@ pip3 install --user -U west
|
||||||
```
|
```
|
||||||
|
|
||||||
:::danger pip user packages
|
:::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`, e.g.:
|
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.
|
||||||
|
:::
|
||||||
|
|
||||||
```
|
<Tabs
|
||||||
|
defaultValue="linux"
|
||||||
|
values={[
|
||||||
|
{label: 'Linux', value: 'linux'},
|
||||||
|
{label: 'Windows', value: 'win'},
|
||||||
|
]}>
|
||||||
|
<TabItem value = 'linux'>
|
||||||
|
Run the following commands:
|
||||||
|
|
||||||
|
```sh
|
||||||
echo 'export PATH=~/.local/bin:"$PATH"' >> ~/.bashrc
|
echo 'export PATH=~/.local/bin:"$PATH"' >> ~/.bashrc
|
||||||
source ~/.bashrc
|
source ~/.bashrc
|
||||||
```
|
```
|
||||||
|
|
||||||
:::
|
</TabItem>
|
||||||
|
<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`.
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
### Toolchain Installation
|
### Toolchain Installation
|
||||||
|
|
||||||
|
@ -341,10 +358,41 @@ pip3 install --user -r zephyr/scripts/requirements-base.txt
|
||||||
|
|
||||||
### Environment Variables
|
### Environment Variables
|
||||||
|
|
||||||
|
#### For GNU ARM Embedded on Windows
|
||||||
|
|
||||||
|
On Windows, you will have to set two environment variables for ZMK to build properly: `ZEPHYR_TOOLCHAIN_VARIANT` and `GNUARMEMB_TOOLCHAIN_PATH`.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary> Steps to Update Environment Variables </summary>
|
||||||
|
|
||||||
|
1. Open Start Menu and type 'env' to find the 'Edit the system environment variables' option. Open it.
|
||||||
|
|
||||||
|
![Environment variables in Start Menu](assets/env-var/start_menu.png)
|
||||||
|
|
||||||
|
2. Click 'Environment Variables...'.
|
||||||
|
|
||||||
|
![Environment variables button](assets/env-var/env_var.png)
|
||||||
|
|
||||||
|
3. Click "New..." under System variables to create a new system variable.
|
||||||
|
|
||||||
|
![Environment variables menu](assets/env-var/new_variable.png)
|
||||||
|
|
||||||
|
4. Set the variable name to 'ZEPHYR_TOOLCHAIN_VARIANT' and value to 'gnuarmemb'. Click OK to save.
|
||||||
|
|
||||||
|
![Adding Zephyr toolchain variable](assets/env-var/zephyr_toolchain.png)
|
||||||
|
|
||||||
|
5. Create another variable with variable name 'GNUARMEMB_TOOLCHAIN_PATH' and value set to wherever you installed your toolchain. Click OK to save.
|
||||||
|
|
||||||
|
![Adding GNUARMEMB variable](assets/env-var/gnuarmemb.png)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
#### For Zephyr
|
||||||
|
|
||||||
By default, the Zephyr™ SDK will create a file named `~/.zephyrrc` with the correct environment variables to build ZMK.
|
By default, the Zephyr™ SDK will create a file named `~/.zephyrrc` with the correct environment variables to build ZMK.
|
||||||
We suggest two main [options](https://docs.zephyrproject.org/2.3.0/guides/env_vars.html?highlight=zephyrrc) for how to load those settings.
|
We suggest two main [options](https://docs.zephyrproject.org/2.3.0/guides/env_vars.html?highlight=zephyrrc) for how to load those settings.
|
||||||
|
|
||||||
#### Per Shell
|
##### Per Shell
|
||||||
|
|
||||||
To load the Zephyr environment properly for just one transient shell, run the following from your ZMK checkout directory:
|
To load the Zephyr environment properly for just one transient shell, run the following from your ZMK checkout directory:
|
||||||
|
|
||||||
|
@ -390,7 +438,7 @@ source zephyr/zephyr-env.cmd
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</OsTabs>
|
</OsTabs>
|
||||||
|
|
||||||
#### All Shells
|
##### All Shells
|
||||||
|
|
||||||
To load the environment variables for your shell every time,
|
To load the environment variables for your shell every time,
|
||||||
append the existing `~/.zephyrrc` file to your shell's RC file and then start a new shell.
|
append the existing `~/.zephyrrc` file to your shell's RC file and then start a new shell.
|
||||||
|
@ -401,7 +449,6 @@ defaultValue="bash"
|
||||||
values={[
|
values={[
|
||||||
{label: 'bash', value: 'bash'},
|
{label: 'bash', value: 'bash'},
|
||||||
{label: 'zsh', value: 'zsh'},
|
{label: 'zsh', value: 'zsh'},
|
||||||
{label: 'cmd.exe', value: 'cmd'},
|
|
||||||
]
|
]
|
||||||
}>
|
}>
|
||||||
|
|
||||||
|
@ -421,61 +468,4 @@ cat ~/.zephyrrc >> ~/.zshrc
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
<TabItem value="cmd">
|
|
||||||
|
|
||||||
`cmd.exe` instructions coming soon!
|
|
||||||
|
|
||||||
</TabItem>
|
|
||||||
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
## Build
|
|
||||||
|
|
||||||
From here on, building and flashing ZMK should all be done from the `app/` subdirectory of the ZMK checkout:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cd app
|
|
||||||
```
|
|
||||||
|
|
||||||
To build for your particular keyboard, the behaviour varies slightly depending on if you are building for a keyboard with
|
|
||||||
an onboard MCU, or one that uses a MCU board addon.
|
|
||||||
|
|
||||||
### Keyboard (Shield) + MCU Board
|
|
||||||
|
|
||||||
ZMK treats keyboards that take a MCU addon board as [shields](https://docs.zephyrproject.org/2.3.0/guides/porting/shields.html), and treats the smaller MCU board as the true [board](https://docs.zephyrproject.org/2.3.0/guides/porting/board_porting.html)
|
|
||||||
|
|
||||||
Given the following:
|
|
||||||
|
|
||||||
- MCU Board: Proton-C
|
|
||||||
- Keyboard PCB: kyria_left
|
|
||||||
- Keymap: default
|
|
||||||
|
|
||||||
You can build ZMK with the following:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
west build -b proton_c -- -DSHIELD=kyria_left -DKEYMAP=default
|
|
||||||
```
|
|
||||||
|
|
||||||
### Keyboard With Onboard MCU
|
|
||||||
|
|
||||||
Keyboards with onboard MCU chips are simply treated as the [board](https://docs.zephyrproject.org/2.3.0/guides/porting/board_porting.html) as far as Zephyr™ is concerned.
|
|
||||||
|
|
||||||
Given the following:
|
|
||||||
|
|
||||||
- Keyboard: Planck (rev6)
|
|
||||||
- Keymap: default
|
|
||||||
|
|
||||||
you can build ZMK with the following:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
west build -b planck_rev6 -- -DKEYMAP=default
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flashing
|
|
||||||
|
|
||||||
Once built, the previously supplied parameters will be remember, so you can simply run the following to flash your
|
|
||||||
board, with it in bootloader mode:
|
|
||||||
|
|
||||||
```
|
|
||||||
west flash
|
|
||||||
```
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ title: Keymaps & Behaviors
|
||||||
sidebar_label: Keymaps
|
sidebar_label: Keymaps
|
||||||
---
|
---
|
||||||
|
|
||||||
ZMK uses an declarative approach to keymaps, instead of using C code for all keymap configuration.
|
ZMK uses a declarative approach to keymaps instead of using C code for all keymap configuration.
|
||||||
Right now, ZMK uses the devicetree syntax to declare those keymaps; future work is envisioned for
|
Right now, ZMK uses the devicetree syntax to declare those keymaps; future work is envisioned for
|
||||||
supporting dynamic loading of declarative keymaps, e.g. over USB Mass Storage or via a custom BLE
|
supporting dynamic loading of declarative keymaps, e.g. over USB Mass Storage or via a custom BLE
|
||||||
service.
|
service.
|
||||||
|
@ -80,7 +80,7 @@ A keymap file is composed of several sections, that together make up a valid dev
|
||||||
|
|
||||||
### Includes
|
### Includes
|
||||||
|
|
||||||
THe devicetree files are actually preprocessed before being finally leveraged by Zephyr. This allows using standard C defines to create meaningful placeholders
|
The devicetree files are actually preprocessed before being finally leveraged by Zephyr. This allows using standard C defines to create meaningful placeholders
|
||||||
for what would otherwise be cryptic integer keycodes, etc. This also allows bringing in _other_ devicetree nodes from separate files.
|
for what would otherwise be cryptic integer keycodes, etc. This also allows bringing in _other_ devicetree nodes from separate files.
|
||||||
|
|
||||||
The top two lines of most keymaps should include:
|
The top two lines of most keymaps should include:
|
||||||
|
|
|
@ -11,7 +11,7 @@ have had their hardware details codified in boards/shields for ZMK.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
Being built on a solid technical foundation of the Zephyr™ RTOS, it's possible to make ZMK support a wide diversity of hardware targets.
|
With the solid technical foundation of Zephyr™ RTOS, ZMK can support a wide diversity of hardware targets.
|
||||||
That being said, there are currently only a few specific [boards](/docs/faq#what-is-a-board)/[shields](/docs/faq#what-is-a-shield) that have been written and tested by the ZMK contributors.
|
That being said, there are currently only a few specific [boards](/docs/faq#what-is-a-board)/[shields](/docs/faq#what-is-a-shield) that have been written and tested by the ZMK contributors.
|
||||||
|
|
||||||
## Boards
|
## Boards
|
||||||
|
|
|
@ -5,7 +5,7 @@ sidebar_label: Introduction
|
||||||
---
|
---
|
||||||
|
|
||||||
ZMK Firmware is an open source (MIT) keyboard
|
ZMK Firmware is an open source (MIT) keyboard
|
||||||
firmware built on the [Zephyr™ Project](https://zephyrproject.com/) RTOS.
|
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
|
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
|
of licensing issues that prevent upstream BLE support as a first-class
|
||||||
|
|
|
@ -11,8 +11,7 @@ Unlike other keyboard firmwares, ZMK Firmware has been built from the ground up
|
||||||
their own keyboard configurations, including keymaps, specific hardware details, etc. all outside of the
|
their own keyboard configurations, including keymaps, specific hardware details, etc. all outside of the
|
||||||
core ZMK Firmware source repository.
|
core ZMK Firmware source repository.
|
||||||
|
|
||||||
In addition to this, most users do not need to install any complicated toolchains or tools to build ZMK,
|
In addition to this, most users will not need to install any complicated toolchains or tools to build ZMK. GitHub Actions is used instead to automatically build the user's configured firmware for them.
|
||||||
instead using GitHub Actions to automatically build the user's configured firmware for them.
|
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
|
@ -170,7 +169,7 @@ a link to download the `firmware` upload:
|
||||||
Once downloaded, extract the zip and you can verify it should contain one or more `uf2` files, which will be copied to
|
Once downloaded, extract the zip and you can verify it should contain one or more `uf2` files, which will be copied to
|
||||||
your keyboard.
|
your keyboard.
|
||||||
|
|
||||||
### Installing UF2 Files
|
### Flashing UF2 Files
|
||||||
|
|
||||||
To flash the firmware, first put your board into bootloader mode by double clicking the reset button (either on the MCU board itself,
|
To flash the firmware, first put your board into bootloader mode by double clicking the reset button (either on the MCU board itself,
|
||||||
or the one that is part of your keyboard). The controller should appear in your OS as a new USB storage device.
|
or the one that is part of your keyboard). The controller should appear in your OS as a new USB storage device.
|
||||||
|
@ -178,24 +177,10 @@ or the one that is part of your keyboard). The controller should appear in your
|
||||||
Once this happens, copy the correct UF2 file (e.g. left or right if working on a split), and paste it onto the root of that USB mass
|
Once this happens, copy the correct UF2 file (e.g. left or right if working on a split), and paste it onto the root of that USB mass
|
||||||
storage device. Once the flash is complete, the controller should automatically restart, and load your newfly flashed firmware.
|
storage device. Once the flash is complete, the controller should automatically restart, and load your newfly flashed firmware.
|
||||||
|
|
||||||
## Customization
|
## Wirelessly Connecting Your Keyboard
|
||||||
|
|
||||||
### Configuration Changes
|
Connecting your keyboard wirelessly is the same as adding other Bluetooth devides: press the reset button and scan for devices. However, pairing and bonding is still currently being worked on to increase relability and ease of use. In addition, users have in general reported that Bluetooth pairing with computers tends to be quite finnicky. Try out the connection with your tablet or phone first, as those devices seem to work much more consistently. See [BLE Reset](./bond-reset.md) for help on resetting your MCUs if you're experiencing connection issues.
|
||||||
|
|
||||||
The setup script creates a `config/<shield>.conf` file that allows you to add additional configuration options to
|
### Connecting Split Keyboard Halves
|
||||||
control what features and options are built into your firmware. Opening that file with your text editor you should see
|
|
||||||
various config settings that can be commented/uncommented to modify how your firmware is built.
|
|
||||||
|
|
||||||
### Keymap
|
For split keyboards, after flashing each half individually you can connect them together by resetting them at the same time. Within a few seconds of resetting, both halves should automatically connect to each other.
|
||||||
|
|
||||||
Once you have the basic user config completed, you can find the file in `config/<shield>.keymap` and customize from there.
|
|
||||||
Refer to the [Keymap](/docs/feature/keymaps) documentation to learn more.
|
|
||||||
|
|
||||||
### Publishing
|
|
||||||
|
|
||||||
After making any changes you want, you should commit the changes and then push them to GitHub. That will trigger a new
|
|
||||||
GitHub Actions job to build your firmware which you can download once it completes.
|
|
||||||
|
|
||||||
:::note
|
|
||||||
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.
|
|
||||||
:::
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
someSidebar: {
|
someSidebar: {
|
||||||
"Getting Started": ["intro", "hardware", "faq", "user-setup", "bond-reset"],
|
"Getting Started": ["intro", "hardware", "faq", "user-setup","customization", "bond-reset"],
|
||||||
Features: [
|
Features: [
|
||||||
"feature/keymaps",
|
"feature/keymaps",
|
||||||
"feature/displays",
|
"feature/displays",
|
||||||
|
@ -18,6 +18,7 @@ module.exports = {
|
||||||
Development: [
|
Development: [
|
||||||
"dev-clean-room",
|
"dev-clean-room",
|
||||||
"dev-setup",
|
"dev-setup",
|
||||||
|
"dev-build-flash",
|
||||||
"dev-boards-shields-keymaps",
|
"dev-boards-shields-keymaps",
|
||||||
"dev-posix-board",
|
"dev-posix-board",
|
||||||
"dev-tests",
|
"dev-tests",
|
||||||
|
|