Start to get layers + keymaps pulled in from DTS.

This commit is contained in:
Pete Johanson 2020-05-03 15:49:33 -04:00
parent 7b4394b3e7
commit fe961d54a3
9 changed files with 113 additions and 13 deletions

View file

@ -9,5 +9,6 @@ project(zmk)
# Add your source file to the "app" target. This must come after # Add your source file to the "app" target. This must come after
# find_package(Zephyr) which defines the target. # find_package(Zephyr) which defines the target.
target_sources(app PRIVATE src/kscan.c) target_sources(app PRIVATE src/kscan.c)
target_sources(app PRIVATE src/keymap.c)
target_sources(app PRIVATE src/main.c) target_sources(app PRIVATE src/main.c)

View file

@ -1,5 +1,35 @@
/ { / {
chosen {
zmk,keymap = &keymap0;
};
layers {
compatible = "zmk,layers";
default: layer_0 {
label = "Default";
keys = <10 2 3 8>;
};
lower: layer_1 {
label = "Default";
keys = <9 2 3 5>;
};
raise: layer_2 {
label = "Default";
keys = <8 1 2 3>;
};
};
keymap0: keymap {
compatible = "zmk,keymap";
label ="Default keymap";
layers = <&default &lower &raise>;
};
kscan { kscan {
compatible = "gpio-kscan"; compatible = "gpio-kscan";
label = "Handwired GPIO KSCAN matrix"; label = "Handwired GPIO KSCAN matrix";

View file

@ -0,0 +1,13 @@
description: |
Allows defining a keymap composed of multiple layers
compatible: "zmk,keymap"
properties:
label:
type: string
required: true
layers:
type: phandles
required: true

View file

@ -0,0 +1,14 @@
description: |
Allows defining the various keymap layers for use.
compatible: "zmk,layers"
child-binding:
description: "A layer to be used in a keymap"
properties:
label:
type: string
keys:
type: array

34
src/keymap.c Normal file
View file

@ -0,0 +1,34 @@
#include "keymap.h"
static enum hid_kbd_code zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_MATRIX_ROWS * ZMK_MATRIX_COLS] = {
#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE,layers,0)
DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE,layers,0,keys),
#endif
#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE,layers,1)
DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE,layers,1,keys),
#endif
#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE,layers,2)
DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE,layers,2,keys),
#endif
#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE,layers,3)
DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE,layers,3,keys),
#endif
#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE,layers,4)
DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE,layers,4,keys),
#endif
#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE,layers,5)
DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE,layers,5,keys),
#endif
#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE,layers,6)
DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE,layers,6,keys),
#endif
#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE,layers,7)
DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE,layers,7,keys),
#endif
};
enum hid_kbd_code zmk_keymap_keycode_from_position(u32_t row, u32_t column)
{
return zmk_keymap[0][(row * ZMK_MATRIX_ROWS) + column];
}

View file

@ -5,17 +5,12 @@
#include <usb/usb_device.h> #include <usb/usb_device.h>
#include <usb/class/usb_hid.h> #include <usb/class/usb_hid.h>
// TODO: Pull these in fro a kscan_gpio.h file from Zephyr! #include "zmk.h"
//
#define MATRIX_NODE_ID DT_PATH(kscan)
#define MATRIX_ROWS DT_PROP_LEN(MATRIX_NODE_ID,row_gpios)
#define MATRIX_COLS DT_PROP_LEN(MATRIX_NODE_ID,col_gpios)
enum hid_kbd_code keymap[MATRIX_ROWS][MATRIX_COLS] = { #define ZMK_KEYMAP_NODE DT_CHOSEN(zmk_keymap)
{ HID_KEY_A, HID_KEY_B }, #define ZMK_KEYMAP_LAYERS_LEN DT_PROP_LEN(ZMK_KEYMAP_NODE,layers)
{ HID_KEY_C, HID_KEY_D }
};
#define zmk_keymap_keycode_from_position(row, column) keymap[row][column]
enum hid_kbd_code zmk_keymap_keycode_from_position(u32_t row, u32_t column);
#endif #endif

View file

@ -35,6 +35,7 @@ static void zmk_kscan_callback(struct device *dev, u32_t row, u32_t column, bool
.column = column, .column = column,
.state = (pressed ? ZMK_KSCAN_EVENT_STATE_PRESSED : ZMK_KSCAN_EVENT_STATE_RELEASED) .state = (pressed ? ZMK_KSCAN_EVENT_STATE_PRESSED : ZMK_KSCAN_EVENT_STATE_RELEASED)
}; };
printk("Row: %d, col: %d, pressed: %s\n", ev.row, ev.column, (pressed ? "true" : "false"));
k_msgq_put(&zmk_kscan_msgq, &ev, K_NO_WAIT); k_msgq_put(&zmk_kscan_msgq, &ev, K_NO_WAIT);
k_work_submit(&msg_processor.work); k_work_submit(&msg_processor.work);
@ -49,7 +50,7 @@ void zmk_kscan_process_msgq(struct k_work *item)
bool pressed = (ev.state == ZMK_KSCAN_EVENT_STATE_PRESSED); bool pressed = (ev.state == ZMK_KSCAN_EVENT_STATE_PRESSED);
// TODO: More than basic mapping, layers, etc. // TODO: More than basic mapping, layers, etc.
enum hid_kbd_code code = zmk_keymap_keycode_from_position(ev.row, ev.column); enum hid_kbd_code code = zmk_keymap_keycode_from_position(ev.row, ev.column);
printk("Row: %d, col: %d, pressed: %s\n", ev.row, ev.column, (pressed ? "true" : "false")); printk("Row: %d, col: %d, code: %d, pressed: %s\n", ev.row, ev.column, code, (pressed ? "true" : "false"));
} }
} }
@ -61,10 +62,11 @@ int zmk_kscan_init(char* name)
return -EINVAL; return -EINVAL;
} }
return 0;
k_work_init(&msg_processor.work, zmk_kscan_process_msgq); k_work_init(&msg_processor.work, zmk_kscan_process_msgq);
kscan_config(dev, zmk_kscan_callback); kscan_config(dev, zmk_kscan_callback);
kscan_enable_callback(dev); kscan_enable_callback(dev);
return 0;
} }

View file

@ -14,5 +14,8 @@ void main(void)
{ {
printk("Welcome to ZMK!\n"); printk("Welcome to ZMK!\n");
zmk_kscan_init(CONFIG_KSCAN_MATRIX_DEV_NAME); if (zmk_kscan_init(CONFIG_KSCAN_MATRIX_DEV_NAME) != 0) {
printk("Keyboard Scan Init Failed\n");
return;
}
} }

8
src/zmk.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef ZMK_H
#define ZMK_H
#define __ZMK_MATRIX_NODE_ID DT_PATH(kscan)
#define ZMK_MATRIX_ROWS DT_PROP_LEN(__ZMK_MATRIX_NODE_ID,row_gpios)
#define ZMK_MATRIX_COLS DT_PROP_LEN(__ZMK_MATRIX_NODE_ID,col_gpios)
#endif