Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ zmk-config/boards/arm/anaphase/widgets/temp
.DS_Store
hardware/kicad_5.99/*.lck

# west workspace (created by `west init -l zmk-config` for local builds)
# Local build artifacts. The west workspace lives in the `zmk-ws` Docker
# volume, not the repo; only output uf2s land here, in dist/.
dist/
# stale guards in case a workspace is ever init'd in the repo again
.west/
zmk/
zephyr/
Expand Down
1 change: 1 addition & 0 deletions build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
# Board IDs = the *_defconfig basenames under zmk-config/boards/arm/anaphase/.
include:
- board: anaphase_left
snippet: studio-rpc-usb-uart
- board: anaphase_right
99 changes: 93 additions & 6 deletions zmk-config/boards/arm/anaphase/Kconfig.defconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# SPDX-License-Identifier: MIT
#
# Shared configuration for both halves lives here as Kconfig defaults.
# The per-half *_defconfig files hold only: SoC/board selection, the
# split-role and USB differences, widget selection, and *choice* symbols —
# choice-default overrides from this file are unreliable (learned the hard
# way with ZMK_LV_FONT_DEFAULT_SMALL), so choice members are set as explicit
# values in the defconfig files instead.

if BOARD_ANAPHASE_LEFT

Expand Down Expand Up @@ -33,6 +40,44 @@ config BOARD
config ZMK_SPLIT
default y

#
# Platform
#

config ARM_MPU
default y

config GPIO
default y

# SPI pins are defined in anaphase-pinctrl.dtsi
config PINCTRL
default y

# Place application at &code_partition, produce a .uf2 natively (family ID
# 0xada52840 and base 0x1000 both derive from the SoC + DT automatically)
config USE_DT_CODE_PARTITION
default y

config BUILD_OUTPUT_UF2
default y

# NVS settings storage (BLE bonds, profiles)
config MPU_ALLOW_FLASH_WRITE
default y

config NVS
default y

config FLASH
default y

config FLASH_PAGE_LAYOUT
default y

config FLASH_MAP
default y

if USB

config USB_NRFX
Expand All @@ -53,6 +98,36 @@ config ZMK_BLE
config ZMK_BATTERY_NRF_VDDH
default y

#
# Power / input tuning
#

config ZMK_SLEEP
default y

# ZMK_IDLE_TIMEOUT / ZMK_IDLE_SLEEP_TIMEOUT / DISPLAY stack size live in the
# *_defconfig files: ZMK's app/Kconfig is the Kconfig root, so its defaults
# are seen before this file's and win the first-default race. Only symbols
# whose upstream defaults come from Zephyr or module Kconfigs (loaded after
# the board dir) can be defaulted here.

# Debounce tuned against the actual switches for minimum first-press latency
# (2ms press) with chatter protection on release (10ms). Asymmetry is
# intentional — do not normalise to the 5/5 default. Last tuned 2022-03-05.
config ZMK_KSCAN_DEBOUNCE_PRESS_MS
default 2

config ZMK_KSCAN_DEBOUNCE_RELEASE_MS
default 10

# BT_MAX_CONN / BT_PERIPHERAL_PREF_* deliberately unset: ZMK v0.3.0's
# role-aware defaults give 6 conns central / 1 peripheral and 6/12/30/400
# conn params (the old hand-tuned 7.5-15ms interval, plus slave latency 30).

#
# Display
#

config ZMK_DISPLAY
select LV_FONT_UNSCII_8
select LV_USE_LABEL
Expand All @@ -64,10 +139,8 @@ endchoice

if ZMK_DISPLAY

# UNSCII-8 everywhere: the 96x48 text layout only fits with this font.
# (ZMK's own default is Montserrat, which does not.)
# The theme "small" font counterpart is set in the *_defconfig files —
# a choice-default override here loses to ZMK's own default.
# UNSCII-8 everywhere: the 64x48 visible text layout only fits with this
# font. (The theme "small" font counterpart is in the *_defconfig files.)
choice LV_FONT_DEFAULT
default LV_FONT_DEFAULT_UNSCII_8

Expand All @@ -79,8 +152,8 @@ config SPI
config SSD1306
default y

# Panel resolution now comes from the width/height DT properties on the
# ssd1306 node (the old LVGL_HOR_RES_MAX/VER_RES_MAX symbols are gone).
# Panel resolution comes from the width/height DT properties on the ssd1306
# node (width is deliberately the full 128-column RAM — see anaphase.dtsi).
config LV_Z_VDB_SIZE
default 100

Expand All @@ -95,6 +168,20 @@ choice LV_COLOR_DEPTH

endchoice

config LV_USE_THEME_MONO
default y

# White-on-black like the 2022 build: LVGL 8's mono theme defaults to the
# light variant (LVGL 7 defaulted dark); this flips it back.
config ZMK_DISPLAY_INVERT
default y

# LVGL pool sized explicitly (a custom status screen gets no upstream
# default; the 2022 build ran on LVGL 7's implicit pool and had a rare,
# unreproduced crash consistent with display-path memory pressure).
config LV_Z_MEM_POOL_SIZE
default 8192

endif # ZMK_DISPLAY

config CUSTOM_WIDGET_BATTERY_STATUS
Expand Down
65 changes: 63 additions & 2 deletions zmk-config/boards/arm/anaphase/anaphase.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>
#include <dt-bindings/zmk/matrix_transform.h>
#include <physical_layouts.dtsi>
#include "anaphase-pinctrl.dtsi"

/ {
Expand All @@ -22,7 +23,10 @@
// display subsystem fails to compile.
zephyr,display = &oled;
zmk,kscan = &kscan0;
zmk,matrix_transform = &transform;
// ZMK Studio: physical layout replaces the old zmk,matrix_transform
// chosen (physical layouts only activate when that chosen is absent);
// the transform is referenced from the layout node instead.
zmk,physical-layout = &physical_layout0;
zmk,battery = &vbatt;
};
#define K(n) RC(0,n)
Expand All @@ -42,6 +46,61 @@
>;
};

// Schematic layout for ZMK Studio's UI: corne-style 6-column stagger,
// flat horizontal 3-key thumb clusters. Positions are representative,
// not measured from the case. Order = keymap position order (rows of
// 6L+6R, then left thumbs BSPC/E/FUNC, right thumbs SHIFT/SPACE/ENTER).
physical_layout0: physical_layout0 {
compatible = "zmk,physical-layout";
display-name = "anaphase";
transform = <&transform>;

keys // w h x y rot rx ry
= <&key_physical_attrs 100 100 0 37 0 0 0>
, <&key_physical_attrs 100 100 100 37 0 0 0>
, <&key_physical_attrs 100 100 200 12 0 0 0>
, <&key_physical_attrs 100 100 300 0 0 0 0>
, <&key_physical_attrs 100 100 400 12 0 0 0>
, <&key_physical_attrs 100 100 500 24 0 0 0>
, <&key_physical_attrs 100 100 800 24 0 0 0>
, <&key_physical_attrs 100 100 900 12 0 0 0>
, <&key_physical_attrs 100 100 1000 0 0 0 0>
, <&key_physical_attrs 100 100 1100 12 0 0 0>
, <&key_physical_attrs 100 100 1200 37 0 0 0>
, <&key_physical_attrs 100 100 1300 37 0 0 0>
, <&key_physical_attrs 100 100 0 137 0 0 0>
, <&key_physical_attrs 100 100 100 137 0 0 0>
, <&key_physical_attrs 100 100 200 112 0 0 0>
, <&key_physical_attrs 100 100 300 100 0 0 0>
, <&key_physical_attrs 100 100 400 112 0 0 0>
, <&key_physical_attrs 100 100 500 124 0 0 0>
, <&key_physical_attrs 100 100 800 124 0 0 0>
, <&key_physical_attrs 100 100 900 112 0 0 0>
, <&key_physical_attrs 100 100 1000 100 0 0 0>
, <&key_physical_attrs 100 100 1100 112 0 0 0>
, <&key_physical_attrs 100 100 1200 137 0 0 0>
, <&key_physical_attrs 100 100 1300 137 0 0 0>
, <&key_physical_attrs 100 100 0 237 0 0 0>
, <&key_physical_attrs 100 100 100 237 0 0 0>
, <&key_physical_attrs 100 100 200 212 0 0 0>
, <&key_physical_attrs 100 100 300 200 0 0 0>
, <&key_physical_attrs 100 100 400 212 0 0 0>
, <&key_physical_attrs 100 100 500 224 0 0 0>
, <&key_physical_attrs 100 100 800 224 0 0 0>
, <&key_physical_attrs 100 100 900 212 0 0 0>
, <&key_physical_attrs 100 100 1000 200 0 0 0>
, <&key_physical_attrs 100 100 1100 212 0 0 0>
, <&key_physical_attrs 100 100 1200 237 0 0 0>
, <&key_physical_attrs 100 100 1300 237 0 0 0>
, <&key_physical_attrs 100 100 300 337 0 0 0>
, <&key_physical_attrs 100 100 400 337 0 0 0>
, <&key_physical_attrs 100 100 500 337 0 0 0>
, <&key_physical_attrs 100 100 800 337 0 0 0>
, <&key_physical_attrs 100 100 900 337 0 0 0>
, <&key_physical_attrs 100 100 1000 337 0 0 0>
;
};

vbatt: vbatt {
compatible = "zmk,battery-nrf-vddh";
};
Expand Down Expand Up @@ -101,7 +160,9 @@
status = "okay";
};

&usbd {
// zephyr_udc0 is the conventional label for the USB device controller;
// the ZMK Studio studio-rpc-usb-uart snippet attaches its CDC-ACM UART to it.
zephyr_udc0: &usbd {
status = "okay";
};

Expand Down
8 changes: 4 additions & 4 deletions zmk-config/boards/arm/anaphase/anaphase.keymap
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@
display-name = "SYS";
bindings = <
//1 2 3 4 5 6 7 8 9 10 11 12
&bt BT_CLR &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &none &none &none &none &none &none
&none &none &none &none &none &none &none &none &none &none &none &none
&none &none &none &none &none &none &none &none &none &none &none &none
&bootloader &none &none &none &none &none
&bt BT_CLR &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &none &none &none &none &none &none
&none &none &none &none &none &none &none &none &none &none &none &none
&none &none &none &none &none &studio_unlock &none &none &none &none &none &none
&bootloader &none &none &none &none &none
>;

};
Expand Down
71 changes: 20 additions & 51 deletions zmk-config/boards/arm/anaphase/anaphase_left_defconfig
Original file line number Diff line number Diff line change
@@ -1,51 +1,25 @@
# SPDX-License-Identifier: MIT
#
# Left half (BLE central). Shared config lives in Kconfig.defconfig as
# defaults; this file holds SoC/board selection, choice symbols (which
# cannot reliably be defaulted from Kconfig.defconfig), and per-half deltas.

CONFIG_SOC_SERIES_NRF52X=y
CONFIG_SOC_NRF52840_QIAA=y
CONFIG_BOARD_ANAPHASE_LEFT=y

# Sleep: 60s idle (display blanks), 2h to deep sleep. Deliberate 2021 tune.
CONFIG_ZMK_SLEEP=y
# ZMK-app defaults that must be overridden as user values (see
# Kconfig.defconfig header for the first-default-race explanation):
# sleep 60s idle / 2h deep (deliberate 2021 tune); display stack 4096 for
# LVGL 8 (upstream default 2048).
CONFIG_ZMK_IDLE_TIMEOUT=60000
CONFIG_ZMK_IDLE_SLEEP_TIMEOUT=7200000
CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_STACK_SIZE=4096

# Enable MPU
CONFIG_ARM_MPU=y

# Enable GPIO + pinctrl (SPI pins are defined in anaphase-pinctrl.dtsi)
CONFIG_GPIO=y
CONFIG_PINCTRL=y

# Place application at &code_partition address, produce a .uf2 natively
# (replaces the old uf2conv.py post-build hook; family ID 0xada52840 and
# base 0x1000 both derive from SOC/DT automatically)
CONFIG_USE_DT_CODE_PARTITION=y
CONFIG_BUILD_OUTPUT_UF2=y
# --- choice symbols ---

# Enable NVS for settings
CONFIG_MPU_ALLOW_FLASH_WRITE=y
CONFIG_NVS=y
CONFIG_SETTINGS_NVS=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y

# (USB_HID_POLL_INTERVAL_MS=1 is now ZMK's own default under ZMK_USB)

# Display: dedicated work queue; stack raised 2048->4096 for LVGL 8, and the
# LVGL pool sized explicitly (a custom status screen gets no upstream default;
# the 2022 build ran on LVGL 7's implicit pool and had a rare, unreproduced
# crash consistent with display-path memory pressure).
CONFIG_ZMK_DISPLAY=y
CONFIG_ZMK_DISPLAY_WORK_QUEUE_DEDICATED=y
CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_STACK_SIZE=4096
CONFIG_LV_Z_MEM_POOL_SIZE=8192
CONFIG_LV_USE_THEME_MONO=y
# White-on-black like the 2022 build: LVGL 8's mono theme defaults to the
# light variant (LVGL 7 defaulted dark); this flips it back.
CONFIG_ZMK_DISPLAY_INVERT=y
# Theme small font: UNSCII-8 like everything else (default is Montserrat 12)
CONFIG_ZMK_LV_FONT_DEFAULT_SMALL_UNSCII_8=y
CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_BASIC=y

# 32kHz source is the internal RC on purpose. Y1/Y2 crystals are fitted but
# their load caps were never populated; the crystal was unstable in testing
Expand All @@ -54,24 +28,19 @@ CONFIG_ZMK_LV_FONT_DEFAULT_SMALL_UNSCII_8=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y

CONFIG_BT_CTLR_TX_PWR_PLUS_8=y
# BT_MAX_CONN / BT_PERIPHERAL_PREF_* deliberately unset: ZMK v0.3.0's
# role-aware defaults are 6 conns on the central and 6/12/30/400 conn params
# (same 7.5-15ms interval as the old hand-tune, plus slave latency 30 for
# ~30x fewer idle radio wakeups at zero added press latency).

# Debounce tuned against the actual switches for minimum first-press latency
# (2ms press) with chatter protection on release (10ms). Asymmetry is
# intentional — do not normalise to the 5/5 default. Last tuned 2022-03-05.
CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS=2
CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS=10
CONFIG_ZMK_DISPLAY=y
CONFIG_ZMK_DISPLAY_WORK_QUEUE_DEDICATED=y
CONFIG_ZMK_DISPLAY_STATUS_SCREEN_CUSTOM=y
# Theme small font: UNSCII-8 like everything else (default is Montserrat 12)
CONFIG_ZMK_LV_FONT_DEFAULT_SMALL_UNSCII_8=y

CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_BASIC=y
# ZMK Studio (runtime keymap editing over USB; build with the
# studio-rpc-usb-uart snippet — see build.yaml)
CONFIG_ZMK_STUDIO=y

# --- per-half widget selection ---
# Custom status screen: BLE profile nickname + pairing status + battery + layer
CONFIG_ZMK_DISPLAY_STATUS_SCREEN_CUSTOM=y
CONFIG_CUSTOM_WIDGET_BATTERY_STATUS=y
CONFIG_ZMK_WIDGET_BATTERY_STATUS=n
CONFIG_CUSTOM_WIDGET_OUTPUT_STATUS=y
CONFIG_ZMK_WIDGET_OUTPUT_STATUS=n
CONFIG_CUSTOM_WIDGET_LAYER_STATUS=y
CONFIG_ZMK_WIDGET_LAYER_STATUS=n
Loading
Loading