feat(mouse): Add support for PIM447 trackball.

This commit is contained in:
Cedric Vincent 2021-09-28 17:44:14 +02:00 committed by Cedric VINCENT
parent b9f900faa7
commit 7b45f80c72
2 changed files with 133 additions and 0 deletions

View file

@ -30,6 +30,7 @@ target_sources(app PRIVATE src/hid.c)
target_sources(app PRIVATE src/mouse/key_listener.c)
target_sources(app PRIVATE src/mouse/main.c)
target_sources(app PRIVATE src/mouse/tick_listener.c)
target_sources_ifdef(CONFIG_ZMK_TRACKBALL_PIM447 app PRIVATE src/mouse/trackball_pim447.c)
target_sources(app PRIVATE src/sensors.c)
target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/wpm.c)
target_sources(app PRIVATE src/event_manager.c)

View file

@ -0,0 +1,132 @@
/*
* Copyright (c) 2021 Cedric VINCENT
*
* SPDX-License-Identifier: MIT
*/
#include <drivers/sensor.h>
#include <logging/log.h>
#include <zmk/hid.h>
#include <zmk/endpoints.h>
LOG_MODULE_REGISTER(PIM447, CONFIG_SENSOR_LOG_LEVEL);
/*
* It feels more natural and more confortable to convert the speed
* reported by the PIM447 trackball.
*/
static int16_t convert_speed(int32_t value)
{
bool negative = (value < 0);
if (negative) {
value = -value;
}
switch (value) {
case 0: value = 0; break;
case 1: value = 1; break;
case 2: value = 4; break;
case 3: value = 8; break;
case 4: value = 18; break;
case 5: value = 32; break;
case 6: value = 50; break;
case 7: value = 72; break;
case 8: value = 98; break;
default: value = 127; break;
}
if (negative) {
value = -value;
}
return value;
}
static void thread_code(void *p1, void *p2, void *p3)
{
const struct device *dev;
int result;
/* PIM447 trackball initialization. */
const char *label = DT_LABEL(DT_INST(0, pimoroni_trackball_pim447));
dev = device_get_binding(label);
if (dev == NULL) {
LOG_ERR("Cannot get TRACKBALL_PIM447 device");
return;
}
/* Event loop. */
bool button_press_sent = false;
bool button_release_sent = false;
while (true) {
struct sensor_value pos_dx, pos_dy, pos_dz;
bool send_report = false;
result = sensor_sample_fetch(dev);
if (result < 0) {
LOG_ERR("Failed to fetch TRACKBALL_PIM447 sample");
return;
}
result = sensor_channel_get(dev, SENSOR_CHAN_POS_DX, &pos_dx);
if (result < 0) {
LOG_ERR("Failed to get TRACKBALL_PIM447 pos_dx channel value");
return;
}
result = sensor_channel_get(dev, SENSOR_CHAN_POS_DY, &pos_dy);
if (result < 0) {
LOG_ERR("Failed to get TRACKBALL_PIM447 pos_dy channel value");
return;
}
result = sensor_channel_get(dev, SENSOR_CHAN_POS_DZ, &pos_dz);
if (result < 0) {
LOG_ERR("Failed to get TRACKBALL_PIM447 pos_dz channel value");
return;
}
if (pos_dx.val1 != 0 || pos_dy.val1 != 0) {
zmk_hid_mouse_movement_update(convert_speed(pos_dx.val1),
convert_speed(pos_dy.val1));
send_report = true;
}
if (pos_dz.val1 == 0x80 && button_press_sent == false) {
zmk_hid_mouse_button_press(0);
button_press_sent = true;
button_release_sent = false;
send_report = true;
} else if (pos_dz.val1 == 0x01 && button_release_sent == false) {
zmk_hid_mouse_button_release(0);
button_press_sent = false;
button_release_sent = true;
send_report = true;
}
if (send_report) {
zmk_endpoints_send_mouse_report();
zmk_hid_mouse_clear();
}
k_sleep(K_MSEC(10));
}
}
#define STACK_SIZE 1024
static K_THREAD_STACK_DEFINE(thread_stack, STACK_SIZE);
static struct k_thread thread;
int zmk_trackball_pim447_init()
{
k_thread_create(&thread, thread_stack, STACK_SIZE, thread_code,
NULL, NULL, NULL, K_PRIO_PREEMPT(8), 0, K_NO_WAIT);
return 0;
}
SYS_INIT(zmk_trackball_pim447_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);