fix(split): Use queue/work for peripheral events.
* Avoid corruption by using work to process peripheral key position events on the main work thread, like local kscan events are. * Fixes #221
This commit is contained in:
parent
969e5568af
commit
4aa78a6f8d
2 changed files with 40 additions and 11 deletions
10
app/Kconfig
10
app/Kconfig
|
@ -94,11 +94,19 @@ config ZMK_SPLIT_BLE
|
||||||
|
|
||||||
if ZMK_SPLIT_BLE
|
if ZMK_SPLIT_BLE
|
||||||
|
|
||||||
config ZMK_SPLIT_BLE_ROLE_CENTRAL
|
menuconfig ZMK_SPLIT_BLE_ROLE_CENTRAL
|
||||||
bool "Central"
|
bool "Central"
|
||||||
select BT_CENTRAL
|
select BT_CENTRAL
|
||||||
select BT_GATT_CLIENT
|
select BT_GATT_CLIENT
|
||||||
|
|
||||||
|
if ZMK_SPLIT_BLE_ROLE_CENTRAL
|
||||||
|
|
||||||
|
config ZMK_SPLIT_BLE_CENTRAL_POSITION_QUEUE_SIZE
|
||||||
|
int "Max number of key position state events to queue when received from peripherals"
|
||||||
|
default 5
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
if !ZMK_SPLIT_BLE_ROLE_CENTRAL
|
if !ZMK_SPLIT_BLE_ROLE_CENTRAL
|
||||||
|
|
||||||
config ZMK_USB
|
config ZMK_USB
|
||||||
|
|
|
@ -33,9 +33,32 @@ static struct bt_uuid_128 uuid = BT_UUID_INIT_128(ZMK_SPLIT_BT_SERVICE_UUID);
|
||||||
static struct bt_gatt_discover_params discover_params;
|
static struct bt_gatt_discover_params discover_params;
|
||||||
static struct bt_gatt_subscribe_params subscribe_params;
|
static struct bt_gatt_subscribe_params subscribe_params;
|
||||||
|
|
||||||
static uint8_t split_central_notify_func(struct bt_conn *conn,
|
struct zmk_split_peripheral_event {
|
||||||
struct bt_gatt_subscribe_params *params, const void *data,
|
uint32_t position;
|
||||||
uint16_t length) {
|
uint32_t state;
|
||||||
|
int32_t timestamp;
|
||||||
|
};
|
||||||
|
|
||||||
|
K_MSGQ_DEFINE(peripheral_event_msgq, sizeof(struct zmk_split_peripheral_event),
|
||||||
|
CONFIG_ZMK_SPLIT_BLE_CENTRAL_POSITION_QUEUE_SIZE, 4);
|
||||||
|
|
||||||
|
void peripheral_event_work_callback(struct k_work *work) {
|
||||||
|
struct zmk_split_peripheral_event ev;
|
||||||
|
while (k_msgq_get(&peripheral_event_msgq, &ev, K_NO_WAIT) == 0) {
|
||||||
|
struct position_state_changed *pos_ev = new_position_state_changed();
|
||||||
|
pos_ev->position = ev.position;
|
||||||
|
pos_ev->state = ev.state;
|
||||||
|
pos_ev->timestamp = ev.timestamp;
|
||||||
|
|
||||||
|
LOG_DBG("Trigger key position state change for %d", ev.position);
|
||||||
|
ZMK_EVENT_RAISE(pos_ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
K_WORK_DEFINE(peripheral_event_work, peripheral_event_work_callback);
|
||||||
|
|
||||||
|
static uint8_t split_central_notify_func(struct bt_conn *conn, struct bt_gatt_subscribe_params *params,
|
||||||
|
const void *data, uint16_t length) {
|
||||||
static uint8_t position_state[POSITION_STATE_DATA_LEN];
|
static uint8_t position_state[POSITION_STATE_DATA_LEN];
|
||||||
|
|
||||||
uint8_t changed_positions[POSITION_STATE_DATA_LEN];
|
uint8_t changed_positions[POSITION_STATE_DATA_LEN];
|
||||||
|
@ -58,13 +81,11 @@ static uint8_t split_central_notify_func(struct bt_conn *conn,
|
||||||
if (changed_positions[i] & BIT(j)) {
|
if (changed_positions[i] & BIT(j)) {
|
||||||
uint32_t position = (i * 8) + j;
|
uint32_t position = (i * 8) + j;
|
||||||
bool pressed = position_state[i] & BIT(j);
|
bool pressed = position_state[i] & BIT(j);
|
||||||
struct position_state_changed *pos_ev = new_position_state_changed();
|
struct zmk_split_peripheral_event ev = {
|
||||||
pos_ev->position = position;
|
.position = position, .state = pressed, .timestamp = k_uptime_get()};
|
||||||
pos_ev->state = pressed;
|
|
||||||
pos_ev->timestamp = k_uptime_get();
|
|
||||||
|
|
||||||
LOG_DBG("Trigger key position state change for %d", position);
|
k_msgq_put(&peripheral_event_msgq, &ev, K_NO_WAIT);
|
||||||
ZMK_EVENT_RAISE(pos_ev);
|
k_work_submit(&peripheral_event_work);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue