aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/features/pointing_device.md32
-rw-r--r--drivers/sensors/adns5050.c6
-rw-r--r--drivers/sensors/adns5050.h2
-rw-r--r--drivers/sensors/adns9800.c11
-rw-r--r--drivers/sensors/adns9800.h2
-rw-r--r--drivers/sensors/analog_joystick.c4
-rw-r--r--drivers/sensors/analog_joystick.h2
-rw-r--r--drivers/sensors/azoteq_iqs5xx.c100
-rw-r--r--drivers/sensors/azoteq_iqs5xx.h2
-rw-r--r--drivers/sensors/cirque_pinnacle.c7
-rw-r--r--drivers/sensors/cirque_pinnacle.h2
-rw-r--r--drivers/sensors/cirque_pinnacle_i2c.c21
-rw-r--r--drivers/sensors/cirque_pinnacle_spi.c41
-rw-r--r--drivers/sensors/paw3204.c16
-rw-r--r--drivers/sensors/paw3204.h2
-rw-r--r--drivers/sensors/pimoroni_trackball.c7
-rw-r--r--drivers/sensors/pimoroni_trackball.h2
-rw-r--r--drivers/sensors/pmw3320.c6
-rw-r--r--drivers/sensors/pmw3320.h2
-rw-r--r--drivers/sensors/pmw3389.c2
-rw-r--r--drivers/sensors/pmw33xx_common.c6
-rw-r--r--drivers/sensors/pmw33xx_common.h2
-rw-r--r--keyboards/splitkb/elora/rev1/myriad.c124
-rw-r--r--quantum/pointing_device/pointing_device.c42
-rw-r--r--quantum/pointing_device/pointing_device.h27
-rw-r--r--tests/pointing/test_pointing.cpp20
-rw-r--r--tests/test_common/pointing_device_driver.c3
27 files changed, 298 insertions, 195 deletions
diff --git a/docs/features/pointing_device.md b/docs/features/pointing_device.md
index a139df9dc4..f25ea1b033 100644
--- a/docs/features/pointing_device.md
+++ b/docs/features/pointing_device.md
@@ -379,7 +379,7 @@ POINTING_DEVICE_DRIVER = custom
Using the custom driver will require implementing the following functions:
```c
-void pointing_device_driver_init(void) {}
+bool pointing_device_driver_init(void) { return true; }
report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) { return mouse_report; }
uint16_t pointing_device_driver_get_cpi(void) { return 0; }
void pointing_device_driver_set_cpi(uint16_t cpi) {}
@@ -467,20 +467,22 @@ If there is a `_RIGHT` configuration option or callback, the [common configurati
## Callbacks and Functions
-| Function | Description |
-| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
-| `pointing_device_init_kb(void)` | Callback to allow for keyboard level initialization. Useful for additional hardware sensors. |
-| `pointing_device_init_user(void)` | Callback to allow for user level initialization. Useful for additional hardware sensors. |
-| `pointing_device_task_kb(mouse_report)` | Callback that sends sensor data, so keyboard code can intercept and modify the data. Returns a mouse report. |
-| `pointing_device_task_user(mouse_report)` | Callback that sends sensor data, so user code can intercept and modify the data. Returns a mouse report. |
-| `pointing_device_handle_buttons(buttons, pressed, button)` | Callback to handle hardware button presses. Returns a `uint8_t`. |
-| `pointing_device_get_cpi(void)` | Gets the current CPI/DPI setting from the sensor, if supported. |
-| `pointing_device_set_cpi(uint16_t)` | Sets the CPI/DPI, if supported. |
-| `pointing_device_get_report(void)` | Returns the current mouse report (as a `report_mouse_t` data structure). |
-| `pointing_device_set_report(mouse_report)` | Sets the mouse report to the assigned `report_mouse_t` data structured passed to the function. |
-| `pointing_device_send(void)` | Sends the current mouse report to the host system. Function can be replaced. |
-| `has_mouse_report_changed(new_report, old_report)` | Compares the old and new `report_mouse_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. |
+| Function | Description |
+| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
+| `pointing_device_init_kb(void)` | Callback to allow for keyboard level initialization. Useful for additional hardware sensors. |
+| `pointing_device_init_user(void)` | Callback to allow for user level initialization. Useful for additional hardware sensors. |
+| `pointing_device_task_kb(mouse_report)` | Callback that sends sensor data, so keyboard code can intercept and modify the data. Returns a mouse report. |
+| `pointing_device_task_user(mouse_report)` | Callback that sends sensor data, so user code can intercept and modify the data. Returns a mouse report. |
+| `pointing_device_handle_buttons(buttons, pressed, button)` | Callback to handle hardware button presses. Returns a `uint8_t`. |
+| `pointing_device_get_cpi(void)` | Gets the current CPI/DPI setting from the sensor, if supported. |
+| `pointing_device_set_cpi(uint16_t)` | Sets the CPI/DPI, if supported. |
+| `pointing_device_get_report(void)` | Returns the current mouse report (as a `report_mouse_t` data structure). |
+| `pointing_device_set_report(mouse_report)` | Sets the mouse report to the assigned `report_mouse_t` data structured passed to the function. |
+| `pointing_device_send(void)` | Sends the current mouse report to the host system. Function can be replaced. |
+| `has_mouse_report_changed(new_report, old_report)` | Compares the old and new `report_mouse_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. |
+| `pointing_device_get_status(void)` | Returns device status as `pointing_device_status_t` a good return is `POINTING_DEVICE_STATUS_SUCCESS`. |
+| `pointing_device_set_status(pointing_device_status_t status)` | Sets device status, anything other than `POINTING_DEVICE_STATUS_SUCCESS` will disable reports from the device.|
## Split Keyboard Callbacks and Functions
diff --git a/drivers/sensors/adns5050.c b/drivers/sensors/adns5050.c
index 1768c9f3b4..ac4c95b0c2 100644
--- a/drivers/sensors/adns5050.c
+++ b/drivers/sensors/adns5050.c
@@ -55,7 +55,7 @@ const pointing_device_driver_t adns5050_pointing_device_driver = {
static bool powered_down = false;
-void adns5050_init(void) {
+bool adns5050_init(void) {
// Initialize the ADNS serial pins.
gpio_set_pin_output(ADNS5050_SCLK_PIN);
gpio_set_pin_output(ADNS5050_SDIO_PIN);
@@ -75,6 +75,8 @@ void adns5050_init(void) {
// gets the adns ready for write commands
// (for example, setting the dpi).
adns5050_read_burst();
+
+ return adns5050_check_signature();
}
// Perform a synchronization with the ADNS.
@@ -220,7 +222,7 @@ uint16_t adns5050_get_cpi(void) {
return (uint16_t)((cpival & 0b10000) * 125);
}
-bool adns5050_check_signature(void) {
+bool __attribute__((weak)) adns5050_check_signature(void) {
uint8_t pid = adns5050_read_reg(REG_PRODUCT_ID);
uint8_t rid = adns5050_read_reg(REG_REVISION_ID);
uint8_t pid2 = adns5050_read_reg(REG_PRODUCT_ID2);
diff --git a/drivers/sensors/adns5050.h b/drivers/sensors/adns5050.h
index 4dfcbc3c70..004c54f560 100644
--- a/drivers/sensors/adns5050.h
+++ b/drivers/sensors/adns5050.h
@@ -75,7 +75,7 @@ const pointing_device_driver_t adns5050_pointing_device_driver;
// A bunch of functions to implement the ADNS5050-specific serial protocol.
// Note that the "serial.h" driver is insufficient, because it does not
// manually manipulate a serial clock signal.
-void adns5050_init(void);
+bool adns5050_init(void);
void adns5050_sync(void);
uint8_t adns5050_serial_read(void);
void adns5050_serial_write(uint8_t data);
diff --git a/drivers/sensors/adns9800.c b/drivers/sensors/adns9800.c
index 0dbc528351..f5958dd350 100644
--- a/drivers/sensors/adns9800.c
+++ b/drivers/sensors/adns9800.c
@@ -115,7 +115,14 @@ uint8_t adns9800_read(uint8_t reg_addr) {
return data;
}
-void adns9800_init(void) {
+bool __attribute__((weak)) adns9800_check_signature(void) {
+ if (adns9800_read(REG_Product_ID) != 0x33) {
+ return false;
+ }
+ return true;
+}
+
+bool adns9800_init(void) {
gpio_set_pin_output(ADNS9800_CS_PIN);
spi_init();
@@ -178,6 +185,8 @@ void adns9800_init(void) {
adns9800_write(REG_LASER_CTRL0, laser_ctrl0 & 0xf0);
adns9800_set_cpi(ADNS9800_CPI);
+
+ return adns9800_check_signature();
}
config_adns9800_t adns9800_get_config(void) {
diff --git a/drivers/sensors/adns9800.h b/drivers/sensors/adns9800.h
index 023f31b132..797aaf3cd0 100644
--- a/drivers/sensors/adns9800.h
+++ b/drivers/sensors/adns9800.h
@@ -63,7 +63,7 @@ typedef struct {
const pointing_device_driver_t adns9800_pointing_device_driver;
-void adns9800_init(void);
+bool adns9800_init(void);
config_adns9800_t adns9800_get_config(void);
void adns9800_set_config(config_adns9800_t);
uint16_t adns9800_get_cpi(void);
diff --git a/drivers/sensors/analog_joystick.c b/drivers/sensors/analog_joystick.c
index 93bbaa1b51..eec97e8eed 100644
--- a/drivers/sensors/analog_joystick.c
+++ b/drivers/sensors/analog_joystick.c
@@ -135,7 +135,7 @@ report_analog_joystick_t analog_joystick_read(void) {
return report;
}
-void analog_joystick_init(void) {
+bool analog_joystick_init(void) {
gpio_set_pin_input_high(ANALOG_JOYSTICK_X_AXIS_PIN);
gpio_set_pin_input_high(ANALOG_JOYSTICK_Y_AXIS_PIN);
@@ -152,6 +152,8 @@ void analog_joystick_init(void) {
maxAxisValues[0] = xOrigin + 100;
maxAxisValues[1] = yOrigin + 100;
#endif
+
+ return true;
}
report_mouse_t analog_joystick_get_report(report_mouse_t mouse_report) {
diff --git a/drivers/sensors/analog_joystick.h b/drivers/sensors/analog_joystick.h
index c84da83db1..4838f502f1 100644
--- a/drivers/sensors/analog_joystick.h
+++ b/drivers/sensors/analog_joystick.h
@@ -51,5 +51,5 @@ typedef struct {
bool button;
} report_analog_joystick_t;
report_analog_joystick_t analog_joystick_read(void);
-void analog_joystick_init(void);
+bool analog_joystick_init(void);
report_mouse_t analog_joystick_get_report(report_mouse_t mouse_report);
diff --git a/drivers/sensors/azoteq_iqs5xx.c b/drivers/sensors/azoteq_iqs5xx.c
index ae26ee60cf..7586ac52d1 100644
--- a/drivers/sensors/azoteq_iqs5xx.c
+++ b/drivers/sensors/azoteq_iqs5xx.c
@@ -321,7 +321,7 @@ void azoteq_iqs5xx_setup_resolution(void) {
static i2c_status_t azoteq_iqs5xx_init_status = 1;
-void azoteq_iqs5xx_init(void) {
+bool azoteq_iqs5xx_init(void) {
i2c_init();
i2c_ping_address(AZOTEQ_IQS5XX_ADDRESS, 1); // wake
azoteq_iqs5xx_reset_suspend(true, false, true);
@@ -349,67 +349,65 @@ void azoteq_iqs5xx_init(void) {
azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_gesture_config(true);
wait_ms(AZOTEQ_IQS5XX_REPORT_RATE + 1);
}
+
+ return azoteq_iqs5xx_init_status == I2C_STATUS_SUCCESS;
};
report_mouse_t azoteq_iqs5xx_get_report(report_mouse_t mouse_report) {
report_mouse_t temp_report = {0};
- if (azoteq_iqs5xx_init_status == I2C_STATUS_SUCCESS) {
- azoteq_iqs5xx_base_data_t base_data = {0};
- i2c_status_t status = azoteq_iqs5xx_get_base_data(&base_data);
- bool ignore_movement = false;
+ azoteq_iqs5xx_base_data_t base_data = {0};
+ i2c_status_t status = azoteq_iqs5xx_get_base_data(&base_data);
+ bool ignore_movement = false;
- if (status == I2C_STATUS_SUCCESS) {
+ if (status == I2C_STATUS_SUCCESS) {
#ifdef POINTING_DEVICE_DEBUG
- if (base_data.previous_cycle_time > AZOTEQ_IQS5XX_REPORT_RATE) {
- pd_dprintf("IQS5XX - previous cycle time missed, took: %dms\n", base_data.previous_cycle_time);
- }
+ if (base_data.previous_cycle_time > AZOTEQ_IQS5XX_REPORT_RATE) {
+ pd_dprintf("IQS5XX - previous cycle time missed, took: %dms\n", base_data.previous_cycle_time);
+ }
#endif
- if (base_data.gesture_events_0.single_tap || base_data.gesture_events_0.press_and_hold) {
- pd_dprintf("IQS5XX - Single tap/hold.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON1);
- } else if (base_data.gesture_events_1.two_finger_tap) {
- pd_dprintf("IQS5XX - Two finger tap.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON2);
- } else if (base_data.gesture_events_0.swipe_x_neg) {
- pd_dprintf("IQS5XX - X-.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON4);
- ignore_movement = true;
- } else if (base_data.gesture_events_0.swipe_x_pos) {
- pd_dprintf("IQS5XX - X+.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON5);
- ignore_movement = true;
- } else if (base_data.gesture_events_0.swipe_y_neg) {
- pd_dprintf("IQS5XX - Y-.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON6);
- ignore_movement = true;
- } else if (base_data.gesture_events_0.swipe_y_pos) {
- pd_dprintf("IQS5XX - Y+.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON3);
- ignore_movement = true;
- } else if (base_data.gesture_events_1.zoom) {
- if (AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l) < 0) {
- pd_dprintf("IQS5XX - Zoom out.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON7);
- } else if (AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l) > 0) {
- pd_dprintf("IQS5XX - Zoom in.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON8);
- }
- } else if (base_data.gesture_events_1.scroll) {
- pd_dprintf("IQS5XX - Scroll.\n");
- temp_report.h = CONSTRAIN_HID(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l));
- temp_report.v = CONSTRAIN_HID(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.y.h, base_data.y.l));
+ if (base_data.gesture_events_0.single_tap || base_data.gesture_events_0.press_and_hold) {
+ pd_dprintf("IQS5XX - Single tap/hold.\n");
+ temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON1);
+ } else if (base_data.gesture_events_1.two_finger_tap) {
+ pd_dprintf("IQS5XX - Two finger tap.\n");
+ temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON2);
+ } else if (base_data.gesture_events_0.swipe_x_neg) {
+ pd_dprintf("IQS5XX - X-.\n");
+ temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON4);
+ ignore_movement = true;
+ } else if (base_data.gesture_events_0.swipe_x_pos) {
+ pd_dprintf("IQS5XX - X+.\n");
+ temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON5);
+ ignore_movement = true;
+ } else if (base_data.gesture_events_0.swipe_y_neg) {
+ pd_dprintf("IQS5XX - Y-.\n");
+ temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON6);
+ ignore_movement = true;
+ } else if (base_data.gesture_events_0.swipe_y_pos) {
+ pd_dprintf("IQS5XX - Y+.\n");
+ temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON3);
+ ignore_movement = true;
+ } else if (base_data.gesture_events_1.zoom) {
+ if (AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l) < 0) {
+ pd_dprintf("IQS5XX - Zoom out.\n");
+ temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON7);
+ } else if (AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l) > 0) {
+ pd_dprintf("IQS5XX - Zoom in.\n");
+ temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON8);
}
- if (base_data.number_of_fingers == 1 && !ignore_movement) {
- temp_report.x = CONSTRAIN_HID_XY(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l));
- temp_report.y = CONSTRAIN_HID_XY(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.y.h, base_data.y.l));
- }
-
- } else {
- pd_dprintf("IQS5XX - get report failed, i2c status: %d \n", status);
+ } else if (base_data.gesture_events_1.scroll) {
+ pd_dprintf("IQS5XX - Scroll.\n");
+ temp_report.h = CONSTRAIN_HID(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l));
+ temp_report.v = CONSTRAIN_HID(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.y.h, base_data.y.l));
}
+ if (base_data.number_of_fingers == 1 && !ignore_movement) {
+ temp_report.x = CONSTRAIN_HID_XY(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l));
+ temp_report.y = CONSTRAIN_HID_XY(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.y.h, base_data.y.l));
+ }
+
} else {
- pd_dprintf("IQS5XX - Init failed, i2c status: %d \n", azoteq_iqs5xx_init_status);
+ pd_dprintf("IQS5XX - get report failed, i2c status: %d \n", status);
}
return temp_report;
diff --git a/drivers/sensors/azoteq_iqs5xx.h b/drivers/sensors/azoteq_iqs5xx.h
index eb01903e33..1a70ac6149 100644
--- a/drivers/sensors/azoteq_iqs5xx.h
+++ b/drivers/sensors/azoteq_iqs5xx.h
@@ -180,7 +180,7 @@ typedef struct {
const pointing_device_driver_t azoteq_iqs5xx_pointing_device_driver;
-void azoteq_iqs5xx_init(void);
+bool azoteq_iqs5xx_init(void);
i2c_status_t azoteq_iqs5xx_wake(void);
report_mouse_t azoteq_iqs5xx_get_report(report_mouse_t mouse_report);
i2c_status_t azoteq_iqs5xx_get_report_rate(azoteq_iqs5xx_report_rate_t *report_rate, azoteq_iqs5xx_charging_modes_t mode, bool end_session);
diff --git a/drivers/sensors/cirque_pinnacle.c b/drivers/sensors/cirque_pinnacle.c
index 893cb98bf0..45072ae874 100644
--- a/drivers/sensors/cirque_pinnacle.c
+++ b/drivers/sensors/cirque_pinnacle.c
@@ -18,7 +18,6 @@
# endif
#endif
-bool touchpad_init;
uint16_t scale_data = CIRQUE_PINNACLE_DEFAULT_SCALE;
void cirque_pinnacle_clear_flags(void);
@@ -232,14 +231,14 @@ bool cirque_pinnacle_connected(void) {
}
/* Pinnacle-based TM040040/TM035035/TM023023 Functions */
-void cirque_pinnacle_init(void) {
+bool cirque_pinnacle_init(void) {
#if defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi)
spi_init();
#elif defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_i2c)
i2c_init();
#endif
- touchpad_init = true;
+ bool touchpad_init = true;
// send a RESET command now, in case QMK had a soft-reset without a power cycle
RAP_Write(HOSTREG__SYSCONFIG1, HOSTREG__SYSCONFIG1__RESET);
@@ -293,6 +292,8 @@ void cirque_pinnacle_init(void) {
#ifndef CIRQUE_PINNACLE_SKIP_SENSOR_CHECK
touchpad_init = cirque_pinnacle_connected();
#endif
+
+ return touchpad_init;
}
pinnacle_data_t cirque_pinnacle_read_data(void) {
diff --git a/drivers/sensors/cirque_pinnacle.h b/drivers/sensors/cirque_pinnacle.h
index 1a17e539a4..3541d62463 100644
--- a/drivers/sensors/cirque_pinnacle.h
+++ b/drivers/sensors/cirque_pinnacle.h
@@ -114,7 +114,7 @@ typedef struct {
#define cirque_pinnacle_spi_pointing_device_driver cirque_pinnacle_pointing_device_driver
const pointing_device_driver_t cirque_pinnacle_pointing_device_driver;
-void cirque_pinnacle_init(void);
+bool cirque_pinnacle_init(void);
void cirque_pinnacle_calibrate(void);
void cirque_pinnacle_cursor_smoothing(bool enable);
pinnacle_data_t cirque_pinnacle_read_data(void);
diff --git a/drivers/sensors/cirque_pinnacle_i2c.c b/drivers/sensors/cirque_pinnacle_i2c.c
index a3622e9d60..8d766c69d9 100644
--- a/drivers/sensors/cirque_pinnacle_i2c.c
+++ b/drivers/sensors/cirque_pinnacle_i2c.c
@@ -7,29 +7,22 @@
#define WRITE_MASK 0x80
#define READ_MASK 0xA0
-extern bool touchpad_init;
-
/* RAP Functions */
// Reads <count> Pinnacle registers starting at <address>
void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count) {
uint8_t cmdByte = READ_MASK | address; // Form the READ command byte
- if (touchpad_init) {
- i2c_write_register(CIRQUE_PINNACLE_ADDR << 1, cmdByte, NULL, 0, CIRQUE_PINNACLE_TIMEOUT);
- if (i2c_read_register(CIRQUE_PINNACLE_ADDR << 1, cmdByte, data, count, CIRQUE_PINNACLE_TIMEOUT) != I2C_STATUS_SUCCESS) {
- pd_dprintf("error cirque_pinnacle i2c_read_register\n");
- touchpad_init = false;
- }
+ i2c_write_register(CIRQUE_PINNACLE_ADDR << 1, cmdByte, NULL, 0, CIRQUE_PINNACLE_TIMEOUT);
+ if (i2c_read_register(CIRQUE_PINNACLE_ADDR << 1, cmdByte, data, count, CIRQUE_PINNACLE_TIMEOUT) != I2C_STATUS_SUCCESS) {
+ pd_dprintf("error cirque_pinnacle i2c_read_register\n");
+ pointing_device_set_status(POINTING_DEVICE_STATUS_FAILED);
}
}
// Writes single-byte <data> to <address>
void RAP_Write(uint8_t address, uint8_t data) {
uint8_t cmdByte = WRITE_MASK | address; // Form the WRITE command byte
-
- if (touchpad_init) {
- if (i2c_write_register(CIRQUE_PINNACLE_ADDR << 1, cmdByte, &data, sizeof(data), CIRQUE_PINNACLE_TIMEOUT) != I2C_STATUS_SUCCESS) {
- pd_dprintf("error cirque_pinnacle i2c_write_register\n");
- touchpad_init = false;
- }
+ if (i2c_write_register(CIRQUE_PINNACLE_ADDR << 1, cmdByte, &data, sizeof(data), CIRQUE_PINNACLE_TIMEOUT) != I2C_STATUS_SUCCESS) {
+ pd_dprintf("error cirque_pinnacle i2c_write_register\n");
+ pointing_device_set_status(POINTING_DEVICE_STATUS_FAILED);
}
}
diff --git a/drivers/sensors/cirque_pinnacle_spi.c b/drivers/sensors/cirque_pinnacle_spi.c
index 5cb39aebb0..eefdb4d0a7 100644
--- a/drivers/sensors/cirque_pinnacle_spi.c
+++ b/drivers/sensors/cirque_pinnacle_spi.c
@@ -7,40 +7,35 @@
#define READ_MASK 0xA0
#define FILLER_BYTE 0xFC
-extern bool touchpad_init;
-
/* RAP Functions */
// Reads <count> Pinnacle registers starting at <address>
void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count) {
uint8_t cmdByte = READ_MASK | address; // Form the READ command byte
- if (touchpad_init) {
- if (spi_start(CIRQUE_PINNACLE_SPI_CS_PIN, CIRQUE_PINNACLE_SPI_LSBFIRST, CIRQUE_PINNACLE_SPI_MODE, CIRQUE_PINNACLE_SPI_DIVISOR)) {
- spi_write(cmdByte); // write command byte, receive filler
- spi_write(FILLER_BYTE); // write & receive filler
- spi_write(FILLER_BYTE); // write & receive filler
- for (uint8_t i = 0; i < count; i++) {
- data[i] = spi_write(FILLER_BYTE); // write filler, receive data on the third filler send
- }
- } else {
- pd_dprintf("error cirque_pinnacle spi_start read\n");
- touchpad_init = false;
+
+ if (spi_start(CIRQUE_PINNACLE_SPI_CS_PIN, CIRQUE_PINNACLE_SPI_LSBFIRST, CIRQUE_PINNACLE_SPI_MODE, CIRQUE_PINNACLE_SPI_DIVISOR)) {
+ spi_write(cmdByte); // write command byte, receive filler
+ spi_write(FILLER_BYTE); // write & receive filler
+ spi_write(FILLER_BYTE); // write & receive filler
+ for (uint8_t i = 0; i < count; i++) {
+ data[i] = spi_write(FILLER_BYTE); // write filler, receive data on the third filler send
}
- spi_stop();
+ } else {
+ pd_dprintf("error cirque_pinnacle spi_start read\n");
+ pointing_device_set_status(POINTING_DEVICE_STATUS_FAILED);
}
+ spi_stop();
}
// Writes single-byte <data> to <address>
void RAP_Write(uint8_t address, uint8_t data) {
uint8_t cmdByte = WRITE_MASK | address; // Form the WRITE command byte
- if (touchpad_init) {
- if (spi_start(CIRQUE_PINNACLE_SPI_CS_PIN, CIRQUE_PINNACLE_SPI_LSBFIRST, CIRQUE_PINNACLE_SPI_MODE, CIRQUE_PINNACLE_SPI_DIVISOR)) {
- spi_write(cmdByte);
- spi_write(data);
- } else {
- pd_dprintf("error cirque_pinnacle spi_start write\n");
- touchpad_init = false;
- }
- spi_stop();
+ if (spi_start(CIRQUE_PINNACLE_SPI_CS_PIN, CIRQUE_PINNACLE_SPI_LSBFIRST, CIRQUE_PINNACLE_SPI_MODE, CIRQUE_PINNACLE_SPI_DIVISOR)) {
+ spi_write(cmdByte);
+ spi_write(data);
+ } else {
+ pd_dprintf("error cirque_pinnacle spi_start write\n");
+ pointing_device_set_status(POINTING_DEVICE_STATUS_FAILED);
}
+ spi_stop();
}
diff --git a/drivers/sensors/paw3204.c b/drivers/sensors/paw3204.c
index 475821f175..228b7fa986 100644
--- a/drivers/sensors/paw3204.c
+++ b/drivers/sensors/paw3204.c
@@ -58,7 +58,15 @@ const pointing_device_driver_t paw3204_pointing_device_driver = {
.get_cpi = paw3204_get_cpi,
};
-void paw3204_init(void) {
+uint8_t read_pid_paw3204(void) {
+ return paw3204_read_reg(REG_PID1);
+}
+
+bool __attribute__((weak)) paw3204_check_signature(void) {
+ return (read_pid_paw3204() == 0x30);
+}
+
+bool paw3204_init(void) {
gpio_set_pin_output(PAW3204_SCLK_PIN); // setclockpin to output
gpio_set_pin_input_high(PAW3204_SDIO_PIN); // set datapin input high
@@ -69,6 +77,8 @@ void paw3204_init(void) {
paw3204_read_reg(0x01); // read id2
// PAW3204_write_reg(REG_SETUP,0x06); // dont reset sensor and set cpi 1600
paw3204_write_reg(REG_IMGTRASH, 0x32); // write image trashhold
+
+ return paw3204_check_signature();
}
uint8_t paw3204_serial_read(void) {
@@ -175,10 +185,6 @@ uint16_t paw3204_get_cpi(void) {
return cpival;
}
-uint8_t read_pid_paw3204(void) {
- return paw3204_read_reg(REG_PID1);
-}
-
report_mouse_t paw3204_get_report(report_mouse_t mouse_report) {
report_paw3204_t data = paw3204_read();
if (data.isMotion) {
diff --git a/drivers/sensors/paw3204.h b/drivers/sensors/paw3204.h
index a4bb8e16a6..11759d64c3 100644
--- a/drivers/sensors/paw3204.h
+++ b/drivers/sensors/paw3204.h
@@ -50,7 +50,7 @@ const pointing_device_driver_t paw3204_pointing_device_driver;
* @return true Initialization was a success
* @return false Initialization failed, do not proceed operation
*/
-void paw3204_init(void);
+bool paw3204_init(void);
/**
* @brief Reads and clears the current delta, and motion register values on the
diff --git a/drivers/sensors/pimoroni_trackball.c b/drivers/sensors/pimoroni_trackball.c
index 06e5042953..daa5786554 100644
--- a/drivers/sensors/pimoroni_trackball.c
+++ b/drivers/sensors/pimoroni_trackball.c
@@ -82,9 +82,12 @@ i2c_status_t read_pimoroni_trackball(pimoroni_data_t *data) {
return status;
}
-__attribute__((weak)) void pimoroni_trackball_device_init(void) {
+__attribute__((weak)) bool pimoroni_trackball_device_init(void) {
i2c_init();
- pimoroni_trackball_set_rgbw(0x00, 0x00, 0x00, 0x00);
+ uint8_t rgbw_data[4] = {0};
+ i2c_status_t status = i2c_write_register(PIMORONI_TRACKBALL_ADDRESS << 1, PIMORONI_TRACKBALL_REG_LED_RED, rgbw_data, sizeof(rgbw_data), PIMORONI_TRACKBALL_TIMEOUT);
+
+ return (status == I2C_STATUS_SUCCESS);
}
int16_t pimoroni_trackball_get_offsets(uint8_t negative_dir, uint8_t positive_dir, uint8_t scale) {
diff --git a/drivers/sensors/pimoroni_trackball.h b/drivers/sensors/pimoroni_trackball.h
index 1904214a74..4b8a2548ae 100644
--- a/drivers/sensors/pimoroni_trackball.h
+++ b/drivers/sensors/pimoroni_trackball.h
@@ -52,7 +52,7 @@ typedef struct {
const pointing_device_driver_t pimoroni_trackball_pointing_device_driver;
-void pimoroni_trackball_device_init(void);
+bool pimoroni_trackball_device_init(void);
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);
uint16_t pimoroni_trackball_get_cpi(void);
diff --git a/drivers/sensors/pmw3320.c b/drivers/sensors/pmw3320.c
index 74fefd4c53..db74540ec1 100644
--- a/drivers/sensors/pmw3320.c
+++ b/drivers/sensors/pmw3320.c
@@ -30,7 +30,7 @@ const pointing_device_driver_t pmw3320_pointing_device_drivera = {
.get_cpi = pmw3320_get_cpi,
};
-void pmw3320_init(void) {
+bool pmw3320_init(void) {
// Initialize sensor serial pins.
gpio_set_pin_output(PMW3320_SCLK_PIN);
gpio_set_pin_output(PMW3320_SDIO_PIN);
@@ -56,6 +56,8 @@ void pmw3320_init(void) {
pmw3320_write_reg(REG_Led_Control, 0x4);
// Disable rest mode
pmw3320_write_reg(REG_Performance, 0x80);
+
+ return pmw3320_check_signature();
}
// Perform a synchronization with sensor.
@@ -192,7 +194,7 @@ void pmw3320_set_cpi(uint16_t cpi) {
pmw3320_write_reg(REG_Resolution, 0x20 | cpival);
}
-bool pmw3320_check_signature(void) {
+bool __attribute__((weak)) pmw3320_check_signature(void) {
uint8_t pid = pmw3320_read_reg(REG_Product_ID);
uint8_t pid2 = pmw3320_read_reg(REG_Inverse_Product_ID);
diff --git a/drivers/sensors/pmw3320.h b/drivers/sensors/pmw3320.h
index cfff25bd8a..42fd72a52c 100644
--- a/drivers/sensors/pmw3320.h
+++ b/drivers/sensors/pmw3320.h
@@ -61,7 +61,7 @@ const pointing_device_driver_t pmw3320_pointing_device_driver;
// Mostly taken from ADNS5050 driver.
// Note that the "serial.h" driver is insufficient, because it does not
// manually manipulate a serial clock signal.
-void pmw3320_init(void);
+bool pmw3320_init(void);
void pmw3320_sync(void);
uint8_t pmw3320_serial_read(void);
void pmw3320_serial_write(uint8_t data);
diff --git a/drivers/sensors/pmw3389.c b/drivers/sensors/pmw3389.c
index 85d2c8a429..efa90c2100 100644
--- a/drivers/sensors/pmw3389.c
+++ b/drivers/sensors/pmw3389.c
@@ -29,4 +29,4 @@ void pmw33xx_set_cpi(uint8_t sensor, uint16_t cpi) {
}
// PID, Inverse PID
-const uint8_t pmw33xx_firmware_signature[2] PROGMEM = {0x42, 0xBD};
+const uint8_t pmw33xx_firmware_signature[2] PROGMEM = {0x47, 0xB8};
diff --git a/drivers/sensors/pmw33xx_common.c b/drivers/sensors/pmw33xx_common.c
index f3285ec497..61e309ea27 100644
--- a/drivers/sensors/pmw33xx_common.c
+++ b/drivers/sensors/pmw33xx_common.c
@@ -102,7 +102,7 @@ uint8_t pmw33xx_read(uint8_t sensor, uint8_t reg_addr) {
return data;
}
-bool pmw33xx_check_signature(uint8_t sensor) {
+__attribute__((weak)) bool pmw33xx_check_signature(uint8_t sensor) {
uint8_t signature_dump[2] = {
pmw33xx_read(sensor, REG_Product_ID),
pmw33xx_read(sensor, REG_Inverse_Product_ID),
@@ -236,8 +236,8 @@ pmw33xx_report_t pmw33xx_read_burst(uint8_t sensor) {
return report;
}
-void pmw33xx_init_wrapper(void) {
- pmw33xx_init(0);
+bool pmw33xx_init_wrapper(void) {
+ return pmw33xx_init(0);
}
void pmw33xx_set_cpi_wrapper(uint16_t cpi) {
diff --git a/drivers/sensors/pmw33xx_common.h b/drivers/sensors/pmw33xx_common.h
index 82303ba6d9..8fb10b1b2f 100644
--- a/drivers/sensors/pmw33xx_common.h
+++ b/drivers/sensors/pmw33xx_common.h
@@ -177,7 +177,7 @@ uint8_t pmw33xx_read(uint8_t sensor, uint8_t reg_addr);
*/
bool pmw33xx_write(uint8_t sensor, uint8_t reg_addr, uint8_t data);
-void pmw33xx_init_wrapper(void);
+bool pmw33xx_init_wrapper(void);
void pmw33xx_set_cpi_wrapper(uint16_t cpi);
uint16_t pmw33xx_get_cpi_wrapper(void);
report_mouse_t pmw33xx_get_report(report_mouse_t mouse_report);
diff --git a/keyboards/splitkb/elora/rev1/myriad.c b/keyboards/splitkb/elora/rev1/myriad.c
index 8bb6054df9..0263821b81 100644
--- a/keyboards/splitkb/elora/rev1/myriad.c
+++ b/keyboards/splitkb/elora/rev1/myriad.c
@@ -9,10 +9,10 @@
#include "analog.h"
typedef struct __attribute__((__packed__)) {
- char magic_numbers[3];
- uint8_t version_major;
- uint8_t version_minor;
- uint8_t version_patch;
+ char magic_numbers[3];
+ uint8_t version_major;
+ uint8_t version_minor;
+ uint8_t version_patch;
uint32_t checksum;
uint16_t payload_length;
} myriad_header_t;
@@ -20,34 +20,36 @@ typedef struct __attribute__((__packed__)) {
typedef struct __attribute__((__packed__)) {
uint16_t vendor_id;
uint16_t product_id;
- uint8_t revision;
+ uint8_t revision;
} identity_record_t;
static bool myriad_reader(uint8_t *data, uint16_t length) {
- const uint8_t eeprom_address = 0x50; // 1010 000 - NOT shifted for R/W bit
- const uint16_t i2c_timeout = 100; // in milliseconds
+ const uint8_t eeprom_address = 0x50; // 1010 000 - NOT shifted for R/W bit
+ const uint16_t i2c_timeout = 100; // in milliseconds
- uint8_t num_pages = (length / 256) + 1;
+ uint8_t num_pages = (length / 256) + 1;
uint8_t last_page_size = length % 256;
for (int i = 0; i < num_pages; i++) {
- uint8_t reg = 0; // We always start on a page boundary, so this is always zero
+ uint8_t reg = 0; // We always start on a page boundary, so this is always zero
uint16_t read_length;
if (i == num_pages - 1) {
read_length = last_page_size;
} else {
read_length = 256;
}
- i2c_status_t s = i2c_read_register((eeprom_address + i) << 1, reg, &(data[i*256]), read_length, i2c_timeout);
- if (s != I2C_STATUS_SUCCESS) { return false; }
+ i2c_status_t s = i2c_read_register((eeprom_address + i) << 1, reg, &(data[i * 256]), read_length, i2c_timeout);
+ if (s != I2C_STATUS_SUCCESS) {
+ return false;
+ }
}
return true;
}
static bool verify_header(myriad_header_t *header) {
- char magic_numbers[] = {'M', 'Y', 'R'};
- uint8_t version_major = 1;
- uint16_t version_minor = 0;
+ char magic_numbers[] = {'M', 'Y', 'R'};
+ uint8_t version_major = 1;
+ uint16_t version_minor = 0;
for (int i = 0; i < sizeof(magic_numbers); i++) {
// Check that the header starts with 'MYR', indicating that this is indeed a Myriad card.
@@ -82,16 +84,15 @@ static bool verify_checksum(uint8_t *data, uint16_t length, uint32_t checksum) {
const uint32_t MOD_ADLER = 65521;
uint32_t a = 1, b = 0;
- size_t index;
-
+ size_t index;
+
// Process each byte of the data in order
- for (index = 0; index < length; ++index)
- {
+ for (index = 0; index < length; ++index) {
a = (a + data[index]) % MOD_ADLER;
b = (b + a) % MOD_ADLER;
}
uint32_t calculated = ((b << 16) | a);
-
+
return calculated == checksum;
}
@@ -108,9 +109,9 @@ static int16_t locate_entry(uint8_t entry_type, uint8_t entry_data_length, uint8
while (offset < maximum) {
if (data[offset] == entry_type) {
// Type matches!
- if (data[offset+1] == entry_data_length) {
+ if (data[offset + 1] == entry_data_length) {
// We found what we are looking for, so return payload reference.
- return offset+2;
+ return offset + 2;
} else {
// The entry is the wrong length?
return -2;
@@ -118,7 +119,7 @@ static int16_t locate_entry(uint8_t entry_type, uint8_t entry_data_length, uint8
} else {
// No type match, so skip this one
// We skip the type byte, the length byte, and any potential data (with length stored in the length byte)
- offset += 2 + data[offset+1];
+ offset += 2 + data[offset + 1];
}
}
@@ -127,13 +128,15 @@ static int16_t locate_entry(uint8_t entry_type, uint8_t entry_data_length, uint8
}
static bool read_card_identity(uint8_t *data, uint16_t length, identity_record_t *record) {
- const uint8_t identity_type = 0x01;
+ const uint8_t identity_type = 0x01;
const uint8_t entry_data_length = sizeof(identity_record_t);
- int16_t result = locate_entry(identity_type, entry_data_length, data, 0, length);
- if (result < 0) { return false; }
+ int16_t result = locate_entry(identity_type, entry_data_length, data, 0, length);
+ if (result < 0) {
+ return false;
+ }
for (int i = 0; i < sizeof(identity_record_t); i++) {
- ((uint8_t*)record)[i] = data[result + i];
+ ((uint8_t *)record)[i] = data[result + i];
}
return true;
}
@@ -141,27 +144,37 @@ static bool read_card_identity(uint8_t *data, uint16_t length, identity_record_t
static myriad_card_t _detect_myriad(void) {
gpio_set_pin_input(MYRIAD_PRESENT);
wait_ms(100);
- // The pin has an external pull-up, and a Myriad card shorts it to ground.
- #ifndef MYRIAD_OVERRIDE_PRESENCE
+// The pin has an external pull-up, and a Myriad card shorts it to ground.
+#ifndef MYRIAD_OVERRIDE_PRESENCE
if (gpio_read_pin(MYRIAD_PRESENT)) {
return NONE;
}
- #endif
+#endif
// Attempt to read header
myriad_header_t header;
- if (!myriad_reader((uint8_t*)&header, sizeof(header))) { return INVALID; }
- if (!verify_header(&header)) { return INVALID; }
+ if (!myriad_reader((uint8_t *)&header, sizeof(header))) {
+ return INVALID;
+ }
+ if (!verify_header(&header)) {
+ return INVALID;
+ }
// Now that we have determined that the header is valid
// and we know the payload length, read the entire thing
- uint8_t data[2048]; // Guaranteed to be large enough.
- uint16_t data_size = sizeof(header)+header.payload_length;
- if (!myriad_reader(data, data_size)) { return INVALID; }
- if (!verify_checksum(data, data_size, header.checksum)) { return INVALID; }
+ uint8_t data[2048]; // Guaranteed to be large enough.
+ uint16_t data_size = sizeof(header) + header.payload_length;
+ if (!myriad_reader(data, data_size)) {
+ return INVALID;
+ }
+ if (!verify_checksum(data, data_size, header.checksum)) {
+ return INVALID;
+ }
identity_record_t identity;
- if (!read_card_identity(data, data_size, &identity)) { return INVALID; }
+ if (!read_card_identity(data, data_size, &identity)) {
+ return INVALID;
+ }
if (identity.vendor_id == 0x0001 && identity.product_id == 0x0001) {
return SKB_ENCODER;
@@ -201,7 +214,7 @@ static void myr_encoder_init(void) {
}
static uint16_t myr_joystick_timer;
-static void myr_joystick_init(void) {
+static void myr_joystick_init(void) {
gpio_set_pin_input_high(MYRIAD_GPIO1); // Press
myr_joystick_timer = timer_read();
@@ -235,7 +248,7 @@ static myriad_card_t myriad_card_init(void) {
bool myriad_hook_matrix(matrix_row_t current_matrix[]) {
myriad_card_t card = myriad_card_init();
- uint8_t word = 0;
+ uint8_t word = 0;
if (card == SKB_SWITCHES) {
word |= ((!gpio_read_pin(MYRIAD_GPIO3)) & 1) << 0;
@@ -252,7 +265,7 @@ bool myriad_hook_matrix(matrix_row_t current_matrix[]) {
// 5 bytes of on-board keys, so we are the 6th
bool matrix_has_changed = current_matrix[5] ^ word;
- current_matrix[5] = word;
+ current_matrix[5] = word;
return matrix_has_changed;
}
@@ -261,16 +274,20 @@ static pin_t encoders_pad_a[NUM_ENCODERS_MAX_PER_SIDE];
static pin_t encoders_pad_b[NUM_ENCODERS_MAX_PER_SIDE];
uint8_t myriad_hook_encoder(uint8_t index, bool pad_b) {
- if (myriad_card_init() != SKB_ENCODER) { return 0; }
+ if (myriad_card_init() != SKB_ENCODER) {
+ return 0;
+ }
// 3 onboard encoders, so we are number 4
- pin_t pin = pad_b ? encoders_pad_b[index] : encoders_pad_a[index];
+ pin_t pin = pad_b ? encoders_pad_b[index] : encoders_pad_a[index];
encoders_pad_a[3] = MYRIAD_GPIO2;
encoders_pad_b[3] = MYRIAD_GPIO3;
return gpio_read_pin(pin) ? 1 : 0;
}
report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
- if (myriad_card_init() != SKB_JOYSTICK) { return mouse_report; }
+ if (myriad_card_init() != SKB_JOYSTICK) {
+ return mouse_report;
+ }
if (timer_elapsed(myr_joystick_timer) < 10) {
wait_ms(2);
@@ -286,10 +303,10 @@ report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
// Create a dead zone in the middle where the mouse doesn't move
const int16_t dead_zone = 10;
- if ((y < 0 && y > -1*dead_zone) || (y > 0 && y < dead_zone)) {
+ if ((y < 0 && y > -1 * dead_zone) || (y > 0 && y < dead_zone)) {
y = 0;
}
- if ((x < 0 && x > -1*dead_zone) || (x > 0 && x < dead_zone)) {
+ if ((x < 0 && x > -1 * dead_zone) || (x > 0 && x < dead_zone)) {
x = 0;
}
@@ -298,10 +315,18 @@ report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
y = abs(y) * y / 5000;
// Clamp final value to make sure we don't under/overflow
- if (y < -127) { y = -127; }
- if (y > 127) { y = 127; }
- if (x < -127) { x = -127; }
- if (x > 127) { x = 127; }
+ if (y < -127) {
+ y = -127;
+ }
+ if (y > 127) {
+ y = 127;
+ }
+ if (x < -127) {
+ x = -127;
+ }
+ if (x > 127) {
+ x = 127;
+ }
mouse_report.x = x;
mouse_report.y = y;
@@ -309,7 +334,8 @@ report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
return mouse_report;
}
-void pointing_device_driver_init(void) {
+bool pointing_device_driver_init(void) {
gpio_set_pin_input(MYRIAD_ADC1); // Y
gpio_set_pin_input(MYRIAD_ADC2); // X
+ return true;
} \ No newline at end of file
diff --git a/quantum/pointing_device/pointing_device.c b/quantum/pointing_device/pointing_device.c
index 564c2d294c..fe88d5a1af 100644
--- a/quantum/pointing_device/pointing_device.c
+++ b/quantum/pointing_device/pointing_device.c
@@ -80,8 +80,10 @@ uint16_t pointing_device_get_shared_cpi(void) {
#endif // defined(SPLIT_POINTING_ENABLE)
-static report_mouse_t local_mouse_report = {};
-static bool pointing_device_force_send = false;
+static report_mouse_t local_mouse_report = {};
+static bool pointing_device_force_send = false;
+static pointing_device_status_t pointing_device_status = POINTING_DEVICE_STATUS_UNKNOWN;
+
#ifdef POINTING_DEVICE_HIRES_SCROLL_ENABLE
static uint16_t hires_scroll_resolution;
#endif
@@ -90,7 +92,9 @@ static uint16_t hires_scroll_resolution;
#define POINTING_DEVICE_DRIVER(name) POINTING_DEVICE_DRIVER_CONCAT(name)
#ifdef POINTING_DEVICE_DRIVER_custom
-__attribute__((weak)) void pointing_device_driver_init(void) {}
+__attribute__((weak)) bool pointing_device_driver_init(void) {
+ return false;
+}
__attribute__((weak)) report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
return mouse_report;
}
@@ -179,7 +183,11 @@ __attribute__((weak)) void pointing_device_init(void) {
if ((POINTING_DEVICE_THIS_SIDE))
#endif
{
- pointing_device_driver->init();
+ if (pointing_device_driver->init()) {
+ pointing_device_status = POINTING_DEVICE_STATUS_SUCCESS;
+ } else {
+ pointing_device_status = POINTING_DEVICE_STATUS_INIT_FAILED;
+ }
#ifdef POINTING_DEVICE_MOTION_PIN
# ifdef POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW
gpio_set_pin_input_high(POINTING_DEVICE_MOTION_PIN);
@@ -201,6 +209,28 @@ __attribute__((weak)) void pointing_device_init(void) {
}
/**
+ * @brief Gets status of pointing device
+ *
+ * Returns current pointing device status
+ * @return pointing_device_status_t
+ */
+__attribute__((weak)) pointing_device_status_t pointing_device_get_status(void) {
+#ifdef SPLIT_POINTING_ENABLE
+ // Assume target side is always good, split transaction checksum should stop additional reports being generated.
+ return POINTING_DEVICE_THIS_SIDE ? pointing_device_status : POINTING_DEVICE_STATUS_SUCCESS;
+#else
+ return pointing_device_status;
+#endif
+}
+
+/**
+ * @brief Sets status of pointing device
+ */
+void pointing_device_set_status(pointing_device_status_t status) {
+ pointing_device_status = status;
+}
+
+/**
* @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.
@@ -281,6 +311,10 @@ __attribute__((weak)) bool pointing_device_task(void) {
last_exec = timer_read32();
#endif
+ if (pointing_device_get_status() != POINTING_DEVICE_STATUS_SUCCESS) {
+ return false;
+ }
+
// Gather report info
#ifdef POINTING_DEVICE_MOTION_PIN
# if defined(SPLIT_POINTING_ENABLE)
diff --git a/quantum/pointing_device/pointing_device.h b/quantum/pointing_device/pointing_device.h
index e7a0819ed9..5dfb9ce196 100644
--- a/quantum/pointing_device/pointing_device.h
+++ b/quantum/pointing_device/pointing_device.h
@@ -23,7 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "report.h"
typedef struct {
- void (*init)(void);
+ bool (*init)(void);
report_mouse_t (*get_report)(report_mouse_t mouse_report);
void (*set_cpi)(uint16_t);
uint16_t (*get_cpi)(void);
@@ -75,7 +75,7 @@ typedef struct {
# include "drivers/sensors/pmw33xx_common.h"
# define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW
#else
-void pointing_device_driver_init(void);
+bool pointing_device_driver_init(void);
report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report);
uint16_t pointing_device_driver_get_cpi(void);
void pointing_device_driver_set_cpi(uint16_t cpi);
@@ -92,6 +92,13 @@ typedef enum {
POINTING_DEVICE_BUTTON8,
} pointing_device_buttons_t;
+typedef enum {
+ POINTING_DEVICE_STATUS_UNKNOWN,
+ POINTING_DEVICE_STATUS_INIT_FAILED,
+ POINTING_DEVICE_STATUS_FAILED,
+ POINTING_DEVICE_STATUS_SUCCESS,
+} pointing_device_status_t;
+
#ifdef MOUSE_EXTENDED_REPORT
typedef int32_t xy_clamp_range_t;
#else
@@ -107,13 +114,15 @@ typedef int16_t hv_clamp_range_t;
#define CONSTRAIN_HID(amt) ((amt) < INT8_MIN ? INT8_MIN : ((amt) > INT8_MAX ? INT8_MAX : (amt)))
#define CONSTRAIN_HID_XY(amt) ((amt) < MOUSE_REPORT_XY_MIN ? MOUSE_REPORT_XY_MIN : ((amt) > MOUSE_REPORT_XY_MAX ? MOUSE_REPORT_XY_MAX : (amt)))
-void pointing_device_init(void);
-bool pointing_device_task(void);
-bool pointing_device_send(void);
-report_mouse_t pointing_device_get_report(void);
-void pointing_device_set_report(report_mouse_t mouse_report);
-uint16_t pointing_device_get_cpi(void);
-void pointing_device_set_cpi(uint16_t cpi);
+void pointing_device_init(void);
+bool pointing_device_task(void);
+bool pointing_device_send(void);
+report_mouse_t pointing_device_get_report(void);
+void pointing_device_set_report(report_mouse_t mouse_report);
+uint16_t pointing_device_get_cpi(void);
+void pointing_device_set_cpi(uint16_t cpi);
+pointing_device_status_t pointing_device_get_status(void);
+void pointing_device_set_status(pointing_device_status_t status);
void pointing_device_init_kb(void);
void pointing_device_init_user(void);
diff --git a/tests/pointing/test_pointing.cpp b/tests/pointing/test_pointing.cpp
index d59d014925..bd886b18a2 100644
--- a/tests/pointing/test_pointing.cpp
+++ b/tests/pointing/test_pointing.cpp
@@ -12,6 +12,26 @@ using testing::_;
class Pointing : public TestFixture {};
class PointingButtonsViaMousekeysParametrized : public ::testing::WithParamInterface<std::pair<KeymapKey, uint8_t>>, public Pointing {};
+TEST_F(Pointing, NoMovementOnInitFailure) {
+ TestDriver driver;
+
+ pointing_device_set_status(POINTING_DEVICE_STATUS_INIT_FAILED);
+ pd_set_x(-50);
+ pd_set_y(100);
+ EXPECT_NO_MOUSE_REPORT(driver);
+ run_one_scan_loop();
+
+ pointing_device_set_status(POINTING_DEVICE_STATUS_SUCCESS);
+ EXPECT_MOUSE_REPORT(driver, (-50, 100, 0, 0, 0));
+ run_one_scan_loop();
+
+ pd_clear_movement();
+ // EXPECT_EMPTY_MOUSE_REPORT(driver);
+ run_one_scan_loop();
+
+ VERIFY_AND_CLEAR(driver);
+}
+
TEST_F(Pointing, SendMouseIsNotCalledWithNoInput) {
TestDriver driver;
EXPECT_NO_MOUSE_REPORT(driver);
diff --git a/tests/test_common/pointing_device_driver.c b/tests/test_common/pointing_device_driver.c
index b64dbad506..42c7a814a4 100644
--- a/tests/test_common/pointing_device_driver.c
+++ b/tests/test_common/pointing_device_driver.c
@@ -22,8 +22,9 @@ typedef struct {
static pd_config_t pd_config = {0};
-void pointing_device_driver_init(void) {
+bool pointing_device_driver_init(void) {
pd_set_init(true);
+ return pd_config.initiated;
}
report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {