mirror of
https://github.com/qmk/qmk_firmware.git
synced 2024-11-22 03:19:24 +00:00
[Core] Split support for pointing devices. (#15304)
* Draft implementation * formatting * fix combined buttons * remove pimoroni throttle * sync pointing on a throttle loop with checksum * no longer used * doh Co-authored-by: Drashna Jaelre <drashna@live.com> * switch pimoroni to a cpi equivalent * add cpi support * allow user modification of seperate mouse reports * a little tidy up * add *_RIGHT defines. * docs * doxygen comments * basic changelog * clean up pimoroni * small doc fixes * Update docs/feature_pointing_device.md Co-authored-by: Drashna Jaelre <drashna@live.com> * performance tweak if side has usb * Don't run init funtions on wrong side * renamed some variables for consistency * fix pimoroni typos * Clamp instead of OR * Promote combined values to uint16_t * Update pointing_device.c Co-authored-by: Drashna Jaelre <drashna@live.com> Co-authored-by: Nick Brassel <nick@tzarc.org>
This commit is contained in:
parent
76a673233c
commit
7f7364c559
13
docs/ChangeLog/20220226/PR15304.md
Normal file
13
docs/ChangeLog/20220226/PR15304.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
### Split Common core now supports Pointing Devices ([#15304](https://github.com/qmk/qmk_firmware/pull/15304))
|
||||||
|
|
||||||
|
Pointing devices can now be shared across a split keyboard with support for a single pointing device or a pointing device on each side.
|
||||||
|
|
||||||
|
This feature can be enabled with `#define SPLIT_POINTING_ENABLE` and one of the following options:
|
||||||
|
|
||||||
|
| Setting | Description |
|
||||||
|
|---------------------------|------------------------------------|
|
||||||
|
|`POINTING_DEVICE_LEFT` | Pointing device on the left side |
|
||||||
|
|`POINTING_DEVICE_RIGHT` | Pointing device on the right side |
|
||||||
|
|`POINTING_DEVICE_COMBINED` | Pointing device on both sides |
|
||||||
|
|
||||||
|
See the [Pointing Device](../feature_pointing_device.md) documentation for further configuration options.
|
@ -127,11 +127,10 @@ The Pimoroni Trackball module is a I2C based breakout board with an RGB enable t
|
|||||||
| Setting | Description | Default |
|
| Setting | Description | Default |
|
||||||
|-------------------------------------|------------------------------------------------------------------------------------|---------|
|
|-------------------------------------|------------------------------------------------------------------------------------|---------|
|
||||||
|`PIMORONI_TRACKBALL_ADDRESS` | (Required) Sets the I2C Address for the Pimoroni Trackball. | `0x0A` |
|
|`PIMORONI_TRACKBALL_ADDRESS` | (Required) Sets the I2C Address for the Pimoroni Trackball. | `0x0A` |
|
||||||
|`PIMORONI_TRACKBALL_TIMEOUT` | (Optional) The timeout for i2c communication with the trackpad in milliseconds. | `100` |
|
|`PIMORONI_TRACKBALL_TIMEOUT` | (Optional) The timeout for i2c communication with the trackball in milliseconds. | `100` |
|
||||||
|`PIMORONI_TRACKBALL_INTERVAL_MS` | (Optional) The update/read interval for the sensor in milliseconds. | `8` |
|
|
||||||
|`PIMORONI_TRACKBALL_SCALE` | (Optional) The multiplier used to generate reports from the sensor. | `5` |
|
|`PIMORONI_TRACKBALL_SCALE` | (Optional) The multiplier used to generate reports from the sensor. | `5` |
|
||||||
|`PIMORONI_TRACKBALL_DEBOUNCE_CYCLES` | (Optional) The number of scan cycles used for debouncing on the ball press. | `20` |
|
|`PIMORONI_TRACKBALL_DEBOUNCE_CYCLES` | (Optional) The number of scan cycles used for debouncing on the ball press. | `20` |
|
||||||
|`PIMORONI_TRACKBALL_ERROR_COUNT` | (Optional) Specifies the number of read/write errors until the sensor is disabled. | `10` |
|
|`PIMORONI_TRACKBALL_ERROR_COUNT` | (Optional) Specifies the number of read/write errors until the sensor is disabled. | `10` |
|
||||||
|
|
||||||
### PMW 3360 Sensor
|
### PMW 3360 Sensor
|
||||||
|
|
||||||
@ -171,14 +170,35 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {}
|
|||||||
|
|
||||||
## Common Configuration
|
## Common Configuration
|
||||||
|
|
||||||
| Setting | Description | Default |
|
| Setting | Description | Default |
|
||||||
|-------------------------------|-----------------------------------------------------------------------|---------------|
|
|----------------------------------|-----------------------------------------------------------------------|-------------------|
|
||||||
|`POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
|
|`POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
|
||||||
|`POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
|
|`POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
|
||||||
|`POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
|
|`POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
|
||||||
|`POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ |
|
|`POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ |
|
||||||
|`POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ |
|
|`POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ |
|
||||||
|`POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ |
|
|`POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_TASK_THROTTLE_MS` | (Optional) Limits the frequency that the sensor is polled for motion. | _not defined_ |
|
||||||
|
|
||||||
|
!> When using `SPLIT_POINTING_ENABLE` the `POINTING_DEVICE_MOTION_PIN` functionality is not supported and would recommend `POINTING_DEVICE_TASK_THROTTLE_MS` be set to `1`. Increasing this value will increase transport performance at the cost of possible mouse responsiveness.
|
||||||
|
|
||||||
|
|
||||||
|
## Split Keyboard Configuration
|
||||||
|
|
||||||
|
The following configuration options are only available when using `SPLIT_POINTING_ENABLE` see [data sync options](feature_split_keyboard.md?id=data-sync-options). The rotation and invert `*_RIGHT` options are only used with `POINTING_DEVICE_COMBINED`. If using `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` use the common configuration above to configure your pointing device.
|
||||||
|
|
||||||
|
| Setting | Description | Default |
|
||||||
|
|----------------------------------------|-----------------------------------------------------------------------|---------------|
|
||||||
|
|`POINTING_DEVICE_LEFT` | Pointing device on the left side (Required - pick one only) | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_RIGHT` | Pointing device on the right side (Required - pick one only) | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_COMBINED` | Pointing device on both sides (Required - pick one only) | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_ROTATION_90_RIGHT` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_ROTATION_180_RIGHT` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_ROTATION_270_RIGHT` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_INVERT_X_RIGHT` | (Optional) Inverts the X axis report. | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_INVERT_Y_RIGHT` | (Optional) Inverts the Y axis report. | _not defined_ |
|
||||||
|
|
||||||
|
!> If there is a `_RIGHT` configuration option or callback, the [common configuration](feature_pointing_device.md?id=common-configuration) option will work for the left. For correct left/right detection you should setup a [handedness option](feature_split_keyboard?id=setting-handedness), `EE_HANDS` is usually a good option for an existing board that doesn't do handedness by hardware.
|
||||||
|
|
||||||
|
|
||||||
## Callbacks and Functions
|
## Callbacks and Functions
|
||||||
@ -196,6 +216,21 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {}
|
|||||||
| `pointing_device_set_report(mouse_report)` | Sets the mouse report to the assigned `mouse_report_t` data structured passed to the function. |
|
| `pointing_device_set_report(mouse_report)` | Sets the mouse report to the assigned `mouse_report_t` data structured passed to the function. |
|
||||||
| `pointing_device_send(void)` | Sends the current mouse report to the host system. Function can be replaced. |
|
| `pointing_device_send(void)` | Sends the current mouse report to the host system. Function can be replaced. |
|
||||||
| `has_mouse_report_changed(old, new)` | Compares the old and new `mouse_report_t` data and returns true only if it has changed. |
|
| `has_mouse_report_changed(old, new)` | Compares the old and new `mouse_report_t` data and returns true only if it has changed. |
|
||||||
|
| `pointing_device_adjust_by_defines(mouse_report)` | Applies rotations and invert configurations to a raw mouse report. |
|
||||||
|
|
||||||
|
|
||||||
|
## Split Keyboard Callbacks and Functions
|
||||||
|
|
||||||
|
The combined functions below are only available when using `SPLIT_POINTING_ENABLE` and `POINTING_DEVICE_COMBINED`. The 2 callbacks `pointing_device_task_combined_*` replace the single sided equivalents above. See the [combined pointing devices example](feature_pointing_device.md?id=combined-pointing-devices)
|
||||||
|
|
||||||
|
| Function | Description |
|
||||||
|
|-----------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| `pointing_device_set_shared_report(mouse_report)` | Sets the shared mouse report to the assigned `mouse_report_t` data structured passed to the function. |
|
||||||
|
| `pointing_device_set_cpi_on_side(bool, uint16_t)` | Sets the CPI/DPI of one side, if supported. Passing `true` will set the left and `false` the right` |
|
||||||
|
| `pointing_device_combine_reports(left_report, right_report)` | Returns a combined mouse_report of left_report and right_report (as a `mouse_report_t` data structure) |
|
||||||
|
| `pointing_device_task_combined_kb(left_report, right_report)` | Callback, so keyboard code can intercept and modify the data. Returns a combined mouse report. |
|
||||||
|
| `pointing_device_task_combined_user(left_report, right_report)` | Callback, so user code can intercept and modify. Returns a combined mouse report using `pointing_device_combine_reports` |
|
||||||
|
| `pointing_device_adjust_by_defines_right(mouse_report)` | Applies right side rotations and invert configurations to a raw mouse report. |
|
||||||
|
|
||||||
|
|
||||||
# Manipulating Mouse Reports
|
# Manipulating Mouse Reports
|
||||||
@ -242,3 +277,62 @@ case MS_SPECIAL:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Recall that the mouse report is set to zero (except the buttons) whenever it is sent, so the scrolling would only occur once in each case.
|
Recall that the mouse report is set to zero (except the buttons) whenever it is sent, so the scrolling would only occur once in each case.
|
||||||
|
|
||||||
|
## Split Examples
|
||||||
|
|
||||||
|
The following examples make use the `SPLIT_POINTING_ENABLE` functionality and show how to manipulate the mouse report for a scrolling mode.
|
||||||
|
|
||||||
|
### Single Pointing Device
|
||||||
|
|
||||||
|
The following example will work with either `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` and enables scrolling mode while on a particular layer.
|
||||||
|
|
||||||
|
```c
|
||||||
|
|
||||||
|
static bool scrolling_mode = false;
|
||||||
|
|
||||||
|
layer_state_t layer_state_set_user(layer_state_t state) {
|
||||||
|
switch (get_highest_layer(state)) {
|
||||||
|
case _RAISE: // If we're on the _RAISE layer enable scrolling mode
|
||||||
|
scrolling_mode = true;
|
||||||
|
pointing_device_set_cpi(2000);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (scrolling_mode) { // check if we were scrolling before and set disable if so
|
||||||
|
scrolling_mode = false;
|
||||||
|
pointing_device_set_cpi(8000);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) {
|
||||||
|
if (scrolling_mode) {
|
||||||
|
mouse_report.h = mouse_report.x;
|
||||||
|
mouse_report.v = mouse_report.y;
|
||||||
|
mouse_report.x = 0;
|
||||||
|
mouse_report.y = 0;
|
||||||
|
}
|
||||||
|
return mouse_report;
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Combined Pointing Devices
|
||||||
|
|
||||||
|
The following example requires `POINTING_DEVICE_COMBINED` and sets the left side pointing device to scroll only.
|
||||||
|
|
||||||
|
```c
|
||||||
|
void keyboard_post_init_user(void) {
|
||||||
|
pointing_device_set_cpi_on_side(true, 1000); //Set cpi on left side to a low value for slower scrolling.
|
||||||
|
pointing_device_set_cpi_on_side(false, 8000); //Set cpi on right side to a reasonable value for mousing.
|
||||||
|
}
|
||||||
|
|
||||||
|
report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, report_mouse_t right_report) {
|
||||||
|
left_report.h = left_report.x;
|
||||||
|
left_report.v = left_report.y;
|
||||||
|
left_report.x = 0;
|
||||||
|
left_report.y = 0;
|
||||||
|
return pointing_device_combine_reports(left_report, right_report);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -266,6 +266,14 @@ This enables transmitting the current OLED on/off status to the slave side of th
|
|||||||
|
|
||||||
This enables transmitting the current ST7565 on/off status to the slave side of the split keyboard. The purpose of this feature is to support state (on/off state only) syncing.
|
This enables transmitting the current ST7565 on/off status to the slave side of the split keyboard. The purpose of this feature is to support state (on/off state only) syncing.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define SPLIT_POINTING_ENABLE
|
||||||
|
```
|
||||||
|
|
||||||
|
This enables transmitting the pointing device status to the master side of the split keyboard. The purpose of this feature is to enable use pointing devices on the slave side.
|
||||||
|
|
||||||
|
!> There is additional required configuration for `SPLIT_POINTING_ENABLE` outlined in the [pointing device documentation](feature_pointing_device.md?id=split-keyboard-configuration).
|
||||||
|
|
||||||
### Custom data sync between sides :id=custom-data-sync
|
### Custom data sync between sides :id=custom-data-sync
|
||||||
|
|
||||||
QMK's split transport allows for arbitrary data transactions at both the keyboard and user levels. This is modelled on a remote procedure call, with the master invoking a function on the slave side, with the ability to send data from master to slave, process it slave side, and send data back from slave to master.
|
QMK's split transport allows for arbitrary data transactions at both the keyboard and user levels. This is modelled on a remote procedure call, with the master invoking a function on the slave side, with the ability to send data from master to slave, process it slave side, and send data back from slave to master.
|
||||||
|
@ -33,8 +33,24 @@
|
|||||||
|
|
||||||
static uint16_t precision = 128;
|
static uint16_t precision = 128;
|
||||||
|
|
||||||
float pimoroni_trackball_get_precision(void) { return ((float)precision / 128); }
|
uint16_t pimoroni_trackball_get_cpi(void) { return (precision * 125); }
|
||||||
void pimoroni_trackball_set_precision(float floatprecision) { precision = (floatprecision * 128); }
|
/**
|
||||||
|
* @brief Sets the scaling value for pimoroni trackball
|
||||||
|
*
|
||||||
|
* Sets a scaling value for pimoroni trackball to allow runtime adjustment. This isn't used by the sensor and is an
|
||||||
|
* approximation so the functions are consistent across drivers.
|
||||||
|
*
|
||||||
|
* NOTE: This rounds down to the nearest number divisable by 125 that's a positive integer, values below 125 are clamped to 125.
|
||||||
|
*
|
||||||
|
* @param cpi uint16_t
|
||||||
|
*/
|
||||||
|
void pimoroni_trackball_set_cpi(uint16_t cpi) {
|
||||||
|
if (cpi < 249) {
|
||||||
|
precision = 1;
|
||||||
|
} else {
|
||||||
|
precision = (cpi - (cpi % 125)) / 125;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pimoroni_trackball_set_rgbw(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
void pimoroni_trackball_set_rgbw(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||||
uint8_t data[4] = {r, g, b, w};
|
uint8_t data[4] = {r, g, b, w};
|
||||||
@ -60,7 +76,7 @@ i2c_status_t read_pimoroni_trackball(pimoroni_data_t* data) {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((weak)) void pimironi_trackball_device_init(void) {
|
__attribute__((weak)) void pimoroni_trackball_device_init(void) {
|
||||||
i2c_init();
|
i2c_init();
|
||||||
pimoroni_trackball_set_rgbw(0x00, 0x00, 0x00, 0x00);
|
pimoroni_trackball_set_rgbw(0x00, 0x00, 0x00, 0x00);
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,6 @@
|
|||||||
#ifndef PIMORONI_TRACKBALL_ADDRESS
|
#ifndef PIMORONI_TRACKBALL_ADDRESS
|
||||||
# define PIMORONI_TRACKBALL_ADDRESS 0x0A
|
# define PIMORONI_TRACKBALL_ADDRESS 0x0A
|
||||||
#endif
|
#endif
|
||||||
#ifndef PIMORONI_TRACKBALL_INTERVAL_MS
|
|
||||||
# define PIMORONI_TRACKBALL_INTERVAL_MS 8
|
|
||||||
#endif
|
|
||||||
#ifndef PIMORONI_TRACKBALL_SCALE
|
#ifndef PIMORONI_TRACKBALL_SCALE
|
||||||
# define PIMORONI_TRACKBALL_SCALE 5
|
# define PIMORONI_TRACKBALL_SCALE 5
|
||||||
#endif
|
#endif
|
||||||
@ -52,10 +49,10 @@ typedef struct {
|
|||||||
uint8_t click;
|
uint8_t click;
|
||||||
} pimoroni_data_t;
|
} pimoroni_data_t;
|
||||||
|
|
||||||
void pimironi_trackball_device_init(void);
|
void pimoroni_trackball_device_init(void);
|
||||||
void pimoroni_trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white);
|
void pimoroni_trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white);
|
||||||
int16_t pimoroni_trackball_get_offsets(uint8_t negative_dir, uint8_t positive_dir, uint8_t scale);
|
int16_t pimoroni_trackball_get_offsets(uint8_t negative_dir, uint8_t positive_dir, uint8_t scale);
|
||||||
void pimoroni_trackball_adapt_values(int8_t* mouse, int16_t* offset);
|
void pimoroni_trackball_adapt_values(int8_t* mouse, int16_t* offset);
|
||||||
float pimoroni_trackball_get_precision(void);
|
uint16_t pimoroni_trackball_get_cpi(void);
|
||||||
void pimoroni_trackball_set_precision(float precision);
|
void pimoroni_trackball_set_cpi(uint16_t cpi);
|
||||||
i2c_status_t read_pimoroni_trackball(pimoroni_data_t* data);
|
i2c_status_t read_pimoroni_trackball(pimoroni_data_t* data);
|
||||||
|
@ -18,24 +18,105 @@
|
|||||||
|
|
||||||
#include "pointing_device.h"
|
#include "pointing_device.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "timer.h"
|
||||||
#ifdef MOUSEKEY_ENABLE
|
#ifdef MOUSEKEY_ENABLE
|
||||||
# include "mousekey.h"
|
# include "mousekey.h"
|
||||||
#endif
|
#endif
|
||||||
#if (defined(POINTING_DEVICE_ROTATION_90) + defined(POINTING_DEVICE_ROTATION_180) + defined(POINTING_DEVICE_ROTATION_270)) > 1
|
#if (defined(POINTING_DEVICE_ROTATION_90) + defined(POINTING_DEVICE_ROTATION_180) + defined(POINTING_DEVICE_ROTATION_270)) > 1
|
||||||
# error More than one rotation selected. This is not supported.
|
# error More than one rotation selected. This is not supported.
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(SPLIT_POINTING_ENABLE)
|
||||||
|
# include "transactions.h"
|
||||||
|
# include "keyboard.h"
|
||||||
|
|
||||||
static report_mouse_t mouseReport = {};
|
report_mouse_t shared_mouse_report = {};
|
||||||
|
uint16_t shared_cpi = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the shared mouse report used be pointing device task
|
||||||
|
*
|
||||||
|
* NOTE : Only available when using SPLIT_POINTING_ENABLE
|
||||||
|
*
|
||||||
|
* @param[in] new_mouse_report report_mouse_t
|
||||||
|
*/
|
||||||
|
void pointing_device_set_shared_report(report_mouse_t new_mouse_report) { shared_mouse_report = new_mouse_report; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets current pointing device CPI if supported
|
||||||
|
*
|
||||||
|
* Gets current cpi of the shared report and returns it as uint16_t
|
||||||
|
*
|
||||||
|
* NOTE : Only available when using SPLIT_POINTING_ENABLE
|
||||||
|
*
|
||||||
|
* @return cpi value as uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t pointing_device_get_shared_cpi(void) { return shared_cpi; }
|
||||||
|
|
||||||
|
# if defined(POINTING_DEVICE_LEFT)
|
||||||
|
# define POINTING_DEVICE_THIS_SIDE is_keyboard_left()
|
||||||
|
# elif defined(POINTING_DEVICE_RIGHT)
|
||||||
|
# define POINTING_DEVICE_THIS_SIDE !is_keyboard_left()
|
||||||
|
# elif defined(POINTING_DEVICE_COMBINED)
|
||||||
|
# define POINTING_DEVICE_THIS_SIDE true
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif // defined(SPLIT_POINTING_ENABLE)
|
||||||
|
|
||||||
|
static report_mouse_t local_mouse_report = {};
|
||||||
|
|
||||||
extern const pointing_device_driver_t pointing_device_driver;
|
extern const pointing_device_driver_t pointing_device_driver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compares 2 mouse reports for difference and returns result
|
||||||
|
*
|
||||||
|
* @param[in] new report_mouse_t
|
||||||
|
* @param[in] old report_mouse_t
|
||||||
|
* @return bool result
|
||||||
|
*/
|
||||||
__attribute__((weak)) bool has_mouse_report_changed(report_mouse_t new, report_mouse_t old) { return memcmp(&new, &old, sizeof(new)); }
|
__attribute__((weak)) bool has_mouse_report_changed(report_mouse_t new, report_mouse_t old) { return memcmp(&new, &old, sizeof(new)); }
|
||||||
|
|
||||||
__attribute__((weak)) void pointing_device_init_kb(void) {}
|
/**
|
||||||
__attribute__((weak)) void pointing_device_init_user(void) {}
|
* @brief Keyboard level code pointing device initialisation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
__attribute__((weak)) void pointing_device_init_kb(void) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief User level code pointing device initialisation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
__attribute__((weak)) void pointing_device_init_user(void) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Weak function allowing for keyboard level mouse report modification
|
||||||
|
*
|
||||||
|
* Takes report_mouse_t struct allowing modification at keyboard level then returns report_mouse_t.
|
||||||
|
*
|
||||||
|
* @param[in] mouse_report report_mouse_t
|
||||||
|
* @return report_mouse_t
|
||||||
|
*/
|
||||||
__attribute__((weak)) report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { return pointing_device_task_user(mouse_report); }
|
__attribute__((weak)) report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { return pointing_device_task_user(mouse_report); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Weak function allowing for user level mouse report modification
|
||||||
|
*
|
||||||
|
* Takes report_mouse_t struct allowing modification at user level then returns report_mouse_t.
|
||||||
|
*
|
||||||
|
* @param[in] mouse_report report_mouse_t
|
||||||
|
* @return report_mouse_t
|
||||||
|
*/
|
||||||
__attribute__((weak)) report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) { return mouse_report; }
|
__attribute__((weak)) report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) { return mouse_report; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handles pointing device buttons
|
||||||
|
*
|
||||||
|
* Returns modified button bitmask using bool pressed and selected pointing_device_buttons_t button in uint8_t buttons bitmask.
|
||||||
|
*
|
||||||
|
* @param buttons[in] uint8_t bitmask
|
||||||
|
* @param pressed[in] bool
|
||||||
|
* @param button[in] pointing_device_buttons_t value
|
||||||
|
* @return Modified uint8_t bitmask buttons
|
||||||
|
*/
|
||||||
__attribute__((weak)) uint8_t pointing_device_handle_buttons(uint8_t buttons, bool pressed, pointing_device_buttons_t button) {
|
__attribute__((weak)) uint8_t pointing_device_handle_buttons(uint8_t buttons, bool pressed, pointing_device_buttons_t button) {
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
buttons |= 1 << (button);
|
buttons |= 1 << (button);
|
||||||
@ -45,7 +126,17 @@ __attribute__((weak)) uint8_t pointing_device_handle_buttons(uint8_t buttons, bo
|
|||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialises pointing device
|
||||||
|
*
|
||||||
|
* Initialises pointing device, perform driver init and optional keyboard/user level code.
|
||||||
|
*/
|
||||||
__attribute__((weak)) void pointing_device_init(void) {
|
__attribute__((weak)) void pointing_device_init(void) {
|
||||||
|
#if defined(SPLIT_POINTING_ENABLE)
|
||||||
|
if (!(POINTING_DEVICE_THIS_SIDE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
pointing_device_driver.init();
|
pointing_device_driver.init();
|
||||||
#ifdef POINTING_DEVICE_MOTION_PIN
|
#ifdef POINTING_DEVICE_MOTION_PIN
|
||||||
setPinInputHigh(POINTING_DEVICE_MOTION_PIN);
|
setPinInputHigh(POINTING_DEVICE_MOTION_PIN);
|
||||||
@ -54,67 +145,299 @@ __attribute__((weak)) void pointing_device_init(void) {
|
|||||||
pointing_device_init_user();
|
pointing_device_init_user();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sends processed mouse report to host
|
||||||
|
*
|
||||||
|
* This sends the mouse report generated by pointing_device_task if changed since the last report. Once send zeros mouse report except buttons.
|
||||||
|
*
|
||||||
|
*/
|
||||||
__attribute__((weak)) void pointing_device_send(void) {
|
__attribute__((weak)) void pointing_device_send(void) {
|
||||||
static report_mouse_t old_report = {};
|
static report_mouse_t old_report = {};
|
||||||
|
|
||||||
// If you need to do other things, like debugging, this is the place to do it.
|
// If you need to do other things, like debugging, this is the place to do it.
|
||||||
if (has_mouse_report_changed(mouseReport, old_report)) {
|
if (has_mouse_report_changed(local_mouse_report, old_report)) {
|
||||||
host_mouse_send(&mouseReport);
|
host_mouse_send(&local_mouse_report);
|
||||||
}
|
}
|
||||||
// send it and 0 it out except for buttons, so those stay until they are explicity over-ridden using update_pointing_device
|
// send it and 0 it out except for buttons, so those stay until they are explicity over-ridden using update_pointing_device
|
||||||
mouseReport.x = 0;
|
local_mouse_report.x = 0;
|
||||||
mouseReport.y = 0;
|
local_mouse_report.y = 0;
|
||||||
mouseReport.v = 0;
|
local_mouse_report.v = 0;
|
||||||
mouseReport.h = 0;
|
local_mouse_report.h = 0;
|
||||||
|
|
||||||
memcpy(&old_report, &mouseReport, sizeof(mouseReport));
|
memcpy(&old_report, &local_mouse_report, sizeof(local_mouse_report));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((weak)) void pointing_device_task(void) {
|
/**
|
||||||
// Gather report info
|
* @brief Adjust mouse report by any optional common pointing configuration defines
|
||||||
#ifdef POINTING_DEVICE_MOTION_PIN
|
*
|
||||||
if (!readPin(POINTING_DEVICE_MOTION_PIN))
|
* This applies rotation or inversion to the mouse report as selected by the pointing device common configuration defines.
|
||||||
#endif
|
*
|
||||||
mouseReport = pointing_device_driver.get_report(mouseReport);
|
* @param mouse_report[in] takes a report_mouse_t to be adjusted
|
||||||
|
* @return report_mouse_t with adjusted values
|
||||||
// Support rotation of the sensor data
|
*/
|
||||||
|
report_mouse_t pointing_device_adjust_by_defines(report_mouse_t mouse_report) {
|
||||||
|
// Support rotation of the sensor data
|
||||||
#if defined(POINTING_DEVICE_ROTATION_90) || defined(POINTING_DEVICE_ROTATION_180) || defined(POINTING_DEVICE_ROTATION_270)
|
#if defined(POINTING_DEVICE_ROTATION_90) || defined(POINTING_DEVICE_ROTATION_180) || defined(POINTING_DEVICE_ROTATION_270)
|
||||||
int8_t x = mouseReport.x, y = mouseReport.y;
|
int8_t x = mouse_report.x, y = mouse_report.y;
|
||||||
# if defined(POINTING_DEVICE_ROTATION_90)
|
# if defined(POINTING_DEVICE_ROTATION_90)
|
||||||
mouseReport.x = y;
|
mouse_report.x = y;
|
||||||
mouseReport.y = -x;
|
mouse_report.y = -x;
|
||||||
# elif defined(POINTING_DEVICE_ROTATION_180)
|
# elif defined(POINTING_DEVICE_ROTATION_180)
|
||||||
mouseReport.x = -x;
|
mouse_report.x = -x;
|
||||||
mouseReport.y = -y;
|
mouse_report.y = -y;
|
||||||
# elif defined(POINTING_DEVICE_ROTATION_270)
|
# elif defined(POINTING_DEVICE_ROTATION_270)
|
||||||
mouseReport.x = -y;
|
mouse_report.x = -y;
|
||||||
mouseReport.y = x;
|
mouse_report.y = x;
|
||||||
# else
|
# else
|
||||||
# error "How the heck did you get here?!"
|
# error "How the heck did you get here?!"
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
// Support Inverting the X and Y Axises
|
// Support Inverting the X and Y Axises
|
||||||
#if defined(POINTING_DEVICE_INVERT_X)
|
#if defined(POINTING_DEVICE_INVERT_X)
|
||||||
mouseReport.x = -mouseReport.x;
|
mouse_report.x = -mouse_report.x;
|
||||||
#endif
|
#endif
|
||||||
#if defined(POINTING_DEVICE_INVERT_Y)
|
#if defined(POINTING_DEVICE_INVERT_Y)
|
||||||
mouseReport.y = -mouseReport.y;
|
mouse_report.y = -mouse_report.y;
|
||||||
|
#endif
|
||||||
|
return mouse_report;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves and processes pointing device data.
|
||||||
|
*
|
||||||
|
* This function is part of the keyboard loop and retrieves the mouse report from the pointing device driver.
|
||||||
|
* It applies any optional configuration e.g. rotation or axis inversion and then initiates a send.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
__attribute__((weak)) void pointing_device_task(void) {
|
||||||
|
#if defined(SPLIT_POINTING_ENABLE)
|
||||||
|
// Don't poll the target side pointing device.
|
||||||
|
if (!is_keyboard_master()) {
|
||||||
|
return;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(POINTING_DEVICE_TASK_THROTTLE_MS)
|
||||||
|
static uint32_t last_exec = 0;
|
||||||
|
if (timer_elapsed32(last_exec) < POINTING_DEVICE_TASK_THROTTLE_MS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
last_exec = timer_read32();
|
||||||
|
#else
|
||||||
|
# if defined(SPLIT_POINTING_ENABLE)
|
||||||
|
# pragma message("It's recommended you enable a throttle when sharing pointing devices.")
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Gather report info
|
||||||
|
#ifdef POINTING_DEVICE_MOTION_PIN
|
||||||
|
# if defined(SPLIT_POINTING_ENABLE)
|
||||||
|
# error POINTING_DEVICE_MOTION_PIN not supported when sharing the pointing device report between sides.
|
||||||
|
# endif
|
||||||
|
if (!readPin(POINTING_DEVICE_MOTION_PIN))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(SPLIT_POINTING_ENABLE)
|
||||||
|
# if defined(POINTING_DEVICE_COMBINED)
|
||||||
|
static uint8_t old_buttons = 0;
|
||||||
|
local_mouse_report.buttons = old_buttons;
|
||||||
|
local_mouse_report = pointing_device_driver.get_report(local_mouse_report);
|
||||||
|
old_buttons = local_mouse_report.buttons;
|
||||||
|
# elif defined(POINTING_DEVICE_LEFT) || defined(POINTING_DEVICE_RIGHT)
|
||||||
|
local_mouse_report = POINTING_DEVICE_THIS_SIDE ? pointing_device_driver.get_report(local_mouse_report) : shared_mouse_report;
|
||||||
|
# else
|
||||||
|
# error "You need to define the side(s) the pointing device is on. POINTING_DEVICE_COMBINED / POINTING_DEVICE_LEFT / POINTING_DEVICE_RIGHT"
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
local_mouse_report = pointing_device_driver.get_report(local_mouse_report);
|
||||||
|
#endif // defined(SPLIT_POINTING_ENABLE)
|
||||||
|
|
||||||
// allow kb to intercept and modify report
|
// allow kb to intercept and modify report
|
||||||
mouseReport = pointing_device_task_kb(mouseReport);
|
#if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED)
|
||||||
|
if (is_keyboard_left()) {
|
||||||
|
local_mouse_report = pointing_device_adjust_by_defines(local_mouse_report);
|
||||||
|
shared_mouse_report = pointing_device_adjust_by_defines_right(shared_mouse_report);
|
||||||
|
} else {
|
||||||
|
local_mouse_report = pointing_device_adjust_by_defines_right(local_mouse_report);
|
||||||
|
shared_mouse_report = pointing_device_adjust_by_defines(shared_mouse_report);
|
||||||
|
}
|
||||||
|
local_mouse_report = is_keyboard_left() ? pointing_device_task_combined_kb(local_mouse_report, shared_mouse_report) : pointing_device_task_combined_kb(shared_mouse_report, local_mouse_report);
|
||||||
|
#else
|
||||||
|
local_mouse_report = pointing_device_adjust_by_defines(local_mouse_report);
|
||||||
|
local_mouse_report = pointing_device_task_kb(local_mouse_report);
|
||||||
|
#endif
|
||||||
// combine with mouse report to ensure that the combined is sent correctly
|
// combine with mouse report to ensure that the combined is sent correctly
|
||||||
#ifdef MOUSEKEY_ENABLE
|
#ifdef MOUSEKEY_ENABLE
|
||||||
report_mouse_t mousekey_report = mousekey_get_report();
|
report_mouse_t mousekey_report = mousekey_get_report();
|
||||||
mouseReport.buttons = mouseReport.buttons | mousekey_report.buttons;
|
local_mouse_report.buttons = local_mouse_report.buttons | mousekey_report.buttons;
|
||||||
#endif
|
#endif
|
||||||
pointing_device_send();
|
pointing_device_send();
|
||||||
}
|
}
|
||||||
|
|
||||||
report_mouse_t pointing_device_get_report(void) { return mouseReport; }
|
/**
|
||||||
|
* @brief Gets current mouse report used by pointing device task
|
||||||
|
*
|
||||||
|
* @return report_mouse_t
|
||||||
|
*/
|
||||||
|
report_mouse_t pointing_device_get_report(void) { return local_mouse_report; }
|
||||||
|
|
||||||
void pointing_device_set_report(report_mouse_t newMouseReport) { mouseReport = newMouseReport; }
|
/**
|
||||||
|
* @brief Sets mouse report used be pointing device task
|
||||||
|
*
|
||||||
|
* @param[in] new_mouse_report
|
||||||
|
*/
|
||||||
|
void pointing_device_set_report(report_mouse_t new_mouse_report) { local_mouse_report = new_mouse_report; }
|
||||||
|
|
||||||
uint16_t pointing_device_get_cpi(void) { return pointing_device_driver.get_cpi(); }
|
/**
|
||||||
|
* @brief Gets current pointing device CPI if supported
|
||||||
|
*
|
||||||
|
* Gets current cpi from pointing device driver if supported and returns it as uint16_t
|
||||||
|
*
|
||||||
|
* @return cpi value as uint16_t
|
||||||
|
*/
|
||||||
|
uint16_t pointing_device_get_cpi(void) {
|
||||||
|
#if defined(SPLIT_POINTING_ENABLE)
|
||||||
|
return POINTING_DEVICE_THIS_SIDE ? pointing_device_driver.get_cpi() : shared_cpi;
|
||||||
|
#else
|
||||||
|
return pointing_device_driver.get_cpi();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void pointing_device_set_cpi(uint16_t cpi) { pointing_device_driver.set_cpi(cpi); }
|
/**
|
||||||
|
* @brief Set pointing device CPI if supported
|
||||||
|
*
|
||||||
|
* Takes a uint16_t value to set pointing device cpi if supported by driver.
|
||||||
|
*
|
||||||
|
* @param[in] cpi uint16_t value.
|
||||||
|
*/
|
||||||
|
void pointing_device_set_cpi(uint16_t cpi) {
|
||||||
|
#if defined(SPLIT_POINTING_ENABLE)
|
||||||
|
if (POINTING_DEVICE_THIS_SIDE) {
|
||||||
|
pointing_device_driver.set_cpi(cpi);
|
||||||
|
} else {
|
||||||
|
shared_cpi = cpi;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
pointing_device_driver.set_cpi(cpi);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED)
|
||||||
|
/**
|
||||||
|
* @brief Set pointing device CPI if supported
|
||||||
|
*
|
||||||
|
* Takes a bool and uint16_t and allows setting cpi for a single side when using 2 pointing devices with a split keyboard.
|
||||||
|
*
|
||||||
|
* NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
|
||||||
|
*
|
||||||
|
* @param[in] left true = left, false = right.
|
||||||
|
* @param[in] cpi uint16_t value.
|
||||||
|
*/
|
||||||
|
void pointing_device_set_cpi_on_side(bool left, uint16_t cpi) {
|
||||||
|
bool local = (is_keyboard_left() & left) ? true : false;
|
||||||
|
if (local) {
|
||||||
|
pointing_device_driver.set_cpi(cpi);
|
||||||
|
} else {
|
||||||
|
shared_cpi = cpi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief clamps int16_t to int8_t
|
||||||
|
*
|
||||||
|
* @param[in] int16_t value
|
||||||
|
* @return int8_t clamped value
|
||||||
|
*/
|
||||||
|
static inline int8_t pointing_device_movement_clamp(int16_t value) {
|
||||||
|
if (value < INT8_MIN) {
|
||||||
|
return INT8_MIN;
|
||||||
|
} else if (value > INT8_MAX) {
|
||||||
|
return INT8_MAX;
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief combines 2 mouse reports and returns 2
|
||||||
|
*
|
||||||
|
* Combines 2 report_mouse_t structs, clamping movement values to int8_t and ignores report_id then returns the resulting report_mouse_t struct.
|
||||||
|
*
|
||||||
|
* NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
|
||||||
|
*
|
||||||
|
* @param[in] left_report left report_mouse_t
|
||||||
|
* @param[in] right_report right report_mouse_t
|
||||||
|
* @return combined report_mouse_t of left_report and right_report
|
||||||
|
*/
|
||||||
|
report_mouse_t pointing_device_combine_reports(report_mouse_t left_report, report_mouse_t right_report) {
|
||||||
|
left_report.x = pointing_device_movement_clamp((int16_t)left_report.x + right_report.x);
|
||||||
|
left_report.y = pointing_device_movement_clamp((int16_t)left_report.y + right_report.y);
|
||||||
|
left_report.h = pointing_device_movement_clamp((int16_t)left_report.h + right_report.h);
|
||||||
|
left_report.v = pointing_device_movement_clamp((int16_t)left_report.v + right_report.v);
|
||||||
|
left_report.buttons |= right_report.buttons;
|
||||||
|
return left_report;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adjust mouse report by any optional right pointing configuration defines
|
||||||
|
*
|
||||||
|
* This applies rotation or inversion to the mouse report as selected by the pointing device common configuration defines.
|
||||||
|
*
|
||||||
|
* NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
|
||||||
|
*
|
||||||
|
* @param[in] mouse_report report_mouse_t to be adjusted
|
||||||
|
* @return report_mouse_t with adjusted values
|
||||||
|
*/
|
||||||
|
report_mouse_t pointing_device_adjust_by_defines_right(report_mouse_t mouse_report) {
|
||||||
|
// Support rotation of the sensor data
|
||||||
|
# if defined(POINTING_DEVICE_ROTATION_90_RIGHT) || defined(POINTING_DEVICE_ROTATION_RIGHT) || defined(POINTING_DEVICE_ROTATION_RIGHT)
|
||||||
|
int8_t x = mouse_report.x, y = mouse_report.y;
|
||||||
|
# if defined(POINTING_DEVICE_ROTATION_90_RIGHT)
|
||||||
|
mouse_report.x = y;
|
||||||
|
mouse_report.y = -x;
|
||||||
|
# elif defined(POINTING_DEVICE_ROTATION_180_RIGHT)
|
||||||
|
mouse_report.x = -x;
|
||||||
|
mouse_report.y = -y;
|
||||||
|
# elif defined(POINTING_DEVICE_ROTATION_270_RIGHT)
|
||||||
|
mouse_report.x = -y;
|
||||||
|
mouse_report.y = x;
|
||||||
|
# else
|
||||||
|
# error "How the heck did you get here?!"
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
// Support Inverting the X and Y Axises
|
||||||
|
# if defined(POINTING_DEVICE_INVERT_X_RIGHT)
|
||||||
|
mouse_report.x = -mouse_report.x;
|
||||||
|
# endif
|
||||||
|
# if defined(POINTING_DEVICE_INVERT_Y_RIGHT)
|
||||||
|
mouse_report.y = -mouse_report.y;
|
||||||
|
# endif
|
||||||
|
return mouse_report;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Weak function allowing for keyboard level mouse report modification
|
||||||
|
*
|
||||||
|
* Takes 2 report_mouse_t structs allowing individual modification of sides at keyboard level then returns pointing_device_task_combined_user.
|
||||||
|
*
|
||||||
|
* NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
|
||||||
|
*
|
||||||
|
* @param[in] left_report report_mouse_t
|
||||||
|
* @param[in] right_report report_mouse_t
|
||||||
|
* @return pointing_device_task_combined_user(left_report, right_report) by default
|
||||||
|
*/
|
||||||
|
__attribute__((weak)) report_mouse_t pointing_device_task_combined_kb(report_mouse_t left_report, report_mouse_t right_report) { return pointing_device_task_combined_user(left_report, right_report); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Weak function allowing for user level mouse report modification
|
||||||
|
*
|
||||||
|
* Takes 2 report_mouse_t structs allowing individual modification of sides at user level then returns pointing_device_combine_reports.
|
||||||
|
*
|
||||||
|
* NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED
|
||||||
|
*
|
||||||
|
* @param[in] left_report report_mouse_t
|
||||||
|
* @param[in] right_report report_mouse_t
|
||||||
|
* @return pointing_device_combine_reports(left_report, right_report) by default
|
||||||
|
*/
|
||||||
|
__attribute__((weak)) report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, report_mouse_t right_report) { return pointing_device_combine_reports(left_report, right_report); }
|
||||||
|
#endif
|
||||||
|
@ -86,3 +86,16 @@ void pointing_device_init_user(void);
|
|||||||
report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report);
|
report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report);
|
||||||
report_mouse_t pointing_device_task_user(report_mouse_t mouse_report);
|
report_mouse_t pointing_device_task_user(report_mouse_t mouse_report);
|
||||||
uint8_t pointing_device_handle_buttons(uint8_t buttons, bool pressed, pointing_device_buttons_t button);
|
uint8_t pointing_device_handle_buttons(uint8_t buttons, bool pressed, pointing_device_buttons_t button);
|
||||||
|
report_mouse_t pointing_device_adjust_by_defines(report_mouse_t mouse_report);
|
||||||
|
|
||||||
|
#if defined(SPLIT_POINTING_ENABLE)
|
||||||
|
void pointing_device_set_shared_report(report_mouse_t report);
|
||||||
|
uint16_t pointing_device_get_shared_cpi(void);
|
||||||
|
# if defined(POINTING_DEVICE_COMBINED)
|
||||||
|
void pointing_device_set_cpi_on_side(bool left, uint16_t cpi);
|
||||||
|
report_mouse_t pointing_device_combine_reports(report_mouse_t left_report, report_mouse_t right_report);
|
||||||
|
report_mouse_t pointing_device_task_combined_kb(report_mouse_t left_report, report_mouse_t right_report);
|
||||||
|
report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, report_mouse_t right_report);
|
||||||
|
report_mouse_t pointing_device_adjust_by_defines_right(report_mouse_t mouse_report);
|
||||||
|
# endif //defined(POINTING_DEVICE_COMBINED)
|
||||||
|
#endif //defined(SPLIT_POINTING_ENABLE)
|
||||||
|
@ -165,14 +165,13 @@ const pointing_device_driver_t pointing_device_driver = {
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball)
|
#elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball)
|
||||||
report_mouse_t pimorono_trackball_get_report(report_mouse_t mouse_report) {
|
report_mouse_t pimoroni_trackball_get_report(report_mouse_t mouse_report) {
|
||||||
static fast_timer_t throttle = 0;
|
static uint16_t debounce = 0;
|
||||||
static uint16_t debounce = 0;
|
static uint8_t error_count = 0;
|
||||||
static uint8_t error_count = 0;
|
pimoroni_data_t pimoroni_data = {0};
|
||||||
pimoroni_data_t pimoroni_data = {0};
|
static int16_t x_offset = 0, y_offset = 0;
|
||||||
static int16_t x_offset = 0, y_offset = 0;
|
|
||||||
|
|
||||||
if (error_count < PIMORONI_TRACKBALL_ERROR_COUNT && timer_elapsed_fast(throttle) >= PIMORONI_TRACKBALL_INTERVAL_MS) {
|
if (error_count < PIMORONI_TRACKBALL_ERROR_COUNT) {
|
||||||
i2c_status_t status = read_pimoroni_trackball(&pimoroni_data);
|
i2c_status_t status = read_pimoroni_trackball(&pimoroni_data);
|
||||||
|
|
||||||
if (status == I2C_STATUS_SUCCESS) {
|
if (status == I2C_STATUS_SUCCESS) {
|
||||||
@ -195,17 +194,16 @@ report_mouse_t pimorono_trackball_get_report(report_mouse_t mouse_report) {
|
|||||||
} else {
|
} else {
|
||||||
error_count++;
|
error_count++;
|
||||||
}
|
}
|
||||||
throttle = timer_read_fast();
|
|
||||||
}
|
}
|
||||||
return mouse_report;
|
return mouse_report;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
const pointing_device_driver_t pointing_device_driver = {
|
const pointing_device_driver_t pointing_device_driver = {
|
||||||
.init = pimironi_trackball_device_init,
|
.init = pimoroni_trackball_device_init,
|
||||||
.get_report = pimorono_trackball_get_report,
|
.get_report = pimoroni_trackball_get_report,
|
||||||
.set_cpi = NULL,
|
.set_cpi = pimoroni_trackball_set_cpi,
|
||||||
.get_cpi = NULL
|
.get_cpi = pimoroni_trackball_get_cpi
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
#elif defined(POINTING_DEVICE_DRIVER_pmw3360)
|
#elif defined(POINTING_DEVICE_DRIVER_pmw3360)
|
||||||
|
@ -78,6 +78,12 @@ enum serial_transaction_id {
|
|||||||
PUT_ST7565,
|
PUT_ST7565,
|
||||||
#endif // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)
|
#endif // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)
|
||||||
|
|
||||||
|
#if defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
||||||
|
GET_POINTING_CHECKSUM,
|
||||||
|
GET_POINTING_DATA,
|
||||||
|
PUT_POINTING_CPI,
|
||||||
|
#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
||||||
|
|
||||||
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
||||||
PUT_RPC_INFO,
|
PUT_RPC_INFO,
|
||||||
PUT_RPC_REQ_DATA,
|
PUT_RPC_REQ_DATA,
|
||||||
|
@ -578,6 +578,82 @@ static void st7565_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sla
|
|||||||
|
|
||||||
#endif // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)
|
#endif // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////
|
||||||
|
// POINTING
|
||||||
|
|
||||||
|
#if defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
||||||
|
|
||||||
|
static bool pointing_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
|
||||||
|
# if defined(POINTING_DEVICE_LEFT)
|
||||||
|
if (is_keyboard_left()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
# elif defined(POINTING_DEVICE_RIGHT)
|
||||||
|
if (!is_keyboard_left()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
static uint32_t last_update = 0;
|
||||||
|
static uint16_t last_cpi = 0;
|
||||||
|
report_mouse_t temp_state;
|
||||||
|
uint16_t temp_cpi;
|
||||||
|
bool okay = read_if_checksum_mismatch(GET_POINTING_CHECKSUM, GET_POINTING_DATA, &last_update, &temp_state, &split_shmem->pointing.report, sizeof(temp_state));
|
||||||
|
if (okay) pointing_device_set_shared_report(temp_state);
|
||||||
|
temp_cpi = pointing_device_get_shared_cpi();
|
||||||
|
if (temp_cpi && memcmp(&last_cpi, &temp_cpi, sizeof(temp_cpi)) != 0) {
|
||||||
|
memcpy(&split_shmem->pointing.cpi, &temp_cpi, sizeof(temp_cpi));
|
||||||
|
okay = transport_write(PUT_POINTING_CPI, &split_shmem->pointing.cpi, sizeof(split_shmem->pointing.cpi));
|
||||||
|
if (okay) {
|
||||||
|
last_cpi = temp_cpi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return okay;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const pointing_device_driver_t pointing_device_driver;
|
||||||
|
|
||||||
|
static void pointing_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
|
||||||
|
# if defined(POINTING_DEVICE_LEFT)
|
||||||
|
if (!is_keyboard_left()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
# elif defined(POINTING_DEVICE_RIGHT)
|
||||||
|
if (is_keyboard_left()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
report_mouse_t temp_report;
|
||||||
|
uint16_t temp_cpi;
|
||||||
|
# ifdef POINTING_DEVICE_TASK_THROTTLE_MS
|
||||||
|
static uint32_t last_exec = 0;
|
||||||
|
if (timer_elapsed32(last_exec) < POINTING_DEVICE_TASK_THROTTLE_MS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
last_exec = timer_read32();
|
||||||
|
# endif
|
||||||
|
temp_cpi = pointing_device_driver.get_cpi();
|
||||||
|
if (split_shmem->pointing.cpi && memcmp(&split_shmem->pointing.cpi, &temp_cpi, sizeof(temp_cpi)) != 0) {
|
||||||
|
pointing_device_driver.set_cpi(split_shmem->pointing.cpi);
|
||||||
|
}
|
||||||
|
memset(&temp_report, 0, sizeof(temp_report));
|
||||||
|
temp_report = pointing_device_driver.get_report(temp_report);
|
||||||
|
memcpy(&split_shmem->pointing.report, &temp_report, sizeof(temp_report));
|
||||||
|
// Now update the checksum given that the pointing has been written to
|
||||||
|
split_shmem->pointing.checksum = crc8(&temp_report, sizeof(temp_report));
|
||||||
|
}
|
||||||
|
|
||||||
|
# define TRANSACTIONS_POINTING_MASTER() TRANSACTION_HANDLER_MASTER(pointing)
|
||||||
|
# define TRANSACTIONS_POINTING_SLAVE() TRANSACTION_HANDLER_SLAVE(pointing)
|
||||||
|
# define TRANSACTIONS_POINTING_REGISTRATIONS [GET_POINTING_CHECKSUM] = trans_target2initiator_initializer(pointing.checksum), [GET_POINTING_DATA] = trans_target2initiator_initializer(pointing.report), [PUT_POINTING_CPI] = trans_initiator2target_initializer(pointing.cpi),
|
||||||
|
|
||||||
|
#else // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
||||||
|
|
||||||
|
# define TRANSACTIONS_POINTING_MASTER()
|
||||||
|
# define TRANSACTIONS_POINTING_SLAVE()
|
||||||
|
# define TRANSACTIONS_POINTING_REGISTRATIONS
|
||||||
|
|
||||||
|
#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
|
|
||||||
uint8_t dummy;
|
uint8_t dummy;
|
||||||
@ -604,6 +680,7 @@ split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = {
|
|||||||
TRANSACTIONS_WPM_REGISTRATIONS
|
TRANSACTIONS_WPM_REGISTRATIONS
|
||||||
TRANSACTIONS_OLED_REGISTRATIONS
|
TRANSACTIONS_OLED_REGISTRATIONS
|
||||||
TRANSACTIONS_ST7565_REGISTRATIONS
|
TRANSACTIONS_ST7565_REGISTRATIONS
|
||||||
|
TRANSACTIONS_POINTING_REGISTRATIONS
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
||||||
@ -629,6 +706,7 @@ bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix
|
|||||||
TRANSACTIONS_WPM_MASTER();
|
TRANSACTIONS_WPM_MASTER();
|
||||||
TRANSACTIONS_OLED_MASTER();
|
TRANSACTIONS_OLED_MASTER();
|
||||||
TRANSACTIONS_ST7565_MASTER();
|
TRANSACTIONS_ST7565_MASTER();
|
||||||
|
TRANSACTIONS_POINTING_MASTER();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,6 +725,7 @@ void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[
|
|||||||
TRANSACTIONS_WPM_SLAVE();
|
TRANSACTIONS_WPM_SLAVE();
|
||||||
TRANSACTIONS_OLED_SLAVE();
|
TRANSACTIONS_OLED_SLAVE();
|
||||||
TRANSACTIONS_ST7565_SLAVE();
|
TRANSACTIONS_ST7565_SLAVE();
|
||||||
|
TRANSACTIONS_POINTING_SLAVE();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
||||||
|
@ -106,6 +106,15 @@ typedef struct _split_mods_sync_t {
|
|||||||
} split_mods_sync_t;
|
} split_mods_sync_t;
|
||||||
#endif // SPLIT_MODS_ENABLE
|
#endif // SPLIT_MODS_ENABLE
|
||||||
|
|
||||||
|
#if defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
||||||
|
# include "pointing_device.h"
|
||||||
|
typedef struct _split_slave_pointing_sync_t {
|
||||||
|
uint8_t checksum;
|
||||||
|
report_mouse_t report;
|
||||||
|
uint16_t cpi;
|
||||||
|
} split_slave_pointing_sync_t;
|
||||||
|
#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
||||||
|
|
||||||
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
||||||
typedef struct _rpc_sync_info_t {
|
typedef struct _rpc_sync_info_t {
|
||||||
int8_t transaction_id;
|
int8_t transaction_id;
|
||||||
@ -173,6 +182,10 @@ typedef struct _split_shared_memory_t {
|
|||||||
uint8_t current_st7565_state;
|
uint8_t current_st7565_state;
|
||||||
#endif // ST7565_ENABLE(OLED_ENABLE) && defined(SPLIT_ST7565_ENABLE)
|
#endif // ST7565_ENABLE(OLED_ENABLE) && defined(SPLIT_ST7565_ENABLE)
|
||||||
|
|
||||||
|
#if defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
||||||
|
split_slave_pointing_sync_t pointing;
|
||||||
|
#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
||||||
|
|
||||||
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
||||||
rpc_sync_info_t rpc_info;
|
rpc_sync_info_t rpc_info;
|
||||||
uint8_t rpc_m2s_buffer[RPC_M2S_BUFFER_SIZE];
|
uint8_t rpc_m2s_buffer[RPC_M2S_BUFFER_SIZE];
|
||||||
|
Loading…
Reference in New Issue
Block a user