diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 25f6c6cd0ef..1cd2176431c 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -45,7 +45,7 @@ target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/events/battery_state_changed target_sources_ifdef(CONFIG_USB app PRIVATE src/events/usb_conn_state_changed.c) target_sources(app PRIVATE src/behaviors/behavior_reset.c) target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/behaviors/behavior_ext_power.c) -if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) +if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL OR CONFIG_ZMK_SPLIT_SERIAL_ROLE_CENTRAL) target_sources(app PRIVATE src/behaviors/behavior_key_press.c) target_sources(app PRIVATE src/behaviors/behavior_hold_tap.c) target_sources(app PRIVATE src/behaviors/behavior_sticky_key.c) @@ -75,6 +75,15 @@ endif() if (CONFIG_ZMK_SPLIT_BLE AND CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) target_sources(app PRIVATE src/split/bluetooth/central.c) endif() +if (CONFIG_ZMK_SPLIT_SERIAL AND (NOT CONFIG_ZMK_SPLIT_SERIAL_ROLE_CENTRAL)) + target_sources(app PRIVATE src/split_listener.c) + target_sources(app PRIVATE src/split/serial/service.c) + target_sources(app PRIVATE src/split/serial/common.c) +endif() +if (CONFIG_ZMK_SPLIT_SERIAL AND CONFIG_ZMK_SPLIT_SERIAL_ROLE_CENTRAL) + target_sources(app PRIVATE src/split/serial/central.c) + target_sources(app PRIVATE src/split/serial/common.c) +endif() target_sources_ifdef(CONFIG_USB app PRIVATE src/usb.c) target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/hog.c) target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/rgb_underglow.c) diff --git a/app/Kconfig b/app/Kconfig index 1c9f929db66..676daa1e3bb 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -155,10 +155,14 @@ config ZMK_SPLIT if ZMK_SPLIT +choice ZMK_SPLIT_TYPE + prompt "ZMK split type" + +if ZMK_BLE + menuconfig ZMK_SPLIT_BLE bool "Split keyboard support via BLE transport" depends on ZMK_BLE - default y select BT_USER_PHY_UPDATE if ZMK_SPLIT_BLE @@ -199,9 +203,6 @@ config ZMK_SPLIT_BLE_PERIPHERAL_POSITION_QUEUE_SIZE int "Max number of key position state events to queue to send to the central" default 10 -config ZMK_USB - default n - config BT_MAX_PAIRED default 1 @@ -217,6 +218,51 @@ endif #ZMK_SPLIT_BLE endif +# ZMK_BLE +endif + +if ZMK_USB + +menuconfig ZMK_SPLIT_SERIAL + bool "Split keyboard support via Serial transport" + depends on ZMK_USB + +if ZMK_SPLIT_SERIAL + +choice ZMK_SPLIT_SERIAL_ROLE + prompt "ZMK split serial role" + +menuconfig ZMK_SPLIT_SERIAL_ROLE_CENTRAL + bool "Central" + +menuconfig ZMK_SPLIT_SERIAL_ROLE_PERIPHERAL + bool "Peripheral" + +# ZMK_SPLIT_SERIAL_ROLE +endchoice + +config ZMK_SPLIT_SERIAL_THREAD_STACK_SIZE + int "Serial split thread stack size" + default 1024 + +config ZMK_SPLIT_SERIAL_THREAD_PRIORITY + int "Serial split thread priority" + default 5 + +config ZMK_SPLIT_SERIAL_THREAD_QUEUE_SIZE + int "Max number of queue size for split data buffering" + default 5 + +# ZMK_SPLIT_SERIAL +endif + +# ZMK_USB +endif + +# ZMK_SPLIT_TYPE +endchoice + + #ZMK_SPLIT endif diff --git a/app/boards/shields/a_dux/Kconfig.defconfig b/app/boards/shields/a_dux/Kconfig.defconfig index 3d77a5f8423..63612e56908 100644 --- a/app/boards/shields/a_dux/Kconfig.defconfig +++ b/app/boards/shields/a_dux/Kconfig.defconfig @@ -1,19 +1,39 @@ # Copyright (c) 2021 The ZMK Contributors # SPDX-License-Identifier: MIT +if SHIELD_A_DUX_LEFT || SHIELD_A_DUX_RIGHT + +config ZMK_SPLIT + default y + if SHIELD_A_DUX_LEFT config ZMK_KEYBOARD_NAME default "A. Dux" +if ZMK_BLE config ZMK_SPLIT_BLE_ROLE_CENTRAL default y +endif +if ZMK_USB +choice ZMK_SPLIT_SERIAL_ROLE + default ZMK_SPLIT_SERIAL_ROLE_CENTRAL +endchoice endif -if SHIELD_A_DUX_LEFT || SHIELD_A_DUX_RIGHT +# SHIELD_A_DUX_LEFT +endif -config ZMK_SPLIT - default y +if SHIELD_A_DUX_RIGHT + +if ZMK_USB +choice ZMK_SPLIT_SERIAL_ROLE + default ZMK_SPLIT_SERIAL_ROLE_PERIPHERAL +endchoice +endif + +# SHIELD_A_DUX_RIGHT +endif endif diff --git a/app/boards/shields/a_dux/boards/stemcell.overlay b/app/boards/shields/a_dux/boards/stemcell.overlay new file mode 100644 index 00000000000..1bedcfebfce --- /dev/null +++ b/app/boards/shields/a_dux/boards/stemcell.overlay @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +/ { + chosen { + zmk,split-serial = &usart1; + }; +}; + +&usart1 { + status = "okay"; +}; + +&kscan0 { + input-gpios = + <&pro_micro_d 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_d 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_a 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_d 16 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_a 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_d 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_d 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, /* Changed since swapped pins */ + <&pro_micro_a 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_d 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_a 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_d 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_d 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_d 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, /* TODO: Use 0 if Console is needed */ + <&pro_micro_d 15 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_d 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_d 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&pro_micro_d 9 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)> + ; +}; diff --git a/app/boards/shields/lily58/Kconfig.defconfig b/app/boards/shields/lily58/Kconfig.defconfig index c09fcd7d4dd..839e31d8fc0 100644 --- a/app/boards/shields/lily58/Kconfig.defconfig +++ b/app/boards/shields/lily58/Kconfig.defconfig @@ -1,18 +1,38 @@ +if SHIELD_LILY58_LEFT || SHIELD_LILY58_RIGHT + +config ZMK_SPLIT + default y + if SHIELD_LILY58_LEFT config ZMK_KEYBOARD_NAME default "Lily58" +if ZMK_BLE config ZMK_SPLIT_BLE_ROLE_CENTRAL default y +endif +if ZMK_USB +choice ZMK_SPLIT_SERIAL_ROLE + default ZMK_SPLIT_SERIAL_ROLE_CENTRAL +endchoice endif -if SHIELD_LILY58_LEFT || SHIELD_LILY58_RIGHT +#SHIELD_LILY58_LEFT +endif -config ZMK_SPLIT - default y +if SHIELD_LILY58_RIGHT + +if ZMK_USB +choice ZMK_SPLIT_SERIAL_ROLE + default ZMK_SPLIT_SERIAL_ROLE_PERIPHERAL +endchoice +endif + +#SHIELD_LILY58_LEFT +endif if ZMK_DISPLAY diff --git a/app/boards/shields/lily58/boards/stemcell.overlay b/app/boards/shields/lily58/boards/stemcell.overlay new file mode 100644 index 00000000000..8bc0ea71b3a --- /dev/null +++ b/app/boards/shields/lily58/boards/stemcell.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +/ { + chosen { + zmk,split-serial = &usart2; + }; +}; + +&usart2 { + status = "okay"; +}; + diff --git a/app/include/zmk/split/bluetooth/central.h b/app/include/zmk/split/bluetooth/central.h index 072408605cf..4c112453ec9 100644 --- a/app/include/zmk/split/bluetooth/central.h +++ b/app/include/zmk/split/bluetooth/central.h @@ -5,4 +5,4 @@ #include int zmk_split_bt_invoke_behavior(uint8_t source, struct zmk_behavior_binding *binding, - struct zmk_behavior_binding_event event, bool state); \ No newline at end of file + struct zmk_behavior_binding_event event, bool state); diff --git a/app/include/zmk/split/bluetooth/service.h b/app/include/zmk/split/bluetooth/service.h index f0c1d79ff7d..27744ebfacc 100644 --- a/app/include/zmk/split/bluetooth/service.h +++ b/app/include/zmk/split/bluetooth/service.h @@ -19,6 +19,3 @@ struct zmk_split_run_behavior_payload { struct zmk_split_run_behavior_data data; char behavior_dev[ZMK_SPLIT_RUN_BEHAVIOR_DEV_LEN]; } __packed; - -int zmk_split_bt_position_pressed(uint8_t position); -int zmk_split_bt_position_released(uint8_t position); \ No newline at end of file diff --git a/app/include/zmk/split/common.h b/app/include/zmk/split/common.h new file mode 100644 index 00000000000..222c52aad8d --- /dev/null +++ b/app/include/zmk/split/common.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include + +#define SPLIT_DATA_LEN 16 + +#define SPLIT_TYPE_KEYPOSITION 0 + +typedef struct _split_data_t { + uint16_t type; + uint8_t data[SPLIT_DATA_LEN]; + uint16_t crc; +} split_data_t; + +int zmk_split_position_pressed(uint8_t position); + +int zmk_split_position_released(uint8_t position); diff --git a/app/include/zmk/split/serial/common.h b/app/include/zmk/split/serial/common.h new file mode 100644 index 00000000000..03b08847d55 --- /dev/null +++ b/app/include/zmk/split/serial/common.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include + +/* Caller does/should not need to free `data` + * Data will be freed immediately after calling this callback */ +typedef int (*rx_complete_t)(const uint8_t *data, size_t length); + +void split_serial_async_init(rx_complete_t complete_fn); + +void split_serial_async_send(uint8_t *data, size_t length); + +uint8_t *alloc_split_serial_buffer(k_timeout_t timeout); + +void free_split_serial_buffer(const uint8_t *data); diff --git a/app/src/activity.c b/app/src/activity.c index f31e608dbc5..458fceead99 100644 --- a/app/src/activity.c +++ b/app/src/activity.c @@ -62,8 +62,8 @@ void activity_work_handler(struct k_work *work) { } else #endif /* IS_ENABLED(CONFIG_ZMK_SLEEP) */ if (inactive_time > MAX_IDLE_MS) { - set_state(ZMK_ACTIVITY_IDLE); - } + set_state(ZMK_ACTIVITY_IDLE); + } } K_WORK_DEFINE(activity_work, activity_work_handler); diff --git a/app/src/split/bluetooth/service.c b/app/src/split/bluetooth/service.c index 7de78506fce..d3fa4dfcd1e 100644 --- a/app/src/split/bluetooth/service.c +++ b/app/src/split/bluetooth/service.c @@ -19,6 +19,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include #include +#include #include #define POS_STATE_LEN 16 @@ -141,12 +142,12 @@ int send_position_state() { return 0; } -int zmk_split_bt_position_pressed(uint8_t position) { +int zmk_split_position_pressed(uint8_t position) { WRITE_BIT(position_state[position / 8], position % 8, true); return send_position_state(); } -int zmk_split_bt_position_released(uint8_t position) { +int zmk_split_position_released(uint8_t position) { WRITE_BIT(position_state[position / 8], position % 8, false); return send_position_state(); } diff --git a/app/src/split/serial/central.c b/app/src/split/serial/central.c new file mode 100644 index 00000000000..ade025c127a --- /dev/null +++ b/app/src/split/serial/central.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include + +#include +#include +#include + +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include +#include + +K_MSGQ_DEFINE(peripheral_event_msgq, sizeof(struct zmk_position_state_changed), + CONFIG_ZMK_SPLIT_SERIAL_THREAD_QUEUE_SIZE, 4); + +static void peripheral_event_work_callback(struct k_work *work) { + struct zmk_position_state_changed ev; + while (k_msgq_get(&peripheral_event_msgq, &ev, K_NO_WAIT) == 0) { + LOG_DBG("Trigger key position state change for %d", ev.position); + ZMK_EVENT_RAISE(new_zmk_position_state_changed(ev)); + } +} + +K_WORK_DEFINE(peripheral_event_work, peripheral_event_work_callback); + +static int split_central_notify_func(const uint8_t *data, size_t length) { + static uint8_t position_state[SPLIT_DATA_LEN]; + uint8_t changed_positions[SPLIT_DATA_LEN]; + const split_data_t *split_data = (const split_data_t *)data; + uint16_t crc; + + LOG_DBG("[NOTIFICATION] data %p type:%u CRC:%u", data, split_data->type, split_data->crc); + + crc = crc16_ansi(split_data->data, sizeof(split_data->data)); + if (crc != split_data->crc) { + LOG_WRN("CRC mismatch (%x:%x), skipping data", crc, split_data->crc); + return 0; + } + + for (int i = 0; i < SPLIT_DATA_LEN; i++) { + changed_positions[i] = split_data->data[i] ^ position_state[i]; + position_state[i] = split_data->data[i]; + } + + for (int i = 0; i < SPLIT_DATA_LEN; i++) { + for (int j = 0; j < 8; j++) { + if (changed_positions[i] & BIT(j)) { + uint32_t position = (i * 8) + j; + bool pressed = position_state[i] & BIT(j); + struct zmk_position_state_changed ev = { + .position = position, .state = pressed, .timestamp = k_uptime_get()}; + + if (position > ZMK_KEYMAP_LEN) { + LOG_WRN("Invalid position: %u", position); + continue; + } + + k_msgq_put(&peripheral_event_msgq, &ev, K_NO_WAIT); + k_work_submit(&peripheral_event_work); + } + } + } + + return 0; +} + +static int split_serial_central_init(const struct device *dev) { + split_serial_async_init(split_central_notify_func); + return 0; +} + +SYS_INIT(split_serial_central_init, APPLICATION, CONFIG_ZMK_USB_INIT_PRIORITY); diff --git a/app/src/split/serial/common.c b/app/src/split/serial/common.c new file mode 100644 index 00000000000..61388edd449 --- /dev/null +++ b/app/src/split/serial/common.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include + +#include +#include +#include + +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include +#include + +#if !DT_HAS_CHOSEN(zmk_split_serial) +#error "No zmk-split-serial node is chosen" +#endif + +#define UART_NODE1 DT_CHOSEN(zmk_split_serial) +const struct device *serial_dev = DEVICE_DT_GET(UART_NODE1); +static int uart_ready = 0; + +K_MEM_SLAB_DEFINE(split_memory_slab, sizeof(split_data_t), + CONFIG_ZMK_SPLIT_SERIAL_THREAD_QUEUE_SIZE, 4); + +static K_SEM_DEFINE(split_serial_rx_sem, 1, 1); + +static K_SEM_DEFINE(split_serial_tx_sem, 1, 1); + +rx_complete_t split_serial_rx_complete_fn = NULL; + +uint8_t *alloc_split_serial_buffer(k_timeout_t timeout) { + uint8_t *block_ptr = NULL; + if (k_mem_slab_alloc(&split_memory_slab, (void **)&block_ptr, timeout) == 0) { + memset(block_ptr, 0, SPLIT_DATA_LEN); + } else { + LOG_WRN("Memory allocation time-out"); + } + return block_ptr; +} + +void free_split_serial_buffer(const uint8_t *data) { + k_mem_slab_free(&split_memory_slab, (void **)&data); +} + +static void enable_rx(const struct device *dev) { + int ret; + uint8_t *buf = NULL; + while (!(buf = alloc_split_serial_buffer(K_MSEC(100)))) { + }; + + while (0 != (ret = uart_rx_enable(serial_dev, buf, sizeof(split_data_t), SYS_FOREVER_MS))) { + LOG_WRN("UART device:%s RX error:%d", serial_dev->name, ret); + k_sleep(K_MSEC(100)); + } + return; +} + +static void uart_callback(const struct device *dev, struct uart_event *evt, void *user_data) { + uint8_t *buf = NULL; + + switch (evt->type) { + + case UART_RX_STOPPED: + LOG_DBG("UART device:%s rx stopped", serial_dev->name); + break; + + case UART_RX_BUF_REQUEST: + LOG_DBG("UART device:%s rx extra buf req", serial_dev->name); + buf = alloc_split_serial_buffer(K_NO_WAIT); + if (NULL != buf) { + int ret = uart_rx_buf_rsp(serial_dev, buf, sizeof(split_data_t)); + if (0 != ret) { + LOG_WRN("UART device:%s rx extra buf req add failed: %d", serial_dev->name, ret); + free_split_serial_buffer(buf); + } + } + break; + + case UART_RX_RDY: + LOG_DBG("UART device:%s rx buf ready", serial_dev->name); + break; + + case UART_RX_BUF_RELEASED: + LOG_DBG("UART device:%s rx buf released", serial_dev->name); + if (split_serial_rx_complete_fn) { + split_serial_rx_complete_fn(evt->data.rx_buf.buf, sizeof(split_data_t)); + } + free_split_serial_buffer(evt->data.rx_buf.buf); + break; + + case UART_RX_DISABLED: + LOG_WRN("UART device:%s rx disabled", serial_dev->name); + enable_rx(serial_dev); + break; + + case UART_TX_DONE: + LOG_DBG("UART device:%s tx done", serial_dev->name); + free_split_serial_buffer(evt->data.tx.buf); + k_sem_give(&split_serial_tx_sem); + break; + + case UART_TX_ABORTED: + LOG_WRN("UART device:%s tx aborted", serial_dev->name); + k_sem_give(&split_serial_tx_sem); + break; + + default: + LOG_DBG("UART device:%s unhandled event: %u", serial_dev->name, evt->type); + break; + }; + return; +} + +void split_serial_async_send(uint8_t *data, size_t len) { + if (!uart_ready) { + return; + } + + k_sem_take(&split_serial_tx_sem, K_FOREVER); + int err = uart_tx(serial_dev, data, len, 0); + if (0 != err) { + LOG_WRN("Failed to send data via UART: (%d)", err); + } +} + +void split_serial_async_init(rx_complete_t rx_comp_fn) { + if (!device_is_ready(serial_dev)) { + LOG_ERR("UART device:%s not ready", serial_dev->name); + return; + } + + int ret = uart_callback_set(serial_dev, uart_callback, NULL); + if (ret == -ENOTSUP || ret == -ENOSYS) { + LOG_ERR("UART device:%s ASYNC not supported", serial_dev->name); + return; + } + + split_serial_rx_complete_fn = rx_comp_fn; + + uart_ready = 1; + LOG_INF("UART device:%s ready", serial_dev->name); + + enable_rx(serial_dev); +} diff --git a/app/src/split/serial/service.c b/app/src/split/serial/service.c new file mode 100644 index 00000000000..6010b02afb2 --- /dev/null +++ b/app/src/split/serial/service.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include + +static uint8_t position_state[SPLIT_DATA_LEN]; + +K_THREAD_STACK_DEFINE(service_q_stack, CONFIG_ZMK_SPLIT_SERIAL_THREAD_STACK_SIZE); + +struct k_work_q service_work_q; + +K_MSGQ_DEFINE(position_state_msgq, sizeof(char[SPLIT_DATA_LEN]), + CONFIG_ZMK_SPLIT_SERIAL_THREAD_QUEUE_SIZE, 4); + +static void send_position_state_callback(struct k_work *work) { + split_data_t *split_data = NULL; + + while (!(split_data = (split_data_t *)alloc_split_serial_buffer(K_MSEC(100)))) { + }; + + memset(split_data, sizeof(split_data_t), 0); + split_data->type = SPLIT_TYPE_KEYPOSITION; + + while (k_msgq_get(&position_state_msgq, split_data->data, K_NO_WAIT) == 0) { + split_data->crc = crc16_ansi(split_data->data, sizeof(split_data->data)); + split_serial_async_send((uint8_t *)split_data, sizeof(*split_data)); + } +}; + +K_WORK_DEFINE(service_position_notify_work, send_position_state_callback); + +static int send_position_state() { + int err = k_msgq_put(&position_state_msgq, position_state, K_MSEC(100)); + if (err) { + switch (err) { + case -EAGAIN: { + LOG_WRN("Position state message queue full, popping first message and queueing again"); + uint8_t discarded_state[SPLIT_DATA_LEN]; + k_msgq_get(&position_state_msgq, &discarded_state, K_NO_WAIT); + return send_position_state(); + } + default: + LOG_WRN("Failed to queue position state to send (%d)", err); + return err; + } + } + + k_work_submit_to_queue(&service_work_q, &service_position_notify_work); + return 0; +} + +int zmk_split_position_pressed(uint8_t position) { + WRITE_BIT(position_state[position / 8], position % 8, true); + return send_position_state(); +} + +int zmk_split_position_released(uint8_t position) { + WRITE_BIT(position_state[position / 8], position % 8, false); + return send_position_state(); +} + +static int split_serial_service_init(const struct device *dev) { + split_serial_async_init(NULL); + k_work_q_start(&service_work_q, service_q_stack, K_THREAD_STACK_SIZEOF(service_q_stack), + CONFIG_ZMK_SPLIT_SERIAL_THREAD_PRIORITY); + + return 0; +} + +SYS_INIT(split_serial_service_init, APPLICATION, CONFIG_ZMK_USB_INIT_PRIORITY); diff --git a/app/src/split_listener.c b/app/src/split_listener.c index 01cd89d912f..1e13d25cc17 100644 --- a/app/src/split_listener.c +++ b/app/src/split_listener.c @@ -8,7 +8,7 @@ #include #include -#include +#include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -22,13 +22,13 @@ int split_listener(const zmk_event_t *eh) { const struct zmk_position_state_changed *ev = as_zmk_position_state_changed(eh); if (ev != NULL) { if (ev->state) { - return zmk_split_bt_position_pressed(ev->position); + return zmk_split_position_pressed(ev->position); } else { - return zmk_split_bt_position_released(ev->position); + return zmk_split_position_released(ev->position); } } return ZMK_EV_EVENT_BUBBLE; } ZMK_LISTENER(split_listener, split_listener); -ZMK_SUBSCRIPTION(split_listener, zmk_position_state_changed); \ No newline at end of file +ZMK_SUBSCRIPTION(split_listener, zmk_position_state_changed); diff --git a/app/west.yml b/app/west.yml index cab02a5a7f7..79a8ea7ec79 100644 --- a/app/west.yml +++ b/app/west.yml @@ -4,12 +4,14 @@ manifest: url-base: https://github.com/zephyrproject-rtos - name: zmkfirmware url-base: https://github.com/zmkfirmware + - name: megamind4089 + url-base: https://github.com/megamind4089 - name: microsoft url-base: https://github.com/microsoft projects: - name: zephyr - remote: zmkfirmware - revision: v2.5.0+zmk-fixes + remote: megamind4089 + revision: v2.5.0+zmk-fixes-stm32f4 clone-depth: 1 import: # TODO: Rename once upstream offers option like `exclude` or `denylist`