chore: clang-format the codebase.
* Use the LLVM style * Override indent width (8) and column limit (100) * Fixes #142.
This commit is contained in:
parent
296a89ce63
commit
191a2d755a
51 changed files with 2171 additions and 2547 deletions
|
@ -56,8 +56,7 @@ static const struct pin_config pinconf[] = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pinmux_stm32_init(struct device *port)
|
static int pinmux_stm32_init(struct device *port) {
|
||||||
{
|
|
||||||
ARG_UNUSED(port);
|
ARG_UNUSED(port);
|
||||||
|
|
||||||
stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf));
|
stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf));
|
||||||
|
@ -65,5 +64,4 @@ static int pinmux_stm32_init(struct device *port)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1,
|
SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY);
|
||||||
CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY);
|
|
|
@ -11,8 +11,7 @@
|
||||||
#include <sys/sys_io.h>
|
#include <sys/sys_io.h>
|
||||||
#include <devicetree.h>
|
#include <devicetree.h>
|
||||||
|
|
||||||
static int pinmux_nrfmicro_init(struct device *port)
|
static int pinmux_nrfmicro_init(struct device *port) {
|
||||||
{
|
|
||||||
ARG_UNUSED(port);
|
ARG_UNUSED(port);
|
||||||
|
|
||||||
struct device *p1 = device_get_binding("GPIO_1");
|
struct device *p1 = device_get_binding("GPIO_1");
|
||||||
|
|
|
@ -56,8 +56,7 @@ static const struct pin_config pinconf[] = {
|
||||||
#endif /* CONFIG_CAN_1 */
|
#endif /* CONFIG_CAN_1 */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pinmux_stm32_init(struct device *port)
|
static int pinmux_stm32_init(struct device *port) {
|
||||||
{
|
|
||||||
ARG_UNUSED(port);
|
ARG_UNUSED(port);
|
||||||
|
|
||||||
stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf));
|
stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf));
|
||||||
|
@ -65,5 +64,4 @@ static int pinmux_stm32_init(struct device *port)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1,
|
SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY);
|
||||||
CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY);
|
|
||||||
|
|
|
@ -56,8 +56,7 @@ static const struct pin_config pinconf[] = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pinmux_stm32_init(struct device *port)
|
static int pinmux_stm32_init(struct device *port) {
|
||||||
{
|
|
||||||
ARG_UNUSED(port);
|
ARG_UNUSED(port);
|
||||||
|
|
||||||
stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf));
|
stm32_setup_pins(pinconf, ARRAY_SIZE(pinconf));
|
||||||
|
@ -65,5 +64,4 @@ static int pinmux_stm32_init(struct device *port)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1,
|
SYS_INIT(pinmux_stm32_init, PRE_KERNEL_1, CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY);
|
||||||
CONFIG_PINMUX_STM32_DEVICE_INITIALIZATION_PRIORITY);
|
|
||||||
|
|
|
@ -18,16 +18,15 @@
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(EC11, CONFIG_SENSOR_LOG_LEVEL);
|
LOG_MODULE_REGISTER(EC11, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
|
|
||||||
static int ec11_get_ab_state(struct device *dev)
|
static int ec11_get_ab_state(struct device *dev) {
|
||||||
{
|
|
||||||
struct ec11_data *drv_data = dev->driver_data;
|
struct ec11_data *drv_data = dev->driver_data;
|
||||||
const struct ec11_config *drv_cfg = dev->config_info;
|
const struct ec11_config *drv_cfg = dev->config_info;
|
||||||
|
|
||||||
return (gpio_pin_get(drv_data->a, drv_cfg->a_pin) << 1) | gpio_pin_get(drv_data->b, drv_cfg->b_pin);
|
return (gpio_pin_get(drv_data->a, drv_cfg->a_pin) << 1) |
|
||||||
|
gpio_pin_get(drv_data->b, drv_cfg->b_pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ec11_sample_fetch(struct device *dev, enum sensor_channel chan)
|
static int ec11_sample_fetch(struct device *dev, enum sensor_channel chan) {
|
||||||
{
|
|
||||||
struct ec11_data *drv_data = dev->driver_data;
|
struct ec11_data *drv_data = dev->driver_data;
|
||||||
const struct ec11_config *drv_cfg = dev->config_info;
|
const struct ec11_config *drv_cfg = dev->config_info;
|
||||||
u8_t val;
|
u8_t val;
|
||||||
|
@ -39,11 +38,17 @@ static int ec11_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||||
|
|
||||||
LOG_DBG("prev: %d, new: %d", drv_data->ab_state, val);
|
LOG_DBG("prev: %d, new: %d", drv_data->ab_state, val);
|
||||||
|
|
||||||
switch(val | (drv_data->ab_state << 2)) {
|
switch (val | (drv_data->ab_state << 2)) {
|
||||||
case 0b0010: case 0b0100: case 0b1101: case 0b1011:
|
case 0b0010:
|
||||||
|
case 0b0100:
|
||||||
|
case 0b1101:
|
||||||
|
case 0b1011:
|
||||||
delta = -1;
|
delta = -1;
|
||||||
break;
|
break;
|
||||||
case 0b0001: case 0b0111: case 0b1110: case 0b1000:
|
case 0b0001:
|
||||||
|
case 0b0111:
|
||||||
|
case 0b1110:
|
||||||
|
case 0b1000:
|
||||||
delta = 1;
|
delta = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -63,10 +68,8 @@ static int ec11_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ec11_channel_get(struct device *dev,
|
static int ec11_channel_get(struct device *dev, enum sensor_channel chan,
|
||||||
enum sensor_channel chan,
|
struct sensor_value *val) {
|
||||||
struct sensor_value *val)
|
|
||||||
{
|
|
||||||
struct ec11_data *drv_data = dev->driver_data;
|
struct ec11_data *drv_data = dev->driver_data;
|
||||||
|
|
||||||
if (chan != SENSOR_CHAN_ROTATION) {
|
if (chan != SENSOR_CHAN_ROTATION) {
|
||||||
|
@ -87,12 +90,12 @@ static const struct sensor_driver_api ec11_driver_api = {
|
||||||
.channel_get = ec11_channel_get,
|
.channel_get = ec11_channel_get,
|
||||||
};
|
};
|
||||||
|
|
||||||
int ec11_init(struct device *dev)
|
int ec11_init(struct device *dev) {
|
||||||
{
|
|
||||||
struct ec11_data *drv_data = dev->driver_data;
|
struct ec11_data *drv_data = dev->driver_data;
|
||||||
const struct ec11_config *drv_cfg = dev->config_info;
|
const struct ec11_config *drv_cfg = dev->config_info;
|
||||||
|
|
||||||
LOG_DBG("A: %s %d B: %s %d resolution %d", drv_cfg->a_label, drv_cfg->a_pin, drv_cfg->b_label, drv_cfg->b_pin, drv_cfg->resolution);
|
LOG_DBG("A: %s %d B: %s %d resolution %d", drv_cfg->a_label, drv_cfg->a_pin, drv_cfg->b_label,
|
||||||
|
drv_cfg->b_pin, drv_cfg->resolution);
|
||||||
|
|
||||||
drv_data->a = device_get_binding(drv_cfg->a_label);
|
drv_data->a = device_get_binding(drv_cfg->a_label);
|
||||||
if (drv_data->a == NULL) {
|
if (drv_data->a == NULL) {
|
||||||
|
@ -106,22 +109,16 @@ int ec11_init(struct device *dev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpio_pin_configure(drv_data->a, drv_cfg->a_pin,
|
if (gpio_pin_configure(drv_data->a, drv_cfg->a_pin, drv_cfg->a_flags | GPIO_INPUT)) {
|
||||||
drv_cfg->a_flags
|
|
||||||
| GPIO_INPUT)) {
|
|
||||||
LOG_DBG("Failed to configure A pin");
|
LOG_DBG("Failed to configure A pin");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpio_pin_configure(drv_data->b, drv_cfg->b_pin,
|
if (gpio_pin_configure(drv_data->b, drv_cfg->b_pin, drv_cfg->b_flags | GPIO_INPUT)) {
|
||||||
drv_cfg->b_flags
|
|
||||||
| GPIO_INPUT)) {
|
|
||||||
LOG_DBG("Failed to configure B pin");
|
LOG_DBG("Failed to configure B pin");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_EC11_TRIGGER
|
#ifdef CONFIG_EC11_TRIGGER
|
||||||
if (ec11_init_interrupt(dev) < 0) {
|
if (ec11_init_interrupt(dev) < 0) {
|
||||||
LOG_DBG("Failed to initialize interrupt!");
|
LOG_DBG("Failed to initialize interrupt!");
|
||||||
|
@ -145,9 +142,7 @@ int ec11_init(struct device *dev)
|
||||||
.b_flags = DT_INST_GPIO_FLAGS(n, b_gpios), \
|
.b_flags = DT_INST_GPIO_FLAGS(n, b_gpios), \
|
||||||
COND_CODE_0(DT_INST_NODE_HAS_PROP(n, resolution), (1), (DT_INST_PROP(n, resolution))), \
|
COND_CODE_0(DT_INST_NODE_HAS_PROP(n, resolution), (1), (DT_INST_PROP(n, resolution))), \
|
||||||
}; \
|
}; \
|
||||||
DEVICE_AND_API_INIT(ec11, DT_INST_LABEL(n), ec11_init, \
|
DEVICE_AND_API_INIT(ec11, DT_INST_LABEL(n), ec11_init, &ec11_data_##n, &ec11_cfg_##n, \
|
||||||
&ec11_data_##n, \
|
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &ec11_driver_api);
|
||||||
&ec11_cfg_##n, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
|
|
||||||
&ec11_driver_api);
|
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(EC11_INST)
|
DT_INST_FOREACH_STATUS_OKAY(EC11_INST)
|
|
@ -51,8 +51,7 @@ struct ec11_data {
|
||||||
|
|
||||||
#ifdef CONFIG_EC11_TRIGGER
|
#ifdef CONFIG_EC11_TRIGGER
|
||||||
|
|
||||||
int ec11_trigger_set(struct device *dev,
|
int ec11_trigger_set(struct device *dev, const struct sensor_trigger *trig,
|
||||||
const struct sensor_trigger *trig,
|
|
||||||
sensor_trigger_handler_t handler);
|
sensor_trigger_handler_t handler);
|
||||||
|
|
||||||
int ec11_init_interrupt(struct device *dev);
|
int ec11_init_interrupt(struct device *dev);
|
||||||
|
|
|
@ -19,36 +19,25 @@ extern struct ec11_data ec11_driver;
|
||||||
#include <logging/log.h>
|
#include <logging/log.h>
|
||||||
LOG_MODULE_DECLARE(EC11, CONFIG_SENSOR_LOG_LEVEL);
|
LOG_MODULE_DECLARE(EC11, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
|
|
||||||
static inline void setup_int(struct device *dev,
|
static inline void setup_int(struct device *dev, bool enable) {
|
||||||
bool enable)
|
|
||||||
{
|
|
||||||
struct ec11_data *data = dev->driver_data;
|
struct ec11_data *data = dev->driver_data;
|
||||||
const struct ec11_config *cfg = dev->config_info;
|
const struct ec11_config *cfg = dev->config_info;
|
||||||
|
|
||||||
LOG_DBG("enabled %s", (enable ? "true" : "false"));
|
LOG_DBG("enabled %s", (enable ? "true" : "false"));
|
||||||
|
|
||||||
if (gpio_pin_interrupt_configure(data->a,
|
if (gpio_pin_interrupt_configure(data->a, cfg->a_pin,
|
||||||
cfg->a_pin,
|
enable ? GPIO_INT_EDGE_BOTH : GPIO_INT_DISABLE)) {
|
||||||
enable
|
|
||||||
? GPIO_INT_EDGE_BOTH
|
|
||||||
: GPIO_INT_DISABLE)) {
|
|
||||||
LOG_WRN("Unable to set A pin GPIO interrupt");
|
LOG_WRN("Unable to set A pin GPIO interrupt");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpio_pin_interrupt_configure(data->b,
|
if (gpio_pin_interrupt_configure(data->b, cfg->b_pin,
|
||||||
cfg->b_pin,
|
enable ? GPIO_INT_EDGE_BOTH : GPIO_INT_DISABLE)) {
|
||||||
enable
|
|
||||||
? GPIO_INT_EDGE_BOTH
|
|
||||||
: GPIO_INT_DISABLE)) {
|
|
||||||
LOG_WRN("Unable to set A pin GPIO interrupt");
|
LOG_WRN("Unable to set A pin GPIO interrupt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ec11_a_gpio_callback(struct device *dev,
|
static void ec11_a_gpio_callback(struct device *dev, struct gpio_callback *cb, u32_t pins) {
|
||||||
struct gpio_callback *cb, u32_t pins)
|
struct ec11_data *drv_data = CONTAINER_OF(cb, struct ec11_data, a_gpio_cb);
|
||||||
{
|
|
||||||
struct ec11_data *drv_data =
|
|
||||||
CONTAINER_OF(cb, struct ec11_data, a_gpio_cb);
|
|
||||||
|
|
||||||
LOG_DBG("");
|
LOG_DBG("");
|
||||||
|
|
||||||
|
@ -61,11 +50,8 @@ static void ec11_a_gpio_callback(struct device *dev,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ec11_b_gpio_callback(struct device *dev,
|
static void ec11_b_gpio_callback(struct device *dev, struct gpio_callback *cb, u32_t pins) {
|
||||||
struct gpio_callback *cb, u32_t pins)
|
struct ec11_data *drv_data = CONTAINER_OF(cb, struct ec11_data, b_gpio_cb);
|
||||||
{
|
|
||||||
struct ec11_data *drv_data =
|
|
||||||
CONTAINER_OF(cb, struct ec11_data, b_gpio_cb);
|
|
||||||
|
|
||||||
LOG_DBG("");
|
LOG_DBG("");
|
||||||
|
|
||||||
|
@ -78,8 +64,7 @@ static void ec11_b_gpio_callback(struct device *dev,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ec11_thread_cb(void *arg)
|
static void ec11_thread_cb(void *arg) {
|
||||||
{
|
|
||||||
struct device *dev = arg;
|
struct device *dev = arg;
|
||||||
struct ec11_data *drv_data = dev->driver_data;
|
struct ec11_data *drv_data = dev->driver_data;
|
||||||
|
|
||||||
|
@ -89,8 +74,7 @@ static void ec11_thread_cb(void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_EC11_TRIGGER_OWN_THREAD
|
#ifdef CONFIG_EC11_TRIGGER_OWN_THREAD
|
||||||
static void ec11_thread(int dev_ptr, int unused)
|
static void ec11_thread(int dev_ptr, int unused) {
|
||||||
{
|
|
||||||
struct device *dev = INT_TO_POINTER(dev_ptr);
|
struct device *dev = INT_TO_POINTER(dev_ptr);
|
||||||
struct ec11_data *drv_data = dev->driver_data;
|
struct ec11_data *drv_data = dev->driver_data;
|
||||||
|
|
||||||
|
@ -104,10 +88,8 @@ static void ec11_thread(int dev_ptr, int unused)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_EC11_TRIGGER_GLOBAL_THREAD
|
#ifdef CONFIG_EC11_TRIGGER_GLOBAL_THREAD
|
||||||
static void ec11_work_cb(struct k_work *work)
|
static void ec11_work_cb(struct k_work *work) {
|
||||||
{
|
struct ec11_data *drv_data = CONTAINER_OF(work, struct ec11_data, work);
|
||||||
struct ec11_data *drv_data =
|
|
||||||
CONTAINER_OF(work, struct ec11_data, work);
|
|
||||||
|
|
||||||
LOG_DBG("");
|
LOG_DBG("");
|
||||||
|
|
||||||
|
@ -115,10 +97,8 @@ static void ec11_work_cb(struct k_work *work)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int ec11_trigger_set(struct device *dev,
|
int ec11_trigger_set(struct device *dev, const struct sensor_trigger *trig,
|
||||||
const struct sensor_trigger *trig,
|
sensor_trigger_handler_t handler) {
|
||||||
sensor_trigger_handler_t handler)
|
|
||||||
{
|
|
||||||
struct ec11_data *drv_data = dev->driver_data;
|
struct ec11_data *drv_data = dev->driver_data;
|
||||||
|
|
||||||
setup_int(dev, false);
|
setup_int(dev, false);
|
||||||
|
@ -133,27 +113,21 @@ int ec11_trigger_set(struct device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ec11_init_interrupt(struct device *dev)
|
int ec11_init_interrupt(struct device *dev) {
|
||||||
{
|
|
||||||
struct ec11_data *drv_data = dev->driver_data;
|
struct ec11_data *drv_data = dev->driver_data;
|
||||||
const struct ec11_config *drv_cfg = dev->config_info;
|
const struct ec11_config *drv_cfg = dev->config_info;
|
||||||
|
|
||||||
drv_data->dev = dev;
|
drv_data->dev = dev;
|
||||||
/* setup gpio interrupt */
|
/* setup gpio interrupt */
|
||||||
|
|
||||||
|
gpio_init_callback(&drv_data->a_gpio_cb, ec11_a_gpio_callback, BIT(drv_cfg->a_pin));
|
||||||
gpio_init_callback(&drv_data->a_gpio_cb,
|
|
||||||
ec11_a_gpio_callback,
|
|
||||||
BIT(drv_cfg->a_pin));
|
|
||||||
|
|
||||||
if (gpio_add_callback(drv_data->a, &drv_data->a_gpio_cb) < 0) {
|
if (gpio_add_callback(drv_data->a, &drv_data->a_gpio_cb) < 0) {
|
||||||
LOG_DBG("Failed to set A callback!");
|
LOG_DBG("Failed to set A callback!");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpio_init_callback(&drv_data->b_gpio_cb,
|
gpio_init_callback(&drv_data->b_gpio_cb, ec11_b_gpio_callback, BIT(drv_cfg->b_pin));
|
||||||
ec11_b_gpio_callback,
|
|
||||||
BIT(drv_cfg->b_pin));
|
|
||||||
|
|
||||||
if (gpio_add_callback(drv_data->b, &drv_data->b_gpio_cb) < 0) {
|
if (gpio_add_callback(drv_data->b, &drv_data->b_gpio_cb) < 0) {
|
||||||
LOG_DBG("Failed to set B callback!");
|
LOG_DBG("Failed to set B callback!");
|
||||||
|
@ -163,11 +137,9 @@ int ec11_init_interrupt(struct device *dev)
|
||||||
#if defined(CONFIG_EC11_TRIGGER_OWN_THREAD)
|
#if defined(CONFIG_EC11_TRIGGER_OWN_THREAD)
|
||||||
k_sem_init(&drv_data->gpio_sem, 0, UINT_MAX);
|
k_sem_init(&drv_data->gpio_sem, 0, UINT_MAX);
|
||||||
|
|
||||||
k_thread_create(&drv_data->thread, drv_data->thread_stack,
|
k_thread_create(&drv_data->thread, drv_data->thread_stack, CONFIG_EC11_THREAD_STACK_SIZE,
|
||||||
CONFIG_EC11_THREAD_STACK_SIZE,
|
(k_thread_entry_t)ec11_thread, dev, 0, NULL,
|
||||||
(k_thread_entry_t)ec11_thread, dev,
|
K_PRIO_COOP(CONFIG_EC11_THREAD_PRIORITY), 0, K_NO_WAIT);
|
||||||
0, NULL, K_PRIO_COOP(CONFIG_EC11_THREAD_PRIORITY),
|
|
||||||
0, K_NO_WAIT);
|
|
||||||
#elif defined(CONFIG_EC11_TRIGGER_GLOBAL_THREAD)
|
#elif defined(CONFIG_EC11_TRIGGER_GLOBAL_THREAD)
|
||||||
k_work_init(&drv_data->work, ec11_work_cb);
|
k_work_init(&drv_data->work, ec11_work_cb);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,8 +15,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||||
|
|
||||||
struct kscan_gpio_item_config
|
struct kscan_gpio_item_config {
|
||||||
{
|
|
||||||
char *label;
|
char *label;
|
||||||
gpio_pin_t pin;
|
gpio_pin_t pin;
|
||||||
gpio_flags_t flags;
|
gpio_flags_t flags;
|
||||||
|
@ -27,15 +26,13 @@ union work_reference {
|
||||||
struct k_work direct;
|
struct k_work direct;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct kscan_gpio_config
|
struct kscan_gpio_config {
|
||||||
{
|
|
||||||
u8_t num_of_inputs;
|
u8_t num_of_inputs;
|
||||||
u8_t debounce_period;
|
u8_t debounce_period;
|
||||||
struct kscan_gpio_item_config inputs[];
|
struct kscan_gpio_item_config inputs[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct kscan_gpio_data
|
struct kscan_gpio_data {
|
||||||
{
|
|
||||||
#if defined(CONFIG_ZMK_KSCAN_GPIO_POLLING)
|
#if defined(CONFIG_ZMK_KSCAN_GPIO_POLLING)
|
||||||
struct k_timer poll_timer;
|
struct k_timer poll_timer;
|
||||||
#endif /* defined(CONFIG_ZMK_KSCAN_GPIO_POLLING) */
|
#endif /* defined(CONFIG_ZMK_KSCAN_GPIO_POLLING) */
|
||||||
|
@ -46,42 +43,36 @@ struct kscan_gpio_data
|
||||||
struct device *inputs[];
|
struct device *inputs[];
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct device **kscan_gpio_input_devices(struct device *dev)
|
static struct device **kscan_gpio_input_devices(struct device *dev) {
|
||||||
{
|
|
||||||
struct kscan_gpio_data *data = dev->driver_data;
|
struct kscan_gpio_data *data = dev->driver_data;
|
||||||
return data->inputs;
|
return data->inputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct kscan_gpio_item_config *kscan_gpio_input_configs(struct device *dev)
|
static const struct kscan_gpio_item_config *kscan_gpio_input_configs(struct device *dev) {
|
||||||
{
|
|
||||||
const struct kscan_gpio_config *cfg = dev->config_info;
|
const struct kscan_gpio_config *cfg = dev->config_info;
|
||||||
return cfg->inputs;
|
return cfg->inputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(CONFIG_ZMK_KSCAN_GPIO_POLLING)
|
#if !defined(CONFIG_ZMK_KSCAN_GPIO_POLLING)
|
||||||
|
|
||||||
struct kscan_gpio_irq_callback
|
struct kscan_gpio_irq_callback {
|
||||||
{
|
|
||||||
union work_reference *work;
|
union work_reference *work;
|
||||||
u8_t debounce_period;
|
u8_t debounce_period;
|
||||||
struct gpio_callback callback;
|
struct gpio_callback callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int kscan_gpio_config_interrupts(struct device *dev, gpio_flags_t flags)
|
static int kscan_gpio_config_interrupts(struct device *dev, gpio_flags_t flags) {
|
||||||
{
|
|
||||||
const struct kscan_gpio_config *cfg = dev->config_info;
|
const struct kscan_gpio_config *cfg = dev->config_info;
|
||||||
struct device **devices = kscan_gpio_input_devices(dev);
|
struct device **devices = kscan_gpio_input_devices(dev);
|
||||||
const struct kscan_gpio_item_config *configs = kscan_gpio_input_configs(dev);
|
const struct kscan_gpio_item_config *configs = kscan_gpio_input_configs(dev);
|
||||||
|
|
||||||
for (int i = 0; i < cfg->num_of_inputs; i++)
|
for (int i = 0; i < cfg->num_of_inputs; i++) {
|
||||||
{
|
|
||||||
struct device *dev = devices[i];
|
struct device *dev = devices[i];
|
||||||
const struct kscan_gpio_item_config *cfg = &configs[i];
|
const struct kscan_gpio_item_config *cfg = &configs[i];
|
||||||
|
|
||||||
int err = gpio_pin_interrupt_configure(dev, cfg->pin, flags);
|
int err = gpio_pin_interrupt_configure(dev, cfg->pin, flags);
|
||||||
|
|
||||||
if (err)
|
if (err) {
|
||||||
{
|
|
||||||
LOG_ERR("Unable to enable matrix GPIO interrupt");
|
LOG_ERR("Unable to enable matrix GPIO interrupt");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -90,20 +81,15 @@ static int kscan_gpio_config_interrupts(struct device *dev, gpio_flags_t flags)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kscan_gpio_direct_enable(struct device *dev)
|
static int kscan_gpio_direct_enable(struct device *dev) {
|
||||||
{
|
return kscan_gpio_config_interrupts(dev, GPIO_INT_DEBOUNCE | GPIO_INT_EDGE_BOTH);
|
||||||
return kscan_gpio_config_interrupts(dev,
|
|
||||||
GPIO_INT_DEBOUNCE | GPIO_INT_EDGE_BOTH);
|
|
||||||
}
|
}
|
||||||
static int kscan_gpio_direct_disable(struct device *dev)
|
static int kscan_gpio_direct_disable(struct device *dev) {
|
||||||
{
|
return kscan_gpio_config_interrupts(dev, GPIO_INT_DISABLE);
|
||||||
return kscan_gpio_config_interrupts(dev,
|
|
||||||
GPIO_INT_DISABLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kscan_gpio_irq_callback_handler(struct device *dev,
|
static void kscan_gpio_irq_callback_handler(struct device *dev, struct gpio_callback *cb,
|
||||||
struct gpio_callback *cb, gpio_port_pins_t pin)
|
gpio_port_pins_t pin) {
|
||||||
{
|
|
||||||
struct kscan_gpio_irq_callback *data =
|
struct kscan_gpio_irq_callback *data =
|
||||||
CONTAINER_OF(cb, struct kscan_gpio_irq_callback, callback);
|
CONTAINER_OF(cb, struct kscan_gpio_irq_callback, callback);
|
||||||
|
|
||||||
|
@ -117,22 +103,18 @@ static void kscan_gpio_irq_callback_handler(struct device *dev,
|
||||||
|
|
||||||
#else /* !defined(CONFIG_ZMK_KSCAN_GPIO_POLLING) */
|
#else /* !defined(CONFIG_ZMK_KSCAN_GPIO_POLLING) */
|
||||||
|
|
||||||
static void kscan_gpio_timer_handler(struct k_timer *timer)
|
static void kscan_gpio_timer_handler(struct k_timer *timer) {
|
||||||
{
|
struct kscan_gpio_data *data = CONTAINER_OF(timer, struct kscan_gpio_data, poll_timer);
|
||||||
struct kscan_gpio_data *data =
|
|
||||||
CONTAINER_OF(timer, struct kscan_gpio_data, poll_timer);
|
|
||||||
|
|
||||||
k_work_submit(&data->work.direct);
|
k_work_submit(&data->work.direct);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kscan_gpio_direct_enable(struct device *dev)
|
static int kscan_gpio_direct_enable(struct device *dev) {
|
||||||
{
|
|
||||||
struct kscan_gpio_data *data = dev->driver_data;
|
struct kscan_gpio_data *data = dev->driver_data;
|
||||||
k_timer_start(&data->poll_timer, K_MSEC(10), K_MSEC(10));
|
k_timer_start(&data->poll_timer, K_MSEC(10), K_MSEC(10));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int kscan_gpio_direct_disable(struct device *dev)
|
static int kscan_gpio_direct_disable(struct device *dev) {
|
||||||
{
|
|
||||||
struct kscan_gpio_data *data = dev->driver_data;
|
struct kscan_gpio_data *data = dev->driver_data;
|
||||||
k_timer_stop(&data->poll_timer);
|
k_timer_stop(&data->poll_timer);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -140,36 +122,29 @@ static int kscan_gpio_direct_disable(struct device *dev)
|
||||||
|
|
||||||
#endif /* defined(CONFIG_ZMK_KSCAN_GPIO_POLLING) */
|
#endif /* defined(CONFIG_ZMK_KSCAN_GPIO_POLLING) */
|
||||||
|
|
||||||
static int kscan_gpio_direct_configure(struct device *dev, kscan_callback_t callback)
|
static int kscan_gpio_direct_configure(struct device *dev, kscan_callback_t callback) {
|
||||||
{
|
|
||||||
struct kscan_gpio_data *data = dev->driver_data;
|
struct kscan_gpio_data *data = dev->driver_data;
|
||||||
if (!callback)
|
if (!callback) {
|
||||||
{
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
data->callback = callback;
|
data->callback = callback;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kscan_gpio_read(struct device *dev)
|
static int kscan_gpio_read(struct device *dev) {
|
||||||
{
|
|
||||||
struct kscan_gpio_data *data = dev->driver_data;
|
struct kscan_gpio_data *data = dev->driver_data;
|
||||||
const struct kscan_gpio_config *cfg = dev->config_info;
|
const struct kscan_gpio_config *cfg = dev->config_info;
|
||||||
u32_t read_state = data->pin_state;
|
u32_t read_state = data->pin_state;
|
||||||
for (int i = 0; i < cfg->num_of_inputs; i++)
|
for (int i = 0; i < cfg->num_of_inputs; i++) {
|
||||||
{
|
|
||||||
struct device *in_dev = kscan_gpio_input_devices(dev)[i];
|
struct device *in_dev = kscan_gpio_input_devices(dev)[i];
|
||||||
const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs(dev)[i];
|
const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs(dev)[i];
|
||||||
WRITE_BIT(read_state, i, gpio_pin_get(in_dev, in_cfg->pin) > 0);
|
WRITE_BIT(read_state, i, gpio_pin_get(in_dev, in_cfg->pin) > 0);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < cfg->num_of_inputs; i++)
|
for (int i = 0; i < cfg->num_of_inputs; i++) {
|
||||||
{
|
|
||||||
bool prev_pressed = BIT(i) & data->pin_state;
|
bool prev_pressed = BIT(i) & data->pin_state;
|
||||||
bool pressed = BIT(i) & read_state;
|
bool pressed = BIT(i) & read_state;
|
||||||
if (pressed != prev_pressed)
|
if (pressed != prev_pressed) {
|
||||||
{
|
LOG_DBG("Sending event at %d,%d state %s", 0, i, (pressed ? "on" : "off"));
|
||||||
LOG_DBG("Sending event at %d,%d state %s",
|
|
||||||
0, i, (pressed ? "on" : "off"));
|
|
||||||
WRITE_BIT(data->pin_state, i, pressed);
|
WRITE_BIT(data->pin_state, i, pressed);
|
||||||
data->callback(dev, 0, i, pressed);
|
data->callback(dev, 0, i, pressed);
|
||||||
}
|
}
|
||||||
|
@ -177,10 +152,8 @@ static int kscan_gpio_read(struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kscan_gpio_work_handler(struct k_work *work)
|
static void kscan_gpio_work_handler(struct k_work *work) {
|
||||||
{
|
struct kscan_gpio_data *data = CONTAINER_OF(work, struct kscan_gpio_data, work);
|
||||||
struct kscan_gpio_data *data =
|
|
||||||
CONTAINER_OF(work, struct kscan_gpio_data, work);
|
|
||||||
kscan_gpio_read(data->dev);
|
kscan_gpio_read(data->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +163,7 @@ static const struct kscan_driver_api gpio_driver_api = {
|
||||||
.disable_callback = kscan_gpio_direct_disable,
|
.disable_callback = kscan_gpio_direct_disable,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define KSCAN_DIRECT_INPUT_ITEM(i,n) \
|
#define KSCAN_DIRECT_INPUT_ITEM(i, n) \
|
||||||
{ \
|
{ \
|
||||||
.label = DT_INST_GPIO_LABEL_BY_IDX(n, input_gpios, i), \
|
.label = DT_INST_GPIO_LABEL_BY_IDX(n, input_gpios, i), \
|
||||||
.pin = DT_INST_GPIO_PIN_BY_IDX(n, input_gpios, i), \
|
.pin = DT_INST_GPIO_PIN_BY_IDX(n, input_gpios, i), \
|
||||||
|
@ -200,47 +173,43 @@ static const struct kscan_driver_api gpio_driver_api = {
|
||||||
#define INST_INPUT_LEN(n) DT_INST_PROP_LEN(n, input_gpios)
|
#define INST_INPUT_LEN(n) DT_INST_PROP_LEN(n, input_gpios)
|
||||||
|
|
||||||
#define GPIO_INST_INIT(n) \
|
#define GPIO_INST_INIT(n) \
|
||||||
COND_CODE_0(CONFIG_ZMK_KSCAN_GPIO_POLLING, (static struct kscan_gpio_irq_callback \
|
COND_CODE_0(CONFIG_ZMK_KSCAN_GPIO_POLLING, \
|
||||||
irq_callbacks_##n[INST_INPUT_LEN(n)];), ()) \
|
(static struct kscan_gpio_irq_callback irq_callbacks_##n[INST_INPUT_LEN(n)];), ()) \
|
||||||
static struct kscan_gpio_data kscan_gpio_data_##n = { \
|
static struct kscan_gpio_data kscan_gpio_data_##n = { \
|
||||||
.inputs = { [INST_INPUT_LEN(n)-1] = NULL } \
|
.inputs = {[INST_INPUT_LEN(n) - 1] = NULL}}; \
|
||||||
}; \
|
static int kscan_gpio_init_##n(struct device *dev) { \
|
||||||
static int kscan_gpio_init_##n(struct device *dev) \
|
|
||||||
{ \
|
|
||||||
struct kscan_gpio_data *data = dev->driver_data; \
|
struct kscan_gpio_data *data = dev->driver_data; \
|
||||||
const struct kscan_gpio_config *cfg = dev->config_info; \
|
const struct kscan_gpio_config *cfg = dev->config_info; \
|
||||||
int err; \
|
int err; \
|
||||||
struct device **input_devices = kscan_gpio_input_devices(dev); \
|
struct device **input_devices = kscan_gpio_input_devices(dev); \
|
||||||
for (int i = 0; i < cfg->num_of_inputs; i++) \
|
for (int i = 0; i < cfg->num_of_inputs; i++) { \
|
||||||
{ \
|
|
||||||
const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs(dev)[i]; \
|
const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs(dev)[i]; \
|
||||||
input_devices[i] = device_get_binding(in_cfg->label); \
|
input_devices[i] = device_get_binding(in_cfg->label); \
|
||||||
if (!input_devices[i]) \
|
if (!input_devices[i]) { \
|
||||||
{ \
|
|
||||||
LOG_ERR("Unable to find input GPIO device"); \
|
LOG_ERR("Unable to find input GPIO device"); \
|
||||||
return -EINVAL; \
|
return -EINVAL; \
|
||||||
} \
|
} \
|
||||||
err = gpio_pin_configure(input_devices[i], in_cfg->pin, GPIO_INPUT | in_cfg->flags); \
|
err = gpio_pin_configure(input_devices[i], in_cfg->pin, GPIO_INPUT | in_cfg->flags); \
|
||||||
if (err) \
|
if (err) { \
|
||||||
{ \
|
|
||||||
LOG_ERR("Unable to configure pin %d on %s for input", in_cfg->pin, in_cfg->label); \
|
LOG_ERR("Unable to configure pin %d on %s for input", in_cfg->pin, in_cfg->label); \
|
||||||
return err; \
|
return err; \
|
||||||
} \
|
} \
|
||||||
COND_CODE_0(CONFIG_ZMK_KSCAN_GPIO_POLLING, \
|
COND_CODE_0( \
|
||||||
( \
|
CONFIG_ZMK_KSCAN_GPIO_POLLING, \
|
||||||
irq_callbacks_##n[i].work = &data->work; \
|
(irq_callbacks_##n[i].work = &data->work; \
|
||||||
irq_callbacks_##n[i].debounce_period = cfg->debounce_period; \
|
irq_callbacks_##n[i].debounce_period = cfg->debounce_period; \
|
||||||
gpio_init_callback(&irq_callbacks_##n[i].callback, kscan_gpio_irq_callback_handler, BIT(in_cfg->pin)); \
|
gpio_init_callback(&irq_callbacks_##n[i].callback, \
|
||||||
|
kscan_gpio_irq_callback_handler, BIT(in_cfg->pin)); \
|
||||||
err = gpio_add_callback(input_devices[i], &irq_callbacks_##n[i].callback); \
|
err = gpio_add_callback(input_devices[i], &irq_callbacks_##n[i].callback); \
|
||||||
if (err) \
|
if (err) { \
|
||||||
{ \
|
|
||||||
LOG_ERR("Error adding the callback to the column device"); \
|
LOG_ERR("Error adding the callback to the column device"); \
|
||||||
return err; \
|
return err; \
|
||||||
} \
|
}), \
|
||||||
), ()) \
|
()) \
|
||||||
} \
|
} \
|
||||||
data->dev = dev; \
|
data->dev = dev; \
|
||||||
COND_CODE_1(CONFIG_ZMK_KSCAN_GPIO_POLLING, (k_timer_init(&data->poll_timer, kscan_gpio_timer_handler, NULL);), ( )) \
|
COND_CODE_1(CONFIG_ZMK_KSCAN_GPIO_POLLING, \
|
||||||
|
(k_timer_init(&data->poll_timer, kscan_gpio_timer_handler, NULL);), ()) \
|
||||||
if (cfg->debounce_period > 0) { \
|
if (cfg->debounce_period > 0) { \
|
||||||
k_delayed_work_init(&data->work.delayed, kscan_gpio_work_handler); \
|
k_delayed_work_init(&data->work.delayed, kscan_gpio_work_handler); \
|
||||||
} else { \
|
} else { \
|
||||||
|
@ -249,14 +218,12 @@ static const struct kscan_driver_api gpio_driver_api = {
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
static const struct kscan_gpio_config kscan_gpio_config_##n = { \
|
static const struct kscan_gpio_config kscan_gpio_config_##n = { \
|
||||||
.inputs = { UTIL_LISTIFY(INST_INPUT_LEN(n), KSCAN_DIRECT_INPUT_ITEM, n) }, \
|
.inputs = {UTIL_LISTIFY(INST_INPUT_LEN(n), KSCAN_DIRECT_INPUT_ITEM, n)}, \
|
||||||
.num_of_inputs = INST_INPUT_LEN(n), \
|
.num_of_inputs = INST_INPUT_LEN(n), \
|
||||||
.debounce_period = DT_INST_PROP(n, debounce_period) \
|
.debounce_period = DT_INST_PROP(n, debounce_period)}; \
|
||||||
}; \
|
|
||||||
DEVICE_AND_API_INIT(kscan_gpio_##n, DT_INST_LABEL(n), kscan_gpio_init_##n, \
|
DEVICE_AND_API_INIT(kscan_gpio_##n, DT_INST_LABEL(n), kscan_gpio_init_##n, \
|
||||||
&kscan_gpio_data_##n, &kscan_gpio_config_##n, \
|
&kscan_gpio_data_##n, &kscan_gpio_config_##n, POST_KERNEL, \
|
||||||
POST_KERNEL, CONFIG_ZMK_KSCAN_INIT_PRIORITY, \
|
CONFIG_ZMK_KSCAN_INIT_PRIORITY, &gpio_driver_api);
|
||||||
&gpio_driver_api);
|
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(GPIO_INST_INIT)
|
DT_INST_FOREACH_STATUS_OKAY(GPIO_INST_INIT)
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,12 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||||
|
|
||||||
struct kscan_gpio_item_config
|
struct kscan_gpio_item_config {
|
||||||
{
|
|
||||||
char *label;
|
char *label;
|
||||||
gpio_pin_t pin;
|
gpio_pin_t pin;
|
||||||
gpio_flags_t flags;
|
gpio_flags_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define _KSCAN_GPIO_ITEM_CFG_INIT(n, prop, idx) \
|
#define _KSCAN_GPIO_ITEM_CFG_INIT(n, prop, idx) \
|
||||||
{ \
|
{ \
|
||||||
.label = DT_INST_GPIO_LABEL_BY_IDX(n, prop, idx), \
|
.label = DT_INST_GPIO_LABEL_BY_IDX(n, prop, idx), \
|
||||||
|
@ -34,18 +32,15 @@ struct kscan_gpio_item_config
|
||||||
#define _KSCAN_GPIO_COL_CFG_INIT(idx, n) _KSCAN_GPIO_ITEM_CFG_INIT(n, col_gpios, idx)
|
#define _KSCAN_GPIO_COL_CFG_INIT(idx, n) _KSCAN_GPIO_ITEM_CFG_INIT(n, col_gpios, idx)
|
||||||
|
|
||||||
static int kscan_gpio_config_interrupts(struct device **devices,
|
static int kscan_gpio_config_interrupts(struct device **devices,
|
||||||
const struct kscan_gpio_item_config *configs,
|
const struct kscan_gpio_item_config *configs, size_t len,
|
||||||
size_t len, gpio_flags_t flags)
|
gpio_flags_t flags) {
|
||||||
{
|
for (int i = 0; i < len; i++) {
|
||||||
for (int i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
struct device *dev = devices[i];
|
struct device *dev = devices[i];
|
||||||
const struct kscan_gpio_item_config *cfg = &configs[i];
|
const struct kscan_gpio_item_config *cfg = &configs[i];
|
||||||
|
|
||||||
int err = gpio_pin_interrupt_configure(dev, cfg->pin, flags);
|
int err = gpio_pin_interrupt_configure(dev, cfg->pin, flags);
|
||||||
|
|
||||||
if (err)
|
if (err) {
|
||||||
{
|
|
||||||
LOG_ERR("Unable to enable matrix GPIO interrupt");
|
LOG_ERR("Unable to enable matrix GPIO interrupt");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -55,24 +50,24 @@ static int kscan_gpio_config_interrupts(struct device **devices,
|
||||||
}
|
}
|
||||||
#define INST_MATRIX_ROWS(n) DT_INST_PROP_LEN(n, row_gpios)
|
#define INST_MATRIX_ROWS(n) DT_INST_PROP_LEN(n, row_gpios)
|
||||||
#define INST_MATRIX_COLS(n) DT_INST_PROP_LEN(n, col_gpios)
|
#define INST_MATRIX_COLS(n) DT_INST_PROP_LEN(n, col_gpios)
|
||||||
#define INST_OUTPUT_LEN(n) COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (INST_MATRIX_ROWS(n)), (INST_MATRIX_COLS(n)))
|
#define INST_OUTPUT_LEN(n) \
|
||||||
#define INST_INPUT_LEN(n) COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (INST_MATRIX_COLS(n)), (INST_MATRIX_ROWS(n)))
|
COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (INST_MATRIX_ROWS(n)), \
|
||||||
|
(INST_MATRIX_COLS(n)))
|
||||||
|
#define INST_INPUT_LEN(n) \
|
||||||
|
COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (INST_MATRIX_COLS(n)), \
|
||||||
|
(INST_MATRIX_ROWS(n)))
|
||||||
|
|
||||||
#define GPIO_INST_INIT(n) \
|
#define GPIO_INST_INIT(n) \
|
||||||
struct kscan_gpio_irq_callback_##n \
|
struct kscan_gpio_irq_callback_##n { \
|
||||||
{ \
|
|
||||||
struct COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work), (k_delayed_work)) * work; \
|
struct COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work), (k_delayed_work)) * work; \
|
||||||
struct gpio_callback callback; \
|
struct gpio_callback callback; \
|
||||||
}; \
|
}; \
|
||||||
static struct kscan_gpio_irq_callback_##n \
|
static struct kscan_gpio_irq_callback_##n irq_callbacks_##n[INST_INPUT_LEN(n)]; \
|
||||||
irq_callbacks_##n[INST_INPUT_LEN(n)]; \
|
struct kscan_gpio_config_##n { \
|
||||||
struct kscan_gpio_config_##n \
|
|
||||||
{ \
|
|
||||||
struct kscan_gpio_item_config rows[INST_MATRIX_ROWS(n)]; \
|
struct kscan_gpio_item_config rows[INST_MATRIX_ROWS(n)]; \
|
||||||
struct kscan_gpio_item_config cols[INST_MATRIX_COLS(n)]; \
|
struct kscan_gpio_item_config cols[INST_MATRIX_COLS(n)]; \
|
||||||
}; \
|
}; \
|
||||||
struct kscan_gpio_data_##n \
|
struct kscan_gpio_data_##n { \
|
||||||
{ \
|
|
||||||
kscan_callback_t callback; \
|
kscan_callback_t callback; \
|
||||||
struct COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work), (k_delayed_work)) work; \
|
struct COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work), (k_delayed_work)) work; \
|
||||||
bool matrix_state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)]; \
|
bool matrix_state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)]; \
|
||||||
|
@ -80,51 +75,53 @@ static int kscan_gpio_config_interrupts(struct device **devices,
|
||||||
struct device *cols[INST_MATRIX_COLS(n)]; \
|
struct device *cols[INST_MATRIX_COLS(n)]; \
|
||||||
struct device *dev; \
|
struct device *dev; \
|
||||||
}; \
|
}; \
|
||||||
static struct device **kscan_gpio_input_devices_##n(struct device *dev) \
|
static struct device **kscan_gpio_input_devices_##n(struct device *dev) { \
|
||||||
{ \
|
|
||||||
struct kscan_gpio_data_##n *data = dev->driver_data; \
|
struct kscan_gpio_data_##n *data = dev->driver_data; \
|
||||||
return (COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (data->cols), (data->rows))); \
|
return (COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (data->cols), \
|
||||||
|
(data->rows))); \
|
||||||
} \
|
} \
|
||||||
static const struct kscan_gpio_item_config *kscan_gpio_input_configs_##n(struct device *dev) \
|
static const struct kscan_gpio_item_config *kscan_gpio_input_configs_##n(struct device *dev) { \
|
||||||
{ \
|
|
||||||
const struct kscan_gpio_config_##n *cfg = dev->config_info; \
|
const struct kscan_gpio_config_##n *cfg = dev->config_info; \
|
||||||
return ((COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (cfg->cols), (cfg->rows)))); \
|
return (( \
|
||||||
|
COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (cfg->cols), (cfg->rows)))); \
|
||||||
} \
|
} \
|
||||||
static struct device **kscan_gpio_output_devices_##n(struct device *dev) \
|
static struct device **kscan_gpio_output_devices_##n(struct device *dev) { \
|
||||||
{ \
|
|
||||||
struct kscan_gpio_data_##n *data = dev->driver_data; \
|
struct kscan_gpio_data_##n *data = dev->driver_data; \
|
||||||
return (COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (data->rows), (data->cols))); \
|
return (COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (data->rows), \
|
||||||
|
(data->cols))); \
|
||||||
} \
|
} \
|
||||||
static const struct kscan_gpio_item_config *kscan_gpio_output_configs_##n(struct device *dev) \
|
static const struct kscan_gpio_item_config *kscan_gpio_output_configs_##n( \
|
||||||
{ \
|
struct device *dev) { \
|
||||||
const struct kscan_gpio_config_##n *cfg = dev->config_info; \
|
const struct kscan_gpio_config_##n *cfg = dev->config_info; \
|
||||||
return (COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (cfg->rows), (cfg->cols))); \
|
return ( \
|
||||||
|
COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (cfg->rows), (cfg->cols))); \
|
||||||
} \
|
} \
|
||||||
static int kscan_gpio_enable_interrupts_##n(struct device *dev) \
|
static int kscan_gpio_enable_interrupts_##n(struct device *dev) { \
|
||||||
{ \
|
return kscan_gpio_config_interrupts(kscan_gpio_input_devices_##n(dev), \
|
||||||
return kscan_gpio_config_interrupts(kscan_gpio_input_devices_##n(dev), kscan_gpio_input_configs_##n(dev), INST_INPUT_LEN(n), \
|
kscan_gpio_input_configs_##n(dev), INST_INPUT_LEN(n), \
|
||||||
GPIO_INT_DEBOUNCE | GPIO_INT_EDGE_BOTH); \
|
GPIO_INT_DEBOUNCE | GPIO_INT_EDGE_BOTH); \
|
||||||
} \
|
} \
|
||||||
static int kscan_gpio_disable_interrupts_##n(struct device *dev) \
|
static int kscan_gpio_disable_interrupts_##n(struct device *dev) { \
|
||||||
{ \
|
return kscan_gpio_config_interrupts(kscan_gpio_input_devices_##n(dev), \
|
||||||
return kscan_gpio_config_interrupts(kscan_gpio_input_devices_##n(dev), kscan_gpio_input_configs_##n(dev), INST_INPUT_LEN(n), \
|
kscan_gpio_input_configs_##n(dev), INST_INPUT_LEN(n), \
|
||||||
GPIO_INT_DISABLE); \
|
GPIO_INT_DISABLE); \
|
||||||
} \
|
} \
|
||||||
static void kscan_gpio_set_output_state_##n(struct device *dev, int value) \
|
static void kscan_gpio_set_output_state_##n(struct device *dev, int value) { \
|
||||||
{ \
|
for (int i = 0; i < INST_OUTPUT_LEN(n); i++) { \
|
||||||
for (int i = 0; i < INST_OUTPUT_LEN(n); i++) \
|
|
||||||
{ \
|
|
||||||
struct device *in_dev = kscan_gpio_output_devices_##n(dev)[i]; \
|
struct device *in_dev = kscan_gpio_output_devices_##n(dev)[i]; \
|
||||||
const struct kscan_gpio_item_config *cfg = &kscan_gpio_output_configs_##n(dev)[i]; \
|
const struct kscan_gpio_item_config *cfg = &kscan_gpio_output_configs_##n(dev)[i]; \
|
||||||
gpio_pin_set(in_dev, cfg->pin, value); \
|
gpio_pin_set(in_dev, cfg->pin, value); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
static void kscan_gpio_set_matrix_state_##n(bool state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)], u32_t input_index, u32_t output_index, bool value) \
|
static void kscan_gpio_set_matrix_state_##n( \
|
||||||
{ \
|
bool state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)], u32_t input_index, \
|
||||||
state[COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (output_index), (input_index))][COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (input_index), (output_index))] = value; \
|
u32_t output_index, bool value) { \
|
||||||
|
state[COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (output_index), \
|
||||||
|
(input_index))] \
|
||||||
|
[COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (input_index), \
|
||||||
|
(output_index))] = value; \
|
||||||
} \
|
} \
|
||||||
static int kscan_gpio_read_##n(struct device *dev) \
|
static int kscan_gpio_read_##n(struct device *dev) { \
|
||||||
{ \
|
|
||||||
bool submit_follow_up_read = false; \
|
bool submit_follow_up_read = false; \
|
||||||
struct kscan_gpio_data_##n *data = dev->driver_data; \
|
struct kscan_gpio_data_##n *data = dev->driver_data; \
|
||||||
static bool read_state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)]; \
|
static bool read_state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)]; \
|
||||||
|
@ -133,16 +130,16 @@ static int kscan_gpio_config_interrupts(struct device **devices,
|
||||||
/* to get pressed state for each matrix cell. */ \
|
/* to get pressed state for each matrix cell. */ \
|
||||||
kscan_gpio_disable_interrupts_##n(dev); \
|
kscan_gpio_disable_interrupts_##n(dev); \
|
||||||
kscan_gpio_set_output_state_##n(dev, 0); \
|
kscan_gpio_set_output_state_##n(dev, 0); \
|
||||||
for (int o = 0; o < INST_OUTPUT_LEN(n); o++) \
|
for (int o = 0; o < INST_OUTPUT_LEN(n); o++) { \
|
||||||
{ \
|
|
||||||
struct device *out_dev = kscan_gpio_output_devices_##n(dev)[o]; \
|
struct device *out_dev = kscan_gpio_output_devices_##n(dev)[o]; \
|
||||||
const struct kscan_gpio_item_config *out_cfg = &kscan_gpio_output_configs_##n(dev)[o]; \
|
const struct kscan_gpio_item_config *out_cfg = &kscan_gpio_output_configs_##n(dev)[o]; \
|
||||||
gpio_pin_set(out_dev, out_cfg->pin, 1); \
|
gpio_pin_set(out_dev, out_cfg->pin, 1); \
|
||||||
for (int i = 0; i < INST_INPUT_LEN(n); i++) \
|
for (int i = 0; i < INST_INPUT_LEN(n); i++) { \
|
||||||
{ \
|
|
||||||
struct device *in_dev = kscan_gpio_input_devices_##n(dev)[i]; \
|
struct device *in_dev = kscan_gpio_input_devices_##n(dev)[i]; \
|
||||||
const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs_##n(dev)[i]; \
|
const struct kscan_gpio_item_config *in_cfg = \
|
||||||
kscan_gpio_set_matrix_state_##n(read_state, i, o, gpio_pin_get(in_dev, in_cfg->pin) > 0); \
|
&kscan_gpio_input_configs_##n(dev)[i]; \
|
||||||
|
kscan_gpio_set_matrix_state_##n(read_state, i, o, \
|
||||||
|
gpio_pin_get(in_dev, in_cfg->pin) > 0); \
|
||||||
} \
|
} \
|
||||||
gpio_pin_set(out_dev, out_cfg->pin, 0); \
|
gpio_pin_set(out_dev, out_cfg->pin, 0); \
|
||||||
} \
|
} \
|
||||||
|
@ -150,116 +147,102 @@ static int kscan_gpio_config_interrupts(struct device **devices,
|
||||||
/* so we can trigger interrupts again for future press/release */ \
|
/* so we can trigger interrupts again for future press/release */ \
|
||||||
kscan_gpio_set_output_state_##n(dev, 1); \
|
kscan_gpio_set_output_state_##n(dev, 1); \
|
||||||
kscan_gpio_enable_interrupts_##n(dev); \
|
kscan_gpio_enable_interrupts_##n(dev); \
|
||||||
for (int r = 0; r < INST_MATRIX_ROWS(n); r++) \
|
for (int r = 0; r < INST_MATRIX_ROWS(n); r++) { \
|
||||||
{ \
|
for (int c = 0; c < INST_MATRIX_COLS(n); c++) { \
|
||||||
for (int c = 0; c < INST_MATRIX_COLS(n); c++) \
|
|
||||||
{ \
|
|
||||||
bool pressed = read_state[r][c]; \
|
bool pressed = read_state[r][c]; \
|
||||||
/* Follow up reads needed because further interrupts won't fire on already tripped input GPIO pins */ \
|
/* Follow up reads needed because further interrupts won't fire on already tripped \
|
||||||
|
* input GPIO pins */ \
|
||||||
submit_follow_up_read = (submit_follow_up_read || pressed); \
|
submit_follow_up_read = (submit_follow_up_read || pressed); \
|
||||||
if (pressed != data->matrix_state[r][c]) \
|
if (pressed != data->matrix_state[r][c]) { \
|
||||||
{ \
|
LOG_DBG("Sending event at %d,%d state %s", r, c, (pressed ? "on" : "off")); \
|
||||||
LOG_DBG("Sending event at %d,%d state %s", \
|
|
||||||
r, c, (pressed ? "on" : "off")); \
|
|
||||||
data->matrix_state[r][c] = pressed; \
|
data->matrix_state[r][c] = pressed; \
|
||||||
data->callback(dev, r, c, pressed); \
|
data->callback(dev, r, c, pressed); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
if (submit_follow_up_read) { \
|
if (submit_follow_up_read) { \
|
||||||
COND_CODE_0(DT_INST_PROP(n, debounce_period), \
|
COND_CODE_0(DT_INST_PROP(n, debounce_period), ({ k_work_submit(&data->work); }), ({ \
|
||||||
({ k_work_submit(&data->work); }), \
|
|
||||||
({ \
|
|
||||||
k_delayed_work_cancel(&data->work); \
|
k_delayed_work_cancel(&data->work); \
|
||||||
k_delayed_work_submit(&data->work, K_MSEC(5)); })) \
|
k_delayed_work_submit(&data->work, K_MSEC(5)); \
|
||||||
|
})) \
|
||||||
} \
|
} \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
static void kscan_gpio_work_handler_##n(struct k_work *work) \
|
static void kscan_gpio_work_handler_##n(struct k_work *work) { \
|
||||||
{ \
|
struct kscan_gpio_data_##n *data = CONTAINER_OF(work, struct kscan_gpio_data_##n, work); \
|
||||||
struct kscan_gpio_data_##n *data = \
|
|
||||||
CONTAINER_OF(work, struct kscan_gpio_data_##n, work); \
|
|
||||||
kscan_gpio_read_##n(data->dev); \
|
kscan_gpio_read_##n(data->dev); \
|
||||||
} \
|
} \
|
||||||
static void kscan_gpio_irq_callback_handler_##n(struct device *dev, \
|
static void kscan_gpio_irq_callback_handler_##n(struct device *dev, struct gpio_callback *cb, \
|
||||||
struct gpio_callback *cb, gpio_port_pins_t pin) \
|
gpio_port_pins_t pin) { \
|
||||||
{ \
|
|
||||||
struct kscan_gpio_irq_callback_##n *data = \
|
struct kscan_gpio_irq_callback_##n *data = \
|
||||||
CONTAINER_OF(cb, struct kscan_gpio_irq_callback_##n, callback); \
|
CONTAINER_OF(cb, struct kscan_gpio_irq_callback_##n, callback); \
|
||||||
COND_CODE_0(DT_INST_PROP(n, debounce_period), \
|
COND_CODE_0(DT_INST_PROP(n, debounce_period), ({ k_work_submit(data->work); }), ({ \
|
||||||
({ k_work_submit(data->work); }), \
|
|
||||||
({ \
|
|
||||||
k_delayed_work_cancel(data->work); \
|
k_delayed_work_cancel(data->work); \
|
||||||
k_delayed_work_submit(data->work, K_MSEC(DT_INST_PROP(n, debounce_period))); })) \
|
k_delayed_work_submit(data->work, \
|
||||||
|
K_MSEC(DT_INST_PROP(n, debounce_period))); \
|
||||||
|
})) \
|
||||||
} \
|
} \
|
||||||
static struct kscan_gpio_data_##n kscan_gpio_data_##n = { \
|
static struct kscan_gpio_data_##n kscan_gpio_data_##n = { \
|
||||||
.rows = { [INST_MATRIX_ROWS(n)-1] = NULL}, \
|
.rows = {[INST_MATRIX_ROWS(n) - 1] = NULL}, .cols = {[INST_MATRIX_COLS(n) - 1] = NULL}}; \
|
||||||
.cols = { [INST_MATRIX_COLS(n)-1] = NULL }\
|
static int kscan_gpio_configure_##n(struct device *dev, kscan_callback_t callback) { \
|
||||||
}; \
|
|
||||||
static int kscan_gpio_configure_##n(struct device *dev, kscan_callback_t callback) \
|
|
||||||
{ \
|
|
||||||
struct kscan_gpio_data_##n *data = dev->driver_data; \
|
struct kscan_gpio_data_##n *data = dev->driver_data; \
|
||||||
if (!callback) \
|
if (!callback) { \
|
||||||
{ \
|
|
||||||
return -EINVAL; \
|
return -EINVAL; \
|
||||||
} \
|
} \
|
||||||
data->callback = callback; \
|
data->callback = callback; \
|
||||||
return 0; \
|
return 0; \
|
||||||
}; \
|
}; \
|
||||||
static int kscan_gpio_enable_##n(struct device *dev) \
|
static int kscan_gpio_enable_##n(struct device *dev) { \
|
||||||
{ \
|
|
||||||
int err = kscan_gpio_enable_interrupts_##n(dev); \
|
int err = kscan_gpio_enable_interrupts_##n(dev); \
|
||||||
if (err) { return err; } \
|
if (err) { \
|
||||||
|
return err; \
|
||||||
|
} \
|
||||||
return kscan_gpio_read_##n(dev); \
|
return kscan_gpio_read_##n(dev); \
|
||||||
}; \
|
}; \
|
||||||
static int kscan_gpio_init_##n(struct device *dev) \
|
static int kscan_gpio_init_##n(struct device *dev) { \
|
||||||
{ \
|
|
||||||
struct kscan_gpio_data_##n *data = dev->driver_data; \
|
struct kscan_gpio_data_##n *data = dev->driver_data; \
|
||||||
int err; \
|
int err; \
|
||||||
struct device **input_devices = kscan_gpio_input_devices_##n(dev); \
|
struct device **input_devices = kscan_gpio_input_devices_##n(dev); \
|
||||||
for (int i = 0; i < INST_INPUT_LEN(n); i++) \
|
for (int i = 0; i < INST_INPUT_LEN(n); i++) { \
|
||||||
{ \
|
|
||||||
const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs_##n(dev)[i]; \
|
const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs_##n(dev)[i]; \
|
||||||
input_devices[i] = device_get_binding(in_cfg->label); \
|
input_devices[i] = device_get_binding(in_cfg->label); \
|
||||||
if (!input_devices[i]) \
|
if (!input_devices[i]) { \
|
||||||
{ \
|
|
||||||
LOG_ERR("Unable to find input GPIO device"); \
|
LOG_ERR("Unable to find input GPIO device"); \
|
||||||
return -EINVAL; \
|
return -EINVAL; \
|
||||||
} \
|
} \
|
||||||
err = gpio_pin_configure(input_devices[i], in_cfg->pin, GPIO_INPUT | in_cfg->flags); \
|
err = gpio_pin_configure(input_devices[i], in_cfg->pin, GPIO_INPUT | in_cfg->flags); \
|
||||||
if (err) \
|
if (err) { \
|
||||||
{ \
|
|
||||||
LOG_ERR("Unable to configure pin %d on %s for input", in_cfg->pin, in_cfg->label); \
|
LOG_ERR("Unable to configure pin %d on %s for input", in_cfg->pin, in_cfg->label); \
|
||||||
return err; \
|
return err; \
|
||||||
} \
|
} \
|
||||||
irq_callbacks_##n[i].work = &data->work; \
|
irq_callbacks_##n[i].work = &data->work; \
|
||||||
gpio_init_callback(&irq_callbacks_##n[i].callback, kscan_gpio_irq_callback_handler_##n, BIT(in_cfg->pin)); \
|
gpio_init_callback(&irq_callbacks_##n[i].callback, \
|
||||||
|
kscan_gpio_irq_callback_handler_##n, BIT(in_cfg->pin)); \
|
||||||
err = gpio_add_callback(input_devices[i], &irq_callbacks_##n[i].callback); \
|
err = gpio_add_callback(input_devices[i], &irq_callbacks_##n[i].callback); \
|
||||||
if (err) \
|
if (err) { \
|
||||||
{ \
|
|
||||||
LOG_ERR("Error adding the callback to the column device"); \
|
LOG_ERR("Error adding the callback to the column device"); \
|
||||||
return err; \
|
return err; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
struct device **output_devices = kscan_gpio_output_devices_##n(dev); \
|
struct device **output_devices = kscan_gpio_output_devices_##n(dev); \
|
||||||
for (int o = 0; o < INST_OUTPUT_LEN(n); o++) \
|
for (int o = 0; o < INST_OUTPUT_LEN(n); o++) { \
|
||||||
{ \
|
|
||||||
const struct kscan_gpio_item_config *out_cfg = &kscan_gpio_output_configs_##n(dev)[o]; \
|
const struct kscan_gpio_item_config *out_cfg = &kscan_gpio_output_configs_##n(dev)[o]; \
|
||||||
output_devices[o] = device_get_binding(out_cfg->label); \
|
output_devices[o] = device_get_binding(out_cfg->label); \
|
||||||
if (!output_devices[o]) \
|
if (!output_devices[o]) { \
|
||||||
{ \
|
|
||||||
LOG_ERR("Unable to find output GPIO device"); \
|
LOG_ERR("Unable to find output GPIO device"); \
|
||||||
return -EINVAL; \
|
return -EINVAL; \
|
||||||
} \
|
} \
|
||||||
err = gpio_pin_configure(output_devices[o], out_cfg->pin, GPIO_OUTPUT_ACTIVE | out_cfg->flags); \
|
err = gpio_pin_configure(output_devices[o], out_cfg->pin, \
|
||||||
if (err) \
|
GPIO_OUTPUT_ACTIVE | out_cfg->flags); \
|
||||||
{ \
|
if (err) { \
|
||||||
LOG_ERR("Unable to configure pin %d on %s for output", out_cfg->pin, out_cfg->label); \
|
LOG_ERR("Unable to configure pin %d on %s for output", out_cfg->pin, \
|
||||||
|
out_cfg->label); \
|
||||||
return err; \
|
return err; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
data->dev = dev; \
|
data->dev = dev; \
|
||||||
(COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work_init), (k_delayed_work_init)))(&data->work, kscan_gpio_work_handler_##n); \
|
(COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work_init), (k_delayed_work_init)))( \
|
||||||
|
&data->work, kscan_gpio_work_handler_##n); \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
static const struct kscan_driver_api gpio_driver_api_##n = { \
|
static const struct kscan_driver_api gpio_driver_api_##n = { \
|
||||||
|
@ -268,13 +251,12 @@ static int kscan_gpio_config_interrupts(struct device **devices,
|
||||||
.disable_callback = kscan_gpio_disable_interrupts_##n, \
|
.disable_callback = kscan_gpio_disable_interrupts_##n, \
|
||||||
}; \
|
}; \
|
||||||
static const struct kscan_gpio_config_##n kscan_gpio_config_##n = { \
|
static const struct kscan_gpio_config_##n kscan_gpio_config_##n = { \
|
||||||
.rows = { UTIL_LISTIFY(INST_MATRIX_ROWS(n), _KSCAN_GPIO_ROW_CFG_INIT, n) }, \
|
.rows = {UTIL_LISTIFY(INST_MATRIX_ROWS(n), _KSCAN_GPIO_ROW_CFG_INIT, n)}, \
|
||||||
.cols = { UTIL_LISTIFY(INST_MATRIX_COLS(n), _KSCAN_GPIO_COL_CFG_INIT, n) }, \
|
.cols = {UTIL_LISTIFY(INST_MATRIX_COLS(n), _KSCAN_GPIO_COL_CFG_INIT, n)}, \
|
||||||
}; \
|
}; \
|
||||||
DEVICE_AND_API_INIT(kscan_gpio_##n, DT_INST_LABEL(n), kscan_gpio_init_##n, \
|
DEVICE_AND_API_INIT(kscan_gpio_##n, DT_INST_LABEL(n), kscan_gpio_init_##n, \
|
||||||
&kscan_gpio_data_##n, &kscan_gpio_config_##n, \
|
&kscan_gpio_data_##n, &kscan_gpio_config_##n, APPLICATION, \
|
||||||
APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY, \
|
CONFIG_APPLICATION_INIT_PRIORITY, &gpio_driver_api_##n);
|
||||||
&gpio_driver_api_##n);
|
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(GPIO_INST_INIT)
|
DT_INST_FOREACH_STATUS_OKAY(GPIO_INST_INIT)
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,10 @@
|
||||||
* (Internal use only.)
|
* (Internal use only.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef int (*behavior_keymap_binding_callback_t)(struct device *dev, u32_t position, u32_t param1, u32_t param2);
|
typedef int (*behavior_keymap_binding_callback_t)(struct device *dev, u32_t position, u32_t param1,
|
||||||
typedef int (*behavior_sensor_keymap_binding_callback_t)(struct device *dev, struct device *sensor, u32_t param1, u32_t param2);
|
u32_t param2);
|
||||||
|
typedef int (*behavior_sensor_keymap_binding_callback_t)(struct device *dev, struct device *sensor,
|
||||||
|
u32_t param1, u32_t param2);
|
||||||
|
|
||||||
__subsystem struct behavior_driver_api {
|
__subsystem struct behavior_driver_api {
|
||||||
behavior_keymap_binding_callback_t binding_pressed;
|
behavior_keymap_binding_callback_t binding_pressed;
|
||||||
|
@ -31,7 +33,6 @@ __subsystem struct behavior_driver_api {
|
||||||
* @endcond
|
* @endcond
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handle the keymap binding being pressed
|
* @brief Handle the keymap binding being pressed
|
||||||
* @param dev Pointer to the device structure for the driver instance.
|
* @param dev Pointer to the device structure for the driver instance.
|
||||||
|
@ -41,12 +42,12 @@ __subsystem struct behavior_driver_api {
|
||||||
* @retval 0 If successful.
|
* @retval 0 If successful.
|
||||||
* @retval Negative errno code if failure.
|
* @retval Negative errno code if failure.
|
||||||
*/
|
*/
|
||||||
__syscall int behavior_keymap_binding_pressed(struct device *dev, u32_t position, u32_t param1, u32_t param2);
|
__syscall int behavior_keymap_binding_pressed(struct device *dev, u32_t position, u32_t param1,
|
||||||
|
u32_t param2);
|
||||||
|
|
||||||
static inline int z_impl_behavior_keymap_binding_pressed(struct device *dev, u32_t position, u32_t param1, u32_t param2)
|
static inline int z_impl_behavior_keymap_binding_pressed(struct device *dev, u32_t position,
|
||||||
{
|
u32_t param1, u32_t param2) {
|
||||||
const struct behavior_driver_api *api =
|
const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->driver_api;
|
||||||
(const struct behavior_driver_api *)dev->driver_api;
|
|
||||||
|
|
||||||
if (api->binding_pressed == NULL) {
|
if (api->binding_pressed == NULL) {
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
@ -63,12 +64,12 @@ static inline int z_impl_behavior_keymap_binding_pressed(struct device *dev, u32
|
||||||
* @retval 0 If successful.
|
* @retval 0 If successful.
|
||||||
* @retval Negative errno code if failure.
|
* @retval Negative errno code if failure.
|
||||||
*/
|
*/
|
||||||
__syscall int behavior_keymap_binding_released(struct device *dev, u32_t position, u32_t param1, u32_t param2);
|
__syscall int behavior_keymap_binding_released(struct device *dev, u32_t position, u32_t param1,
|
||||||
|
u32_t param2);
|
||||||
|
|
||||||
static inline int z_impl_behavior_keymap_binding_released(struct device *dev, u32_t position, u32_t param1, u32_t param2)
|
static inline int z_impl_behavior_keymap_binding_released(struct device *dev, u32_t position,
|
||||||
{
|
u32_t param1, u32_t param2) {
|
||||||
const struct behavior_driver_api *api =
|
const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->driver_api;
|
||||||
(const struct behavior_driver_api *)dev->driver_api;
|
|
||||||
|
|
||||||
if (api->binding_released == NULL) {
|
if (api->binding_released == NULL) {
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
@ -87,12 +88,13 @@ static inline int z_impl_behavior_keymap_binding_released(struct device *dev, u3
|
||||||
* @retval 0 If successful.
|
* @retval 0 If successful.
|
||||||
* @retval Negative errno code if failure.
|
* @retval Negative errno code if failure.
|
||||||
*/
|
*/
|
||||||
__syscall int behavior_sensor_keymap_binding_triggered(struct device *dev, struct device *sensor, u32_t param1, u32_t param2);
|
__syscall int behavior_sensor_keymap_binding_triggered(struct device *dev, struct device *sensor,
|
||||||
|
u32_t param1, u32_t param2);
|
||||||
|
|
||||||
static inline int z_impl_behavior_sensor_keymap_binding_triggered(struct device *dev, struct device *sensor, u32_t param1, u32_t param2)
|
static inline int z_impl_behavior_sensor_keymap_binding_triggered(struct device *dev,
|
||||||
{
|
struct device *sensor,
|
||||||
const struct behavior_driver_api *api =
|
u32_t param1, u32_t param2) {
|
||||||
(const struct behavior_driver_api *)dev->driver_api;
|
const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->driver_api;
|
||||||
|
|
||||||
if (api->sensor_binding_triggered == NULL) {
|
if (api->sensor_binding_triggered == NULL) {
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
@ -101,7 +103,6 @@ static inline int z_impl_behavior_sensor_keymap_binding_triggered(struct device
|
||||||
return api->sensor_binding_triggered(dev, sensor, param1, param2);
|
return api->sensor_binding_triggered(dev, sensor, param1, param2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#define RST_WARM 0x00
|
#define RST_WARM 0x00
|
||||||
#define RST_COLD 0x01
|
#define RST_COLD 0x01
|
||||||
|
|
||||||
// AdaFruit nrf52 Bootloader Specific. See https://github.com/adafruit/Adafruit_nRF52_Bootloader/blob/d6b28e66053eea467166f44875e3c7ec741cb471/src/main.c#L107
|
// AdaFruit nrf52 Bootloader Specific. See
|
||||||
|
// https://github.com/adafruit/Adafruit_nRF52_Bootloader/blob/d6b28e66053eea467166f44875e3c7ec741cb471/src/main.c#L107
|
||||||
|
|
||||||
#define RST_UF2 0x57
|
#define RST_UF2 0x57
|
|
@ -10,13 +10,12 @@
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
|
|
||||||
struct zmk_event_type
|
struct zmk_event_type {
|
||||||
{
|
|
||||||
const char *name;
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zmk_event_header {
|
struct zmk_event_header {
|
||||||
const struct zmk_event_type* event;
|
const struct zmk_event_type *event;
|
||||||
u8_t last_listener_index;
|
u8_t last_listener_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,8 +23,7 @@ struct zmk_event_header {
|
||||||
#define ZMK_EV_EVENT_CAPTURED 2
|
#define ZMK_EV_EVENT_CAPTURED 2
|
||||||
|
|
||||||
typedef int (*zmk_listener_callback_t)(const struct zmk_event_header *eh);
|
typedef int (*zmk_listener_callback_t)(const struct zmk_event_header *eh);
|
||||||
struct zmk_listener
|
struct zmk_listener {
|
||||||
{
|
|
||||||
zmk_listener_callback_t callback;
|
zmk_listener_callback_t callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,54 +33,49 @@ struct zmk_event_subscription {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ZMK_EVENT_DECLARE(event_type) \
|
#define ZMK_EVENT_DECLARE(event_type) \
|
||||||
struct event_type* new_##event_type(); \
|
struct event_type *new_##event_type(); \
|
||||||
bool is_##event_type(const struct zmk_event_header *eh); \
|
bool is_##event_type(const struct zmk_event_header *eh); \
|
||||||
struct event_type* cast_##event_type(const struct zmk_event_header *eh); \
|
struct event_type *cast_##event_type(const struct zmk_event_header *eh); \
|
||||||
extern const struct zmk_event_type zmk_event_##event_type;
|
extern const struct zmk_event_type zmk_event_##event_type;
|
||||||
|
|
||||||
#define ZMK_EVENT_IMPL(event_type) \
|
#define ZMK_EVENT_IMPL(event_type) \
|
||||||
const struct zmk_event_type zmk_event_##event_type = { \
|
const struct zmk_event_type zmk_event_##event_type = {.name = STRINGIFY(event_type)}; \
|
||||||
.name = STRINGIFY(event_type) \
|
const struct zmk_event_type *zmk_event_ref_##event_type __used \
|
||||||
}; \
|
__attribute__((__section__(".event_type"))) = &zmk_event_##event_type; \
|
||||||
const struct zmk_event_type* zmk_event_ref_##event_type __used __attribute__((__section__(".event_type"))) = &zmk_event_##event_type; \
|
struct event_type *new_##event_type() { \
|
||||||
struct event_type* new_##event_type() { \
|
struct event_type *ev = (struct event_type *)k_malloc(sizeof(struct event_type)); \
|
||||||
struct event_type* ev = (struct event_type *) k_malloc(sizeof(struct event_type)); \
|
|
||||||
ev->header.event = &zmk_event_##event_type; \
|
ev->header.event = &zmk_event_##event_type; \
|
||||||
return ev; \
|
return ev; \
|
||||||
}; \
|
}; \
|
||||||
bool is_##event_type(const struct zmk_event_header *eh) { \
|
bool is_##event_type(const struct zmk_event_header *eh) { \
|
||||||
return eh->event == &zmk_event_##event_type; \
|
return eh->event == &zmk_event_##event_type; \
|
||||||
}; \
|
}; \
|
||||||
struct event_type* cast_##event_type(const struct zmk_event_header *eh) {\
|
struct event_type *cast_##event_type(const struct zmk_event_header *eh) { \
|
||||||
return (struct event_type*)eh; \
|
return (struct event_type *)eh; \
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ZMK_LISTENER(mod, cb) const struct zmk_listener zmk_listener_##mod = {.callback = cb};
|
||||||
#define ZMK_LISTENER(mod, cb) \
|
|
||||||
const struct zmk_listener zmk_listener_##mod = { \
|
|
||||||
.callback = cb \
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ZMK_SUBSCRIPTION(mod, ev_type) \
|
#define ZMK_SUBSCRIPTION(mod, ev_type) \
|
||||||
const Z_DECL_ALIGN(struct zmk_event_subscription) _CONCAT(_CONCAT(zmk_event_sub_,mod),ev_type) __used __attribute__((__section__(".event_subscription"))) = { \
|
const Z_DECL_ALIGN(struct zmk_event_subscription) \
|
||||||
|
_CONCAT(_CONCAT(zmk_event_sub_, mod), ev_type) __used \
|
||||||
|
__attribute__((__section__(".event_subscription"))) = { \
|
||||||
.event_type = &zmk_event_##ev_type, \
|
.event_type = &zmk_event_##ev_type, \
|
||||||
.listener = &zmk_listener_##mod, \
|
.listener = &zmk_listener_##mod, \
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ZMK_EVENT_RAISE(ev) \
|
#define ZMK_EVENT_RAISE(ev) zmk_event_manager_raise((struct zmk_event_header *)ev);
|
||||||
zmk_event_manager_raise((struct zmk_event_header *)ev);
|
|
||||||
|
|
||||||
#define ZMK_EVENT_RAISE_AFTER(ev, mod) \
|
#define ZMK_EVENT_RAISE_AFTER(ev, mod) \
|
||||||
zmk_event_manager_raise_after((struct zmk_event_header *)ev, &zmk_listener_##mod);
|
zmk_event_manager_raise_after((struct zmk_event_header *)ev, &zmk_listener_##mod);
|
||||||
|
|
||||||
|
|
||||||
#define ZMK_EVENT_RAISE_AT(ev, mod) \
|
#define ZMK_EVENT_RAISE_AT(ev, mod) \
|
||||||
zmk_event_manager_raise_at((struct zmk_event_header *)ev, &zmk_listener_##mod);
|
zmk_event_manager_raise_at((struct zmk_event_header *)ev, &zmk_listener_##mod);
|
||||||
|
|
||||||
#define ZMK_EVENT_RELEASE(ev) \
|
#define ZMK_EVENT_RELEASE(ev) zmk_event_manager_release((struct zmk_event_header *)ev);
|
||||||
zmk_event_manager_release((struct zmk_event_header *)ev);
|
|
||||||
|
|
||||||
int zmk_event_manager_raise(struct zmk_event_header *event);
|
int zmk_event_manager_raise(struct zmk_event_header *event);
|
||||||
int zmk_event_manager_raise_after(struct zmk_event_header *event, const struct zmk_listener *listener);
|
int zmk_event_manager_raise_after(struct zmk_event_header *event,
|
||||||
|
const struct zmk_listener *listener);
|
||||||
int zmk_event_manager_raise_at(struct zmk_event_header *event, const struct zmk_listener *listener);
|
int zmk_event_manager_raise_at(struct zmk_event_header *event, const struct zmk_listener *listener);
|
||||||
int zmk_event_manager_release(struct zmk_event_header *event);
|
int zmk_event_manager_release(struct zmk_event_header *event);
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include <zmk/ble/profile.h>
|
#include <zmk/ble/profile.h>
|
||||||
|
|
||||||
|
|
||||||
struct ble_active_profile_changed {
|
struct ble_active_profile_changed {
|
||||||
struct zmk_event_header header;
|
struct zmk_event_header header;
|
||||||
u8_t index;
|
u8_t index;
|
||||||
|
|
|
@ -18,9 +18,9 @@ struct keycode_state_changed {
|
||||||
|
|
||||||
ZMK_EVENT_DECLARE(keycode_state_changed);
|
ZMK_EVENT_DECLARE(keycode_state_changed);
|
||||||
|
|
||||||
inline struct keycode_state_changed* create_keycode_state_changed(u8_t usage_page, u32_t keycode, bool state)
|
inline struct keycode_state_changed *create_keycode_state_changed(u8_t usage_page, u32_t keycode,
|
||||||
{
|
bool state) {
|
||||||
struct keycode_state_changed* ev = new_keycode_state_changed();
|
struct keycode_state_changed *ev = new_keycode_state_changed();
|
||||||
ev->usage_page = usage_page;
|
ev->usage_page = usage_page;
|
||||||
ev->keycode = keycode;
|
ev->keycode = keycode;
|
||||||
ev->state = state;
|
ev->state = state;
|
||||||
|
|
|
@ -18,9 +18,9 @@ struct modifiers_state_changed {
|
||||||
|
|
||||||
ZMK_EVENT_DECLARE(modifiers_state_changed);
|
ZMK_EVENT_DECLARE(modifiers_state_changed);
|
||||||
|
|
||||||
inline struct modifiers_state_changed* create_modifiers_state_changed(zmk_mod_flags modifiers, bool state)
|
inline struct modifiers_state_changed *create_modifiers_state_changed(zmk_mod_flags modifiers,
|
||||||
{
|
bool state) {
|
||||||
struct modifiers_state_changed* ev = new_modifiers_state_changed();
|
struct modifiers_state_changed *ev = new_modifiers_state_changed();
|
||||||
ev->modifiers = modifiers;
|
ev->modifiers = modifiers;
|
||||||
ev->state = state;
|
ev->state = state;
|
||||||
|
|
||||||
|
|
|
@ -140,25 +140,21 @@ static const u8_t zmk_hid_report_desc[] = {
|
||||||
// u8_t keys[6];
|
// u8_t keys[6];
|
||||||
// } __packed;
|
// } __packed;
|
||||||
|
|
||||||
struct zmk_hid_keypad_report_body
|
struct zmk_hid_keypad_report_body {
|
||||||
{
|
|
||||||
zmk_mod_flags modifiers;
|
zmk_mod_flags modifiers;
|
||||||
u8_t keys[13];
|
u8_t keys[13];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct zmk_hid_keypad_report
|
struct zmk_hid_keypad_report {
|
||||||
{
|
|
||||||
u8_t report_id;
|
u8_t report_id;
|
||||||
struct zmk_hid_keypad_report_body body;
|
struct zmk_hid_keypad_report_body body;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct zmk_hid_consumer_report_body
|
struct zmk_hid_consumer_report_body {
|
||||||
{
|
|
||||||
u8_t keys[6];
|
u8_t keys[6];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct zmk_hid_consumer_report
|
struct zmk_hid_consumer_report {
|
||||||
{
|
|
||||||
u8_t report_id;
|
u8_t report_id;
|
||||||
struct zmk_hid_consumer_report_body body;
|
struct zmk_hid_consumer_report_body body;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
|
@ -14,8 +14,7 @@ typedef u8_t zmk_action;
|
||||||
typedef u8_t zmk_mod;
|
typedef u8_t zmk_mod;
|
||||||
typedef u8_t zmk_mod_flags;
|
typedef u8_t zmk_mod_flags;
|
||||||
|
|
||||||
struct zmk_key_event
|
struct zmk_key_event {
|
||||||
{
|
|
||||||
u32_t column;
|
u32_t column;
|
||||||
u32_t row;
|
u32_t row;
|
||||||
zmk_key key;
|
zmk_key key;
|
||||||
|
|
|
@ -15,20 +15,20 @@
|
||||||
#define ZMK_KEYMAP_TRANSFORM_NODE DT_CHOSEN(zmk_matrix_transform)
|
#define ZMK_KEYMAP_TRANSFORM_NODE DT_CHOSEN(zmk_matrix_transform)
|
||||||
#define ZMK_KEYMAP_LEN DT_PROP_LEN(ZMK_KEYMAP_TRANSFORM_NODE, map)
|
#define ZMK_KEYMAP_LEN DT_PROP_LEN(ZMK_KEYMAP_TRANSFORM_NODE, map)
|
||||||
|
|
||||||
#define ZMK_MATRIX_ROWS DT_PROP(ZMK_KEYMAP_TRANSFORM_NODE,rows)
|
#define ZMK_MATRIX_ROWS DT_PROP(ZMK_KEYMAP_TRANSFORM_NODE, rows)
|
||||||
#define ZMK_MATRIX_COLS DT_PROP(ZMK_KEYMAP_TRANSFORM_NODE,columns)
|
#define ZMK_MATRIX_COLS DT_PROP(ZMK_KEYMAP_TRANSFORM_NODE, columns)
|
||||||
|
|
||||||
#else /* DT_HAS_CHOSEN(zmk_matrix_transform) */
|
#else /* DT_HAS_CHOSEN(zmk_matrix_transform) */
|
||||||
|
|
||||||
#if DT_NODE_HAS_PROP(ZMK_MATRIX_NODE_ID,row_gpios)
|
#if DT_NODE_HAS_PROP(ZMK_MATRIX_NODE_ID, row_gpios)
|
||||||
#define ZMK_MATRIX_ROWS DT_PROP_LEN(ZMK_MATRIX_NODE_ID,row_gpios)
|
#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)
|
#define ZMK_MATRIX_COLS DT_PROP_LEN(ZMK_MATRIX_NODE_ID, col_gpios)
|
||||||
#elif DT_NODE_HAS_PROP(ZMK_MATRIX_NODE_ID,input_gpios)
|
#elif DT_NODE_HAS_PROP(ZMK_MATRIX_NODE_ID, input_gpios)
|
||||||
#define ZMK_MATRIX_ROWS 1
|
#define ZMK_MATRIX_ROWS 1
|
||||||
#define ZMK_MATRIX_COLS DT_PROP_LEN(ZMK_MATRIX_NODE_ID,input_gpios)
|
#define ZMK_MATRIX_COLS DT_PROP_LEN(ZMK_MATRIX_NODE_ID, input_gpios)
|
||||||
#else
|
#else
|
||||||
#define ZMK_MATRIX_ROWS DT_PROP(ZMK_MATRIX_NODE_ID,rows)
|
#define ZMK_MATRIX_ROWS DT_PROP(ZMK_MATRIX_NODE_ID, rows)
|
||||||
#define ZMK_MATRIX_COLS DT_PROP(ZMK_MATRIX_NODE_ID,columns)
|
#define ZMK_MATRIX_COLS DT_PROP(ZMK_MATRIX_NODE_ID, columns)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZMK_KEYMAP_LEN (ZMK_MATRIX_COLS * ZMK_MATRIX_ROWS)
|
#define ZMK_KEYMAP_LEN (ZMK_MATRIX_COLS * ZMK_MATRIX_ROWS)
|
||||||
|
|
|
@ -9,4 +9,3 @@
|
||||||
#define ZMK_BT_SPLIT_UUID(num) BT_UUID_128_ENCODE(num, 0x0096, 0x7107, 0xc967, 0xc5cfb1c2482a)
|
#define ZMK_BT_SPLIT_UUID(num) BT_UUID_128_ENCODE(num, 0x0096, 0x7107, 0xc967, 0xc5cfb1c2482a)
|
||||||
#define ZMK_SPLIT_BT_SERVICE_UUID ZMK_BT_SPLIT_UUID(0x00000000)
|
#define ZMK_SPLIT_BT_SERVICE_UUID ZMK_BT_SPLIT_UUID(0x00000000)
|
||||||
#define ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID ZMK_BT_SPLIT_UUID(0x00000001)
|
#define ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID ZMK_BT_SPLIT_UUID(0x00000001)
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#include <zmk/ble.h>
|
#include <zmk/ble.h>
|
||||||
|
|
||||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t command, u32_t arg)
|
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t command, u32_t arg) {
|
||||||
{
|
switch (command) {
|
||||||
switch (command)
|
|
||||||
{
|
|
||||||
case BT_CLR_CMD:
|
case BT_CLR_CMD:
|
||||||
return zmk_ble_clear_bonds();
|
return zmk_ble_clear_bonds();
|
||||||
case BT_NXT_CMD:
|
case BT_NXT_CMD:
|
||||||
|
@ -37,13 +35,10 @@ static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t c
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int behavior_bt_init(struct device *dev)
|
static int behavior_bt_init(struct device *dev) { return 0; };
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t command, u32_t arg)
|
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t command,
|
||||||
{
|
u32_t arg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,9 +47,5 @@ static const struct behavior_driver_api behavior_bt_driver_api = {
|
||||||
.binding_released = on_keymap_binding_released,
|
.binding_released = on_keymap_binding_released,
|
||||||
};
|
};
|
||||||
|
|
||||||
DEVICE_AND_API_INIT(behavior_bt, DT_INST_LABEL(0),
|
DEVICE_AND_API_INIT(behavior_bt, DT_INST_LABEL(0), behavior_bt_init, NULL, NULL, APPLICATION,
|
||||||
behavior_bt_init,
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_bt_driver_api);
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
|
||||||
&behavior_bt_driver_api);
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
// increase if you have keyboard with more keys.
|
// increase if you have keyboard with more keys.
|
||||||
#define ZMK_BHV_HOLD_TAP_POSITION_NOT_USED 9999
|
#define ZMK_BHV_HOLD_TAP_POSITION_NOT_USED 9999
|
||||||
|
|
||||||
|
|
||||||
enum flavor {
|
enum flavor {
|
||||||
ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED = 0,
|
ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED = 0,
|
||||||
ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED = 1,
|
ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED = 1,
|
||||||
|
@ -71,8 +70,7 @@ struct active_hold_tap active_hold_taps[ZMK_BHV_HOLD_TAP_MAX_HELD] = {};
|
||||||
// We capture most position_state_changed events and some modifiers_state_changed events.
|
// We capture most position_state_changed events and some modifiers_state_changed events.
|
||||||
const struct zmk_event_header *captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {};
|
const struct zmk_event_header *captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {};
|
||||||
|
|
||||||
static int capture_event(const struct zmk_event_header *event)
|
static int capture_event(const struct zmk_event_header *event) {
|
||||||
{
|
|
||||||
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) {
|
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) {
|
||||||
if (captured_events[i] == NULL) {
|
if (captured_events[i] == NULL) {
|
||||||
captured_events[i] = event;
|
captured_events[i] = event;
|
||||||
|
@ -82,8 +80,7 @@ static int capture_event(const struct zmk_event_header *event)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct position_state_changed *find_captured_keydown_event(u32_t position)
|
static struct position_state_changed *find_captured_keydown_event(u32_t position) {
|
||||||
{
|
|
||||||
struct position_state_changed *last_match = NULL;
|
struct position_state_changed *last_match = NULL;
|
||||||
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) {
|
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) {
|
||||||
const struct zmk_event_header *eh = captured_events[i];
|
const struct zmk_event_header *eh = captured_events[i];
|
||||||
|
@ -103,8 +100,7 @@ static struct position_state_changed *find_captured_keydown_event(u32_t position
|
||||||
|
|
||||||
const struct zmk_listener zmk_listener_behavior_hold_tap;
|
const struct zmk_listener zmk_listener_behavior_hold_tap;
|
||||||
|
|
||||||
static void release_captured_events()
|
static void release_captured_events() {
|
||||||
{
|
|
||||||
if (undecided_hold_tap != NULL) {
|
if (undecided_hold_tap != NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -125,8 +121,8 @@ static void release_captured_events()
|
||||||
// [null, k1_down, k1_up, mt2_up, null, ...]
|
// [null, k1_down, k1_up, mt2_up, null, ...]
|
||||||
// ^
|
// ^
|
||||||
// k1_down is captured by the mt2 mod-tap
|
// k1_down is captured by the mt2 mod-tap
|
||||||
// !note that searches for find_captured_keydown_event by the mt2 behavior will stop at the first null encountered
|
// !note that searches for find_captured_keydown_event by the mt2 behavior will stop at the
|
||||||
// [mt1_down, null, k1_up, mt2_up, null, ...]
|
// first null encountered [mt1_down, null, k1_up, mt2_up, null, ...]
|
||||||
// ^
|
// ^
|
||||||
// k1_up event is captured by the new hold-tap:
|
// k1_up event is captured by the new hold-tap:
|
||||||
// [k1_down, k1_up, null, mt2_up, null, ...]
|
// [k1_down, k1_up, null, mt2_up, null, ...]
|
||||||
|
@ -144,18 +140,21 @@ static void release_captured_events()
|
||||||
k_msleep(10);
|
k_msleep(10);
|
||||||
}
|
}
|
||||||
if (is_position_state_changed(captured_event)) {
|
if (is_position_state_changed(captured_event)) {
|
||||||
struct position_state_changed *position_event = cast_position_state_changed(captured_event);
|
struct position_state_changed *position_event =
|
||||||
LOG_DBG("Releasing key position event for position %d %s", position_event->position, (position_event->state ? "pressed" : "released"));
|
cast_position_state_changed(captured_event);
|
||||||
|
LOG_DBG("Releasing key position event for position %d %s", position_event->position,
|
||||||
|
(position_event->state ? "pressed" : "released"));
|
||||||
} else {
|
} else {
|
||||||
struct keycode_state_changed *modifier_event = cast_keycode_state_changed(captured_event);
|
struct keycode_state_changed *modifier_event =
|
||||||
LOG_DBG("Releasing mods changed event 0x%02X %s", modifier_event->keycode, (modifier_event->state ? "pressed" : "released"));
|
cast_keycode_state_changed(captured_event);
|
||||||
|
LOG_DBG("Releasing mods changed event 0x%02X %s", modifier_event->keycode,
|
||||||
|
(modifier_event->state ? "pressed" : "released"));
|
||||||
}
|
}
|
||||||
ZMK_EVENT_RAISE_AT(captured_event, behavior_hold_tap);
|
ZMK_EVENT_RAISE_AT(captured_event, behavior_hold_tap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct active_hold_tap *find_hold_tap(u32_t position)
|
static struct active_hold_tap *find_hold_tap(u32_t position) {
|
||||||
{
|
|
||||||
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) {
|
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) {
|
||||||
if (active_hold_taps[i].position == position) {
|
if (active_hold_taps[i].position == position) {
|
||||||
return &active_hold_taps[i];
|
return &active_hold_taps[i];
|
||||||
|
@ -164,8 +163,8 @@ static struct active_hold_tap *find_hold_tap(u32_t position)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct active_hold_tap *store_hold_tap(u32_t position, u32_t param_hold, u32_t param_tap, const struct behavior_hold_tap_config *config)
|
static struct active_hold_tap *store_hold_tap(u32_t position, u32_t param_hold, u32_t param_tap,
|
||||||
{
|
const struct behavior_hold_tap_config *config) {
|
||||||
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) {
|
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) {
|
||||||
if (active_hold_taps[i].position != ZMK_BHV_HOLD_TAP_POSITION_NOT_USED) {
|
if (active_hold_taps[i].position != ZMK_BHV_HOLD_TAP_POSITION_NOT_USED) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -181,8 +180,7 @@ static struct active_hold_tap *store_hold_tap(u32_t position, u32_t param_hold,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_hold_tap(struct active_hold_tap *hold_tap)
|
static void clear_hold_tap(struct active_hold_tap *hold_tap) {
|
||||||
{
|
|
||||||
hold_tap->position = ZMK_BHV_HOLD_TAP_POSITION_NOT_USED;
|
hold_tap->position = ZMK_BHV_HOLD_TAP_POSITION_NOT_USED;
|
||||||
hold_tap->is_decided = false;
|
hold_tap->is_decided = false;
|
||||||
hold_tap->is_hold = false;
|
hold_tap->is_hold = false;
|
||||||
|
@ -196,8 +194,7 @@ enum decision_moment {
|
||||||
HT_TIMER_EVENT = 3,
|
HT_TIMER_EVENT = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void decide_balanced(struct active_hold_tap *hold_tap, enum decision_moment event)
|
static void decide_balanced(struct active_hold_tap *hold_tap, enum decision_moment event) {
|
||||||
{
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case HT_KEY_UP:
|
case HT_KEY_UP:
|
||||||
hold_tap->is_hold = 0;
|
hold_tap->is_hold = 0;
|
||||||
|
@ -208,12 +205,12 @@ static void decide_balanced(struct active_hold_tap *hold_tap, enum decision_mome
|
||||||
hold_tap->is_hold = 1;
|
hold_tap->is_hold = 1;
|
||||||
hold_tap->is_decided = true;
|
hold_tap->is_decided = true;
|
||||||
break;
|
break;
|
||||||
default: return;
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decide_tap_preferred(struct active_hold_tap *hold_tap, enum decision_moment event)
|
static void decide_tap_preferred(struct active_hold_tap *hold_tap, enum decision_moment event) {
|
||||||
{
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case HT_KEY_UP:
|
case HT_KEY_UP:
|
||||||
hold_tap->is_hold = 0;
|
hold_tap->is_hold = 0;
|
||||||
|
@ -223,12 +220,12 @@ static void decide_tap_preferred(struct active_hold_tap *hold_tap, enum decision
|
||||||
hold_tap->is_hold = 1;
|
hold_tap->is_hold = 1;
|
||||||
hold_tap->is_decided = true;
|
hold_tap->is_decided = true;
|
||||||
break;
|
break;
|
||||||
default: return;
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decide_hold_preferred(struct active_hold_tap *hold_tap, enum decision_moment event)
|
static void decide_hold_preferred(struct active_hold_tap *hold_tap, enum decision_moment event) {
|
||||||
{
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case HT_KEY_UP:
|
case HT_KEY_UP:
|
||||||
hold_tap->is_hold = 0;
|
hold_tap->is_hold = 0;
|
||||||
|
@ -239,12 +236,13 @@ static void decide_hold_preferred(struct active_hold_tap *hold_tap, enum decisio
|
||||||
hold_tap->is_hold = 1;
|
hold_tap->is_hold = 1;
|
||||||
hold_tap->is_decided = true;
|
hold_tap->is_decided = true;
|
||||||
break;
|
break;
|
||||||
default: return;
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char* flavor_str(enum flavor flavor) {
|
static inline char *flavor_str(enum flavor flavor) {
|
||||||
switch(flavor) {
|
switch (flavor) {
|
||||||
case ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED:
|
case ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED:
|
||||||
return "hold-preferred";
|
return "hold-preferred";
|
||||||
case ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED:
|
case ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED:
|
||||||
|
@ -255,8 +253,7 @@ static inline char* flavor_str(enum flavor flavor) {
|
||||||
return "UNKNOWN FLAVOR";
|
return "UNKNOWN FLAVOR";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_moment event)
|
static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_moment event) {
|
||||||
{
|
|
||||||
if (hold_tap->is_decided) {
|
if (hold_tap->is_decided) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -266,7 +263,7 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_mome
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(hold_tap->config->flavor) {
|
switch (hold_tap->config->flavor) {
|
||||||
case ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED:
|
case ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED:
|
||||||
decide_hold_preferred(hold_tap, event);
|
decide_hold_preferred(hold_tap, event);
|
||||||
case ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED:
|
case ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED:
|
||||||
|
@ -279,28 +276,27 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_mome
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DBG("%d decided %s (%s event %d)",
|
LOG_DBG("%d decided %s (%s event %d)", hold_tap->position, hold_tap->is_hold ? "hold" : "tap",
|
||||||
hold_tap->position,
|
flavor_str(hold_tap->config->flavor), event);
|
||||||
hold_tap->is_hold ? "hold" : "tap",
|
|
||||||
flavor_str(hold_tap->config->flavor),
|
|
||||||
event);
|
|
||||||
undecided_hold_tap = NULL;
|
undecided_hold_tap = NULL;
|
||||||
|
|
||||||
struct zmk_behavior_binding *behavior;
|
struct zmk_behavior_binding *behavior;
|
||||||
if (hold_tap->is_hold) {
|
if (hold_tap->is_hold) {
|
||||||
behavior = &hold_tap->config->behaviors->hold;
|
behavior = &hold_tap->config->behaviors->hold;
|
||||||
struct device *behavior_device = device_get_binding(behavior->behavior_dev);
|
struct device *behavior_device = device_get_binding(behavior->behavior_dev);
|
||||||
behavior_keymap_binding_pressed(behavior_device, hold_tap->position, hold_tap->param_hold, 0);
|
behavior_keymap_binding_pressed(behavior_device, hold_tap->position, hold_tap->param_hold,
|
||||||
|
0);
|
||||||
} else {
|
} else {
|
||||||
behavior = &hold_tap->config->behaviors->tap;
|
behavior = &hold_tap->config->behaviors->tap;
|
||||||
struct device *behavior_device = device_get_binding(behavior->behavior_dev);
|
struct device *behavior_device = device_get_binding(behavior->behavior_dev);
|
||||||
behavior_keymap_binding_pressed(behavior_device, hold_tap->position, hold_tap->param_tap, 0);
|
behavior_keymap_binding_pressed(behavior_device, hold_tap->position, hold_tap->param_tap,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
release_captured_events();
|
release_captured_events();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_hold_tap_binding_pressed(struct device *dev, u32_t position, u32_t param_hold, u32_t param_tap)
|
static int on_hold_tap_binding_pressed(struct device *dev, u32_t position, u32_t param_hold,
|
||||||
{
|
u32_t param_tap) {
|
||||||
const struct behavior_hold_tap_config *cfg = dev->config_info;
|
const struct behavior_hold_tap_config *cfg = dev->config_info;
|
||||||
|
|
||||||
if (undecided_hold_tap != NULL) {
|
if (undecided_hold_tap != NULL) {
|
||||||
|
@ -311,7 +307,8 @@ static int on_hold_tap_binding_pressed(struct device *dev, u32_t position, u32_t
|
||||||
|
|
||||||
struct active_hold_tap *hold_tap = store_hold_tap(position, param_hold, param_tap, cfg);
|
struct active_hold_tap *hold_tap = store_hold_tap(position, param_hold, param_tap, cfg);
|
||||||
if (hold_tap == NULL) {
|
if (hold_tap == NULL) {
|
||||||
LOG_ERR("unable to store hold-tap info, did you press more than %d hold-taps?", ZMK_BHV_HOLD_TAP_MAX_HELD);
|
LOG_ERR("unable to store hold-tap info, did you press more than %d hold-taps?",
|
||||||
|
ZMK_BHV_HOLD_TAP_MAX_HELD);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,14 +316,13 @@ static int on_hold_tap_binding_pressed(struct device *dev, u32_t position, u32_t
|
||||||
undecided_hold_tap = hold_tap;
|
undecided_hold_tap = hold_tap;
|
||||||
k_delayed_work_submit(&hold_tap->work, cfg->tapping_term_ms());
|
k_delayed_work_submit(&hold_tap->work, cfg->tapping_term_ms());
|
||||||
|
|
||||||
// todo: once we get timing info for keypresses, start the timer relative to the original keypress
|
// todo: once we get timing info for keypresses, start the timer relative to the original
|
||||||
// don't forget to simulate a timer-event before the event after that time was handled.
|
// keypress don't forget to simulate a timer-event before the event after that time was handled.
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_hold_tap_binding_released(struct device *dev, u32_t position, u32_t _, u32_t __)
|
static int on_hold_tap_binding_released(struct device *dev, u32_t position, u32_t _, u32_t __) {
|
||||||
{
|
|
||||||
struct active_hold_tap *hold_tap = find_hold_tap(position);
|
struct active_hold_tap *hold_tap = find_hold_tap(position);
|
||||||
|
|
||||||
if (hold_tap == NULL) {
|
if (hold_tap == NULL) {
|
||||||
|
@ -341,14 +337,15 @@ static int on_hold_tap_binding_released(struct device *dev, u32_t position, u32_
|
||||||
if (hold_tap->is_hold) {
|
if (hold_tap->is_hold) {
|
||||||
behavior = &hold_tap->config->behaviors->hold;
|
behavior = &hold_tap->config->behaviors->hold;
|
||||||
struct device *behavior_device = device_get_binding(behavior->behavior_dev);
|
struct device *behavior_device = device_get_binding(behavior->behavior_dev);
|
||||||
behavior_keymap_binding_released(behavior_device, hold_tap->position, hold_tap->param_hold, 0);
|
behavior_keymap_binding_released(behavior_device, hold_tap->position, hold_tap->param_hold,
|
||||||
|
0);
|
||||||
} else {
|
} else {
|
||||||
behavior = &hold_tap->config->behaviors->tap;
|
behavior = &hold_tap->config->behaviors->tap;
|
||||||
struct device *behavior_device = device_get_binding(behavior->behavior_dev);
|
struct device *behavior_device = device_get_binding(behavior->behavior_dev);
|
||||||
behavior_keymap_binding_released(behavior_device, hold_tap->position, hold_tap->param_tap, 0);
|
behavior_keymap_binding_released(behavior_device, hold_tap->position, hold_tap->param_tap,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (work_cancel_result == -EINPROGRESS) {
|
if (work_cancel_result == -EINPROGRESS) {
|
||||||
// let the timer handler clean up
|
// let the timer handler clean up
|
||||||
// if we'd clear now, the timer may call back for an uninitialized active_hold_tap.
|
// if we'd clear now, the timer may call back for an uninitialized active_hold_tap.
|
||||||
|
@ -367,9 +364,7 @@ static const struct behavior_driver_api behavior_hold_tap_driver_api = {
|
||||||
.binding_released = on_hold_tap_binding_released,
|
.binding_released = on_hold_tap_binding_released,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int position_state_changed_listener(const struct zmk_event_header *eh) {
|
||||||
static int position_state_changed_listener(const struct zmk_event_header *eh)
|
|
||||||
{
|
|
||||||
struct position_state_changed *ev = cast_position_state_changed(eh);
|
struct position_state_changed *ev = cast_position_state_changed(eh);
|
||||||
|
|
||||||
if (undecided_hold_tap == NULL) {
|
if (undecided_hold_tap == NULL) {
|
||||||
|
@ -390,23 +385,23 @@ static int position_state_changed_listener(const struct zmk_event_header *eh)
|
||||||
if (!ev->state && find_captured_keydown_event(ev->position) == NULL) {
|
if (!ev->state && find_captured_keydown_event(ev->position) == NULL) {
|
||||||
// no keydown event has been captured, let it bubble.
|
// no keydown event has been captured, let it bubble.
|
||||||
// we'll catch modifiers later in modifier_state_changed_listener
|
// we'll catch modifiers later in modifier_state_changed_listener
|
||||||
LOG_DBG("%d bubbling %d %s event", undecided_hold_tap->position, ev->position, ev->state ? "down" : "up");
|
LOG_DBG("%d bubbling %d %s event", undecided_hold_tap->position, ev->position,
|
||||||
|
ev->state ? "down" : "up");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DBG("%d capturing %d %s event", undecided_hold_tap->position, ev->position, ev->state ? "down" : "up");
|
LOG_DBG("%d capturing %d %s event", undecided_hold_tap->position, ev->position,
|
||||||
|
ev->state ? "down" : "up");
|
||||||
capture_event(eh);
|
capture_event(eh);
|
||||||
decide_hold_tap(undecided_hold_tap, ev->state ? HT_OTHER_KEY_DOWN : HT_OTHER_KEY_UP);
|
decide_hold_tap(undecided_hold_tap, ev->state ? HT_OTHER_KEY_DOWN : HT_OTHER_KEY_UP);
|
||||||
return ZMK_EV_EVENT_CAPTURED;
|
return ZMK_EV_EVENT_CAPTURED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_mod(struct keycode_state_changed *ev)
|
static bool is_mod(struct keycode_state_changed *ev) {
|
||||||
{
|
|
||||||
return ev->usage_page == USAGE_KEYPAD && ev->keycode >= LCTL && ev->keycode <= RGUI;
|
return ev->usage_page == USAGE_KEYPAD && ev->keycode >= LCTL && ev->keycode <= RGUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int keycode_state_changed_listener(const struct zmk_event_header *eh)
|
static int keycode_state_changed_listener(const struct zmk_event_header *eh) {
|
||||||
{
|
|
||||||
// we want to catch layer-up events too... how?
|
// we want to catch layer-up events too... how?
|
||||||
struct keycode_state_changed *ev = cast_keycode_state_changed(eh);
|
struct keycode_state_changed *ev = cast_keycode_state_changed(eh);
|
||||||
|
|
||||||
|
@ -422,14 +417,13 @@ static int keycode_state_changed_listener(const struct zmk_event_header *eh)
|
||||||
|
|
||||||
// only key-up events will bubble through position_state_changed_listener
|
// only key-up events will bubble through position_state_changed_listener
|
||||||
// if a undecided_hold_tap is active.
|
// if a undecided_hold_tap is active.
|
||||||
LOG_DBG("%d capturing 0x%02X %s event", undecided_hold_tap->position, ev->keycode, ev->state ? "down" : "up");
|
LOG_DBG("%d capturing 0x%02X %s event", undecided_hold_tap->position, ev->keycode,
|
||||||
|
ev->state ? "down" : "up");
|
||||||
capture_event(eh);
|
capture_event(eh);
|
||||||
return ZMK_EV_EVENT_CAPTURED;
|
return ZMK_EV_EVENT_CAPTURED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int behavior_hold_tap_listener(const struct zmk_event_header *eh) {
|
||||||
int behavior_hold_tap_listener(const struct zmk_event_header *eh)
|
|
||||||
{
|
|
||||||
if (is_position_state_changed(eh)) {
|
if (is_position_state_changed(eh)) {
|
||||||
return position_state_changed_listener(eh);
|
return position_state_changed_listener(eh);
|
||||||
} else if (is_keycode_state_changed(eh)) {
|
} else if (is_keycode_state_changed(eh)) {
|
||||||
|
@ -443,8 +437,7 @@ ZMK_SUBSCRIPTION(behavior_hold_tap, position_state_changed);
|
||||||
// this should be modifiers_state_changed, but unfrotunately that's not implemented yet.
|
// this should be modifiers_state_changed, but unfrotunately that's not implemented yet.
|
||||||
ZMK_SUBSCRIPTION(behavior_hold_tap, keycode_state_changed);
|
ZMK_SUBSCRIPTION(behavior_hold_tap, keycode_state_changed);
|
||||||
|
|
||||||
void behavior_hold_tap_timer_work_handler(struct k_work *item)
|
void behavior_hold_tap_timer_work_handler(struct k_work *item) {
|
||||||
{
|
|
||||||
struct active_hold_tap *hold_tap = CONTAINER_OF(item, struct active_hold_tap, work);
|
struct active_hold_tap *hold_tap = CONTAINER_OF(item, struct active_hold_tap, work);
|
||||||
|
|
||||||
if (hold_tap->work_is_cancelled) {
|
if (hold_tap->work_is_cancelled) {
|
||||||
|
@ -454,8 +447,7 @@ void behavior_hold_tap_timer_work_handler(struct k_work *item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int behavior_hold_tap_init(struct device *dev)
|
static int behavior_hold_tap_init(struct device *dev) {
|
||||||
{
|
|
||||||
static bool init_first_run = true;
|
static bool init_first_run = true;
|
||||||
|
|
||||||
if (init_first_run) {
|
if (init_first_run) {
|
||||||
|
@ -474,29 +466,27 @@ static struct behavior_hold_tap_data behavior_hold_tap_data;
|
||||||
#define _TRANSFORM_ENTRY(idx, node) \
|
#define _TRANSFORM_ENTRY(idx, node) \
|
||||||
{ \
|
{ \
|
||||||
.behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \
|
.behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \
|
||||||
.param1 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param1), (0), (DT_INST_PHA_BY_IDX(node, bindings, idx, param1))), \
|
.param1 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param1), (0), \
|
||||||
.param2 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param2), (0), (DT_INST_PHA_BY_IDX(node, bindings, idx, param2))), \
|
(DT_INST_PHA_BY_IDX(node, bindings, idx, param1))), \
|
||||||
|
.param2 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param2), (0), \
|
||||||
|
(DT_INST_PHA_BY_IDX(node, bindings, idx, param2))), \
|
||||||
},
|
},
|
||||||
|
|
||||||
#define KP_INST(n) \
|
#define KP_INST(n) \
|
||||||
static k_timeout_t behavior_hold_tap_config_##n##_gettime() { return K_MSEC(DT_INST_PROP(n, tapping_term_ms)); } \
|
static k_timeout_t behavior_hold_tap_config_##n##_gettime() { \
|
||||||
|
return K_MSEC(DT_INST_PROP(n, tapping_term_ms)); \
|
||||||
|
} \
|
||||||
static struct behavior_hold_tap_behaviors behavior_hold_tap_behaviors_##n = { \
|
static struct behavior_hold_tap_behaviors behavior_hold_tap_behaviors_##n = { \
|
||||||
.hold = _TRANSFORM_ENTRY(0, n) \
|
.hold = _TRANSFORM_ENTRY(0, n).tap = _TRANSFORM_ENTRY(1, n)}; \
|
||||||
.tap = _TRANSFORM_ENTRY(1, n) \
|
|
||||||
}; \
|
|
||||||
static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \
|
static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \
|
||||||
.behaviors = &behavior_hold_tap_behaviors_##n, \
|
.behaviors = &behavior_hold_tap_behaviors_##n, \
|
||||||
.tapping_term_ms = &behavior_hold_tap_config_##n##_gettime, \
|
.tapping_term_ms = &behavior_hold_tap_config_##n##_gettime, \
|
||||||
.flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \
|
.flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \
|
||||||
}; \
|
}; \
|
||||||
DEVICE_AND_API_INIT( \
|
DEVICE_AND_API_INIT(behavior_hold_tap_##n, DT_INST_LABEL(n), behavior_hold_tap_init, \
|
||||||
behavior_hold_tap_##n, DT_INST_LABEL(n), behavior_hold_tap_init, \
|
&behavior_hold_tap_data, &behavior_hold_tap_config_##n, APPLICATION, \
|
||||||
&behavior_hold_tap_data, \
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_hold_tap_driver_api);
|
||||||
&behavior_hold_tap_config_##n, \
|
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
|
||||||
&behavior_hold_tap_driver_api);
|
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(KP_INST)
|
DT_INST_FOREACH_STATUS_OKAY(KP_INST)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -18,23 +18,18 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
struct behavior_key_press_config {
|
struct behavior_key_press_config {
|
||||||
u8_t usage_page;
|
u8_t usage_page;
|
||||||
};
|
};
|
||||||
struct behavior_key_press_data { };
|
struct behavior_key_press_data {};
|
||||||
|
|
||||||
static int behavior_key_press_init(struct device *dev)
|
static int behavior_key_press_init(struct device *dev) { return 0; };
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t keycode, u32_t _)
|
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t keycode, u32_t _) {
|
||||||
{
|
|
||||||
const struct behavior_key_press_config *cfg = dev->config_info;
|
const struct behavior_key_press_config *cfg = dev->config_info;
|
||||||
LOG_DBG("position %d usage_page 0x%02X keycode 0x%02X", position, cfg->usage_page, keycode);
|
LOG_DBG("position %d usage_page 0x%02X keycode 0x%02X", position, cfg->usage_page, keycode);
|
||||||
|
|
||||||
return ZMK_EVENT_RAISE(create_keycode_state_changed(cfg->usage_page, keycode, true));
|
return ZMK_EVENT_RAISE(create_keycode_state_changed(cfg->usage_page, keycode, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t keycode, u32_t _)
|
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t keycode, u32_t _) {
|
||||||
{
|
|
||||||
const struct behavior_key_press_config *cfg = dev->config_info;
|
const struct behavior_key_press_config *cfg = dev->config_info;
|
||||||
LOG_DBG("position %d usage_page 0x%02X keycode 0x%02X", position, cfg->usage_page, keycode);
|
LOG_DBG("position %d usage_page 0x%02X keycode 0x%02X", position, cfg->usage_page, keycode);
|
||||||
|
|
||||||
|
@ -42,19 +37,14 @@ static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct behavior_driver_api behavior_key_press_driver_api = {
|
static const struct behavior_driver_api behavior_key_press_driver_api = {
|
||||||
.binding_pressed = on_keymap_binding_pressed,
|
.binding_pressed = on_keymap_binding_pressed, .binding_released = on_keymap_binding_released};
|
||||||
.binding_released = on_keymap_binding_released
|
|
||||||
};
|
|
||||||
|
|
||||||
#define KP_INST(n) \
|
#define KP_INST(n) \
|
||||||
static const struct behavior_key_press_config behavior_key_press_config_##n = { \
|
static const struct behavior_key_press_config behavior_key_press_config_##n = { \
|
||||||
.usage_page = DT_INST_PROP(n, usage_page) \
|
.usage_page = DT_INST_PROP(n, usage_page)}; \
|
||||||
}; \
|
|
||||||
static struct behavior_key_press_data behavior_key_press_data_##n; \
|
static struct behavior_key_press_data behavior_key_press_data_##n; \
|
||||||
DEVICE_AND_API_INIT(behavior_key_press_##n, DT_INST_LABEL(n), behavior_key_press_init, \
|
DEVICE_AND_API_INIT(behavior_key_press_##n, DT_INST_LABEL(n), behavior_key_press_init, \
|
||||||
&behavior_key_press_data_##n, \
|
&behavior_key_press_data_##n, &behavior_key_press_config_##n, APPLICATION, \
|
||||||
&behavior_key_press_config_##n, \
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_key_press_driver_api);
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
|
||||||
&behavior_key_press_driver_api);
|
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(KP_INST)
|
DT_INST_FOREACH_STATUS_OKAY(KP_INST)
|
|
@ -14,41 +14,30 @@
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
struct behavior_mo_config { };
|
struct behavior_mo_config {};
|
||||||
struct behavior_mo_data { };
|
struct behavior_mo_data {};
|
||||||
|
|
||||||
static int behavior_mo_init(struct device *dev)
|
static int behavior_mo_init(struct device *dev) { return 0; };
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
static int mo_keymap_binding_pressed(struct device *dev, u32_t position, u32_t layer, u32_t _) {
|
||||||
static int mo_keymap_binding_pressed(struct device *dev, u32_t position, u32_t layer, u32_t _)
|
|
||||||
{
|
|
||||||
LOG_DBG("position %d layer %d", position, layer);
|
LOG_DBG("position %d layer %d", position, layer);
|
||||||
|
|
||||||
return zmk_keymap_layer_activate(layer);
|
return zmk_keymap_layer_activate(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mo_keymap_binding_released(struct device *dev, u32_t position, u32_t layer, u32_t _)
|
static int mo_keymap_binding_released(struct device *dev, u32_t position, u32_t layer, u32_t _) {
|
||||||
{
|
|
||||||
LOG_DBG("position %d layer %d", position, layer);
|
LOG_DBG("position %d layer %d", position, layer);
|
||||||
|
|
||||||
return zmk_keymap_layer_deactivate(layer);
|
return zmk_keymap_layer_deactivate(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct behavior_driver_api behavior_mo_driver_api = {
|
static const struct behavior_driver_api behavior_mo_driver_api = {
|
||||||
.binding_pressed = mo_keymap_binding_pressed,
|
.binding_pressed = mo_keymap_binding_pressed, .binding_released = mo_keymap_binding_released};
|
||||||
.binding_released = mo_keymap_binding_released
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static const struct behavior_mo_config behavior_mo_config = {};
|
static const struct behavior_mo_config behavior_mo_config = {};
|
||||||
|
|
||||||
static struct behavior_mo_data behavior_mo_data;
|
static struct behavior_mo_data behavior_mo_data;
|
||||||
|
|
||||||
DEVICE_AND_API_INIT(behavior_mo, DT_INST_LABEL(0), behavior_mo_init,
|
DEVICE_AND_API_INIT(behavior_mo, DT_INST_LABEL(0), behavior_mo_init, &behavior_mo_data,
|
||||||
&behavior_mo_data,
|
&behavior_mo_config, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||||
&behavior_mo_config,
|
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
|
||||||
&behavior_mo_driver_api);
|
&behavior_mo_driver_api);
|
||||||
|
|
|
@ -13,21 +13,18 @@
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
struct behavior_none_config { };
|
struct behavior_none_config {};
|
||||||
struct behavior_none_data { };
|
struct behavior_none_data {};
|
||||||
|
|
||||||
static int behavior_none_init(struct device *dev)
|
static int behavior_none_init(struct device *dev) { return 0; };
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1, u32_t _param2)
|
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1,
|
||||||
{
|
u32_t _param2) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t _param1, u32_t _param2)
|
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t _param1,
|
||||||
{
|
u32_t _param2) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,13 +33,10 @@ static const struct behavior_driver_api behavior_none_driver_api = {
|
||||||
.binding_released = on_keymap_binding_released,
|
.binding_released = on_keymap_binding_released,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const struct behavior_none_config behavior_none_config = {};
|
static const struct behavior_none_config behavior_none_config = {};
|
||||||
|
|
||||||
static struct behavior_none_data behavior_none_data;
|
static struct behavior_none_data behavior_none_data;
|
||||||
|
|
||||||
DEVICE_AND_API_INIT(behavior_none, DT_INST_LABEL(0), behavior_none_init,
|
DEVICE_AND_API_INIT(behavior_none, DT_INST_LABEL(0), behavior_none_init, &behavior_none_data,
|
||||||
&behavior_none_data,
|
&behavior_none_config, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||||
&behavior_none_config,
|
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
|
||||||
&behavior_none_driver_api);
|
&behavior_none_driver_api);
|
|
@ -17,17 +17,15 @@ struct behavior_reset_config {
|
||||||
int type;
|
int type;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int behavior_reset_init(struct device *dev)
|
static int behavior_reset_init(struct device *dev) { return 0; };
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1, u32_t _param2)
|
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1,
|
||||||
{
|
u32_t _param2) {
|
||||||
const struct behavior_reset_config *cfg = dev->config_info;
|
const struct behavior_reset_config *cfg = dev->config_info;
|
||||||
|
|
||||||
// TODO: Correct magic code for going into DFU?
|
// TODO: Correct magic code for going into DFU?
|
||||||
// See https://github.com/adafruit/Adafruit_nRF52_Bootloader/blob/d6b28e66053eea467166f44875e3c7ec741cb471/src/main.c#L107
|
// See
|
||||||
|
// https://github.com/adafruit/Adafruit_nRF52_Bootloader/blob/d6b28e66053eea467166f44875e3c7ec741cb471/src/main.c#L107
|
||||||
sys_reboot(cfg->type);
|
sys_reboot(cfg->type);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -36,15 +34,11 @@ static const struct behavior_driver_api behavior_reset_driver_api = {
|
||||||
.binding_pressed = on_keymap_binding_pressed,
|
.binding_pressed = on_keymap_binding_pressed,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define RST_INST(n) \
|
#define RST_INST(n) \
|
||||||
static const struct behavior_reset_config behavior_reset_config_##n = { \
|
static const struct behavior_reset_config behavior_reset_config_##n = { \
|
||||||
.type = DT_INST_PROP(n, type) \
|
.type = DT_INST_PROP(n, type)}; \
|
||||||
}; \
|
DEVICE_AND_API_INIT(behavior_reset_##n, DT_INST_LABEL(n), behavior_reset_init, NULL, \
|
||||||
DEVICE_AND_API_INIT(behavior_reset_##n, DT_INST_LABEL(n), behavior_reset_init, \
|
&behavior_reset_config_##n, APPLICATION, \
|
||||||
NULL, \
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_reset_driver_api);
|
||||||
&behavior_reset_config_##n, \
|
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
|
||||||
&behavior_reset_driver_api);
|
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(RST_INST)
|
DT_INST_FOREACH_STATUS_OKAY(RST_INST)
|
|
@ -15,15 +15,10 @@
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
static int behavior_rgb_underglow_init(struct device *dev)
|
static int behavior_rgb_underglow_init(struct device *dev) { return 0; }
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t action, u32_t _)
|
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t action, u32_t _) {
|
||||||
{
|
switch (action) {
|
||||||
switch (action)
|
|
||||||
{
|
|
||||||
case RGB_TOG:
|
case RGB_TOG:
|
||||||
return zmk_rgb_underglow_toggle();
|
return zmk_rgb_underglow_toggle();
|
||||||
case RGB_HUI:
|
case RGB_HUI:
|
||||||
|
@ -55,8 +50,6 @@ static const struct behavior_driver_api behavior_rgb_underglow_driver_api = {
|
||||||
.binding_pressed = on_keymap_binding_pressed,
|
.binding_pressed = on_keymap_binding_pressed,
|
||||||
};
|
};
|
||||||
|
|
||||||
DEVICE_AND_API_INIT(behavior_rgb_underglow, DT_INST_LABEL(0), behavior_rgb_underglow_init,
|
DEVICE_AND_API_INIT(behavior_rgb_underglow, DT_INST_LABEL(0), behavior_rgb_underglow_init, NULL,
|
||||||
NULL,
|
NULL, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||||
NULL,
|
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
|
||||||
&behavior_rgb_underglow_driver_api);
|
&behavior_rgb_underglow_driver_api);
|
|
@ -19,22 +19,19 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
struct behavior_sensor_rotate_key_press_config {
|
struct behavior_sensor_rotate_key_press_config {
|
||||||
u8_t usage_page;
|
u8_t usage_page;
|
||||||
};
|
};
|
||||||
struct behavior_sensor_rotate_key_press_data { };
|
struct behavior_sensor_rotate_key_press_data {};
|
||||||
|
|
||||||
static int behavior_sensor_rotate_key_press_init(struct device *dev)
|
static int behavior_sensor_rotate_key_press_init(struct device *dev) { return 0; };
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
static int on_sensor_binding_triggered(struct device *dev, struct device *sensor,
|
||||||
static int on_sensor_binding_triggered(struct device *dev, struct device *sensor, u32_t increment_keycode, u32_t decrement_keycode)
|
u32_t increment_keycode, u32_t decrement_keycode) {
|
||||||
{
|
|
||||||
const struct behavior_sensor_rotate_key_press_config *cfg = dev->config_info;
|
const struct behavior_sensor_rotate_key_press_config *cfg = dev->config_info;
|
||||||
struct sensor_value value;
|
struct sensor_value value;
|
||||||
int err;
|
int err;
|
||||||
u32_t keycode;
|
u32_t keycode;
|
||||||
struct keycode_state_changed *ev;
|
struct keycode_state_changed *ev;
|
||||||
LOG_DBG("usage_page 0x%02X inc keycode 0x%02X dec keycode 0x%02X", cfg->usage_page, increment_keycode, decrement_keycode);
|
LOG_DBG("usage_page 0x%02X inc keycode 0x%02X dec keycode 0x%02X", cfg->usage_page,
|
||||||
|
increment_keycode, decrement_keycode);
|
||||||
|
|
||||||
err = sensor_channel_get(sensor, SENSOR_CHAN_ROTATION, &value);
|
err = sensor_channel_get(sensor, SENSOR_CHAN_ROTATION, &value);
|
||||||
|
|
||||||
|
@ -56,7 +53,6 @@ static int on_sensor_binding_triggered(struct device *dev, struct device *sensor
|
||||||
|
|
||||||
LOG_DBG("SEND %d", keycode);
|
LOG_DBG("SEND %d", keycode);
|
||||||
|
|
||||||
|
|
||||||
ev = new_keycode_state_changed();
|
ev = new_keycode_state_changed();
|
||||||
ev->usage_page = cfg->usage_page;
|
ev->usage_page = cfg->usage_page;
|
||||||
ev->keycode = keycode;
|
ev->keycode = keycode;
|
||||||
|
@ -74,18 +70,16 @@ static int on_sensor_binding_triggered(struct device *dev, struct device *sensor
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct behavior_driver_api behavior_sensor_rotate_key_press_driver_api = {
|
static const struct behavior_driver_api behavior_sensor_rotate_key_press_driver_api = {
|
||||||
.sensor_binding_triggered = on_sensor_binding_triggered
|
.sensor_binding_triggered = on_sensor_binding_triggered};
|
||||||
};
|
|
||||||
|
|
||||||
#define KP_INST(n) \
|
#define KP_INST(n) \
|
||||||
static const struct behavior_sensor_rotate_key_press_config behavior_sensor_rotate_key_press_config_##n = { \
|
static const struct behavior_sensor_rotate_key_press_config \
|
||||||
.usage_page = DT_INST_PROP(n, usage_page) \
|
behavior_sensor_rotate_key_press_config_##n = {.usage_page = DT_INST_PROP(n, usage_page)}; \
|
||||||
}; \
|
|
||||||
static struct behavior_sensor_rotate_key_press_data behavior_sensor_rotate_key_press_data_##n; \
|
static struct behavior_sensor_rotate_key_press_data behavior_sensor_rotate_key_press_data_##n; \
|
||||||
DEVICE_AND_API_INIT(behavior_sensor_rotate_key_press_##n, DT_INST_LABEL(n), behavior_sensor_rotate_key_press_init, \
|
DEVICE_AND_API_INIT( \
|
||||||
&behavior_sensor_rotate_key_press_data_##n, \
|
behavior_sensor_rotate_key_press_##n, DT_INST_LABEL(n), \
|
||||||
&behavior_sensor_rotate_key_press_config_##n, \
|
behavior_sensor_rotate_key_press_init, &behavior_sensor_rotate_key_press_data_##n, \
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
&behavior_sensor_rotate_key_press_config_##n, APPLICATION, \
|
||||||
&behavior_sensor_rotate_key_press_driver_api);
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_sensor_rotate_key_press_driver_api);
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(KP_INST)
|
DT_INST_FOREACH_STATUS_OKAY(KP_INST)
|
|
@ -14,27 +14,18 @@
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
struct behavior_tog_config
|
struct behavior_tog_config {};
|
||||||
{
|
struct behavior_tog_data {};
|
||||||
};
|
|
||||||
struct behavior_tog_data
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
static int behavior_tog_init(struct device *dev)
|
static int behavior_tog_init(struct device *dev) { return 0; };
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int tog_keymap_binding_pressed(struct device *dev, u32_t position, u32_t layer, u32_t _)
|
static int tog_keymap_binding_pressed(struct device *dev, u32_t position, u32_t layer, u32_t _) {
|
||||||
{
|
|
||||||
LOG_DBG("position %d layer %d", position, layer);
|
LOG_DBG("position %d layer %d", position, layer);
|
||||||
|
|
||||||
return zmk_keymap_layer_toggle(layer);
|
return zmk_keymap_layer_toggle(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tog_keymap_binding_released(struct device *dev, u32_t position, u32_t layer, u32_t _)
|
static int tog_keymap_binding_released(struct device *dev, u32_t position, u32_t layer, u32_t _) {
|
||||||
{
|
|
||||||
LOG_DBG("position %d layer %d", position, layer);
|
LOG_DBG("position %d layer %d", position, layer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -49,8 +40,6 @@ static const struct behavior_tog_config behavior_tog_config = {};
|
||||||
|
|
||||||
static struct behavior_tog_data behavior_tog_data;
|
static struct behavior_tog_data behavior_tog_data;
|
||||||
|
|
||||||
DEVICE_AND_API_INIT(behavior_tog, DT_INST_LABEL(0), behavior_tog_init,
|
DEVICE_AND_API_INIT(behavior_tog, DT_INST_LABEL(0), behavior_tog_init, &behavior_tog_data,
|
||||||
&behavior_tog_data,
|
&behavior_tog_config, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||||
&behavior_tog_config,
|
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
|
||||||
&behavior_tog_driver_api);
|
&behavior_tog_driver_api);
|
||||||
|
|
|
@ -13,21 +13,18 @@
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
struct behavior_transparent_config { };
|
struct behavior_transparent_config {};
|
||||||
struct behavior_transparent_data { };
|
struct behavior_transparent_data {};
|
||||||
|
|
||||||
static int behavior_transparent_init(struct device *dev)
|
static int behavior_transparent_init(struct device *dev) { return 0; };
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1, u32_t _param2)
|
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1,
|
||||||
{
|
u32_t _param2) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t _param1, u32_t _param2)
|
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t _param1,
|
||||||
{
|
u32_t _param2) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,13 +33,10 @@ static const struct behavior_driver_api behavior_transparent_driver_api = {
|
||||||
.binding_released = on_keymap_binding_released,
|
.binding_released = on_keymap_binding_released,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const struct behavior_transparent_config behavior_transparent_config = {};
|
static const struct behavior_transparent_config behavior_transparent_config = {};
|
||||||
|
|
||||||
static struct behavior_transparent_data behavior_transparent_data;
|
static struct behavior_transparent_data behavior_transparent_data;
|
||||||
|
|
||||||
DEVICE_AND_API_INIT(behavior_transparent, DT_INST_LABEL(0), behavior_transparent_init,
|
DEVICE_AND_API_INIT(behavior_transparent, DT_INST_LABEL(0), behavior_transparent_init,
|
||||||
&behavior_transparent_data,
|
&behavior_transparent_data, &behavior_transparent_config, APPLICATION,
|
||||||
&behavior_transparent_config,
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_transparent_driver_api);
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
|
||||||
&behavior_transparent_driver_api);
|
|
150
app/src/ble.c
150
app/src/ble.c
|
@ -45,7 +45,6 @@ static u8_t passkey_digit = 0;
|
||||||
#define PROFILE_COUNT CONFIG_BT_MAX_PAIRED
|
#define PROFILE_COUNT CONFIG_BT_MAX_PAIRED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static struct zmk_ble_profile profiles[PROFILE_COUNT];
|
static struct zmk_ble_profile profiles[PROFILE_COUNT];
|
||||||
static u8_t active_profile;
|
static u8_t active_profile;
|
||||||
|
|
||||||
|
@ -58,8 +57,7 @@ static const struct bt_data zmk_ble_ad[] = {
|
||||||
0x0f, 0x18 /* Battery Service */
|
0x0f, 0x18 /* Battery Service */
|
||||||
),
|
),
|
||||||
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL)
|
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL)
|
||||||
BT_DATA_BYTES(BT_DATA_UUID128_ALL,
|
BT_DATA_BYTES(BT_DATA_UUID128_ALL, ZMK_SPLIT_BT_SERVICE_UUID)
|
||||||
ZMK_SPLIT_BT_SERVICE_UUID)
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,8 +67,7 @@ static bt_addr_le_t peripheral_addr;
|
||||||
|
|
||||||
#endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) */
|
#endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) */
|
||||||
|
|
||||||
static void raise_profile_changed_event()
|
static void raise_profile_changed_event() {
|
||||||
{
|
|
||||||
struct ble_active_profile_changed *ev = new_ble_active_profile_changed();
|
struct ble_active_profile_changed *ev = new_ble_active_profile_changed();
|
||||||
ev->index = active_profile;
|
ev->index = active_profile;
|
||||||
ev->profile = &profiles[active_profile];
|
ev->profile = &profiles[active_profile];
|
||||||
|
@ -78,13 +75,11 @@ static void raise_profile_changed_event()
|
||||||
ZMK_EVENT_RAISE(ev);
|
ZMK_EVENT_RAISE(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool active_profile_is_open()
|
static bool active_profile_is_open() {
|
||||||
{
|
|
||||||
return !bt_addr_le_cmp(&profiles[active_profile].peer, BT_ADDR_LE_ANY);
|
return !bt_addr_le_cmp(&profiles[active_profile].peer, BT_ADDR_LE_ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_profile_address(u8_t index, const bt_addr_le_t *addr)
|
void set_profile_address(u8_t index, const bt_addr_le_t *addr) {
|
||||||
{
|
|
||||||
char setting_name[15];
|
char setting_name[15];
|
||||||
char addr_str[BT_ADDR_LE_STR_LEN];
|
char addr_str[BT_ADDR_LE_STR_LEN];
|
||||||
|
|
||||||
|
@ -97,8 +92,7 @@ void set_profile_address(u8_t index, const bt_addr_le_t *addr)
|
||||||
raise_profile_changed_event();
|
raise_profile_changed_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_ble_adv_pause()
|
int zmk_ble_adv_pause() {
|
||||||
{
|
|
||||||
int err = bt_le_adv_stop();
|
int err = bt_le_adv_stop();
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG_ERR("Failed to stop advertising (err %d)", err);
|
LOG_ERR("Failed to stop advertising (err %d)", err);
|
||||||
|
@ -108,16 +102,12 @@ int zmk_ble_adv_pause()
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
int zmk_ble_adv_resume()
|
int zmk_ble_adv_resume() {
|
||||||
{
|
LOG_DBG("active_profile %d, directed? %s", active_profile,
|
||||||
LOG_DBG("active_profile %d, directed? %s", active_profile, active_profile_is_open() ? "no" : "yes");
|
active_profile_is_open() ? "no" : "yes");
|
||||||
|
|
||||||
int err = bt_le_adv_start(
|
int err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), NULL, 0);
|
||||||
BT_LE_ADV_CONN_NAME,
|
if (err) {
|
||||||
zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad),
|
|
||||||
NULL, 0);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
LOG_ERR("Advertising failed to start (err %d)", err);
|
LOG_ERR("Advertising failed to start (err %d)", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -125,8 +115,7 @@ int zmk_ble_adv_resume()
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
int zmk_ble_clear_bonds()
|
int zmk_ble_clear_bonds() {
|
||||||
{
|
|
||||||
LOG_DBG("");
|
LOG_DBG("");
|
||||||
|
|
||||||
if (bt_addr_le_cmp(&profiles[active_profile].peer, BT_ADDR_LE_ANY)) {
|
if (bt_addr_le_cmp(&profiles[active_profile].peer, BT_ADDR_LE_ANY)) {
|
||||||
|
@ -138,8 +127,7 @@ int zmk_ble_clear_bonds()
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
int zmk_ble_prof_select(u8_t index)
|
int zmk_ble_prof_select(u8_t index) {
|
||||||
{
|
|
||||||
LOG_DBG("profile %d", index);
|
LOG_DBG("profile %d", index);
|
||||||
if (active_profile == index) {
|
if (active_profile == index) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -151,32 +139,23 @@ int zmk_ble_prof_select(u8_t index)
|
||||||
raise_profile_changed_event();
|
raise_profile_changed_event();
|
||||||
};
|
};
|
||||||
|
|
||||||
int zmk_ble_prof_next()
|
int zmk_ble_prof_next() {
|
||||||
{
|
|
||||||
LOG_DBG("");
|
LOG_DBG("");
|
||||||
return zmk_ble_prof_select((active_profile + 1) % PROFILE_COUNT);
|
return zmk_ble_prof_select((active_profile + 1) % PROFILE_COUNT);
|
||||||
};
|
};
|
||||||
|
|
||||||
int zmk_ble_prof_prev()
|
int zmk_ble_prof_prev() {
|
||||||
{
|
|
||||||
LOG_DBG("");
|
LOG_DBG("");
|
||||||
return zmk_ble_prof_select((active_profile + PROFILE_COUNT - 1) % PROFILE_COUNT);
|
return zmk_ble_prof_select((active_profile + PROFILE_COUNT - 1) % PROFILE_COUNT);
|
||||||
};
|
};
|
||||||
|
|
||||||
bt_addr_le_t *zmk_ble_active_profile_addr()
|
bt_addr_le_t *zmk_ble_active_profile_addr() { return &profiles[active_profile].peer; }
|
||||||
{
|
|
||||||
return &profiles[active_profile].peer;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *zmk_ble_active_profile_name()
|
char *zmk_ble_active_profile_name() { return profiles[active_profile].name; }
|
||||||
{
|
|
||||||
return profiles[active_profile].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL)
|
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL)
|
||||||
|
|
||||||
void zmk_ble_set_peripheral_addr(bt_addr_le_t *addr)
|
void zmk_ble_set_peripheral_addr(bt_addr_le_t *addr) {
|
||||||
{
|
|
||||||
memcpy(&peripheral_addr, addr, sizeof(bt_addr_le_t));
|
memcpy(&peripheral_addr, addr, sizeof(bt_addr_le_t));
|
||||||
settings_save_one("ble/peripheral_address", addr, sizeof(bt_addr_le_t));
|
settings_save_one("ble/peripheral_address", addr, sizeof(bt_addr_le_t));
|
||||||
}
|
}
|
||||||
|
@ -185,8 +164,8 @@ void zmk_ble_set_peripheral_addr(bt_addr_le_t *addr)
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||||
|
|
||||||
static int ble_profiles_handle_set(const char *name, size_t len, settings_read_cb read_cb, void *cb_arg)
|
static int ble_profiles_handle_set(const char *name, size_t len, settings_read_cb read_cb,
|
||||||
{
|
void *cb_arg) {
|
||||||
const char *next;
|
const char *next;
|
||||||
|
|
||||||
LOG_DBG("Setting BLE value %s", log_strdup(name));
|
LOG_DBG("Setting BLE value %s", log_strdup(name));
|
||||||
|
@ -200,7 +179,8 @@ static int ble_profiles_handle_set(const char *name, size_t len, settings_read_c
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len != sizeof(struct zmk_ble_profile)) {
|
if (len != sizeof(struct zmk_ble_profile)) {
|
||||||
LOG_ERR("Invalid profile size (got %d expected %d)", len, sizeof(struct zmk_ble_profile));
|
LOG_ERR("Invalid profile size (got %d expected %d)", len,
|
||||||
|
sizeof(struct zmk_ble_profile));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,19 +227,14 @@ static int ble_profiles_handle_set(const char *name, size_t len, settings_read_c
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct settings_handler profiles_handler = {
|
struct settings_handler profiles_handler = {.name = "ble", .h_set = ble_profiles_handle_set};
|
||||||
.name = "ble",
|
|
||||||
.h_set = ble_profiles_handle_set
|
|
||||||
};
|
|
||||||
#endif /* IS_ENABLED(CONFIG_SETTINGS) */
|
#endif /* IS_ENABLED(CONFIG_SETTINGS) */
|
||||||
|
|
||||||
static void connected(struct bt_conn *conn, u8_t err)
|
static void connected(struct bt_conn *conn, u8_t err) {
|
||||||
{
|
|
||||||
char addr[BT_ADDR_LE_STR_LEN];
|
char addr[BT_ADDR_LE_STR_LEN];
|
||||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||||
|
|
||||||
if (err)
|
if (err) {
|
||||||
{
|
|
||||||
LOG_WRN("Failed to connect to %s (%u)", log_strdup(addr), err);
|
LOG_WRN("Failed to connect to %s (%u)", log_strdup(addr), err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -272,14 +247,12 @@ static void connected(struct bt_conn *conn, u8_t err)
|
||||||
bt_conn_le_phy_update(conn, BT_CONN_LE_PHY_PARAM_2M);
|
bt_conn_le_phy_update(conn, BT_CONN_LE_PHY_PARAM_2M);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (bt_conn_set_security(conn, BT_SECURITY_L2))
|
if (bt_conn_set_security(conn, BT_SECURITY_L2)) {
|
||||||
{
|
|
||||||
LOG_ERR("Failed to set security");
|
LOG_ERR("Failed to set security");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disconnected(struct bt_conn *conn, u8_t reason)
|
static void disconnected(struct bt_conn *conn, u8_t reason) {
|
||||||
{
|
|
||||||
char addr[BT_ADDR_LE_STR_LEN];
|
char addr[BT_ADDR_LE_STR_LEN];
|
||||||
|
|
||||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||||
|
@ -287,7 +260,8 @@ static void disconnected(struct bt_conn *conn, u8_t reason)
|
||||||
LOG_DBG("Disconnected from %s (reason 0x%02x)", log_strdup(addr), reason);
|
LOG_DBG("Disconnected from %s (reason 0x%02x)", log_strdup(addr), reason);
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL)
|
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL)
|
||||||
// if (bt_addr_le_cmp(&peripheral_addr, BT_ADDR_LE_ANY) && bt_addr_le_cmp(&peripheral_addr, bt_conn_get_dst(conn))) {
|
// if (bt_addr_le_cmp(&peripheral_addr, BT_ADDR_LE_ANY) && bt_addr_le_cmp(&peripheral_addr,
|
||||||
|
// bt_conn_get_dst(conn))) {
|
||||||
// zmk_ble_adv_resume();
|
// zmk_ble_adv_resume();
|
||||||
// }
|
// }
|
||||||
#else
|
#else
|
||||||
|
@ -295,21 +269,15 @@ static void disconnected(struct bt_conn *conn, u8_t reason)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void security_changed(struct bt_conn *conn, bt_security_t level,
|
static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) {
|
||||||
enum bt_security_err err)
|
|
||||||
{
|
|
||||||
char addr[BT_ADDR_LE_STR_LEN];
|
char addr[BT_ADDR_LE_STR_LEN];
|
||||||
|
|
||||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||||
|
|
||||||
if (!err)
|
if (!err) {
|
||||||
{
|
|
||||||
LOG_DBG("Security changed: %s level %u", log_strdup(addr), level);
|
LOG_DBG("Security changed: %s level %u", log_strdup(addr), level);
|
||||||
}
|
} else {
|
||||||
else
|
LOG_ERR("Security failed: %s level %u err %d", log_strdup(addr), level, err);
|
||||||
{
|
|
||||||
LOG_ERR("Security failed: %s level %u err %d", log_strdup(addr), level,
|
|
||||||
err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,8 +287,7 @@ static struct bt_conn_cb conn_callbacks = {
|
||||||
.security_changed = security_changed,
|
.security_changed = security_changed,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey)
|
static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey) {
|
||||||
{
|
|
||||||
char addr[BT_ADDR_LE_STR_LEN];
|
char addr[BT_ADDR_LE_STR_LEN];
|
||||||
|
|
||||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||||
|
@ -330,8 +297,7 @@ static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey)
|
||||||
|
|
||||||
#ifdef CONFIG_ZMK_BLE_PASSKEY_ENTRY
|
#ifdef CONFIG_ZMK_BLE_PASSKEY_ENTRY
|
||||||
|
|
||||||
static void auth_passkey_entry(struct bt_conn *conn)
|
static void auth_passkey_entry(struct bt_conn *conn) {
|
||||||
{
|
|
||||||
char addr[BT_ADDR_LE_STR_LEN];
|
char addr[BT_ADDR_LE_STR_LEN];
|
||||||
|
|
||||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||||
|
@ -342,14 +308,12 @@ static void auth_passkey_entry(struct bt_conn *conn)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void auth_cancel(struct bt_conn *conn)
|
static void auth_cancel(struct bt_conn *conn) {
|
||||||
{
|
|
||||||
char addr[BT_ADDR_LE_STR_LEN];
|
char addr[BT_ADDR_LE_STR_LEN];
|
||||||
|
|
||||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||||
|
|
||||||
if (auth_passkey_entry_conn)
|
if (auth_passkey_entry_conn) {
|
||||||
{
|
|
||||||
bt_conn_unref(auth_passkey_entry_conn);
|
bt_conn_unref(auth_passkey_entry_conn);
|
||||||
auth_passkey_entry_conn = NULL;
|
auth_passkey_entry_conn = NULL;
|
||||||
}
|
}
|
||||||
|
@ -360,8 +324,8 @@ static void auth_cancel(struct bt_conn *conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL)
|
#if !IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL)
|
||||||
static enum bt_security_err auth_pairing_accept(struct bt_conn *conn, const struct bt_conn_pairing_feat *const feat)
|
static enum bt_security_err auth_pairing_accept(struct bt_conn *conn,
|
||||||
{
|
const struct bt_conn_pairing_feat *const feat) {
|
||||||
struct bt_conn_info info;
|
struct bt_conn_info info;
|
||||||
bt_conn_get_info(conn, &info);
|
bt_conn_get_info(conn, &info);
|
||||||
|
|
||||||
|
@ -375,8 +339,7 @@ static enum bt_security_err auth_pairing_accept(struct bt_conn *conn, const stru
|
||||||
};
|
};
|
||||||
#endif /* !IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL) */
|
#endif /* !IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL) */
|
||||||
|
|
||||||
static void auth_pairing_complete(struct bt_conn *conn, bool bonded)
|
static void auth_pairing_complete(struct bt_conn *conn, bool bonded) {
|
||||||
{
|
|
||||||
struct bt_conn_info info;
|
struct bt_conn_info info;
|
||||||
char addr[BT_ADDR_LE_STR_LEN];
|
char addr[BT_ADDR_LE_STR_LEN];
|
||||||
const bt_addr_le_t *dst = bt_conn_get_dst(conn);
|
const bt_addr_le_t *dst = bt_conn_get_dst(conn);
|
||||||
|
@ -413,12 +376,9 @@ static struct bt_conn_auth_cb zmk_ble_auth_cb_display = {
|
||||||
.cancel = auth_cancel,
|
.cancel = auth_cancel,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void zmk_ble_ready(int err) {
|
||||||
static void zmk_ble_ready(int err)
|
|
||||||
{
|
|
||||||
LOG_DBG("ready? %d", err);
|
LOG_DBG("ready? %d", err);
|
||||||
if (err)
|
if (err) {
|
||||||
{
|
|
||||||
LOG_ERR("Bluetooth init failed (err %d)", err);
|
LOG_ERR("Bluetooth init failed (err %d)", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -426,12 +386,10 @@ static void zmk_ble_ready(int err)
|
||||||
zmk_ble_adv_resume();
|
zmk_ble_adv_resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zmk_ble_init(struct device *_arg)
|
static int zmk_ble_init(struct device *_arg) {
|
||||||
{
|
|
||||||
int err = bt_enable(NULL);
|
int err = bt_enable(NULL);
|
||||||
|
|
||||||
if (err)
|
if (err) {
|
||||||
{
|
|
||||||
LOG_ERR("BLUETOOTH FAILED (%d)", err);
|
LOG_ERR("BLUETOOTH FAILED (%d)", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -475,8 +433,7 @@ static int zmk_ble_init(struct device *_arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_ble_unpair_all()
|
int zmk_ble_unpair_all() {
|
||||||
{
|
|
||||||
int resp = 0;
|
int resp = 0;
|
||||||
for (int i = BT_ID_DEFAULT; i < CONFIG_BT_ID_MAX; i++) {
|
for (int i = BT_ID_DEFAULT; i < CONFIG_BT_ID_MAX; i++) {
|
||||||
|
|
||||||
|
@ -490,17 +447,14 @@ int zmk_ble_unpair_all()
|
||||||
return resp;
|
return resp;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool zmk_ble_handle_key_user(struct zmk_key_event *key_event)
|
bool zmk_ble_handle_key_user(struct zmk_key_event *key_event) {
|
||||||
{
|
|
||||||
zmk_key key = key_event->key;
|
zmk_key key = key_event->key;
|
||||||
|
|
||||||
if (!auth_passkey_entry_conn)
|
if (!auth_passkey_entry_conn) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key < NUM_1 || key > NUM_0)
|
if (key < NUM_1 || key > NUM_0) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,11 +462,9 @@ bool zmk_ble_handle_key_user(struct zmk_key_event *key_event)
|
||||||
|
|
||||||
passkey_entries[passkey_digit++] = val;
|
passkey_entries[passkey_digit++] = val;
|
||||||
|
|
||||||
if (passkey_digit == 6)
|
if (passkey_digit == 6) {
|
||||||
{
|
|
||||||
u32_t passkey = 0;
|
u32_t passkey = 0;
|
||||||
for (int i = 5; i >= 0; i--)
|
for (int i = 5; i >= 0; i--) {
|
||||||
{
|
|
||||||
passkey = (passkey * 10) + val;
|
passkey = (passkey * 10) + val;
|
||||||
}
|
}
|
||||||
bt_conn_auth_passkey_entry(auth_passkey_entry_conn, passkey);
|
bt_conn_auth_passkey_entry(auth_passkey_entry_conn, passkey);
|
||||||
|
@ -523,6 +475,4 @@ bool zmk_ble_handle_key_user(struct zmk_key_event *key_event)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_INIT(zmk_ble_init,
|
SYS_INIT(zmk_ble_init, APPLICATION, CONFIG_ZMK_BLE_INIT_PRIORITY);
|
||||||
APPLICATION,
|
|
||||||
CONFIG_ZMK_BLE_INIT_PRIORITY);
|
|
||||||
|
|
|
@ -18,14 +18,12 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
#include <zmk/event-manager.h>
|
#include <zmk/event-manager.h>
|
||||||
#include <zmk/events/position-state-changed.h>
|
#include <zmk/events/position-state-changed.h>
|
||||||
|
|
||||||
|
|
||||||
static u8_t combo_state;
|
static u8_t combo_state;
|
||||||
|
|
||||||
const u32_t key_positions[] = DT_INST_PROP(0, key_positions);
|
const u32_t key_positions[] = DT_INST_PROP(0, key_positions);
|
||||||
#define KP_LEN DT_INST_PROP_LEN(0, key_positions)
|
#define KP_LEN DT_INST_PROP_LEN(0, key_positions)
|
||||||
|
|
||||||
int index_for_key_position(u32_t kp)
|
int index_for_key_position(u32_t kp) {
|
||||||
{
|
|
||||||
for (int i = 0; i < KP_LEN; i++) {
|
for (int i = 0; i < KP_LEN; i++) {
|
||||||
if (key_positions[i] == kp) {
|
if (key_positions[i] == kp) {
|
||||||
return i;
|
return i;
|
||||||
|
@ -35,8 +33,7 @@ int index_for_key_position(u32_t kp)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unpair_combo_listener(const struct zmk_event_header *eh)
|
int unpair_combo_listener(const struct zmk_event_header *eh) {
|
||||||
{
|
|
||||||
if (is_position_state_changed(eh)) {
|
if (is_position_state_changed(eh)) {
|
||||||
const struct position_state_changed *psc = cast_position_state_changed(eh);
|
const struct position_state_changed *psc = cast_position_state_changed(eh);
|
||||||
|
|
||||||
|
@ -51,8 +48,7 @@ int unpair_combo_listener(const struct zmk_event_header *eh)
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void unpair_combo_work_handler(struct k_work *work)
|
void unpair_combo_work_handler(struct k_work *work) {
|
||||||
{
|
|
||||||
for (int i = 0; i < KP_LEN; i++) {
|
for (int i = 0; i < KP_LEN; i++) {
|
||||||
if (!(combo_state & BIT(i))) {
|
if (!(combo_state & BIT(i))) {
|
||||||
LOG_DBG("Key position %d not held, skipping unpair combo", key_positions[i]);
|
LOG_DBG("Key position %d not held, skipping unpair combo", key_positions[i]);
|
||||||
|
@ -65,8 +61,7 @@ void unpair_combo_work_handler(struct k_work *work)
|
||||||
|
|
||||||
struct k_delayed_work unpair_combo_work;
|
struct k_delayed_work unpair_combo_work;
|
||||||
|
|
||||||
int zmk_ble_unpair_combo_init(struct device *_unused)
|
int zmk_ble_unpair_combo_init(struct device *_unused) {
|
||||||
{
|
|
||||||
k_delayed_work_init(&unpair_combo_work, unpair_combo_work_handler);
|
k_delayed_work_init(&unpair_combo_work, unpair_combo_work_handler);
|
||||||
k_delayed_work_submit(&unpair_combo_work, K_SECONDS(2));
|
k_delayed_work_submit(&unpair_combo_work, K_SECONDS(2));
|
||||||
|
|
||||||
|
@ -76,8 +71,6 @@ int zmk_ble_unpair_combo_init(struct device *_unused)
|
||||||
ZMK_LISTENER(zmk_ble_unpair_combo, unpair_combo_listener);
|
ZMK_LISTENER(zmk_ble_unpair_combo, unpair_combo_listener);
|
||||||
ZMK_SUBSCRIPTION(zmk_ble_unpair_combo, position_state_changed);
|
ZMK_SUBSCRIPTION(zmk_ble_unpair_combo, position_state_changed);
|
||||||
|
|
||||||
SYS_INIT(zmk_ble_unpair_combo_init,
|
SYS_INIT(zmk_ble_unpair_combo_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
|
||||||
APPLICATION,
|
|
||||||
CONFIG_APPLICATION_INIT_PRIORITY);
|
|
||||||
|
|
||||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
||||||
|
|
|
@ -20,8 +20,7 @@ static struct device *display;
|
||||||
|
|
||||||
static lv_obj_t *screen;
|
static lv_obj_t *screen;
|
||||||
|
|
||||||
int zmk_display_init()
|
int zmk_display_init() {
|
||||||
{
|
|
||||||
lv_obj_t *hello_world_label;
|
lv_obj_t *hello_world_label;
|
||||||
lv_obj_t *count_label;
|
lv_obj_t *count_label;
|
||||||
|
|
||||||
|
@ -48,8 +47,7 @@ int zmk_display_init()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmk_display_task_handler()
|
void zmk_display_task_handler() {
|
||||||
{
|
|
||||||
lv_tick_inc(10);
|
lv_tick_inc(10);
|
||||||
lv_task_handler();
|
lv_task_handler();
|
||||||
k_sleep(K_MSEC(10));
|
k_sleep(K_MSEC(10));
|
||||||
|
|
|
@ -12,27 +12,24 @@
|
||||||
#include <logging/log.h>
|
#include <logging/log.h>
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
int zmk_endpoints_send_report(u8_t usage_page)
|
int zmk_endpoints_send_report(u8_t usage_page) {
|
||||||
{
|
|
||||||
int err;
|
int err;
|
||||||
struct zmk_hid_keypad_report *keypad_report;
|
struct zmk_hid_keypad_report *keypad_report;
|
||||||
struct zmk_hid_consumer_report *consumer_report;
|
struct zmk_hid_consumer_report *consumer_report;
|
||||||
LOG_DBG("usage page 0x%02X", usage_page);
|
LOG_DBG("usage page 0x%02X", usage_page);
|
||||||
switch (usage_page)
|
switch (usage_page) {
|
||||||
{
|
|
||||||
case USAGE_KEYPAD:
|
case USAGE_KEYPAD:
|
||||||
keypad_report = zmk_hid_get_keypad_report();
|
keypad_report = zmk_hid_get_keypad_report();
|
||||||
#ifdef CONFIG_ZMK_USB
|
#ifdef CONFIG_ZMK_USB
|
||||||
if (zmk_usb_hid_send_report((u8_t *)keypad_report, sizeof(struct zmk_hid_keypad_report)) != 0)
|
if (zmk_usb_hid_send_report((u8_t *)keypad_report, sizeof(struct zmk_hid_keypad_report)) !=
|
||||||
{
|
0) {
|
||||||
LOG_DBG("USB Send Failed");
|
LOG_DBG("USB Send Failed");
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_ZMK_USB */
|
#endif /* CONFIG_ZMK_USB */
|
||||||
|
|
||||||
#ifdef CONFIG_ZMK_BLE
|
#ifdef CONFIG_ZMK_BLE
|
||||||
err = zmk_hog_send_keypad_report(&keypad_report->body);
|
err = zmk_hog_send_keypad_report(&keypad_report->body);
|
||||||
if (err)
|
if (err) {
|
||||||
{
|
|
||||||
LOG_ERR("FAILED TO SEND OVER HOG: %d", err);
|
LOG_ERR("FAILED TO SEND OVER HOG: %d", err);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_ZMK_BLE */
|
#endif /* CONFIG_ZMK_BLE */
|
||||||
|
@ -41,16 +38,15 @@ int zmk_endpoints_send_report(u8_t usage_page)
|
||||||
case USAGE_CONSUMER:
|
case USAGE_CONSUMER:
|
||||||
consumer_report = zmk_hid_get_consumer_report();
|
consumer_report = zmk_hid_get_consumer_report();
|
||||||
#ifdef CONFIG_ZMK_USB
|
#ifdef CONFIG_ZMK_USB
|
||||||
if (zmk_usb_hid_send_report((u8_t *)consumer_report, sizeof(struct zmk_hid_consumer_report)) != 0)
|
if (zmk_usb_hid_send_report((u8_t *)consumer_report,
|
||||||
{
|
sizeof(struct zmk_hid_consumer_report)) != 0) {
|
||||||
LOG_DBG("USB Send Failed");
|
LOG_DBG("USB Send Failed");
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_ZMK_USB */
|
#endif /* CONFIG_ZMK_USB */
|
||||||
|
|
||||||
#ifdef CONFIG_ZMK_BLE
|
#ifdef CONFIG_ZMK_BLE
|
||||||
err = zmk_hog_send_consumer_report(&consumer_report->body);
|
err = zmk_hog_send_consumer_report(&consumer_report->body);
|
||||||
if (err)
|
if (err) {
|
||||||
{
|
|
||||||
LOG_ERR("FAILED TO SEND OVER HOG: %d", err);
|
LOG_ERR("FAILED TO SEND OVER HOG: %d", err);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_ZMK_BLE */
|
#endif /* CONFIG_ZMK_BLE */
|
||||||
|
@ -63,4 +59,3 @@ int zmk_endpoints_send_report(u8_t usage_page)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,15 +11,13 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#include <zmk/event-manager.h>
|
#include <zmk/event-manager.h>
|
||||||
|
|
||||||
extern struct zmk_event_type* __event_type_start[];
|
extern struct zmk_event_type *__event_type_start[];
|
||||||
extern struct zmk_event_type* __event_type_end[];
|
extern struct zmk_event_type *__event_type_end[];
|
||||||
|
|
||||||
extern struct zmk_event_subscription __event_subscriptions_start[];
|
extern struct zmk_event_subscription __event_subscriptions_start[];
|
||||||
extern struct zmk_event_subscription __event_subscriptions_end[];
|
extern struct zmk_event_subscription __event_subscriptions_end[];
|
||||||
|
|
||||||
|
int zmk_event_manager_handle_from(struct zmk_event_header *event, u8_t start_index) {
|
||||||
int zmk_event_manager_handle_from(struct zmk_event_header *event, u8_t start_index)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u8_t len = __event_subscriptions_end - __event_subscriptions_start;
|
u8_t len = __event_subscriptions_end - __event_subscriptions_start;
|
||||||
for (int i = start_index; i < len; i++) {
|
for (int i = start_index; i < len; i++) {
|
||||||
|
@ -50,19 +48,18 @@ release:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_event_manager_raise(struct zmk_event_header *event)
|
int zmk_event_manager_raise(struct zmk_event_header *event) {
|
||||||
{
|
|
||||||
return zmk_event_manager_handle_from(event, 0);
|
return zmk_event_manager_handle_from(event, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_event_manager_raise_after(struct zmk_event_header *event, const struct zmk_listener *listener)
|
int zmk_event_manager_raise_after(struct zmk_event_header *event,
|
||||||
{
|
const struct zmk_listener *listener) {
|
||||||
u8_t len = __event_subscriptions_end - __event_subscriptions_start;
|
u8_t len = __event_subscriptions_end - __event_subscriptions_start;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
struct zmk_event_subscription *ev_sub = __event_subscriptions_start + i;
|
struct zmk_event_subscription *ev_sub = __event_subscriptions_start + i;
|
||||||
|
|
||||||
if (ev_sub->event_type == event->event && ev_sub->listener == listener) {
|
if (ev_sub->event_type == event->event && ev_sub->listener == listener) {
|
||||||
return zmk_event_manager_handle_from(event, i+1);
|
return zmk_event_manager_handle_from(event, i + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,8 +68,8 @@ int zmk_event_manager_raise_after(struct zmk_event_header *event, const struct z
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_event_manager_raise_at(struct zmk_event_header *event, const struct zmk_listener *listener)
|
int zmk_event_manager_raise_at(struct zmk_event_header *event,
|
||||||
{
|
const struct zmk_listener *listener) {
|
||||||
u8_t len = __event_subscriptions_end - __event_subscriptions_start;
|
u8_t len = __event_subscriptions_end - __event_subscriptions_start;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
struct zmk_event_subscription *ev_sub = __event_subscriptions_start + i;
|
struct zmk_event_subscription *ev_sub = __event_subscriptions_start + i;
|
||||||
|
@ -87,7 +84,6 @@ int zmk_event_manager_raise_at(struct zmk_event_header *event, const struct zmk_
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_event_manager_release(struct zmk_event_header *event)
|
int zmk_event_manager_release(struct zmk_event_header *event) {
|
||||||
{
|
|
||||||
return zmk_event_manager_handle_from(event, event->last_listener_index + 1);
|
return zmk_event_manager_handle_from(event, event->last_listener_index + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,41 +10,27 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
#include <zmk/hid.h>
|
#include <zmk/hid.h>
|
||||||
|
|
||||||
static struct zmk_hid_keypad_report kp_report = {
|
static struct zmk_hid_keypad_report kp_report = {
|
||||||
.report_id = 1,
|
.report_id = 1, .body = {.modifiers = 0, .keys = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}};
|
||||||
.body = {
|
|
||||||
.modifiers = 0,
|
|
||||||
.keys = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}};
|
|
||||||
|
|
||||||
static struct zmk_hid_consumer_report consumer_report = {
|
static struct zmk_hid_consumer_report consumer_report = {.report_id = 2,
|
||||||
.report_id = 2,
|
.body = {.keys = {0, 0, 0, 0, 0, 0}}};
|
||||||
.body = {
|
|
||||||
.keys = {0,0,0,0,0,0}}};
|
|
||||||
|
|
||||||
#define _TOGGLE_MOD(mod, state) \
|
#define _TOGGLE_MOD(mod, state) \
|
||||||
if (modifier > MOD_RGUI) \
|
if (modifier > MOD_RGUI) { \
|
||||||
{ \
|
|
||||||
return -EINVAL; \
|
return -EINVAL; \
|
||||||
} \
|
} \
|
||||||
WRITE_BIT(kp_report.body.modifiers, mod, state); \
|
WRITE_BIT(kp_report.body.modifiers, mod, state); \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int zmk_hid_register_mod(zmk_mod modifier)
|
int zmk_hid_register_mod(zmk_mod modifier) { _TOGGLE_MOD(modifier, true); }
|
||||||
{
|
int zmk_hid_unregister_mod(zmk_mod modifier) { _TOGGLE_MOD(modifier, false); }
|
||||||
_TOGGLE_MOD(modifier, true);
|
|
||||||
}
|
|
||||||
int zmk_hid_unregister_mod(zmk_mod modifier)
|
|
||||||
{
|
|
||||||
_TOGGLE_MOD(modifier, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int zmk_hid_register_mods(zmk_mod_flags modifiers)
|
int zmk_hid_register_mods(zmk_mod_flags modifiers) {
|
||||||
{
|
|
||||||
kp_report.body.modifiers |= modifiers;
|
kp_report.body.modifiers |= modifiers;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_hid_unregister_mods(zmk_mod_flags modifiers)
|
int zmk_hid_unregister_mods(zmk_mod_flags modifiers) {
|
||||||
{
|
|
||||||
kp_report.body.modifiers &= ~modifiers;
|
kp_report.body.modifiers &= ~modifiers;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -68,27 +54,20 @@ int zmk_hid_unregister_mods(zmk_mod_flags modifiers)
|
||||||
#define TOGGLE_KEY(code, val) WRITE_BIT(kp_report.body.keys[code / 8], code % 8, val)
|
#define TOGGLE_KEY(code, val) WRITE_BIT(kp_report.body.keys[code / 8], code % 8, val)
|
||||||
|
|
||||||
#define TOGGLE_CONSUMER(match, val) \
|
#define TOGGLE_CONSUMER(match, val) \
|
||||||
for (int idx = 0; idx < MAX_KEYS; idx++) \
|
for (int idx = 0; idx < MAX_KEYS; idx++) { \
|
||||||
{ \
|
if (consumer_report.body.keys[idx] != match) { \
|
||||||
if (consumer_report.body.keys[idx] != match) \
|
|
||||||
{ \
|
|
||||||
continue; \
|
continue; \
|
||||||
} \
|
} \
|
||||||
consumer_report.body.keys[idx] = val; \
|
consumer_report.body.keys[idx] = val; \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int zmk_hid_keypad_press(zmk_key code) {
|
||||||
int zmk_hid_keypad_press(zmk_key code)
|
if (code >= LCTL && code <= RGUI) {
|
||||||
{
|
|
||||||
if (code >= LCTL && code <= RGUI)
|
|
||||||
{
|
|
||||||
return zmk_hid_register_mod(code - LCTL);
|
return zmk_hid_register_mod(code - LCTL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (code > ZMK_HID_MAX_KEYCODE) {
|
||||||
if (code > ZMK_HID_MAX_KEYCODE)
|
|
||||||
{
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,15 +78,12 @@ int zmk_hid_keypad_press(zmk_key code)
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
int zmk_hid_keypad_release(zmk_key code)
|
int zmk_hid_keypad_release(zmk_key code) {
|
||||||
{
|
if (code >= LCTL && code <= RGUI) {
|
||||||
if (code >= LCTL && code <= RGUI)
|
|
||||||
{
|
|
||||||
return zmk_hid_unregister_mod(code - LCTL);
|
return zmk_hid_unregister_mod(code - LCTL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code > ZMK_HID_MAX_KEYCODE)
|
if (code > ZMK_HID_MAX_KEYCODE) {
|
||||||
{
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,25 +94,20 @@ int zmk_hid_keypad_release(zmk_key code)
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
int zmk_hid_consumer_press(zmk_key code)
|
int zmk_hid_consumer_press(zmk_key code) {
|
||||||
{
|
|
||||||
TOGGLE_CONSUMER(0U, code);
|
TOGGLE_CONSUMER(0U, code);
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int zmk_hid_consumer_release(zmk_key code) {
|
||||||
int zmk_hid_consumer_release(zmk_key code)
|
|
||||||
{
|
|
||||||
TOGGLE_CONSUMER(code, 0U);
|
TOGGLE_CONSUMER(code, 0U);
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zmk_hid_keypad_report *zmk_hid_get_keypad_report()
|
struct zmk_hid_keypad_report *zmk_hid_get_keypad_report() {
|
||||||
{
|
|
||||||
return &kp_report;
|
return &kp_report;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct zmk_hid_consumer_report *zmk_hid_get_consumer_report()
|
struct zmk_hid_consumer_report *zmk_hid_get_consumer_report() {
|
||||||
{
|
|
||||||
return &consumer_report;
|
return &consumer_report;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
#include <zmk/hid.h>
|
#include <zmk/hid.h>
|
||||||
#include <zmk/endpoints.h>
|
#include <zmk/endpoints.h>
|
||||||
|
|
||||||
|
static int hid_listener_keycode_pressed(u8_t usage_page, u32_t keycode) {
|
||||||
static int hid_listener_keycode_pressed(u8_t usage_page, u32_t keycode)
|
|
||||||
{
|
|
||||||
int err;
|
int err;
|
||||||
LOG_DBG("usage_page 0x%02X keycode 0x%02X", usage_page, keycode);
|
LOG_DBG("usage_page 0x%02X keycode 0x%02X", usage_page, keycode);
|
||||||
|
|
||||||
|
@ -41,8 +39,7 @@ static int hid_listener_keycode_pressed(u8_t usage_page, u32_t keycode)
|
||||||
return zmk_endpoints_send_report(usage_page);
|
return zmk_endpoints_send_report(usage_page);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hid_listener_keycode_released(u8_t usage_page, u32_t keycode)
|
static int hid_listener_keycode_released(u8_t usage_page, u32_t keycode) {
|
||||||
{
|
|
||||||
int err;
|
int err;
|
||||||
LOG_DBG("usage_page 0x%02X keycode 0x%02X", usage_page, keycode);
|
LOG_DBG("usage_page 0x%02X keycode 0x%02X", usage_page, keycode);
|
||||||
|
|
||||||
|
@ -65,24 +62,21 @@ static int hid_listener_keycode_released(u8_t usage_page, u32_t keycode)
|
||||||
return zmk_endpoints_send_report(usage_page);
|
return zmk_endpoints_send_report(usage_page);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hid_listener_modifiers_pressed(zmk_mod_flags modifiers)
|
static int hid_listener_modifiers_pressed(zmk_mod_flags modifiers) {
|
||||||
{
|
|
||||||
LOG_DBG("modifiers %d", modifiers);
|
LOG_DBG("modifiers %d", modifiers);
|
||||||
|
|
||||||
zmk_hid_register_mods(modifiers);
|
zmk_hid_register_mods(modifiers);
|
||||||
return zmk_endpoints_send_report(USAGE_KEYPAD);
|
return zmk_endpoints_send_report(USAGE_KEYPAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hid_listener_modifiers_released(zmk_mod_flags modifiers)
|
static int hid_listener_modifiers_released(zmk_mod_flags modifiers) {
|
||||||
{
|
|
||||||
LOG_DBG("modifiers %d", modifiers);
|
LOG_DBG("modifiers %d", modifiers);
|
||||||
|
|
||||||
zmk_hid_unregister_mods(modifiers);
|
zmk_hid_unregister_mods(modifiers);
|
||||||
return zmk_endpoints_send_report(USAGE_KEYPAD);
|
return zmk_endpoints_send_report(USAGE_KEYPAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hid_listener(const struct zmk_event_header *eh)
|
int hid_listener(const struct zmk_event_header *eh) {
|
||||||
{
|
|
||||||
if (is_keycode_state_changed(eh)) {
|
if (is_keycode_state_changed(eh)) {
|
||||||
const struct keycode_state_changed *ev = cast_keycode_state_changed(eh);
|
const struct keycode_state_changed *ev = cast_keycode_state_changed(eh);
|
||||||
if (ev->state) {
|
if (ev->state) {
|
||||||
|
|
118
app/src/hog.c
118
app/src/hog.c
|
@ -17,21 +17,18 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
#include <zmk/hog.h>
|
#include <zmk/hog.h>
|
||||||
#include <zmk/hid.h>
|
#include <zmk/hid.h>
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
HIDS_REMOTE_WAKE = BIT(0),
|
HIDS_REMOTE_WAKE = BIT(0),
|
||||||
HIDS_NORMALLY_CONNECTABLE = BIT(1),
|
HIDS_NORMALLY_CONNECTABLE = BIT(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hids_info
|
struct hids_info {
|
||||||
{
|
|
||||||
u16_t version; /* version number of base USB HID Specification */
|
u16_t version; /* version number of base USB HID Specification */
|
||||||
u8_t code; /* country HID Device hardware is localized for. */
|
u8_t code; /* country HID Device hardware is localized for. */
|
||||||
u8_t flags;
|
u8_t flags;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct hids_report
|
struct hids_report {
|
||||||
{
|
|
||||||
u8_t id; /* report id */
|
u8_t id; /* report id */
|
||||||
u8_t type; /* report type */
|
u8_t type; /* report type */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
@ -42,8 +39,7 @@ static struct hids_info info = {
|
||||||
.flags = HIDS_NORMALLY_CONNECTABLE & HIDS_REMOTE_WAKE,
|
.flags = HIDS_NORMALLY_CONNECTABLE & HIDS_REMOTE_WAKE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
HIDS_INPUT = 0x01,
|
HIDS_INPUT = 0x01,
|
||||||
HIDS_OUTPUT = 0x02,
|
HIDS_OUTPUT = 0x02,
|
||||||
HIDS_FEATURE = 0x03,
|
HIDS_FEATURE = 0x03,
|
||||||
|
@ -63,31 +59,37 @@ static bool host_requests_notification = false;
|
||||||
static u8_t ctrl_point;
|
static u8_t ctrl_point;
|
||||||
// static u8_t proto_mode;
|
// static u8_t proto_mode;
|
||||||
|
|
||||||
static ssize_t read_hids_info(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset)
|
static ssize_t read_hids_info(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
|
||||||
{
|
u16_t len, u16_t offset) {
|
||||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, attr->user_data, sizeof(struct hids_info));
|
return bt_gatt_attr_read(conn, attr, buf, len, offset, attr->user_data,
|
||||||
|
sizeof(struct hids_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t read_hids_report_ref(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset)
|
static ssize_t read_hids_report_ref(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||||
{
|
void *buf, u16_t len, u16_t offset) {
|
||||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, attr->user_data, sizeof(struct hids_report));
|
return bt_gatt_attr_read(conn, attr, buf, len, offset, attr->user_data,
|
||||||
|
sizeof(struct hids_report));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t read_hids_report_map(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset)
|
static ssize_t read_hids_report_map(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||||
{
|
void *buf, u16_t len, u16_t offset) {
|
||||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, zmk_hid_report_desc, sizeof(zmk_hid_report_desc));
|
return bt_gatt_attr_read(conn, attr, buf, len, offset, zmk_hid_report_desc,
|
||||||
|
sizeof(zmk_hid_report_desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t read_hids_input_report(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset)
|
static ssize_t read_hids_input_report(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||||
{
|
void *buf, u16_t len, u16_t offset) {
|
||||||
struct zmk_hid_keypad_report_body *report_body = &zmk_hid_get_keypad_report()->body;
|
struct zmk_hid_keypad_report_body *report_body = &zmk_hid_get_keypad_report()->body;
|
||||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, report_body, sizeof(struct zmk_hid_keypad_report_body));
|
return bt_gatt_attr_read(conn, attr, buf, len, offset, report_body,
|
||||||
|
sizeof(struct zmk_hid_keypad_report_body));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t read_hids_consumer_input_report(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset)
|
static ssize_t read_hids_consumer_input_report(struct bt_conn *conn,
|
||||||
{
|
const struct bt_gatt_attr *attr, void *buf,
|
||||||
|
u16_t len, u16_t offset) {
|
||||||
struct zmk_hid_consumer_report_body *report_body = &zmk_hid_get_consumer_report()->body;
|
struct zmk_hid_consumer_report_body *report_body = &zmk_hid_get_consumer_report()->body;
|
||||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, report_body, sizeof(struct zmk_hid_consumer_report_body));
|
return bt_gatt_attr_read(conn, attr, buf, len, offset, report_body,
|
||||||
|
sizeof(struct zmk_hid_consumer_report_body));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static ssize_t write_proto_mode(struct bt_conn *conn,
|
// static ssize_t write_proto_mode(struct bt_conn *conn,
|
||||||
|
@ -99,20 +101,15 @@ static ssize_t read_hids_consumer_input_report(struct bt_conn *conn, const struc
|
||||||
// return 0;
|
// return 0;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
static void input_ccc_changed(const struct bt_gatt_attr *attr, u16_t value)
|
static void input_ccc_changed(const struct bt_gatt_attr *attr, u16_t value) {
|
||||||
{
|
|
||||||
host_requests_notification = (value == BT_GATT_CCC_NOTIFY) ? 1 : 0;
|
host_requests_notification = (value == BT_GATT_CCC_NOTIFY) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t write_ctrl_point(struct bt_conn *conn,
|
static ssize_t write_ctrl_point(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||||
const struct bt_gatt_attr *attr,
|
const void *buf, u16_t len, u16_t offset, u8_t flags) {
|
||||||
const void *buf, u16_t len, u16_t offset,
|
|
||||||
u8_t flags)
|
|
||||||
{
|
|
||||||
u8_t *value = attr->user_data;
|
u8_t *value = attr->user_data;
|
||||||
|
|
||||||
if (offset + len > sizeof(ctrl_point))
|
if (offset + len > sizeof(ctrl_point)) {
|
||||||
{
|
|
||||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
|
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,35 +119,27 @@ static ssize_t write_ctrl_point(struct bt_conn *conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HID Service Declaration */
|
/* HID Service Declaration */
|
||||||
BT_GATT_SERVICE_DEFINE(hog_svc,
|
BT_GATT_SERVICE_DEFINE(
|
||||||
BT_GATT_PRIMARY_SERVICE(BT_UUID_HIDS),
|
hog_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_HIDS),
|
||||||
// BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_PROTOCOL_MODE, BT_GATT_CHRC_WRITE_WITHOUT_RESP,
|
// BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_PROTOCOL_MODE, BT_GATT_CHRC_WRITE_WITHOUT_RESP,
|
||||||
// BT_GATT_PERM_WRITE, NULL, write_proto_mode, &proto_mode),
|
// BT_GATT_PERM_WRITE, NULL, write_proto_mode, &proto_mode),
|
||||||
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_INFO, BT_GATT_CHRC_READ,
|
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_INFO, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, read_hids_info,
|
||||||
BT_GATT_PERM_READ, read_hids_info, NULL, &info),
|
NULL, &info),
|
||||||
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT_MAP, BT_GATT_CHRC_READ,
|
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT_MAP, BT_GATT_CHRC_READ, BT_GATT_PERM_READ,
|
||||||
BT_GATT_PERM_READ, read_hids_report_map, NULL, NULL),
|
read_hids_report_map, NULL, NULL),
|
||||||
|
|
||||||
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT,
|
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
|
||||||
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
|
BT_GATT_PERM_READ_ENCRYPT, read_hids_input_report, NULL, NULL),
|
||||||
BT_GATT_PERM_READ_ENCRYPT,
|
BT_GATT_CCC(input_ccc_changed, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
|
||||||
read_hids_input_report, NULL, NULL),
|
BT_GATT_DESCRIPTOR(BT_UUID_HIDS_REPORT_REF, BT_GATT_PERM_READ, read_hids_report_ref, NULL,
|
||||||
BT_GATT_CCC(input_ccc_changed,
|
&input),
|
||||||
BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
|
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
|
||||||
BT_GATT_DESCRIPTOR(BT_UUID_HIDS_REPORT_REF, BT_GATT_PERM_READ,
|
BT_GATT_PERM_READ_ENCRYPT, read_hids_consumer_input_report, NULL, NULL),
|
||||||
read_hids_report_ref, NULL, &input),
|
BT_GATT_CCC(input_ccc_changed, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
|
||||||
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT,
|
BT_GATT_DESCRIPTOR(BT_UUID_HIDS_REPORT_REF, BT_GATT_PERM_READ, read_hids_report_ref, NULL,
|
||||||
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
|
&consumer_input),
|
||||||
BT_GATT_PERM_READ_ENCRYPT,
|
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_CTRL_POINT, BT_GATT_CHRC_WRITE_WITHOUT_RESP,
|
||||||
read_hids_consumer_input_report, NULL, NULL),
|
BT_GATT_PERM_WRITE, NULL, write_ctrl_point, &ctrl_point));
|
||||||
BT_GATT_CCC(input_ccc_changed,
|
|
||||||
BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
|
|
||||||
BT_GATT_DESCRIPTOR(BT_UUID_HIDS_REPORT_REF, BT_GATT_PERM_READ,
|
|
||||||
read_hids_report_ref, NULL, &consumer_input),
|
|
||||||
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_CTRL_POINT,
|
|
||||||
BT_GATT_CHRC_WRITE_WITHOUT_RESP,
|
|
||||||
BT_GATT_PERM_WRITE,
|
|
||||||
NULL, write_ctrl_point, &ctrl_point));
|
|
||||||
|
|
||||||
struct bt_conn *destination_connection() {
|
struct bt_conn *destination_connection() {
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
|
@ -165,11 +154,9 @@ struct bt_conn *destination_connection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return conn;
|
return conn;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_hog_send_keypad_report(struct zmk_hid_keypad_report_body *report)
|
int zmk_hog_send_keypad_report(struct zmk_hid_keypad_report_body *report) {
|
||||||
{
|
|
||||||
struct bt_conn *conn = destination_connection();
|
struct bt_conn *conn = destination_connection();
|
||||||
if (conn == NULL) {
|
if (conn == NULL) {
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
|
@ -177,15 +164,16 @@ int zmk_hog_send_keypad_report(struct zmk_hid_keypad_report_body *report)
|
||||||
|
|
||||||
LOG_DBG("Sending to NULL? %s", conn == NULL ? "yes" : "no");
|
LOG_DBG("Sending to NULL? %s", conn == NULL ? "yes" : "no");
|
||||||
|
|
||||||
return bt_gatt_notify(conn, &hog_svc.attrs[5], report, sizeof(struct zmk_hid_keypad_report_body));
|
return bt_gatt_notify(conn, &hog_svc.attrs[5], report,
|
||||||
|
sizeof(struct zmk_hid_keypad_report_body));
|
||||||
};
|
};
|
||||||
|
|
||||||
int zmk_hog_send_consumer_report(struct zmk_hid_consumer_report_body *report)
|
int zmk_hog_send_consumer_report(struct zmk_hid_consumer_report_body *report) {
|
||||||
{
|
|
||||||
struct bt_conn *conn = destination_connection();
|
struct bt_conn *conn = destination_connection();
|
||||||
if (conn == NULL) {
|
if (conn == NULL) {
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bt_gatt_notify(conn, &hog_svc.attrs[10], report, sizeof(struct zmk_hid_consumer_report_body));
|
return bt_gatt_notify(conn, &hog_svc.attrs[10], report,
|
||||||
|
sizeof(struct zmk_hid_consumer_report_body));
|
||||||
};
|
};
|
||||||
|
|
111
app/src/keymap.c
111
app/src/keymap.c
|
@ -24,32 +24,37 @@ static u8_t zmk_keymap_layer_default = 0;
|
||||||
|
|
||||||
#define DT_DRV_COMPAT zmk_keymap
|
#define DT_DRV_COMPAT zmk_keymap
|
||||||
|
|
||||||
#define LAYER_CHILD_LEN(node) 1+
|
#define LAYER_CHILD_LEN(node) 1 +
|
||||||
#define ZMK_KEYMAP_NODE DT_DRV_INST(0)
|
#define ZMK_KEYMAP_NODE DT_DRV_INST(0)
|
||||||
#define ZMK_KEYMAP_LAYERS_LEN (DT_INST_FOREACH_CHILD(0, LAYER_CHILD_LEN) 0)
|
#define ZMK_KEYMAP_LAYERS_LEN (DT_INST_FOREACH_CHILD(0, LAYER_CHILD_LEN) 0)
|
||||||
|
|
||||||
#define LAYER_NODE(l) DT_PHANDLE_BY_IDX(ZMK_KEYMAP_NODE, layers, l)
|
#define LAYER_NODE(l) DT_PHANDLE_BY_IDX(ZMK_KEYMAP_NODE, layers, l)
|
||||||
|
|
||||||
#define _TRANSFORM_ENTRY(idx, layer) \
|
#define _TRANSFORM_ENTRY(idx, layer) \
|
||||||
{ .behavior_dev = DT_LABEL(DT_PHANDLE_BY_IDX(layer, bindings, idx)), \
|
{ \
|
||||||
.param1 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(layer, bindings, idx, param1), (0), (DT_PHA_BY_IDX(layer, bindings, idx, param1))), \
|
.behavior_dev = DT_LABEL(DT_PHANDLE_BY_IDX(layer, bindings, idx)), \
|
||||||
.param2 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(layer, bindings, idx, param2), (0), (DT_PHA_BY_IDX(layer, bindings, idx, param2))), \
|
.param1 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(layer, bindings, idx, param1), (0), \
|
||||||
|
(DT_PHA_BY_IDX(layer, bindings, idx, param1))), \
|
||||||
|
.param2 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(layer, bindings, idx, param2), (0), \
|
||||||
|
(DT_PHA_BY_IDX(layer, bindings, idx, param2))), \
|
||||||
},
|
},
|
||||||
|
|
||||||
#define TRANSFORMED_LAYER(node) \
|
#define TRANSFORMED_LAYER(node) {UTIL_LISTIFY(DT_PROP_LEN(node, bindings), _TRANSFORM_ENTRY, node)},
|
||||||
{ UTIL_LISTIFY(DT_PROP_LEN(node, bindings), _TRANSFORM_ENTRY, node) },
|
|
||||||
|
|
||||||
|
|
||||||
#if ZMK_KEYMAP_HAS_SENSORS
|
#if ZMK_KEYMAP_HAS_SENSORS
|
||||||
#define _TRANSFORM_SENSOR_ENTRY(idx, layer) \
|
#define _TRANSFORM_SENSOR_ENTRY(idx, layer) \
|
||||||
{ .behavior_dev = DT_LABEL(DT_PHANDLE_BY_IDX(layer, sensor_bindings, idx)), \
|
{ \
|
||||||
.param1 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(layer, sensor_bindings, idx, param1), (0), (DT_PHA_BY_IDX(layer, sensor_bindings, idx, param1))), \
|
.behavior_dev = DT_LABEL(DT_PHANDLE_BY_IDX(layer, sensor_bindings, idx)), \
|
||||||
.param2 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(layer, sensor_bindings, idx, param2), (0), (DT_PHA_BY_IDX(layer, sensor_bindings, idx, param2))), \
|
.param1 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(layer, sensor_bindings, idx, param1), (0), \
|
||||||
|
(DT_PHA_BY_IDX(layer, sensor_bindings, idx, param1))), \
|
||||||
|
.param2 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(layer, sensor_bindings, idx, param2), (0), \
|
||||||
|
(DT_PHA_BY_IDX(layer, sensor_bindings, idx, param2))), \
|
||||||
},
|
},
|
||||||
|
|
||||||
#define SENSOR_LAYER(node) \
|
#define SENSOR_LAYER(node) \
|
||||||
COND_CODE_1(DT_NODE_HAS_PROP(node, sensor_bindings), \
|
COND_CODE_1( \
|
||||||
({ UTIL_LISTIFY(DT_PROP_LEN(node, sensor_bindings), _TRANSFORM_SENSOR_ENTRY, node) }), \
|
DT_NODE_HAS_PROP(node, sensor_bindings), \
|
||||||
|
({UTIL_LISTIFY(DT_PROP_LEN(node, sensor_bindings), _TRANSFORM_SENSOR_ENTRY, node)}), \
|
||||||
({})),
|
({})),
|
||||||
|
|
||||||
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
||||||
|
@ -62,62 +67,49 @@ static u8_t zmk_keymap_layer_default = 0;
|
||||||
static u32_t zmk_keymap_active_behavior_layer[ZMK_KEYMAP_LEN];
|
static u32_t zmk_keymap_active_behavior_layer[ZMK_KEYMAP_LEN];
|
||||||
|
|
||||||
static struct zmk_behavior_binding zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_KEYMAP_LEN] = {
|
static struct zmk_behavior_binding zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_KEYMAP_LEN] = {
|
||||||
DT_INST_FOREACH_CHILD(0, TRANSFORMED_LAYER)
|
DT_INST_FOREACH_CHILD(0, TRANSFORMED_LAYER)};
|
||||||
};
|
|
||||||
|
|
||||||
#if ZMK_KEYMAP_HAS_SENSORS
|
#if ZMK_KEYMAP_HAS_SENSORS
|
||||||
|
|
||||||
static struct zmk_behavior_binding zmk_sensor_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_KEYMAP_SENSORS_LEN] = {
|
static struct zmk_behavior_binding zmk_sensor_keymap[ZMK_KEYMAP_LAYERS_LEN]
|
||||||
DT_INST_FOREACH_CHILD(0, SENSOR_LAYER)
|
[ZMK_KEYMAP_SENSORS_LEN] = {
|
||||||
};
|
DT_INST_FOREACH_CHILD(0, SENSOR_LAYER)};
|
||||||
|
|
||||||
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
||||||
|
|
||||||
#define SET_LAYER_STATE(layer, state) \
|
#define SET_LAYER_STATE(layer, state) \
|
||||||
if (layer >= 32) \
|
if (layer >= 32) { \
|
||||||
{ \
|
|
||||||
return -EINVAL; \
|
return -EINVAL; \
|
||||||
} \
|
} \
|
||||||
WRITE_BIT(zmk_keymap_layer_state, layer, state); \
|
WRITE_BIT(zmk_keymap_layer_state, layer, state); \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bool zmk_keymap_layer_active(u8_t layer)
|
bool zmk_keymap_layer_active(u8_t layer) {
|
||||||
{
|
|
||||||
return (zmk_keymap_layer_state & (BIT(layer))) == (BIT(layer));
|
return (zmk_keymap_layer_state & (BIT(layer))) == (BIT(layer));
|
||||||
};
|
};
|
||||||
|
|
||||||
int zmk_keymap_layer_activate(u8_t layer)
|
int zmk_keymap_layer_activate(u8_t layer) { SET_LAYER_STATE(layer, true); };
|
||||||
{
|
|
||||||
SET_LAYER_STATE(layer, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
int zmk_keymap_layer_deactivate(u8_t layer)
|
int zmk_keymap_layer_deactivate(u8_t layer) { SET_LAYER_STATE(layer, false); };
|
||||||
{
|
|
||||||
SET_LAYER_STATE(layer, false);
|
|
||||||
};
|
|
||||||
|
|
||||||
int zmk_keymap_layer_toggle(u8_t layer)
|
int zmk_keymap_layer_toggle(u8_t layer) {
|
||||||
{
|
if (zmk_keymap_layer_active(layer)) {
|
||||||
if (zmk_keymap_layer_active(layer))
|
|
||||||
{
|
|
||||||
return zmk_keymap_layer_deactivate(layer);
|
return zmk_keymap_layer_deactivate(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return zmk_keymap_layer_activate(layer);
|
return zmk_keymap_layer_activate(layer);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool is_active_layer(u8_t layer, u32_t layer_state)
|
bool is_active_layer(u8_t layer, u32_t layer_state) {
|
||||||
{
|
return (layer_state & BIT(layer)) == BIT(layer) || layer == zmk_keymap_layer_default;
|
||||||
return (layer_state & BIT(layer)) == BIT(layer)
|
|
||||||
|| layer == zmk_keymap_layer_default;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_keymap_apply_position_state(int layer, u32_t position, bool pressed)
|
int zmk_keymap_apply_position_state(int layer, u32_t position, bool pressed) {
|
||||||
{
|
|
||||||
struct zmk_behavior_binding *binding = &zmk_keymap[layer][position];
|
struct zmk_behavior_binding *binding = &zmk_keymap[layer][position];
|
||||||
struct device *behavior;
|
struct device *behavior;
|
||||||
|
|
||||||
LOG_DBG("layer: %d position: %d, binding name: %s", layer, position, log_strdup(binding->behavior_dev));
|
LOG_DBG("layer: %d position: %d, binding name: %s", layer, position,
|
||||||
|
log_strdup(binding->behavior_dev));
|
||||||
|
|
||||||
behavior = device_get_binding(binding->behavior_dev);
|
behavior = device_get_binding(binding->behavior_dev);
|
||||||
|
|
||||||
|
@ -127,19 +119,19 @@ int zmk_keymap_apply_position_state(int layer, u32_t position, bool pressed)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
return behavior_keymap_binding_pressed(behavior, position, binding->param1, binding->param2);
|
return behavior_keymap_binding_pressed(behavior, position, binding->param1,
|
||||||
|
binding->param2);
|
||||||
} else {
|
} else {
|
||||||
return behavior_keymap_binding_released(behavior, position, binding->param1, binding->param2);
|
return behavior_keymap_binding_released(behavior, position, binding->param1,
|
||||||
|
binding->param2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_keymap_position_state_changed(u32_t position, bool pressed)
|
int zmk_keymap_position_state_changed(u32_t position, bool pressed) {
|
||||||
{
|
for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= zmk_keymap_layer_default; layer--) {
|
||||||
for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= zmk_keymap_layer_default; layer--)
|
u32_t layer_state =
|
||||||
{
|
pressed ? zmk_keymap_layer_state : zmk_keymap_active_behavior_layer[position];
|
||||||
u32_t layer_state = pressed ? zmk_keymap_layer_state : zmk_keymap_active_behavior_layer[position];
|
if (is_active_layer(layer, layer_state)) {
|
||||||
if (is_active_layer(layer, layer_state))
|
|
||||||
{
|
|
||||||
int ret = zmk_keymap_apply_position_state(layer, position, pressed);
|
int ret = zmk_keymap_apply_position_state(layer, position, pressed);
|
||||||
|
|
||||||
zmk_keymap_active_behavior_layer[position] = zmk_keymap_layer_state;
|
zmk_keymap_active_behavior_layer[position] = zmk_keymap_layer_state;
|
||||||
|
@ -160,17 +152,17 @@ int zmk_keymap_position_state_changed(u32_t position, bool pressed)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ZMK_KEYMAP_HAS_SENSORS
|
#if ZMK_KEYMAP_HAS_SENSORS
|
||||||
int zmk_keymap_sensor_triggered(u8_t sensor_number, struct device *sensor)
|
int zmk_keymap_sensor_triggered(u8_t sensor_number, struct device *sensor) {
|
||||||
{
|
for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= zmk_keymap_layer_default; layer--) {
|
||||||
for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= zmk_keymap_layer_default; layer--)
|
if (((zmk_keymap_layer_state & BIT(layer)) == BIT(layer) ||
|
||||||
{
|
layer == zmk_keymap_layer_default) &&
|
||||||
if (((zmk_keymap_layer_state & BIT(layer)) == BIT(layer) || layer == zmk_keymap_layer_default) && zmk_sensor_keymap[layer] != NULL)
|
zmk_sensor_keymap[layer] != NULL) {
|
||||||
{
|
|
||||||
struct zmk_behavior_binding *binding = &zmk_sensor_keymap[layer][sensor_number];
|
struct zmk_behavior_binding *binding = &zmk_sensor_keymap[layer][sensor_number];
|
||||||
struct device *behavior;
|
struct device *behavior;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
LOG_DBG("layer: %d sensor_number: %d, binding name: %s", layer, sensor_number, log_strdup(binding->behavior_dev));
|
LOG_DBG("layer: %d sensor_number: %d, binding name: %s", layer, sensor_number,
|
||||||
|
log_strdup(binding->behavior_dev));
|
||||||
|
|
||||||
behavior = device_get_binding(binding->behavior_dev);
|
behavior = device_get_binding(binding->behavior_dev);
|
||||||
|
|
||||||
|
@ -179,7 +171,8 @@ int zmk_keymap_sensor_triggered(u8_t sensor_number, struct device *sensor)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = behavior_sensor_keymap_binding_triggered(behavior, sensor, binding->param1, binding->param2);
|
ret = behavior_sensor_keymap_binding_triggered(behavior, sensor, binding->param1,
|
||||||
|
binding->param2);
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
LOG_DBG("behavior processing to continue to next layer");
|
LOG_DBG("behavior processing to continue to next layer");
|
||||||
|
@ -198,8 +191,7 @@ int zmk_keymap_sensor_triggered(u8_t sensor_number, struct device *sensor)
|
||||||
|
|
||||||
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
||||||
|
|
||||||
int keymap_listener(const struct zmk_event_header *eh)
|
int keymap_listener(const struct zmk_event_header *eh) {
|
||||||
{
|
|
||||||
if (is_position_state_changed(eh)) {
|
if (is_position_state_changed(eh)) {
|
||||||
const struct position_state_changed *ev = cast_position_state_changed(eh);
|
const struct position_state_changed *ev = cast_position_state_changed(eh);
|
||||||
return zmk_keymap_position_state_changed(ev->position, ev->state);
|
return zmk_keymap_position_state_changed(ev->position, ev->state);
|
||||||
|
@ -219,4 +211,3 @@ ZMK_SUBSCRIPTION(keymap, position_state_changed);
|
||||||
#if ZMK_KEYMAP_HAS_SENSORS
|
#if ZMK_KEYMAP_HAS_SENSORS
|
||||||
ZMK_SUBSCRIPTION(keymap, sensor_event);
|
ZMK_SUBSCRIPTION(keymap, sensor_event);
|
||||||
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
||||||
|
|
||||||
|
|
|
@ -18,22 +18,19 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
#define ZMK_KSCAN_EVENT_STATE_PRESSED 0
|
#define ZMK_KSCAN_EVENT_STATE_PRESSED 0
|
||||||
#define ZMK_KSCAN_EVENT_STATE_RELEASED 1
|
#define ZMK_KSCAN_EVENT_STATE_RELEASED 1
|
||||||
|
|
||||||
struct zmk_kscan_event
|
struct zmk_kscan_event {
|
||||||
{
|
|
||||||
u32_t row;
|
u32_t row;
|
||||||
u32_t column;
|
u32_t column;
|
||||||
u32_t state;
|
u32_t state;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zmk_kscan_msg_processor
|
struct zmk_kscan_msg_processor {
|
||||||
{
|
|
||||||
struct k_work work;
|
struct k_work work;
|
||||||
} msg_processor;
|
} msg_processor;
|
||||||
|
|
||||||
K_MSGQ_DEFINE(zmk_kscan_msgq, sizeof(struct zmk_kscan_event), CONFIG_ZMK_KSCAN_EVENT_QUEUE_SIZE, 4);
|
K_MSGQ_DEFINE(zmk_kscan_msgq, sizeof(struct zmk_kscan_event), CONFIG_ZMK_KSCAN_EVENT_QUEUE_SIZE, 4);
|
||||||
|
|
||||||
static void zmk_kscan_callback(struct device *dev, u32_t row, u32_t column, bool pressed)
|
static void zmk_kscan_callback(struct device *dev, u32_t row, u32_t column, bool pressed) {
|
||||||
{
|
|
||||||
struct zmk_kscan_event ev = {
|
struct zmk_kscan_event ev = {
|
||||||
.row = row,
|
.row = row,
|
||||||
.column = column,
|
.column = column,
|
||||||
|
@ -43,16 +40,15 @@ static void zmk_kscan_callback(struct device *dev, u32_t row, u32_t column, bool
|
||||||
k_work_submit(&msg_processor.work);
|
k_work_submit(&msg_processor.work);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmk_kscan_process_msgq(struct k_work *item)
|
void zmk_kscan_process_msgq(struct k_work *item) {
|
||||||
{
|
|
||||||
struct zmk_kscan_event ev;
|
struct zmk_kscan_event ev;
|
||||||
|
|
||||||
while (k_msgq_get(&zmk_kscan_msgq, &ev, K_NO_WAIT) == 0)
|
while (k_msgq_get(&zmk_kscan_msgq, &ev, K_NO_WAIT) == 0) {
|
||||||
{
|
|
||||||
bool pressed = (ev.state == ZMK_KSCAN_EVENT_STATE_PRESSED);
|
bool pressed = (ev.state == ZMK_KSCAN_EVENT_STATE_PRESSED);
|
||||||
u32_t position = zmk_matrix_transform_row_column_to_position(ev.row, ev.column);
|
u32_t position = zmk_matrix_transform_row_column_to_position(ev.row, ev.column);
|
||||||
struct position_state_changed *pos_ev;
|
struct position_state_changed *pos_ev;
|
||||||
LOG_DBG("Row: %d, col: %d, position: %d, pressed: %s\n", ev.row, ev.column, position, (pressed ? "true" : "false"));
|
LOG_DBG("Row: %d, col: %d, position: %d, pressed: %s\n", ev.row, ev.column, position,
|
||||||
|
(pressed ? "true" : "false"));
|
||||||
pos_ev = new_position_state_changed();
|
pos_ev = new_position_state_changed();
|
||||||
pos_ev->state = pressed;
|
pos_ev->state = pressed;
|
||||||
pos_ev->position = position;
|
pos_ev->position = position;
|
||||||
|
@ -60,11 +56,9 @@ void zmk_kscan_process_msgq(struct k_work *item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_kscan_init(char *name)
|
int zmk_kscan_init(char *name) {
|
||||||
{
|
|
||||||
struct device *dev = device_get_binding(name);
|
struct device *dev = device_get_binding(name);
|
||||||
if (dev == NULL)
|
if (dev == NULL) {
|
||||||
{
|
|
||||||
LOG_ERR("Failed to get the KSCAN device");
|
LOG_ERR("Failed to get the KSCAN device");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,37 +15,31 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
#define MATRIX_ROWS DT_PROP(MATRIX_NODE_ID, rows)
|
#define MATRIX_ROWS DT_PROP(MATRIX_NODE_ID, rows)
|
||||||
#define MATRIX_COLS DT_PROP(MATRIX_NODE_ID, columns)
|
#define MATRIX_COLS DT_PROP(MATRIX_NODE_ID, columns)
|
||||||
|
|
||||||
struct kscan_composite_child_config
|
struct kscan_composite_child_config {
|
||||||
{
|
|
||||||
char *label;
|
char *label;
|
||||||
u8_t row_offset;
|
u8_t row_offset;
|
||||||
u8_t column_offset;
|
u8_t column_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CHILD_CONFIG(inst) \
|
#define CHILD_CONFIG(inst) \
|
||||||
{ \
|
{.label = DT_LABEL(DT_PHANDLE(inst, kscan)), \
|
||||||
.label = DT_LABEL(DT_PHANDLE(inst, kscan)), \
|
|
||||||
.row_offset = DT_PROP(inst, row_offset), \
|
.row_offset = DT_PROP(inst, row_offset), \
|
||||||
.column_offset = DT_PROP(inst, column_offset)},
|
.column_offset = DT_PROP(inst, column_offset)},
|
||||||
|
|
||||||
const struct kscan_composite_child_config kscan_composite_children[] = {
|
const struct kscan_composite_child_config kscan_composite_children[] = {
|
||||||
DT_FOREACH_CHILD(MATRIX_NODE_ID, CHILD_CONFIG)};
|
DT_FOREACH_CHILD(MATRIX_NODE_ID, CHILD_CONFIG)};
|
||||||
|
|
||||||
struct kscan_composite_config
|
struct kscan_composite_config {};
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
struct kscan_composite_data
|
struct kscan_composite_data {
|
||||||
{
|
|
||||||
kscan_callback_t callback;
|
kscan_callback_t callback;
|
||||||
|
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int kscan_composite_enable_callback(struct device *dev)
|
static int kscan_composite_enable_callback(struct device *dev) {
|
||||||
{
|
for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]);
|
||||||
for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]); i++)
|
i++) {
|
||||||
{
|
|
||||||
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
|
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
|
||||||
|
|
||||||
kscan_enable_callback(device_get_binding(cfg->label));
|
kscan_enable_callback(device_get_binding(cfg->label));
|
||||||
|
@ -53,10 +47,9 @@ static int kscan_composite_enable_callback(struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kscan_composite_disable_callback(struct device *dev)
|
static int kscan_composite_disable_callback(struct device *dev) {
|
||||||
{
|
for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]);
|
||||||
for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]); i++)
|
i++) {
|
||||||
{
|
|
||||||
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
|
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
|
||||||
|
|
||||||
kscan_disable_callback(device_get_binding(cfg->label));
|
kscan_disable_callback(device_get_binding(cfg->label));
|
||||||
|
@ -64,18 +57,17 @@ static int kscan_composite_disable_callback(struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kscan_composite_child_callback(struct device *child_dev, u32_t row, u32_t column, bool pressed)
|
static void kscan_composite_child_callback(struct device *child_dev, u32_t row, u32_t column,
|
||||||
{
|
bool pressed) {
|
||||||
// TODO: Ideally we can get this passed into our callback!
|
// TODO: Ideally we can get this passed into our callback!
|
||||||
struct device *dev = device_get_binding(DT_INST_LABEL(0));
|
struct device *dev = device_get_binding(DT_INST_LABEL(0));
|
||||||
struct kscan_composite_data *data = dev->driver_data;
|
struct kscan_composite_data *data = dev->driver_data;
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]); i++)
|
for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]);
|
||||||
{
|
i++) {
|
||||||
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
|
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
|
||||||
|
|
||||||
if (device_get_binding(cfg->label) != child_dev)
|
if (device_get_binding(cfg->label) != child_dev) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,17 +75,15 @@ static void kscan_composite_child_callback(struct device *child_dev, u32_t row,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kscan_composite_configure(struct device *dev, kscan_callback_t callback)
|
static int kscan_composite_configure(struct device *dev, kscan_callback_t callback) {
|
||||||
{
|
|
||||||
struct kscan_composite_data *data = dev->driver_data;
|
struct kscan_composite_data *data = dev->driver_data;
|
||||||
|
|
||||||
if (!callback)
|
if (!callback) {
|
||||||
{
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]); i++)
|
for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]);
|
||||||
{
|
i++) {
|
||||||
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
|
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
|
||||||
|
|
||||||
kscan_config(device_get_binding(cfg->label), &kscan_composite_child_callback);
|
kscan_config(device_get_binding(cfg->label), &kscan_composite_child_callback);
|
||||||
|
@ -104,8 +94,7 @@ static int kscan_composite_configure(struct device *dev, kscan_callback_t callba
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kscan_composite_init(struct device *dev)
|
static int kscan_composite_init(struct device *dev) {
|
||||||
{
|
|
||||||
struct kscan_composite_data *data = dev->driver_data;
|
struct kscan_composite_data *data = dev->driver_data;
|
||||||
|
|
||||||
data->dev = dev;
|
data->dev = dev;
|
||||||
|
@ -123,8 +112,6 @@ static const struct kscan_composite_config kscan_composite_config = {};
|
||||||
|
|
||||||
static struct kscan_composite_data kscan_composite_data;
|
static struct kscan_composite_data kscan_composite_data;
|
||||||
|
|
||||||
DEVICE_AND_API_INIT(kscan_composite, DT_INST_LABEL(0), kscan_composite_init,
|
DEVICE_AND_API_INIT(kscan_composite, DT_INST_LABEL(0), kscan_composite_init, &kscan_composite_data,
|
||||||
&kscan_composite_data,
|
&kscan_composite_config, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||||
&kscan_composite_config,
|
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
|
||||||
&mock_driver_api);
|
&mock_driver_api);
|
||||||
|
|
|
@ -15,8 +15,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#include <dt-bindings/zmk/kscan-mock.h>
|
#include <dt-bindings/zmk/kscan-mock.h>
|
||||||
|
|
||||||
struct kscan_mock_data
|
struct kscan_mock_data {
|
||||||
{
|
|
||||||
kscan_callback_t callback;
|
kscan_callback_t callback;
|
||||||
|
|
||||||
u8_t event_index;
|
u8_t event_index;
|
||||||
|
@ -24,20 +23,17 @@ struct kscan_mock_data
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int kscan_mock_disable_callback(struct device *dev)
|
static int kscan_mock_disable_callback(struct device *dev) {
|
||||||
{
|
|
||||||
struct kscan_mock_data *data = dev->driver_data;
|
struct kscan_mock_data *data = dev->driver_data;
|
||||||
|
|
||||||
k_delayed_work_cancel(&data->work);
|
k_delayed_work_cancel(&data->work);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kscan_mock_configure(struct device *dev, kscan_callback_t callback)
|
static int kscan_mock_configure(struct device *dev, kscan_callback_t callback) {
|
||||||
{
|
|
||||||
struct kscan_mock_data *data = dev->driver_data;
|
struct kscan_mock_data *data = dev->driver_data;
|
||||||
|
|
||||||
if (!callback)
|
if (!callback) {
|
||||||
{
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,17 +44,14 @@ static int kscan_mock_configure(struct device *dev, kscan_callback_t callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MOCK_INST_INIT(n) \
|
#define MOCK_INST_INIT(n) \
|
||||||
struct kscan_mock_config_##n \
|
struct kscan_mock_config_##n { \
|
||||||
{ \
|
|
||||||
u32_t events[DT_INST_PROP_LEN(n, events)]; \
|
u32_t events[DT_INST_PROP_LEN(n, events)]; \
|
||||||
bool exit_after; \
|
bool exit_after; \
|
||||||
}; \
|
}; \
|
||||||
static void kscan_mock_schedule_next_event_##n(struct device *dev) \
|
static void kscan_mock_schedule_next_event_##n(struct device *dev) { \
|
||||||
{ \
|
|
||||||
struct kscan_mock_data *data = dev->driver_data; \
|
struct kscan_mock_data *data = dev->driver_data; \
|
||||||
const struct kscan_mock_config_##n *cfg = dev->config_info; \
|
const struct kscan_mock_config_##n *cfg = dev->config_info; \
|
||||||
if (data->event_index < DT_INST_PROP_LEN(n, events)) \
|
if (data->event_index < DT_INST_PROP_LEN(n, events)) { \
|
||||||
{ \
|
|
||||||
u32_t ev = cfg->events[data->event_index]; \
|
u32_t ev = cfg->events[data->event_index]; \
|
||||||
LOG_DBG("delaying next keypress: %d", ZMK_MOCK_MSEC(ev)); \
|
LOG_DBG("delaying next keypress: %d", ZMK_MOCK_MSEC(ev)); \
|
||||||
k_delayed_work_submit(&data->work, K_MSEC(ZMK_MOCK_MSEC(ev))); \
|
k_delayed_work_submit(&data->work, K_MSEC(ZMK_MOCK_MSEC(ev))); \
|
||||||
|
@ -67,28 +60,23 @@ static int kscan_mock_configure(struct device *dev, kscan_callback_t callback)
|
||||||
exit(0); \
|
exit(0); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
static void kscan_mock_work_handler_##n(struct k_work *work) \
|
static void kscan_mock_work_handler_##n(struct k_work *work) { \
|
||||||
{ \
|
struct kscan_mock_data *data = CONTAINER_OF(work, struct kscan_mock_data, work); \
|
||||||
struct kscan_mock_data *data = \
|
|
||||||
CONTAINER_OF(work, struct kscan_mock_data, work); \
|
|
||||||
const struct kscan_mock_config_##n *cfg = data->dev->config_info; \
|
const struct kscan_mock_config_##n *cfg = data->dev->config_info; \
|
||||||
u32_t ev = cfg->events[data->event_index]; \
|
u32_t ev = cfg->events[data->event_index]; \
|
||||||
LOG_DBG("ev %u row %d column %d state %d\n", ev, \
|
LOG_DBG("ev %u row %d column %d state %d\n", ev, ZMK_MOCK_ROW(ev), ZMK_MOCK_COL(ev), \
|
||||||
ZMK_MOCK_ROW(ev), ZMK_MOCK_COL(ev), ZMK_MOCK_IS_PRESS(ev)); \
|
ZMK_MOCK_IS_PRESS(ev)); \
|
||||||
data->callback(data->dev, \
|
data->callback(data->dev, ZMK_MOCK_ROW(ev), ZMK_MOCK_COL(ev), ZMK_MOCK_IS_PRESS(ev)); \
|
||||||
ZMK_MOCK_ROW(ev), ZMK_MOCK_COL(ev), ZMK_MOCK_IS_PRESS(ev)); \
|
|
||||||
kscan_mock_schedule_next_event_##n(data->dev); \
|
kscan_mock_schedule_next_event_##n(data->dev); \
|
||||||
data->event_index++; \
|
data->event_index++; \
|
||||||
} \
|
} \
|
||||||
static int kscan_mock_init_##n(struct device *dev) \
|
static int kscan_mock_init_##n(struct device *dev) { \
|
||||||
{ \
|
|
||||||
struct kscan_mock_data *data = dev->driver_data; \
|
struct kscan_mock_data *data = dev->driver_data; \
|
||||||
data->dev = dev; \
|
data->dev = dev; \
|
||||||
k_delayed_work_init(&data->work, kscan_mock_work_handler_##n); \
|
k_delayed_work_init(&data->work, kscan_mock_work_handler_##n); \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
static int kscan_mock_enable_callback_##n(struct device *dev) \
|
static int kscan_mock_enable_callback_##n(struct device *dev) { \
|
||||||
{ \
|
|
||||||
kscan_mock_schedule_next_event_##n(dev); \
|
kscan_mock_schedule_next_event_##n(dev); \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
|
@ -99,12 +87,9 @@ static int kscan_mock_configure(struct device *dev, kscan_callback_t callback)
|
||||||
}; \
|
}; \
|
||||||
static struct kscan_mock_data kscan_mock_data_##n; \
|
static struct kscan_mock_data kscan_mock_data_##n; \
|
||||||
static const struct kscan_mock_config_##n kscan_mock_config_##n = { \
|
static const struct kscan_mock_config_##n kscan_mock_config_##n = { \
|
||||||
.events = DT_INST_PROP(n, events), \
|
.events = DT_INST_PROP(n, events), .exit_after = DT_INST_PROP(n, exit_after)}; \
|
||||||
.exit_after = DT_INST_PROP(n, exit_after) }; \
|
|
||||||
DEVICE_AND_API_INIT(kscan_mock_##n, DT_INST_LABEL(n), kscan_mock_init_##n, \
|
DEVICE_AND_API_INIT(kscan_mock_##n, DT_INST_LABEL(n), kscan_mock_init_##n, \
|
||||||
&kscan_mock_data_##n, \
|
&kscan_mock_data_##n, &kscan_mock_config_##n, APPLICATION, \
|
||||||
&kscan_mock_config_##n, \
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &mock_driver_api_##n);
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
|
||||||
&mock_driver_api_##n);
|
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(MOCK_INST_INIT)
|
DT_INST_FOREACH_STATUS_OKAY(MOCK_INST_INIT)
|
||||||
|
|
|
@ -18,12 +18,10 @@ LOG_MODULE_REGISTER(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#define ZMK_KSCAN_DEV DT_LABEL(ZMK_MATRIX_NODE_ID)
|
#define ZMK_KSCAN_DEV DT_LABEL(ZMK_MATRIX_NODE_ID)
|
||||||
|
|
||||||
void main(void)
|
void main(void) {
|
||||||
{
|
|
||||||
LOG_INF("Welcome to ZMK!\n");
|
LOG_INF("Welcome to ZMK!\n");
|
||||||
|
|
||||||
if (zmk_kscan_init(ZMK_KSCAN_DEV) != 0)
|
if (zmk_kscan_init(ZMK_KSCAN_DEV) != 0) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,15 +12,14 @@
|
||||||
#ifdef ZMK_KEYMAP_TRANSFORM_NODE
|
#ifdef ZMK_KEYMAP_TRANSFORM_NODE
|
||||||
|
|
||||||
#define _TRANSFORM_ENTRY(i, _) \
|
#define _TRANSFORM_ENTRY(i, _) \
|
||||||
[(KT_ROW(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i)) * ZMK_MATRIX_COLS) + KT_COL(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i))] = i,
|
[(KT_ROW(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i)) * ZMK_MATRIX_COLS) + \
|
||||||
|
KT_COL(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i))] = i,
|
||||||
|
|
||||||
static u32_t transform[] =
|
static u32_t transform[] = {UTIL_LISTIFY(ZMK_KEYMAP_LEN, _TRANSFORM_ENTRY, 0)};
|
||||||
{ UTIL_LISTIFY(ZMK_KEYMAP_LEN, _TRANSFORM_ENTRY, 0) };
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u32_t zmk_matrix_transform_row_column_to_position(u32_t row, u32_t column)
|
u32_t zmk_matrix_transform_row_column_to_position(u32_t row, u32_t column) {
|
||||||
{
|
|
||||||
u32_t matrix_index;
|
u32_t matrix_index;
|
||||||
|
|
||||||
#if DT_NODE_HAS_PROP(ZMK_KEYMAP_TRANSFORM_NODE, col_offset)
|
#if DT_NODE_HAS_PROP(ZMK_KEYMAP_TRANSFORM_NODE, col_offset)
|
||||||
|
|
|
@ -51,8 +51,7 @@ struct device *led_strip;
|
||||||
|
|
||||||
struct led_rgb pixels[STRIP_NUM_PIXELS];
|
struct led_rgb pixels[STRIP_NUM_PIXELS];
|
||||||
|
|
||||||
static struct led_rgb hsb_to_rgb(struct led_hsb hsb)
|
static struct led_rgb hsb_to_rgb(struct led_hsb hsb) {
|
||||||
{
|
|
||||||
double r, g, b;
|
double r, g, b;
|
||||||
|
|
||||||
u8_t i = hsb.h / 60;
|
u8_t i = hsb.h / 60;
|
||||||
|
@ -63,44 +62,63 @@ static struct led_rgb hsb_to_rgb(struct led_hsb hsb)
|
||||||
double q = v * (1 - f * s);
|
double q = v * (1 - f * s);
|
||||||
double t = v * (1 - (1 - f) * s);
|
double t = v * (1 - (1 - f) * s);
|
||||||
|
|
||||||
switch (i % 6)
|
switch (i % 6) {
|
||||||
{
|
case 0:
|
||||||
case 0: r = v; g = t; b = p; break;
|
r = v;
|
||||||
case 1: r = q; g = v; b = p; break;
|
g = t;
|
||||||
case 2: r = p; g = v; b = t; break;
|
b = p;
|
||||||
case 3: r = p; g = q; b = v; break;
|
break;
|
||||||
case 4: r = t; g = p; b = v; break;
|
case 1:
|
||||||
case 5: r = v; g = p; b = q; break;
|
r = q;
|
||||||
|
g = v;
|
||||||
|
b = p;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
r = p;
|
||||||
|
g = v;
|
||||||
|
b = t;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
r = p;
|
||||||
|
g = q;
|
||||||
|
b = v;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
r = t;
|
||||||
|
g = p;
|
||||||
|
b = v;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
r = v;
|
||||||
|
g = p;
|
||||||
|
b = q;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct led_rgb rgb = { r: r*255, g: g*255, b: b*255 };
|
struct led_rgb rgb = {r : r * 255, g : g * 255, b : b * 255};
|
||||||
|
|
||||||
return rgb;
|
return rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zmk_rgb_underglow_effect_solid()
|
static void zmk_rgb_underglow_effect_solid() {
|
||||||
{
|
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
|
||||||
for (int i=0; i<STRIP_NUM_PIXELS; i++)
|
|
||||||
{
|
|
||||||
int hue = state.hue;
|
int hue = state.hue;
|
||||||
int sat = state.saturation;
|
int sat = state.saturation;
|
||||||
int brt = state.brightness;
|
int brt = state.brightness;
|
||||||
|
|
||||||
struct led_hsb hsb = { hue, sat, brt };
|
struct led_hsb hsb = {hue, sat, brt};
|
||||||
|
|
||||||
pixels[i] = hsb_to_rgb(hsb);
|
pixels[i] = hsb_to_rgb(hsb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zmk_rgb_underglow_effect_breathe()
|
static void zmk_rgb_underglow_effect_breathe() {
|
||||||
{
|
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
|
||||||
for (int i=0; i<STRIP_NUM_PIXELS; i++)
|
|
||||||
{
|
|
||||||
int hue = state.hue;
|
int hue = state.hue;
|
||||||
int sat = state.saturation;
|
int sat = state.saturation;
|
||||||
int brt = abs(state.animation_step - 1200) / 12;
|
int brt = abs(state.animation_step - 1200) / 12;
|
||||||
|
|
||||||
struct led_hsb hsb = { hue, sat, brt };
|
struct led_hsb hsb = {hue, sat, brt};
|
||||||
|
|
||||||
pixels[i] = hsb_to_rgb(hsb);
|
pixels[i] = hsb_to_rgb(hsb);
|
||||||
}
|
}
|
||||||
|
@ -112,15 +130,13 @@ static void zmk_rgb_underglow_effect_breathe()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zmk_rgb_underglow_effect_spectrum()
|
static void zmk_rgb_underglow_effect_spectrum() {
|
||||||
{
|
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
|
||||||
for (int i=0; i<STRIP_NUM_PIXELS; i++)
|
|
||||||
{
|
|
||||||
int hue = state.animation_step;
|
int hue = state.animation_step;
|
||||||
int sat = state.saturation;
|
int sat = state.saturation;
|
||||||
int brt = state.brightness;
|
int brt = state.brightness;
|
||||||
|
|
||||||
struct led_hsb hsb = { hue, sat, brt };
|
struct led_hsb hsb = {hue, sat, brt};
|
||||||
|
|
||||||
pixels[i] = hsb_to_rgb(hsb);
|
pixels[i] = hsb_to_rgb(hsb);
|
||||||
}
|
}
|
||||||
|
@ -129,15 +145,13 @@ static void zmk_rgb_underglow_effect_spectrum()
|
||||||
state.animation_step = state.animation_step % 360;
|
state.animation_step = state.animation_step % 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zmk_rgb_underglow_effect_swirl()
|
static void zmk_rgb_underglow_effect_swirl() {
|
||||||
{
|
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
|
||||||
for (int i=0; i<STRIP_NUM_PIXELS; i++)
|
|
||||||
{
|
|
||||||
int hue = (360 / STRIP_NUM_PIXELS * i + state.animation_step) % 360;
|
int hue = (360 / STRIP_NUM_PIXELS * i + state.animation_step) % 360;
|
||||||
int sat = state.saturation;
|
int sat = state.saturation;
|
||||||
int brt = state.brightness;
|
int brt = state.brightness;
|
||||||
|
|
||||||
struct led_hsb hsb = { hue, sat, brt };
|
struct led_hsb hsb = {hue, sat, brt};
|
||||||
|
|
||||||
pixels[i] = hsb_to_rgb(hsb);
|
pixels[i] = hsb_to_rgb(hsb);
|
||||||
}
|
}
|
||||||
|
@ -146,10 +160,8 @@ static void zmk_rgb_underglow_effect_swirl()
|
||||||
state.animation_step = state.animation_step % 360;
|
state.animation_step = state.animation_step % 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zmk_rgb_underglow_tick(struct k_work *work)
|
static void zmk_rgb_underglow_tick(struct k_work *work) {
|
||||||
{
|
switch (state.current_effect) {
|
||||||
switch (state.current_effect)
|
|
||||||
{
|
|
||||||
case UNDERGLOW_EFFECT_SOLID:
|
case UNDERGLOW_EFFECT_SOLID:
|
||||||
zmk_rgb_underglow_effect_solid();
|
zmk_rgb_underglow_effect_solid();
|
||||||
break;
|
break;
|
||||||
|
@ -169,15 +181,13 @@ static void zmk_rgb_underglow_tick(struct k_work *work)
|
||||||
|
|
||||||
K_WORK_DEFINE(underglow_work, zmk_rgb_underglow_tick);
|
K_WORK_DEFINE(underglow_work, zmk_rgb_underglow_tick);
|
||||||
|
|
||||||
static void zmk_rgb_underglow_tick_handler(struct k_timer *timer)
|
static void zmk_rgb_underglow_tick_handler(struct k_timer *timer) {
|
||||||
{
|
|
||||||
k_work_submit(&underglow_work);
|
k_work_submit(&underglow_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
K_TIMER_DEFINE(underglow_tick, zmk_rgb_underglow_tick_handler, NULL);
|
K_TIMER_DEFINE(underglow_tick, zmk_rgb_underglow_tick_handler, NULL);
|
||||||
|
|
||||||
static int zmk_rgb_underglow_init(struct device *_arg)
|
static int zmk_rgb_underglow_init(struct device *_arg) {
|
||||||
{
|
|
||||||
led_strip = device_get_binding(STRIP_LABEL);
|
led_strip = device_get_binding(STRIP_LABEL);
|
||||||
if (led_strip) {
|
if (led_strip) {
|
||||||
LOG_INF("Found LED strip device %s", STRIP_LABEL);
|
LOG_INF("Found LED strip device %s", STRIP_LABEL);
|
||||||
|
@ -187,13 +197,13 @@ static int zmk_rgb_underglow_init(struct device *_arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
state = (struct rgb_underglow_state){
|
state = (struct rgb_underglow_state){
|
||||||
hue: 0,
|
hue : 0,
|
||||||
saturation: 100,
|
saturation : 100,
|
||||||
brightness: 100,
|
brightness : 100,
|
||||||
animation_speed: 3,
|
animation_speed : 3,
|
||||||
current_effect: 0,
|
current_effect : 0,
|
||||||
animation_step: 0,
|
animation_step : 0,
|
||||||
on: true
|
on : true
|
||||||
};
|
};
|
||||||
|
|
||||||
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50));
|
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50));
|
||||||
|
@ -201,9 +211,9 @@ static int zmk_rgb_underglow_init(struct device *_arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_rgb_underglow_cycle_effect(int direction)
|
int zmk_rgb_underglow_cycle_effect(int direction) {
|
||||||
{
|
if (!led_strip)
|
||||||
if (!led_strip) return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (state.current_effect == 0 && direction < 0) {
|
if (state.current_effect == 0 && direction < 0) {
|
||||||
state.current_effect = UNDERGLOW_EFFECT_NUMBER - 1;
|
state.current_effect = UNDERGLOW_EFFECT_NUMBER - 1;
|
||||||
|
@ -221,9 +231,9 @@ int zmk_rgb_underglow_cycle_effect(int direction)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_rgb_underglow_toggle()
|
int zmk_rgb_underglow_toggle() {
|
||||||
{
|
if (!led_strip)
|
||||||
if (!led_strip) return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
state.on = !state.on;
|
state.on = !state.on;
|
||||||
|
|
||||||
|
@ -232,9 +242,8 @@ int zmk_rgb_underglow_toggle()
|
||||||
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50));
|
k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50));
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
for (int i=0; i<STRIP_NUM_PIXELS; i++)
|
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
|
||||||
{
|
pixels[i] = (struct led_rgb){r : 0, g : 0, b : 0};
|
||||||
pixels[i] = (struct led_rgb){ r: 0, g: 0, b: 0};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
led_strip_update_rgb(led_strip, pixels, STRIP_NUM_PIXELS);
|
led_strip_update_rgb(led_strip, pixels, STRIP_NUM_PIXELS);
|
||||||
|
@ -245,9 +254,9 @@ int zmk_rgb_underglow_toggle()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_rgb_underglow_change_hue(int direction)
|
int zmk_rgb_underglow_change_hue(int direction) {
|
||||||
{
|
if (!led_strip)
|
||||||
if (!led_strip) return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (state.hue == 0 && direction < 0) {
|
if (state.hue == 0 && direction < 0) {
|
||||||
state.hue = 350;
|
state.hue = 350;
|
||||||
|
@ -263,9 +272,9 @@ int zmk_rgb_underglow_change_hue(int direction)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_rgb_underglow_change_sat(int direction)
|
int zmk_rgb_underglow_change_sat(int direction) {
|
||||||
{
|
if (!led_strip)
|
||||||
if (!led_strip) return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (state.saturation == 0 && direction < 0) {
|
if (state.saturation == 0 && direction < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -280,9 +289,9 @@ int zmk_rgb_underglow_change_sat(int direction)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_rgb_underglow_change_brt(int direction)
|
int zmk_rgb_underglow_change_brt(int direction) {
|
||||||
{
|
if (!led_strip)
|
||||||
if (!led_strip) return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (state.brightness == 0 && direction < 0) {
|
if (state.brightness == 0 && direction < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -297,9 +306,9 @@ int zmk_rgb_underglow_change_brt(int direction)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_rgb_underglow_change_spd(int direction)
|
int zmk_rgb_underglow_change_spd(int direction) {
|
||||||
{
|
if (!led_strip)
|
||||||
if (!led_strip) return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (state.animation_speed == 1 && direction < 0) {
|
if (state.animation_speed == 1 && direction < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -314,6 +323,4 @@ int zmk_rgb_underglow_change_spd(int direction)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_INIT(zmk_rgb_underglow_init,
|
SYS_INIT(zmk_rgb_underglow_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
|
||||||
APPLICATION,
|
|
||||||
CONFIG_APPLICATION_INIT_PRIORITY);
|
|
||||||
|
|
|
@ -24,17 +24,17 @@ struct sensors_data_item {
|
||||||
struct sensor_trigger trigger;
|
struct sensor_trigger trigger;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define _SENSOR_ITEM(node) {.dev = NULL, .trigger = { .type = SENSOR_TRIG_DELTA, .chan = SENSOR_CHAN_ROTATION } },
|
#define _SENSOR_ITEM(node) \
|
||||||
#define SENSOR_ITEM(idx, _) COND_CODE_1(DT_NODE_HAS_STATUS(ZMK_KEYMAP_SENSORS_BY_IDX(idx),okay), (_SENSOR_ITEM(ZMK_KEYMAP_SENSORS_BY_IDX(idx))),())
|
{.dev = NULL, .trigger = {.type = SENSOR_TRIG_DELTA, .chan = SENSOR_CHAN_ROTATION}},
|
||||||
|
#define SENSOR_ITEM(idx, _) \
|
||||||
|
COND_CODE_1(DT_NODE_HAS_STATUS(ZMK_KEYMAP_SENSORS_BY_IDX(idx), okay), \
|
||||||
|
(_SENSOR_ITEM(ZMK_KEYMAP_SENSORS_BY_IDX(idx))), ())
|
||||||
|
|
||||||
static struct sensors_data_item sensors[] = {
|
static struct sensors_data_item sensors[] = {UTIL_LISTIFY(ZMK_KEYMAP_SENSORS_LEN, SENSOR_ITEM, 0)};
|
||||||
UTIL_LISTIFY(ZMK_KEYMAP_SENSORS_LEN, SENSOR_ITEM, 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
static void zmk_sensors_trigger_handler(struct device *dev, struct sensor_trigger *trigger)
|
static void zmk_sensors_trigger_handler(struct device *dev, struct sensor_trigger *trigger) {
|
||||||
{
|
|
||||||
int err;
|
int err;
|
||||||
struct sensors_data_item * item = CONTAINER_OF(trigger, struct sensors_data_item, trigger);
|
struct sensors_data_item *item = CONTAINER_OF(trigger, struct sensors_data_item, trigger);
|
||||||
struct sensor_event *event;
|
struct sensor_event *event;
|
||||||
|
|
||||||
LOG_DBG("sensor %d", item->sensor_number);
|
LOG_DBG("sensor %d", item->sensor_number);
|
||||||
|
@ -52,8 +52,7 @@ static void zmk_sensors_trigger_handler(struct device *dev, struct sensor_trigge
|
||||||
ZMK_EVENT_RAISE(event);
|
ZMK_EVENT_RAISE(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zmk_sensors_init_item(const char *node, u8_t i, u8_t abs_i)
|
static void zmk_sensors_init_item(const char *node, u8_t i, u8_t abs_i) {
|
||||||
{
|
|
||||||
LOG_DBG("Init %s at index %d with sensor_number %d", node, i, abs_i);
|
LOG_DBG("Init %s at index %d with sensor_number %d", node, i, abs_i);
|
||||||
|
|
||||||
sensors[i].dev = device_get_binding(node);
|
sensors[i].dev = device_get_binding(node);
|
||||||
|
@ -68,10 +67,11 @@ static void zmk_sensors_init_item(const char *node, u8_t i, u8_t abs_i)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _SENSOR_INIT(node) zmk_sensors_init_item(DT_LABEL(node), local_index++, absolute_index++);
|
#define _SENSOR_INIT(node) zmk_sensors_init_item(DT_LABEL(node), local_index++, absolute_index++);
|
||||||
#define SENSOR_INIT(idx, _i) COND_CODE_1(DT_NODE_HAS_STATUS(ZMK_KEYMAP_SENSORS_BY_IDX(idx),okay), (_SENSOR_INIT(ZMK_KEYMAP_SENSORS_BY_IDX(idx))),(absolute_index++;))
|
#define SENSOR_INIT(idx, _i) \
|
||||||
|
COND_CODE_1(DT_NODE_HAS_STATUS(ZMK_KEYMAP_SENSORS_BY_IDX(idx), okay), \
|
||||||
|
(_SENSOR_INIT(ZMK_KEYMAP_SENSORS_BY_IDX(idx))), (absolute_index++;))
|
||||||
|
|
||||||
static int zmk_sensors_init(struct device *_arg)
|
static int zmk_sensors_init(struct device *_arg) {
|
||||||
{
|
|
||||||
int local_index = 0;
|
int local_index = 0;
|
||||||
int absolute_index = 0;
|
int absolute_index = 0;
|
||||||
|
|
||||||
|
@ -79,8 +79,6 @@ static int zmk_sensors_init(struct device *_arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_INIT(zmk_sensors_init,
|
SYS_INIT(zmk_sensors_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
|
||||||
APPLICATION,
|
|
||||||
CONFIG_APPLICATION_INIT_PRIORITY);
|
|
||||||
|
|
||||||
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
|
@ -33,10 +33,8 @@ 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 u8_t split_central_notify_func(struct bt_conn *conn,
|
static u8_t split_central_notify_func(struct bt_conn *conn, struct bt_gatt_subscribe_params *params,
|
||||||
struct bt_gatt_subscribe_params *params,
|
const void *data, u16_t length) {
|
||||||
const void *data, u16_t length)
|
|
||||||
{
|
|
||||||
static u8_t position_state[POSITION_STATE_DATA_LEN];
|
static u8_t position_state[POSITION_STATE_DATA_LEN];
|
||||||
|
|
||||||
u8_t changed_positions[POSITION_STATE_DATA_LEN];
|
u8_t changed_positions[POSITION_STATE_DATA_LEN];
|
||||||
|
@ -69,12 +67,10 @@ static u8_t split_central_notify_func(struct bt_conn *conn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return BT_GATT_ITER_CONTINUE;
|
return BT_GATT_ITER_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int split_central_subscribe(struct bt_conn *conn)
|
static int split_central_subscribe(struct bt_conn *conn) {
|
||||||
{
|
|
||||||
int err = bt_gatt_subscribe(conn, &subscribe_params);
|
int err = bt_gatt_subscribe(conn, &subscribe_params);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case -EALREADY:
|
case -EALREADY:
|
||||||
|
@ -94,10 +90,8 @@ static int split_central_subscribe(struct bt_conn *conn)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8_t split_central_discovery_func(struct bt_conn *conn,
|
static u8_t split_central_discovery_func(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||||
const struct bt_gatt_attr *attr,
|
struct bt_gatt_discover_params *params) {
|
||||||
struct bt_gatt_discover_params *params)
|
|
||||||
{
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!attr) {
|
if (!attr) {
|
||||||
|
@ -172,11 +166,11 @@ static void split_central_process_connection(struct bt_conn *conn) {
|
||||||
|
|
||||||
bt_conn_get_info(conn, &info);
|
bt_conn_get_info(conn, &info);
|
||||||
|
|
||||||
LOG_DBG("New connection params: Interval: %d, Latency: %d, PHY: %d", info.le.interval, info.le.latency, info.le.phy->rx_phy);
|
LOG_DBG("New connection params: Interval: %d, Latency: %d, PHY: %d", info.le.interval,
|
||||||
|
info.le.latency, info.le.phy->rx_phy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool split_central_eir_found(struct bt_data *data, void *user_data)
|
static bool split_central_eir_found(struct bt_data *data, void *user_data) {
|
||||||
{
|
|
||||||
bt_addr_le_t *addr = user_data;
|
bt_addr_le_t *addr = user_data;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -205,8 +199,10 @@ static bool split_central_eir_found(struct bt_data *data, void *user_data)
|
||||||
char service_uuid_str[BT_UUID_STR_LEN];
|
char service_uuid_str[BT_UUID_STR_LEN];
|
||||||
|
|
||||||
bt_uuid_to_str(&uuid, uuid_str, sizeof(uuid_str));
|
bt_uuid_to_str(&uuid, uuid_str, sizeof(uuid_str));
|
||||||
bt_uuid_to_str(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID), service_uuid_str, sizeof(service_uuid_str));
|
bt_uuid_to_str(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID), service_uuid_str,
|
||||||
LOG_DBG("UUID %s does not match split UUID: %s", log_strdup(uuid_str), log_strdup(service_uuid_str));
|
sizeof(service_uuid_str));
|
||||||
|
LOG_DBG("UUID %s does not match split UUID: %s", log_strdup(uuid_str),
|
||||||
|
log_strdup(service_uuid_str));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,10 +223,10 @@ static bool split_central_eir_found(struct bt_data *data, void *user_data)
|
||||||
} else {
|
} else {
|
||||||
param = BT_LE_CONN_PARAM(0x0006, 0x0006, 30, 400);
|
param = BT_LE_CONN_PARAM(0x0006, 0x0006, 30, 400);
|
||||||
|
|
||||||
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
|
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, param, &default_conn);
|
||||||
param, &default_conn);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG_ERR("Create conn failed (err %d) (create conn? 0x%04x)", err, BT_HCI_OP_LE_CREATE_CONN);
|
LOG_ERR("Create conn failed (err %d) (create conn? 0x%04x)", err,
|
||||||
|
BT_HCI_OP_LE_CREATE_CONN);
|
||||||
start_scan();
|
start_scan();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,23 +245,20 @@ static bool split_central_eir_found(struct bt_data *data, void *user_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void split_central_device_found(const bt_addr_le_t *addr, s8_t rssi, u8_t type,
|
static void split_central_device_found(const bt_addr_le_t *addr, s8_t rssi, u8_t type,
|
||||||
struct net_buf_simple *ad)
|
struct net_buf_simple *ad) {
|
||||||
{
|
|
||||||
char dev[BT_ADDR_LE_STR_LEN];
|
char dev[BT_ADDR_LE_STR_LEN];
|
||||||
|
|
||||||
bt_addr_le_to_str(addr, dev, sizeof(dev));
|
bt_addr_le_to_str(addr, dev, sizeof(dev));
|
||||||
LOG_DBG("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i",
|
LOG_DBG("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i", log_strdup(dev), type, ad->len,
|
||||||
log_strdup(dev), type, ad->len, rssi);
|
rssi);
|
||||||
|
|
||||||
/* We're only interested in connectable events */
|
/* We're only interested in connectable events */
|
||||||
if (type == BT_GAP_ADV_TYPE_ADV_IND ||
|
if (type == BT_GAP_ADV_TYPE_ADV_IND || type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {
|
||||||
type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {
|
|
||||||
bt_data_parse(ad, split_central_eir_found, (void *)addr);
|
bt_data_parse(ad, split_central_eir_found, (void *)addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int start_scan(void)
|
static int start_scan(void) {
|
||||||
{
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, split_central_device_found);
|
err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, split_central_device_found);
|
||||||
|
@ -278,13 +271,11 @@ static int start_scan(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void split_central_connected(struct bt_conn *conn, u8_t conn_err)
|
static void split_central_connected(struct bt_conn *conn, u8_t conn_err) {
|
||||||
{
|
|
||||||
char addr[BT_ADDR_LE_STR_LEN];
|
char addr[BT_ADDR_LE_STR_LEN];
|
||||||
|
|
||||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||||
|
|
||||||
|
|
||||||
if (conn_err) {
|
if (conn_err) {
|
||||||
LOG_ERR("Failed to connect to %s (%u)", log_strdup(addr), conn_err);
|
LOG_ERR("Failed to connect to %s (%u)", log_strdup(addr), conn_err);
|
||||||
|
|
||||||
|
@ -300,8 +291,7 @@ static void split_central_connected(struct bt_conn *conn, u8_t conn_err)
|
||||||
split_central_process_connection(conn);
|
split_central_process_connection(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void split_central_disconnected(struct bt_conn *conn, u8_t reason)
|
static void split_central_disconnected(struct bt_conn *conn, u8_t reason) {
|
||||||
{
|
|
||||||
char addr[BT_ADDR_LE_STR_LEN];
|
char addr[BT_ADDR_LE_STR_LEN];
|
||||||
|
|
||||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||||
|
@ -323,13 +313,10 @@ static struct bt_conn_cb conn_callbacks = {
|
||||||
.disconnected = split_central_disconnected,
|
.disconnected = split_central_disconnected,
|
||||||
};
|
};
|
||||||
|
|
||||||
int zmk_split_bt_central_init(struct device *_arg)
|
int zmk_split_bt_central_init(struct device *_arg) {
|
||||||
{
|
|
||||||
bt_conn_cb_register(&conn_callbacks);
|
bt_conn_cb_register(&conn_callbacks);
|
||||||
|
|
||||||
return start_scan();
|
return start_scan();
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_INIT(zmk_split_bt_central_init,
|
SYS_INIT(zmk_split_bt_central_init, APPLICATION, CONFIG_ZMK_BLE_INIT_PRIORITY);
|
||||||
APPLICATION,
|
|
||||||
CONFIG_ZMK_BLE_INIT_PRIORITY);
|
|
|
@ -21,41 +21,36 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
static u8_t num_of_positions = ZMK_KEYMAP_LEN;
|
static u8_t num_of_positions = ZMK_KEYMAP_LEN;
|
||||||
static u8_t position_state[16];
|
static u8_t position_state[16];
|
||||||
|
|
||||||
static ssize_t split_svc_pos_state(struct bt_conn *conn, const struct bt_gatt_attr *attrs, void *buf, u16_t len, u16_t offset)
|
static ssize_t split_svc_pos_state(struct bt_conn *conn, const struct bt_gatt_attr *attrs,
|
||||||
{
|
void *buf, u16_t len, u16_t offset) {
|
||||||
return bt_gatt_attr_read(conn, attrs, buf, len, offset, &position_state, sizeof(position_state));
|
return bt_gatt_attr_read(conn, attrs, buf, len, offset, &position_state,
|
||||||
|
sizeof(position_state));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t split_svc_num_of_positions(struct bt_conn *conn, const struct bt_gatt_attr *attrs, void *buf, u16_t len, u16_t offset)
|
static ssize_t split_svc_num_of_positions(struct bt_conn *conn, const struct bt_gatt_attr *attrs,
|
||||||
{
|
void *buf, u16_t len, u16_t offset) {
|
||||||
return bt_gatt_attr_read(conn, attrs, buf, len, offset, attrs->user_data, sizeof(u8_t));
|
return bt_gatt_attr_read(conn, attrs, buf, len, offset, attrs->user_data, sizeof(u8_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void split_svc_pos_state_ccc(const struct bt_gatt_attr *attr, u16_t value)
|
static void split_svc_pos_state_ccc(const struct bt_gatt_attr *attr, u16_t value) {
|
||||||
{
|
|
||||||
LOG_DBG("value %d", value);
|
LOG_DBG("value %d", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BT_GATT_SERVICE_DEFINE(
|
||||||
BT_GATT_SERVICE_DEFINE(split_svc,
|
split_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID)),
|
||||||
BT_GATT_PRIMARY_SERVICE(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID)),
|
BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID),
|
||||||
BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID), BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
|
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_READ_ENCRYPT,
|
||||||
BT_GATT_PERM_READ_ENCRYPT,
|
|
||||||
split_svc_pos_state, NULL, &position_state),
|
split_svc_pos_state, NULL, &position_state),
|
||||||
BT_GATT_CCC(split_svc_pos_state_ccc,
|
BT_GATT_CCC(split_svc_pos_state_ccc, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
|
||||||
BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
|
BT_GATT_DESCRIPTOR(BT_UUID_NUM_OF_DIGITALS, BT_GATT_PERM_READ, split_svc_num_of_positions, NULL,
|
||||||
BT_GATT_DESCRIPTOR(BT_UUID_NUM_OF_DIGITALS, BT_GATT_PERM_READ,
|
&num_of_positions), );
|
||||||
split_svc_num_of_positions, NULL, &num_of_positions),
|
|
||||||
);
|
|
||||||
|
|
||||||
int zmk_split_bt_position_pressed(u8_t position)
|
int zmk_split_bt_position_pressed(u8_t position) {
|
||||||
{
|
|
||||||
WRITE_BIT(position_state[position / 8], position % 8, true);
|
WRITE_BIT(position_state[position / 8], position % 8, true);
|
||||||
return bt_gatt_notify(NULL, &split_svc.attrs[1], &position_state, sizeof(position_state));
|
return bt_gatt_notify(NULL, &split_svc.attrs[1], &position_state, sizeof(position_state));
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_split_bt_position_released(u8_t position)
|
int zmk_split_bt_position_released(u8_t position) {
|
||||||
{
|
|
||||||
WRITE_BIT(position_state[position / 8], position % 8, false);
|
WRITE_BIT(position_state[position / 8], position % 8, false);
|
||||||
return bt_gatt_notify(NULL, &split_svc.attrs[1], &position_state, sizeof(position_state));
|
return bt_gatt_notify(NULL, &split_svc.attrs[1], &position_state, sizeof(position_state));
|
||||||
}
|
}
|
|
@ -19,8 +19,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
#include <zmk/hid.h>
|
#include <zmk/hid.h>
|
||||||
#include <zmk/endpoints.h>
|
#include <zmk/endpoints.h>
|
||||||
|
|
||||||
int split_listener(const struct zmk_event_header *eh)
|
int split_listener(const struct zmk_event_header *eh) {
|
||||||
{
|
|
||||||
LOG_DBG("");
|
LOG_DBG("");
|
||||||
if (is_position_state_changed(eh)) {
|
if (is_position_state_changed(eh)) {
|
||||||
const struct position_state_changed *ev = cast_position_state_changed(eh);
|
const struct position_state_changed *ev = cast_position_state_changed(eh);
|
||||||
|
|
|
@ -22,19 +22,14 @@ static struct device *hid_dev;
|
||||||
|
|
||||||
static K_SEM_DEFINE(hid_sem, 1, 1);
|
static K_SEM_DEFINE(hid_sem, 1, 1);
|
||||||
|
|
||||||
static void in_ready_cb(void)
|
static void in_ready_cb(void) { k_sem_give(&hid_sem); }
|
||||||
{
|
|
||||||
k_sem_give(&hid_sem);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct hid_ops ops =
|
static const struct hid_ops ops = {
|
||||||
{
|
|
||||||
.int_in_ready = in_ready_cb,
|
.int_in_ready = in_ready_cb,
|
||||||
};
|
};
|
||||||
|
|
||||||
int zmk_usb_hid_send_report(const u8_t *report, size_t len)
|
int zmk_usb_hid_send_report(const u8_t *report, size_t len) {
|
||||||
{
|
switch (usb_status) {
|
||||||
switch(usb_status) {
|
|
||||||
case USB_DC_SUSPEND:
|
case USB_DC_SUSPEND:
|
||||||
return usb_wakeup_request();
|
return usb_wakeup_request();
|
||||||
case USB_DC_ERROR:
|
case USB_DC_ERROR:
|
||||||
|
@ -54,32 +49,24 @@ int zmk_usb_hid_send_report(const u8_t *report, size_t len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_hid_status_cb(enum usb_dc_status_code status, const u8_t *params)
|
void usb_hid_status_cb(enum usb_dc_status_code status, const u8_t *params) { usb_status = status; };
|
||||||
{
|
|
||||||
usb_status = status;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int zmk_usb_hid_init(struct device *_arg)
|
static int zmk_usb_hid_init(struct device *_arg) {
|
||||||
{
|
|
||||||
int usb_enable_ret;
|
int usb_enable_ret;
|
||||||
|
|
||||||
hid_dev = device_get_binding("HID_0");
|
hid_dev = device_get_binding("HID_0");
|
||||||
if (hid_dev == NULL)
|
if (hid_dev == NULL) {
|
||||||
{
|
|
||||||
LOG_ERR("Unable to locate HID device");
|
LOG_ERR("Unable to locate HID device");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_hid_register_device(hid_dev,
|
usb_hid_register_device(hid_dev, zmk_hid_report_desc, sizeof(zmk_hid_report_desc), &ops);
|
||||||
zmk_hid_report_desc, sizeof(zmk_hid_report_desc),
|
|
||||||
&ops);
|
|
||||||
|
|
||||||
usb_hid_init(hid_dev);
|
usb_hid_init(hid_dev);
|
||||||
|
|
||||||
usb_enable_ret = usb_enable(usb_hid_status_cb);
|
usb_enable_ret = usb_enable(usb_hid_status_cb);
|
||||||
|
|
||||||
if (usb_enable_ret != 0)
|
if (usb_enable_ret != 0) {
|
||||||
{
|
|
||||||
LOG_ERR("Unable to enable USB");
|
LOG_ERR("Unable to enable USB");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -87,6 +74,4 @@ static int zmk_usb_hid_init(struct device *_arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_INIT(zmk_usb_hid_init,
|
SYS_INIT(zmk_usb_hid_init, APPLICATION, CONFIG_ZMK_USB_INIT_PRIORITY);
|
||||||
APPLICATION,
|
|
||||||
CONFIG_ZMK_USB_INIT_PRIORITY);
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue