diff options
author | Dasky <32983009+daskygit@users.noreply.github.com> | 2021-12-27 01:05:51 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-27 12:05:51 +1100 |
commit | 7f7364c55912879baaff8fafca550d02f17b4d44 (patch) | |
tree | 8afd414f6b202a126632a8c047dcf200312c78ff /quantum | |
parent | 76a673233c8cb3d97130a6dece364c24b29f5fd7 (diff) |
[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>
Diffstat (limited to 'quantum')
-rw-r--r-- | quantum/pointing_device.c | 389 | ||||
-rw-r--r-- | quantum/pointing_device.h | 13 | ||||
-rw-r--r-- | quantum/pointing_device_drivers.c | 24 | ||||
-rw-r--r-- | quantum/split_common/transaction_id_define.h | 6 | ||||
-rw-r--r-- | quantum/split_common/transactions.c | 79 | ||||
-rw-r--r-- | quantum/split_common/transport.h | 13 |
6 files changed, 478 insertions, 46 deletions
diff --git a/quantum/pointing_device.c b/quantum/pointing_device.c index 2fefdb67b6..23d93fa15f 100644 --- a/quantum/pointing_device.c +++ b/quantum/pointing_device.c @@ -18,24 +18,105 @@ #include "pointing_device.h" #include <string.h> +#include "timer.h" #ifdef MOUSEKEY_ENABLE # include "mousekey.h" #endif #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. #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; +/** + * @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)) 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); } + +/** + * @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; } +/** + * @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) { if (pressed) { buttons |= 1 << (button); @@ -45,7 +126,17 @@ __attribute__((weak)) uint8_t pointing_device_handle_buttons(uint8_t buttons, bo 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) { +#if defined(SPLIT_POINTING_ENABLE) + if (!(POINTING_DEVICE_THIS_SIDE)) { + return; + } +#endif pointing_device_driver.init(); #ifdef POINTING_DEVICE_MOTION_PIN setPinInputHigh(POINTING_DEVICE_MOTION_PIN); @@ -54,67 +145,299 @@ __attribute__((weak)) void pointing_device_init(void) { 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) { static report_mouse_t old_report = {}; // If you need to do other things, like debugging, this is the place to do it. - if (has_mouse_report_changed(mouseReport, old_report)) { - host_mouse_send(&mouseReport); + if (has_mouse_report_changed(local_mouse_report, old_report)) { + 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 - mouseReport.x = 0; - mouseReport.y = 0; - mouseReport.v = 0; - mouseReport.h = 0; + local_mouse_report.x = 0; + local_mouse_report.y = 0; + local_mouse_report.v = 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 -#ifdef POINTING_DEVICE_MOTION_PIN - if (!readPin(POINTING_DEVICE_MOTION_PIN)) -#endif - mouseReport = pointing_device_driver.get_report(mouseReport); - - // Support rotation of the sensor data +/** + * @brief Adjust mouse report by any optional common pointing configuration defines + * + * This applies rotation or inversion to the mouse report as selected by the pointing device common configuration defines. + * + * @param mouse_report[in] takes a report_mouse_t to be adjusted + * @return report_mouse_t with adjusted values + */ +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) - int8_t x = mouseReport.x, y = mouseReport.y; + int8_t x = mouse_report.x, y = mouse_report.y; # if defined(POINTING_DEVICE_ROTATION_90) - mouseReport.x = y; - mouseReport.y = -x; + mouse_report.x = y; + mouse_report.y = -x; # elif defined(POINTING_DEVICE_ROTATION_180) - mouseReport.x = -x; - mouseReport.y = -y; + mouse_report.x = -x; + mouse_report.y = -y; # elif defined(POINTING_DEVICE_ROTATION_270) - mouseReport.x = -y; - mouseReport.y = x; + 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) - mouseReport.x = -mouseReport.x; + mouse_report.x = -mouse_report.x; #endif #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 + +#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 - 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 #ifdef MOUSEKEY_ENABLE 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 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; } + +/** + * @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; } + +/** + * @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_report(report_mouse_t newMouseReport) { mouseReport = newMouseReport; } +/** + * @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 +} -uint16_t pointing_device_get_cpi(void) { return pointing_device_driver.get_cpi(); } +#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; + } +} -void pointing_device_set_cpi(uint16_t cpi) { pointing_device_driver.set_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 diff --git a/quantum/pointing_device.h b/quantum/pointing_device.h index 5106c26660..78398d8999 100644 --- a/quantum/pointing_device.h +++ b/quantum/pointing_device.h @@ -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_user(report_mouse_t mouse_report); 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) diff --git a/quantum/pointing_device_drivers.c b/quantum/pointing_device_drivers.c index 9ad5e76ba6..0852a0bea7 100644 --- a/quantum/pointing_device_drivers.c +++ b/quantum/pointing_device_drivers.c @@ -165,14 +165,13 @@ const pointing_device_driver_t pointing_device_driver = { // clang-format on #elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball) -report_mouse_t pimorono_trackball_get_report(report_mouse_t mouse_report) { - static fast_timer_t throttle = 0; - static uint16_t debounce = 0; - static uint8_t error_count = 0; - pimoroni_data_t pimoroni_data = {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) { +report_mouse_t pimoroni_trackball_get_report(report_mouse_t mouse_report) { + static uint16_t debounce = 0; + static uint8_t error_count = 0; + pimoroni_data_t pimoroni_data = {0}; + static int16_t x_offset = 0, y_offset = 0; + + if (error_count < PIMORONI_TRACKBALL_ERROR_COUNT) { i2c_status_t status = read_pimoroni_trackball(&pimoroni_data); if (status == I2C_STATUS_SUCCESS) { @@ -195,17 +194,16 @@ report_mouse_t pimorono_trackball_get_report(report_mouse_t mouse_report) { } else { error_count++; } - throttle = timer_read_fast(); } return mouse_report; } // clang-format off const pointing_device_driver_t pointing_device_driver = { - .init = pimironi_trackball_device_init, - .get_report = pimorono_trackball_get_report, - .set_cpi = NULL, - .get_cpi = NULL + .init = pimoroni_trackball_device_init, + .get_report = pimoroni_trackball_get_report, + .set_cpi = pimoroni_trackball_set_cpi, + .get_cpi = pimoroni_trackball_get_cpi }; // clang-format on #elif defined(POINTING_DEVICE_DRIVER_pmw3360) diff --git a/quantum/split_common/transaction_id_define.h b/quantum/split_common/transaction_id_define.h index 535bc21aea..aa71c3621e 100644 --- a/quantum/split_common/transaction_id_define.h +++ b/quantum/split_common/transaction_id_define.h @@ -78,6 +78,12 @@ enum serial_transaction_id { PUT_ST7565, #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) PUT_RPC_INFO, PUT_RPC_REQ_DATA, diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c index 3ff87710e7..9622acb377 100644 --- a/quantum/split_common/transactions.c +++ b/quantum/split_common/transactions.c @@ -579,6 +579,82 @@ static void st7565_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sla #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; split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = { @@ -604,6 +680,7 @@ split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = { TRANSACTIONS_WPM_REGISTRATIONS TRANSACTIONS_OLED_REGISTRATIONS TRANSACTIONS_ST7565_REGISTRATIONS + TRANSACTIONS_POINTING_REGISTRATIONS // clang-format on #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_OLED_MASTER(); TRANSACTIONS_ST7565_MASTER(); + TRANSACTIONS_POINTING_MASTER(); return true; } @@ -647,6 +725,7 @@ void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[ TRANSACTIONS_WPM_SLAVE(); TRANSACTIONS_OLED_SLAVE(); TRANSACTIONS_ST7565_SLAVE(); + TRANSACTIONS_POINTING_SLAVE(); } #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) diff --git a/quantum/split_common/transport.h b/quantum/split_common/transport.h index 1d4f6ed0cd..31b804908b 100644 --- a/quantum/split_common/transport.h +++ b/quantum/split_common/transport.h @@ -106,6 +106,15 @@ typedef struct _split_mods_sync_t { } split_mods_sync_t; #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) typedef struct _rpc_sync_info_t { int8_t transaction_id; @@ -173,6 +182,10 @@ typedef struct _split_shared_memory_t { uint8_t current_st7565_state; #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) rpc_sync_info_t rpc_info; uint8_t rpc_m2s_buffer[RPC_M2S_BUFFER_SIZE]; |