Merge branch 'zmkfirmware:main' into main

This commit is contained in:
MakerJake 2021-10-05 22:32:40 -04:00 committed by GitHub
commit 93a52c563d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 161 additions and 16 deletions

View file

@ -25,7 +25,57 @@ config USB_DEVICE_PID
config USB_DEVICE_MANUFACTURER config USB_DEVICE_MANUFACTURER
default "ZMK Project" default "ZMK Project"
menu "HID Output Types" menu "HID"
choice ZMK_HID_REPORT_TYPE
prompt "HID Report Type"
config ZMK_HID_REPORT_TYPE_HKRO
bool "#-Key Roll Over (HKRO) HID Report"
help
Enable # key roll over for HID report. This selection is "boot keyboard" compatible
but limits the total number of possible keys to report as held to #.
config ZMK_HID_REPORT_TYPE_NKRO
bool "Full N-Key Roll Over (NKRO) HID Report"
help
Enable full N-Key Roll Over for HID output. This selection will prevent the keyboard
from working with some BIOS/UEFI versions that only support "boot keyboard" support.
This option also prevents using some infrequently used higher range HID usages.
endchoice
if ZMK_HID_REPORT_TYPE_HKRO
config ZMK_HID_KEYBOARD_REPORT_SIZE
int "# Keyboard Keys Reportable"
default 6
endif
config ZMK_HID_CONSUMER_REPORT_SIZE
int "# Consumer Keys Reportable"
default 6
choice ZMK_HID_CONSUMER_REPORT_USAGES
prompt "HID Report Type"
config ZMK_HID_CONSUMER_REPORT_USAGES_FULL
bool "Full Consumer HID Usage Support"
help
Enable full Consumer usage ID values to be sent to hosts. Allows for less
frequently used usages, but has compatibability issues with some host OSes.
config ZMK_HID_CONSUMER_REPORT_USAGES_BASIC
bool "Basic Consumer HID Usage Support"
help
Enable Consumer usage ID values up to "Playback Speed - Slow" to be sent to
hosts. Allows for broader compatibability with more host OSes.
endchoice
menu "Output Types"
config ZMK_USB config ZMK_USB
bool "USB" bool "USB"
@ -92,7 +142,10 @@ config ZMK_BLE_PASSKEY_ENTRY
#ZMK_BLE #ZMK_BLE
endif endif
#HID Output Types #Output Types
endmenu
# HID
endmenu endmenu
menu "Split Support" menu "Split Support"

View file

@ -13,12 +13,10 @@
#include <dt-bindings/zmk/hid_usage.h> #include <dt-bindings/zmk/hid_usage.h>
#include <dt-bindings/zmk/hid_usage_pages.h> #include <dt-bindings/zmk/hid_usage_pages.h>
#define ZMK_HID_KEYBOARD_NKRO_MAX_USAGE HID_USAGE_KEY_KEYPAD_EQUAL
#define COLLECTION_REPORT 0x03 #define COLLECTION_REPORT 0x03
#define ZMK_HID_KEYBOARD_NKRO_SIZE 6
#define ZMK_HID_CONSUMER_NKRO_SIZE 6
static const uint8_t zmk_hid_report_desc[] = { static const uint8_t zmk_hid_report_desc[] = {
/* USAGE_PAGE (Generic Desktop) */ /* USAGE_PAGE (Generic Desktop) */
HID_GI_USAGE_PAGE, HID_GI_USAGE_PAGE,
@ -74,6 +72,30 @@ static const uint8_t zmk_hid_report_desc[] = {
/* USAGE_PAGE (Keyboard/Keypad) */ /* USAGE_PAGE (Keyboard/Keypad) */
HID_GI_USAGE_PAGE, HID_GI_USAGE_PAGE,
HID_USAGE_KEY, HID_USAGE_KEY,
#if IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_NKRO)
/* LOGICAL_MINIMUM (0) */
HID_GI_LOGICAL_MIN(1),
0x00,
/* LOGICAL_MAXIMUM (1) */
HID_GI_LOGICAL_MAX(1),
0x01,
/* USAGE_MINIMUM (Reserved) */
HID_LI_USAGE_MIN(1),
0x00,
/* USAGE_MAXIMUM (Keyboard Application) */
HID_LI_USAGE_MAX(1),
ZMK_HID_KEYBOARD_NKRO_MAX_USAGE,
/* REPORT_SIZE (8) */
HID_GI_REPORT_SIZE,
0x01,
/* REPORT_COUNT (6) */
HID_GI_REPORT_COUNT,
ZMK_HID_KEYBOARD_NKRO_MAX_USAGE + 1,
/* INPUT (Data,Ary,Abs) */
HID_MI_INPUT,
0x02,
#elif IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_HKRO)
/* LOGICAL_MINIMUM (0) */ /* LOGICAL_MINIMUM (0) */
HID_GI_LOGICAL_MIN(1), HID_GI_LOGICAL_MIN(1),
0x00, 0x00,
@ -89,12 +111,15 @@ static const uint8_t zmk_hid_report_desc[] = {
/* REPORT_SIZE (1) */ /* REPORT_SIZE (1) */
HID_GI_REPORT_SIZE, HID_GI_REPORT_SIZE,
0x08, 0x08,
/* REPORT_COUNT (ZMK_HID_KEYBOARD_NKRO_SIZE) */ /* REPORT_COUNT (CONFIG_ZMK_HID_KEYBOARD_REPORT_SIZE) */
HID_GI_REPORT_COUNT, HID_GI_REPORT_COUNT,
ZMK_HID_KEYBOARD_NKRO_SIZE, CONFIG_ZMK_HID_KEYBOARD_REPORT_SIZE,
/* INPUT (Data,Ary,Abs) */ /* INPUT (Data,Ary,Abs) */
HID_MI_INPUT, HID_MI_INPUT,
0x00, 0x00,
#else
#error "A proper HID report type must be selected"
#endif
/* END_COLLECTION */ /* END_COLLECTION */
HID_MI_COLLECTION_END, HID_MI_COLLECTION_END,
@ -113,6 +138,24 @@ static const uint8_t zmk_hid_report_desc[] = {
/* USAGE_PAGE (Consumer) */ /* USAGE_PAGE (Consumer) */
HID_GI_USAGE_PAGE, HID_GI_USAGE_PAGE,
HID_USAGE_CONSUMER, HID_USAGE_CONSUMER,
#if IS_ENABLED(CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_BASIC)
/* LOGICAL_MINIMUM (0) */
HID_GI_LOGICAL_MIN(1),
0x00,
/* LOGICAL_MAXIMUM (0xFFFF) */
HID_GI_LOGICAL_MAX(1),
0xFF,
HID_LI_USAGE_MIN(1),
0x00,
/* USAGE_MAXIMUM (0xFFFF) */
HID_LI_USAGE_MAX(1),
0xFF,
/* INPUT (Data,Ary,Abs) */
/* REPORT_SIZE (8) */
HID_GI_REPORT_SIZE,
0x08,
#elif IS_ENABLED(CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_FULL)
/* LOGICAL_MINIMUM (0) */ /* LOGICAL_MINIMUM (0) */
HID_GI_LOGICAL_MIN(1), HID_GI_LOGICAL_MIN(1),
0x00, 0x00,
@ -130,9 +173,12 @@ static const uint8_t zmk_hid_report_desc[] = {
/* REPORT_SIZE (16) */ /* REPORT_SIZE (16) */
HID_GI_REPORT_SIZE, HID_GI_REPORT_SIZE,
0x10, 0x10,
/* REPORT_COUNT (ZMK_HID_CONSUMER_NKRO_SIZE) */ #else
#error "A proper consumer HID report usage range must be selected"
#endif
/* REPORT_COUNT (CONFIG_ZMK_HID_CONSUMER_REPORT_SIZE) */
HID_GI_REPORT_COUNT, HID_GI_REPORT_COUNT,
ZMK_HID_CONSUMER_NKRO_SIZE, CONFIG_ZMK_HID_CONSUMER_REPORT_SIZE,
HID_MI_INPUT, HID_MI_INPUT,
0x00, 0x00,
/* END COLLECTION */ /* END COLLECTION */
@ -149,7 +195,11 @@ static const uint8_t zmk_hid_report_desc[] = {
struct zmk_hid_keyboard_report_body { struct zmk_hid_keyboard_report_body {
zmk_mod_flags_t modifiers; zmk_mod_flags_t modifiers;
uint8_t _reserved; uint8_t _reserved;
uint8_t keys[ZMK_HID_KEYBOARD_NKRO_SIZE]; #if IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_NKRO)
uint8_t keys[(ZMK_HID_KEYBOARD_NKRO_MAX_USAGE + 1) / 8];
#elif IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_HKRO)
uint8_t keys[CONFIG_ZMK_HID_KEYBOARD_REPORT_SIZE];
#endif
} __packed; } __packed;
struct zmk_hid_keyboard_report { struct zmk_hid_keyboard_report {
@ -158,7 +208,11 @@ struct zmk_hid_keyboard_report {
} __packed; } __packed;
struct zmk_hid_consumer_report_body { struct zmk_hid_consumer_report_body {
uint16_t keys[ZMK_HID_CONSUMER_NKRO_SIZE]; #if IS_ENABLED(CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_BASIC)
uint8_t keys[CONFIG_ZMK_HID_CONSUMER_REPORT_SIZE];
#elif IS_ENABLED(CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_FULL)
uint16_t keys[CONFIG_ZMK_HID_CONSUMER_REPORT_SIZE];
#endif
} __packed; } __packed;
struct zmk_hid_consumer_report { struct zmk_hid_consumer_report {

View file

@ -69,8 +69,30 @@ int zmk_hid_unregister_mods(zmk_mod_flags_t modifiers) {
return 0; return 0;
} }
#if IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_NKRO)
#define TOGGLE_KEYBOARD(code, val) WRITE_BIT(keyboard_report.body.keys[code / 8], code % 8, val)
static inline int select_keyboard_usage(zmk_key_t usage) {
if (usage > ZMK_HID_KEYBOARD_NKRO_MAX_USAGE) {
return -EINVAL;
}
TOGGLE_KEYBOARD(usage, 1);
return 0;
}
static inline int deselect_keyboard_usage(zmk_key_t usage) {
if (usage > ZMK_HID_KEYBOARD_NKRO_MAX_USAGE) {
return -EINVAL;
}
TOGGLE_KEYBOARD(usage, 0);
return 0;
}
#elif IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_HKRO)
#define TOGGLE_KEYBOARD(match, val) \ #define TOGGLE_KEYBOARD(match, val) \
for (int idx = 0; idx < ZMK_HID_KEYBOARD_NKRO_SIZE; idx++) { \ for (int idx = 0; idx < CONFIG_ZMK_HID_KEYBOARD_REPORT_SIZE; idx++) { \
if (keyboard_report.body.keys[idx] != match) { \ if (keyboard_report.body.keys[idx] != match) { \
continue; \ continue; \
} \ } \
@ -80,8 +102,24 @@ int zmk_hid_unregister_mods(zmk_mod_flags_t modifiers) {
} \ } \
} }
static inline int select_keyboard_usage(zmk_key_t usage) {
TOGGLE_KEYBOARD(0U, usage);
return 0;
}
static inline int deselect_keyboard_usage(zmk_key_t usage) {
TOGGLE_KEYBOARD(usage, 0U);
return 0;
}
#else
#error "A proper HID report type must be selected"
#endif
#define TOGGLE_CONSUMER(match, val) \ #define TOGGLE_CONSUMER(match, val) \
for (int idx = 0; idx < ZMK_HID_CONSUMER_NKRO_SIZE; idx++) { \ COND_CODE_1(IS_ENABLED(CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_BASIC), \
(if (val > 0xFF) { return -ENOTSUP; }), ()) \
for (int idx = 0; idx < CONFIG_ZMK_HID_CONSUMER_REPORT_SIZE; idx++) { \
if (consumer_report.body.keys[idx] != match) { \ if (consumer_report.body.keys[idx] != match) { \
continue; \ continue; \
} \ } \
@ -105,7 +143,7 @@ int zmk_hid_keyboard_press(zmk_key_t code) {
if (code >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL && code <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI) { if (code >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL && code <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI) {
return zmk_hid_register_mod(code - HID_USAGE_KEY_KEYBOARD_LEFTCONTROL); return zmk_hid_register_mod(code - HID_USAGE_KEY_KEYBOARD_LEFTCONTROL);
} }
TOGGLE_KEYBOARD(0U, code); select_keyboard_usage(code);
return 0; return 0;
}; };
@ -113,7 +151,7 @@ int zmk_hid_keyboard_release(zmk_key_t code) {
if (code >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL && code <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI) { if (code >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL && code <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI) {
return zmk_hid_unregister_mod(code - HID_USAGE_KEY_KEYBOARD_LEFTCONTROL); return zmk_hid_unregister_mod(code - HID_USAGE_KEY_KEYBOARD_LEFTCONTROL);
} }
TOGGLE_KEYBOARD(code, 0U); deselect_keyboard_usage(code);
return 0; return 0;
}; };