Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(deps-dev): bump eslint from 7.12.0 to 7.17.0 in /docs #6

Closed
wants to merge 25 commits into from
Closed
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
16 changes: 16 additions & 0 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "gnu++14",
"intelliSenseMode": "gcc-x64"
}
],
"version": 4
}
2 changes: 2 additions & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ target_sources(app PRIVATE src/kscan.c)
target_sources(app PRIVATE src/matrix_transform.c)
target_sources(app PRIVATE src/hid.c)
target_sources(app PRIVATE src/sensors.c)
target_sources(app PRIVATE src/wpm.c)
target_sources(app PRIVATE src/event_manager.c)
target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/ext_power_generic.c)
target_sources(app PRIVATE src/events/activity_state_changed.c)
Expand All @@ -36,6 +37,7 @@ target_sources(app PRIVATE src/events/layer_state_changed.c)
target_sources(app PRIVATE src/events/keycode_state_changed.c)
target_sources(app PRIVATE src/events/modifiers_state_changed.c)
target_sources(app PRIVATE src/events/sensor_event.c)
target_sources_ifdef(CONFIG_ZMK_WIDGET_WPM_STATUS app PRIVATE src/events/wpm_state_changed.c)
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/events/ble_active_profile_changed.c)
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/events/battery_state_changed.c)
target_sources_ifdef(CONFIG_USB app PRIVATE src/events/usb_conn_state_changed.c)
Expand Down
6 changes: 3 additions & 3 deletions app/boards/shields/sofle/sofle.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# SPDX-License-Identifier: MIT

# Uncomment the following line to enable the Sofle OLED Display
# CONFIG_ZMK_DISPLAY=y
CONFIG_ZMK_DISPLAY=y

# Uncomment these two lines to add support for encoders
# CONFIG_EC11=y
# CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y
CONFIG_EC11=y
CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y
18 changes: 18 additions & 0 deletions app/include/zmk/display/widgets/wpm_status.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2020 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

#include <lvgl.h>
#include <kernel.h>

struct zmk_widget_wpm_status {
sys_snode_t node;
lv_obj_t *obj;
};

int zmk_widget_wpm_status_init(struct zmk_widget_wpm_status *widget, lv_obj_t *parent);
lv_obj_t *zmk_widget_wpm_status_obj(struct zmk_widget_wpm_status *widget);
25 changes: 25 additions & 0 deletions app/include/zmk/events/wpm_state_changed.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2020 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

#include <zephyr.h>
#include <zmk/event_manager.h>
#include <zmk/wpm.h>

struct wpm_state_changed {
struct zmk_event_header header;
int state;
};

ZMK_EVENT_DECLARE(wpm_state_changed);

static inline struct wpm_state_changed *create_wpm_state_changed(int state) {
struct wpm_state_changed *ev = new_wpm_state_changed();
ev->state = state;

return ev;
}
9 changes: 9 additions & 0 deletions app/include/zmk/wpm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2020 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#pragma once

int zmk_wpm_get_state();
9 changes: 9 additions & 0 deletions app/src/display/status_screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <zmk/display/widgets/output_status.h>
#include <zmk/display/widgets/battery_status.h>
#include <zmk/display/widgets/layer_status.h>
#include <zmk/display/widgets/wpm_status.h>
#include <zmk/display/status_screen.h>

#include <logging/log.h>
Expand All @@ -24,6 +25,10 @@ static struct zmk_widget_output_status output_status_widget;
static struct zmk_widget_layer_status layer_status_widget;
#endif

#if IS_ENABLED(CONFIG_ZMK_WIDGET_WPM_STATUS)
static struct zmk_widget_wpm_status wpm_status_widget;
#endif

lv_obj_t *zmk_display_status_screen() {
lv_obj_t *screen;

Expand All @@ -47,5 +52,9 @@ lv_obj_t *zmk_display_status_screen() {
0, 0);
#endif

#if IS_ENABLED(CONFIG_ZMK_WIDGET_WPM_STATUS)
zmk_widget_wpm_status_init(&wpm_status_widget, screen);
lv_obj_align(zmk_widget_wpm_status_obj(&wpm_status_widget), NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
#endif
return screen;
}
1 change: 1 addition & 0 deletions app/src/display/widgets/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
target_sources_ifdef(CONFIG_ZMK_WIDGET_BATTERY_STATUS app PRIVATE battery_status.c)
target_sources_ifdef(CONFIG_ZMK_WIDGET_OUTPUT_STATUS app PRIVATE output_status.c)
target_sources_ifdef(CONFIG_ZMK_WIDGET_LAYER_STATUS app PRIVATE layer_status.c)
target_sources_ifdef(CONFIG_ZMK_WIDGET_WPM_STATUS app PRIVATE wpm_status.c)
6 changes: 6 additions & 0 deletions app/src/display/widgets/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,11 @@ config ZMK_WIDGET_OUTPUT_STATUS
default y if BT
select LVGL_USE_LABEL
select LVGL_FONT_MONTSERRAT_16

config ZMK_WIDGET_WPM_STATUS
bool "Widget for displaying typed words per minute"
depends on !ZMK_SPLIT || ZMK_SPLIT_BLE_ROLE_CENTRAL
select LVGL_USE_LABEL
select LVGL_FONT_MONTSERRAT_16

endmenu
6 changes: 3 additions & 3 deletions app/src/display/widgets/output_status.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ void set_status_symbol(lv_obj_t *label) {
case ZMK_ENDPOINT_BLE:
if (active_profie_bonded) {
if (active_profile_connected) {
sprintf(text, LV_SYMBOL_WIFI "%i " LV_SYMBOL_OK, active_profile_index);
sprintf(text, LV_SYMBOL_BLUETOOTH "%i " LV_SYMBOL_OK, active_profile_index);
} else {
sprintf(text, LV_SYMBOL_WIFI "%i " LV_SYMBOL_CLOSE, active_profile_index);
sprintf(text, LV_SYMBOL_BLUETOOTH "%i " LV_SYMBOL_CLOSE, active_profile_index);
}
} else {
sprintf(text, LV_SYMBOL_WIFI "%i " LV_SYMBOL_SETTINGS, active_profile_index);
sprintf(text, LV_SYMBOL_BLUETOOTH "%i " LV_SYMBOL_SETTINGS, active_profile_index);
}
break;
}
Expand Down
66 changes: 66 additions & 0 deletions app/src/display/widgets/wpm_status.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2020 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#include <logging/log.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

#include <zmk/display/widgets/wpm_status.h>
#include <zmk/events/wpm_state_changed.h>
#include <zmk/event_manager.h>
#include <zmk/endpoints.h>
#include <zmk/wpm.h>

static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets);
static lv_style_t label_style;

static bool style_initialized = false;

void wpm_status_init() {
if (style_initialized) {
return;
}

style_initialized = true;
lv_style_init(&label_style);
lv_style_set_text_color(&label_style, LV_STATE_DEFAULT, LV_COLOR_BLACK);
lv_style_set_text_font(&label_style, LV_STATE_DEFAULT, &lv_font_montserrat_16);
lv_style_set_text_letter_space(&label_style, LV_STATE_DEFAULT, 1);
lv_style_set_text_line_space(&label_style, LV_STATE_DEFAULT, 1);
}

void set_wpm_symbol(lv_obj_t *label, int wpm) {
char text[4] = {};

LOG_DBG("WPM changed to %i", wpm);
sprintf(text, "%i ", wpm);

lv_label_set_text(label, text);
}

int zmk_widget_wpm_status_init(struct zmk_widget_wpm_status *widget, lv_obj_t *parent) {
wpm_status_init();
widget->obj = lv_label_create(parent, NULL);
lv_obj_add_style(widget->obj, LV_LABEL_PART_MAIN, &label_style);

lv_obj_set_size(widget->obj, 40, 15);
set_wpm_symbol(widget->obj, 0);

sys_slist_append(&widgets, &widget->node);

return 0;
}

lv_obj_t *zmk_widget_wpm_status_obj(struct zmk_widget_wpm_status *widget) { return widget->obj; }

int wpm_status_listener(const struct zmk_event_header *eh) {
struct wpm_state_changed *ev = cast_wpm_state_changed(eh);
struct zmk_widget_wpm_status *widget;
SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_wpm_symbol(widget->obj, ev->state); }
return 0;
}

ZMK_LISTENER(widget_wpm_status, wpm_status_listener)
ZMK_SUBSCRIPTION(widget_wpm_status, wpm_state_changed);
10 changes: 10 additions & 0 deletions app/src/events/wpm_state_changed.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright (c) 2020 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#include <kernel.h>
#include <zmk/events/wpm_state_changed.h>

ZMK_EVENT_IMPL(wpm_state_changed);
84 changes: 84 additions & 0 deletions app/src/wpm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2020 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#include <device.h>
#include <init.h>
#include <kernel.h>

#include <logging/log.h>

LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

#include <zmk/event_manager.h>
#include <zmk/events/wpm_state_changed.h>
#include <zmk/events/keycode_state_changed.h>

#include <zmk/wpm.h>

#define WPM_UPDATE_INTERVAL_SECONDS 1
#define WPM_RESET_INTERVAL_SECONDS 5

// See https://en.wikipedia.org/wiki/Words_per_minute
// "Since the length or duration of words is clearly variable, for the purpose of measurement of
// text entry, the definition of each "word" is often standardized to be five characters or
// keystrokes long in English"
#define CHARS_PER_WORD 5.0

static uint8_t wpm_state = -1;
static uint8_t last_wpm_state;
static uint8_t wpm_update_counter;
static uint32_t key_pressed_count;

int zmk_wpm_get_state() { return wpm_state; }

int wpm_event_listener(const struct zmk_event_header *eh) {
if (is_keycode_state_changed(eh)) {
struct keycode_state_changed *ev = cast_keycode_state_changed(eh);
// count only key up events
if (!ev->state) {
key_pressed_count++;
LOG_DBG("key_pressed_count %d keycode %d", key_pressed_count, ev->keycode);
}
}
return 0;
}

void wpm_work_handler(struct k_work *work) {
wpm_update_counter++;
wpm_state = (key_pressed_count / CHARS_PER_WORD) /
(wpm_update_counter * WPM_UPDATE_INTERVAL_SECONDS / 60.0);

if (last_wpm_state != wpm_state) {
LOG_DBG("Raised WPM state changed %d wpm_update_counter %d", wpm_state, wpm_update_counter,
wpm_update_counter);
ZMK_EVENT_RAISE(create_wpm_state_changed(wpm_state));
last_wpm_state = wpm_state;
}

if (wpm_update_counter >= WPM_RESET_INTERVAL_SECONDS) {
wpm_update_counter = 0;
key_pressed_count = 0;
}
}

K_WORK_DEFINE(wpm_work, wpm_work_handler);

void wpm_expiry_function() { k_work_submit(&wpm_work); }

K_TIMER_DEFINE(wpm_timer, wpm_expiry_function, NULL);

int wpm_init() {
wpm_state = 0;
wpm_update_counter = 0;
k_timer_start(&wpm_timer, K_SECONDS(WPM_UPDATE_INTERVAL_SECONDS),
K_SECONDS(WPM_UPDATE_INTERVAL_SECONDS));
return 0;
}

ZMK_LISTENER(wpm, wpm_event_listener);
ZMK_SUBSCRIPTION(wpm, keycode_state_changed);

SYS_INIT(wpm_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
2 changes: 2 additions & 0 deletions app/tests/wpm/1-single_keypress/events.patterns
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
s/.*wpm_work_handler: //p
s/.*wpm_event_listener: //p
7 changes: 7 additions & 0 deletions app/tests/wpm/1-single_keypress/keycode_events.snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
key_pressed_count 1 keycode 5
Raised WPM state changed 12 wpm_update_counter 1
Raised WPM state changed 6 wpm_update_counter 2
Raised WPM state changed 4 wpm_update_counter 3
Raised WPM state changed 3 wpm_update_counter 4
Raised WPM state changed 2 wpm_update_counter 5
Raised WPM state changed 0 wpm_update_counter 1
10 changes: 10 additions & 0 deletions app/tests/wpm/1-single_keypress/native_posix.keymap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "../behavior_keymap.dtsi"

&kscan {
events = <
ZMK_MOCK_PRESS(0,0,10)
ZMK_MOCK_RELEASE(0,0,10)
/* Wait for the worker to trigger and reset after 5 seconds, followed by a 0 at 6 seconds */
ZMK_MOCK_PRESS(0,0,6000)
>;
};
2 changes: 2 additions & 0 deletions app/tests/wpm/2-multiple_keypress/events.patterns
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
s/.*wpm_work_handler: //p
s/.*wpm_event_listener: //p
4 changes: 4 additions & 0 deletions app/tests/wpm/2-multiple_keypress/keycode_events.snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
key_pressed_count 1 keycode 5
Raised WPM state changed 12 wpm_update_counter 1
key_pressed_count 2 keycode 5
Raised WPM state changed 8 wpm_update_counter 3
15 changes: 15 additions & 0 deletions app/tests/wpm/2-multiple_keypress/native_posix.keymap
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "../behavior_keymap.dtsi"

&kscan {
events = <
ZMK_MOCK_PRESS(0,0,10)
ZMK_MOCK_RELEASE(0,0,10)
//1st WPM worker call - 12wpm - 1 key press in 1 second
ZMK_MOCK_PRESS(0,0,1000)
ZMK_MOCK_RELEASE(0,0,10)
// 2nd WPM worker call - 12wpm - 2 key press in 2 second
// note there is no event for this as WPM hasn't changed
// 3rd WPM worker call - 8wpm - 2 key press in 3 seconds
ZMK_MOCK_PRESS(0,0,2000)
>;
};
17 changes: 17 additions & 0 deletions app/tests/wpm/behavior_keymap.dtsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>

/ {
keymap {
compatible = "zmk,keymap";
label ="Default keymap";

default_layer {
bindings = <
&kp B &none
&none &none
>;
};
};
};
Loading