feat(mouse): Add support for PIM447 trackball.
This commit is contained in:
parent
b9f900faa7
commit
7b45f80c72
2 changed files with 133 additions and 0 deletions
|
@ -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/key_listener.c)
|
||||||
target_sources(app PRIVATE src/mouse/main.c)
|
target_sources(app PRIVATE src/mouse/main.c)
|
||||||
target_sources(app PRIVATE src/mouse/tick_listener.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(app PRIVATE src/sensors.c)
|
||||||
target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/wpm.c)
|
target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/wpm.c)
|
||||||
target_sources(app PRIVATE src/event_manager.c)
|
target_sources(app PRIVATE src/event_manager.c)
|
||||||
|
|
132
app/src/mouse/trackball_pim447.c
Normal file
132
app/src/mouse/trackball_pim447.c
Normal 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);
|
Loading…
Add table
Reference in a new issue