From 300fb2bc1df14ad1a7df840353eba1292a475dbc Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Mon, 20 Nov 2023 16:57:19 -0800 Subject: [PATCH 01/10] [Pointing] Add space mouse module uart support --- builddefs/common_features.mk | 4 +- drivers/sensors/spacemouse_module.c | 138 ++++++++++++++++++ drivers/sensors/spacemouse_module.h | 48 ++++++ quantum/pointing_device/pointing_device.h | 2 + .../pointing_device/pointing_device_drivers.c | 35 +++++ 5 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 drivers/sensors/spacemouse_module.c create mode 100644 drivers/sensors/spacemouse_module.h diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk index 68f9a1dd08a..8be17d73707 100644 --- a/builddefs/common_features.mk +++ b/builddefs/common_features.mk @@ -120,7 +120,7 @@ ifeq ($(strip $(MOUSEKEY_ENABLE)), yes) MOUSE_ENABLE := yes endif -VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick azoteq_iqs5xx cirque_pinnacle_i2c cirque_pinnacle_spi paw3204 pmw3320 pmw3360 pmw3389 pimoroni_trackball custom +VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick azoteq_iqs5xx cirque_pinnacle_i2c cirque_pinnacle_spi paw3204 pmw3320 pmw3360 pmw3389 pimoroni_trackball spacemouse_module custom ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes) ifeq ($(filter $(POINTING_DEVICE_DRIVER),$(VALID_POINTING_DEVICE_DRIVER_TYPES)),) $(call CATASTROPHIC_ERROR,Invalid POINTING_DEVICE_DRIVER,POINTING_DEVICE_DRIVER="$(POINTING_DEVICE_DRIVER)" is not a valid pointing device type) @@ -154,6 +154,8 @@ ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes) SRC += $(QUANTUM_DIR)/pointing_device/pointing_device_gestures.c else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pimoroni_trackball) I2C_DRIVER_REQUIRED = yes + else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), spacemouse_module) + UART_DRIVER_REQUIRED = yes else ifneq ($(filter $(strip $(POINTING_DEVICE_DRIVER)),pmw3360 pmw3389),) SPI_DRIVER_REQUIRED = yes SRC += drivers/sensors/pmw33xx_common.c diff --git a/drivers/sensors/spacemouse_module.c b/drivers/sensors/spacemouse_module.c new file mode 100644 index 00000000000..8722f941394 --- /dev/null +++ b/drivers/sensors/spacemouse_module.c @@ -0,0 +1,138 @@ +// Copyright 2023 Christopher Courtney, aka Drashna Jael're (@drashna) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "spacemouse_module.h" +#include "pointing_device_internal.h" +#include "uart.h" + +// REQUEST_DATA (the important part) +// Function: requests position data from the 3D-Sensor Command: 172 (0xAC) +// Returns: 16 bytes data +// Structure: B1 B2 ... B16 +// Byte 1: start-byte 0x96 (150 decimal); every data set starts with this byte Byte 2: high byte of X value +// Byte 3: low byte of X value +// Byte 4: high byte of Y value +// Byte 5: low byte of Y value +// Byte 6: high byte of Z value +// Byte 7: low byte of Z value +// Byte 8: high byte of A value (X rotation) Byte 9: low byte of A value (X rotation) Byte 10: high byte of B value (Y rotation) Byte 11: low byte of B value (Y rotation) Byte 12: high byte of C value (Z rotation) Byte 13: low byte of C value (Z rotation) Byte 14: high byte of Checksum +// Byte 15: low byte of Checksum +// Byte 16: end-byte 0x8D; every response ends with this byte +// +// X, Y, Z, A, B, C values and the Checksum are transmitted as unsigned 14-Bit values. This is due to the fact, that the MSB of payload data is always cleared (logic 0). +// Calculating a value: +// high byte (X) low byte (X) +// 14-bit value (unsigned) +// Xvalue = (high byte (X) * 128 + low byte (X)) - 8192 +// Transmitted Checksum: +// Checksumtrans = (high byte (Checksumtrans) * 128 + low byte (Checksumtrans)) +// Calculating the Checksum: +// Checksumcalc = (Byte1 + Byte2 + ... + Byte13) & 0x3FFF. +// By masking the Checksum with 0x3FFF (logic AND operation), the value is reduced to a 14-Bit value. +// The value range for X, Y, Z, A, B, C values is -350 up to +350. + +#define SPACEMOUSE_INPUT_OFFSET (8192) + +bool spacemouse_send_command(uint8_t cmd) { + uart_write(cmd); + uint8_t buf[2]; + uart_receive(buf, 2); + return (buf[0] == cmd && buf[1] == SPACEMOUSE_CMD_END); +} + +/** + * @brief Set the zero position of the module + * + * @return true command ran successfully + * @return false command failed + */ +bool spacemouse_cmd_set_zero_position(void) { + return spacemouse_send_command(SPACEMOUSE_CMD_SET_ZERO_POSITION); +} + +/** + * @brief Starts automatic transmission of data, at 30ms invervals + * Automatic data transmission happens at 30 ms intervals, but device can be polled at 100/s or 10ms intervals + * Since 10ms is what pointing device polling defaults to, we don't need need the stream command, but + * it is here for completeness, in case somebody wants to implement it elsewhere. + * + * @return true command ran successfully + * @return false command failed + */ +bool spacemouse_cmd_enable_stream(void) { + return spacemouse_send_command(SPACEMOUSE_CMD_AUTO_DATA_ON); +} + +/** + * @brief Stops automatic transmission of data, at 30ms invervals + * + * @return true command ran successfully + * @return false command failed + */ +bool spacemouse_cmd_disable_stream(void) { + return spacemouse_send_command(SPACEMOUSE_CMD_AUTO_DATA_OFF); +} + +/** + * @brief Initialize UART connection and send command to zero out starting position. + * + * @return true + * @return false + */ +bool spacemouse_init(void) { + uart_init(SPACEMOUSE_BAUD_RATE); + // position is zeroed out during device start, but re-zero it out to ensure that the + // device is present and working properly. + return spacemouse_cmd_set_zero_position(); +} + +spacemouse_data_t spacemouse_get_data(void) { + spacemouse_data_t data = {0}; + uint8_t retry_attempts = 0, index = 0, payload[SPACEMOUSE_LENGTH_DATA + SPACEMOUSE_LENGTH_CHECKSUM] = {0}; + uint16_t checksum = 0, checksum_received = 0; + bool has_started = false; + uart_write(SPACEMOUSE_CMD_REQUEST_DATA); + while (retry_attempts <= 15) { + uint8_t buf = uart_read(); + if (buf == SPACEMOUSE_DATA_REQUEST_START) { + has_started = true; + checksum = buf; + retry_attempts = 0; + continue; + } else if (has_started) { + if (buf == SPACEMOUSE_CMD_END) { + break; + } else { + if (index >= SPACEMOUSE_LENGTH_DATA) { + if (index == SPACEMOUSE_LENGTH_DATA) { + checksum_received = buf << 7; + } else { + checksum_received += buf; + } + } else { + payload[index] = buf; + checksum += buf; + } + index++; + } + } + retry_attempts++; + }; + + checksum &= 0x3FFF; + + if (has_started) { + if (checksum_received == checksum) { + data.x = (int16_t)((payload[0] << 7) + payload[1]) - SPACEMOUSE_INPUT_OFFSET; + data.z = (int16_t)((payload[2] << 7) + payload[3]) - SPACEMOUSE_INPUT_OFFSET; + data.y = (int16_t)((payload[4] << 7) + payload[5]) - SPACEMOUSE_INPUT_OFFSET; + data.a = (int16_t)((payload[6] << 7) + payload[7]) - SPACEMOUSE_INPUT_OFFSET; + data.b = (int16_t)((payload[8] << 7) + payload[9]) - SPACEMOUSE_INPUT_OFFSET; + data.c = (int16_t)((payload[10] << 7) + payload[11]) - SPACEMOUSE_INPUT_OFFSET; + } else { + pd_dprintf("Space Mouse Checksum error: 0x%04x != 0x%04x \n", checksum_received, checksum); + } + } + + return data; +} diff --git a/drivers/sensors/spacemouse_module.h b/drivers/sensors/spacemouse_module.h new file mode 100644 index 00000000000..f46125678d9 --- /dev/null +++ b/drivers/sensors/spacemouse_module.h @@ -0,0 +1,48 @@ +// Copyright 2023 Christopher Courtney, aka Drashna Jael're (@drashna) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +// Datasheet UART settings specify: +// - 38400 baud +// - 8 data bits +// - 1 stop bit +// - no parity +// - 100/s data rate + +#ifndef SPACEMOUSE_BAUD_RATE +# define SPACEMOUSE_BAUD_RATE 38400 +#endif + +#define SPACEMOUSE_AXIS_COUNT 6 + +#define SPACEMOUSE_LENGTH_HEADER 1 +#define SPACEMOUSE_LENGTH_DATA (2 * SPACEMOUSE_AXIS_COUNT) +#define SPACEMOUSE_LENGTH_CHECKSUM 2 +#define SPACEMOUSE_LENGTH_FOOTER 1 +#define SPACEMOUSE_LENGTH_PACKET (SPACEMOUSE_LENGTH_HEADER + SPACEMOUSE_LENGTH_DATA + SPACEMOUSE_LENGTH_CHECKSUM + SPACEMOUSE_LENGTH_FOOTER) + +enum spacemouse_commands { + SPACEMOUSE_CMD_REQUEST_DATA = 0xAC, + SPACEMOUSE_CMD_SET_ZERO_POSITION = 0xAD, + SPACEMOUSE_CMD_AUTO_DATA_ON = 0xAE, + SPACEMOUSE_CMD_AUTO_DATA_OFF = 0xAF, + SPACEMOUSE_CMD_END = 0x8D, + SPACEMOUSE_DATA_REQUEST_START = 0x96, +}; + +typedef struct { + int16_t x; + int16_t y; + int16_t z; + int16_t a; + int16_t b; + int16_t c; +} spacemouse_data_t; + +bool spacemouse_send_command(uint8_t cmd); +bool spacemouse_init(void); +spacemouse_data_t spacemouse_get_data(void); diff --git a/quantum/pointing_device/pointing_device.h b/quantum/pointing_device/pointing_device.h index 1cd4b0b5e60..c2523d1428b 100644 --- a/quantum/pointing_device/pointing_device.h +++ b/quantum/pointing_device/pointing_device.h @@ -67,6 +67,8 @@ along with this program. If not, see . # include "spi_master.h" # include "drivers/sensors/pmw33xx_common.h" # define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW +#elif defined(POINTING_DEVICE_DRIVER_spacemouse_module) +# include "drivers/sensors/spacemouse_module.h" #else void pointing_device_driver_init(void); report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report); diff --git a/quantum/pointing_device/pointing_device_drivers.c b/quantum/pointing_device/pointing_device_drivers.c index bf131c6eda5..1164bfbcaab 100644 --- a/quantum/pointing_device/pointing_device_drivers.c +++ b/quantum/pointing_device/pointing_device_drivers.c @@ -492,6 +492,41 @@ const pointing_device_driver_t pointing_device_driver = { }; // clang-format on +#elif defined(POINTING_DEVICE_DRIVER_spacemouse_module) + +static bool spacemouse_present = false; + +__attribute__((weak)) void spacemouse_module_handle_axises(spacemouse_data_t *spacemouse_data, report_mouse_t* mouse_report) { + mouse_report->x = CONSTRAIN_HID_XY(spacemouse_data->x); + mouse_report->y = CONSTRAIN_HID_XY(spacemouse_data->y); +// mouse_report->h = CONSTRAIN_HID(spacemouse_data->b); +// mouse_report->v = CONSTRAIN_HID(spacemouse_data->c); +} + +static report_mouse_t spacemouse_get_report(report_mouse_t mouse_report) { + if (spacemouse_present) { + spacemouse_data_t data = spacemouse_get_data(); + + if (data.x || data.y || data.z || data.a || data.b || data.c) { + pd_dprintf("Raw ] X: %d, Y: %d, Z: %d, A: %d, B: %d, C: %d\n", data.x, data.y, data.z, data.a, data.b, data.c); + } + spacemouse_module_handle_axises(&data, &mouse_report); + } + return mouse_report; +} + +static void init(void) { + spacemouse_present = spacemouse_init(); +} + +// clang-format off +const pointing_device_driver_t pointing_device_driver = { + .init = init, + .get_report = spacemouse_get_report, + .set_cpi = NULL, + .get_cpi = NULL +}; +// clang-format on #else __attribute__((weak)) void pointing_device_driver_init(void) {} __attribute__((weak)) report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) { From 9efbd110528ec2dcad0640a71e322675d8014ad9 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Mon, 20 Nov 2023 18:40:22 -0800 Subject: [PATCH 02/10] Add docs To be honest, there isn't a lot that needs to be customized here, but there is a lot that could/shold be done for handling the other axises. But drashna doesn't want to do it, at this time --- docs/features/pointing_device.md | 21 +++++++++++++++++++++ drivers/sensors/spacemouse_module.h | 4 +--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/features/pointing_device.md b/docs/features/pointing_device.md index a6bf521a184..caef376ddf2 100644 --- a/docs/features/pointing_device.md +++ b/docs/features/pointing_device.md @@ -368,6 +368,27 @@ report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { ``` +### SpaceMouse Module (UART) + +To use the SpaceMouse module to control the pointer, add this to your `rules.mk` + +```make +POINTING_DEVICE_DRIVER = spacemouse_module +``` + +The SpaceMouse Module is a UART driven sensor, with 6 axises of motion. + +While there isn't a whole lot to configure here, only the X and Y movement is enabled by default. The Z axis and the twist and turn axises are not supported out of box. These can be handled with a custom function: + +```c +void spacemouse_module_handle_axises(spacemouse_data_t *spacemouse_data, report_mouse_t* mouse_report) { + mouse_report->x = CONSTRAIN_HID_XY(spacemouse_data->x); + mouse_report->y = CONSTRAIN_HID_XY(spacemouse_data->y); + mouse_report->h = CONSTRAIN_HID(spacemouse_data->b); + mouse_report->v = CONSTRAIN_HID(spacemouse_data->c); +} +``` + ### Custom Driver If you have a sensor type that isn't supported above, a custom option is available by adding the following to your `rules.mk` diff --git a/drivers/sensors/spacemouse_module.h b/drivers/sensors/spacemouse_module.h index f46125678d9..4d389fa8cc8 100644 --- a/drivers/sensors/spacemouse_module.h +++ b/drivers/sensors/spacemouse_module.h @@ -13,9 +13,7 @@ // - no parity // - 100/s data rate -#ifndef SPACEMOUSE_BAUD_RATE -# define SPACEMOUSE_BAUD_RATE 38400 -#endif +#define SPACEMOUSE_BAUD_RATE 38400 #define SPACEMOUSE_AXIS_COUNT 6 From 24dc311de158a5d3d02f6422bce0f42811afb38e Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Mon, 20 Nov 2023 19:33:37 -0800 Subject: [PATCH 03/10] Fix axis names --- drivers/sensors/spacemouse_module.c | 18 +++++++++--------- drivers/sensors/spacemouse_module.h | 6 +++--- .../pointing_device/pointing_device_drivers.c | 6 ++---- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/sensors/spacemouse_module.c b/drivers/sensors/spacemouse_module.c index 8722f941394..4dca98f9248 100644 --- a/drivers/sensors/spacemouse_module.c +++ b/drivers/sensors/spacemouse_module.c @@ -88,9 +88,9 @@ bool spacemouse_init(void) { spacemouse_data_t spacemouse_get_data(void) { spacemouse_data_t data = {0}; - uint8_t retry_attempts = 0, index = 0, payload[SPACEMOUSE_LENGTH_DATA + SPACEMOUSE_LENGTH_CHECKSUM] = {0}; - uint16_t checksum = 0, checksum_received = 0; - bool has_started = false; + uint8_t retry_attempts = 0, index = 0, payload[SPACEMOUSE_LENGTH_DATA + SPACEMOUSE_LENGTH_CHECKSUM] = {0}; + uint16_t checksum = 0, checksum_received = 0; + bool has_started = false; uart_write(SPACEMOUSE_CMD_REQUEST_DATA); while (retry_attempts <= 15) { uint8_t buf = uart_read(); @@ -123,12 +123,12 @@ spacemouse_data_t spacemouse_get_data(void) { if (has_started) { if (checksum_received == checksum) { - data.x = (int16_t)((payload[0] << 7) + payload[1]) - SPACEMOUSE_INPUT_OFFSET; - data.z = (int16_t)((payload[2] << 7) + payload[3]) - SPACEMOUSE_INPUT_OFFSET; - data.y = (int16_t)((payload[4] << 7) + payload[5]) - SPACEMOUSE_INPUT_OFFSET; - data.a = (int16_t)((payload[6] << 7) + payload[7]) - SPACEMOUSE_INPUT_OFFSET; - data.b = (int16_t)((payload[8] << 7) + payload[9]) - SPACEMOUSE_INPUT_OFFSET; - data.c = (int16_t)((payload[10] << 7) + payload[11]) - SPACEMOUSE_INPUT_OFFSET; + data.x = (int16_t)((payload[0] << 7) + payload[1]) - SPACEMOUSE_INPUT_OFFSET; + data.z = (int16_t)((payload[2] << 7) + payload[3]) - SPACEMOUSE_INPUT_OFFSET; + data.y = (int16_t)((payload[4] << 7) + payload[5]) - SPACEMOUSE_INPUT_OFFSET; + data.tilt_y = (int16_t)((payload[6] << 7) + payload[7]) - SPACEMOUSE_INPUT_OFFSET; + data.twist = (int16_t)((payload[8] << 7) + payload[9]) - SPACEMOUSE_INPUT_OFFSET; + data.tilt_x = (int16_t)((payload[10] << 7) + payload[11]) - SPACEMOUSE_INPUT_OFFSET; } else { pd_dprintf("Space Mouse Checksum error: 0x%04x != 0x%04x \n", checksum_received, checksum); } diff --git a/drivers/sensors/spacemouse_module.h b/drivers/sensors/spacemouse_module.h index 4d389fa8cc8..367f52ba07a 100644 --- a/drivers/sensors/spacemouse_module.h +++ b/drivers/sensors/spacemouse_module.h @@ -36,9 +36,9 @@ typedef struct { int16_t x; int16_t y; int16_t z; - int16_t a; - int16_t b; - int16_t c; + int16_t twist; + int16_t tilt_x; + int16_t tilt_y; } spacemouse_data_t; bool spacemouse_send_command(uint8_t cmd); diff --git a/quantum/pointing_device/pointing_device_drivers.c b/quantum/pointing_device/pointing_device_drivers.c index 1164bfbcaab..7fe7357f1b2 100644 --- a/quantum/pointing_device/pointing_device_drivers.c +++ b/quantum/pointing_device/pointing_device_drivers.c @@ -499,16 +499,14 @@ static bool spacemouse_present = false; __attribute__((weak)) void spacemouse_module_handle_axises(spacemouse_data_t *spacemouse_data, report_mouse_t* mouse_report) { mouse_report->x = CONSTRAIN_HID_XY(spacemouse_data->x); mouse_report->y = CONSTRAIN_HID_XY(spacemouse_data->y); -// mouse_report->h = CONSTRAIN_HID(spacemouse_data->b); -// mouse_report->v = CONSTRAIN_HID(spacemouse_data->c); } static report_mouse_t spacemouse_get_report(report_mouse_t mouse_report) { if (spacemouse_present) { spacemouse_data_t data = spacemouse_get_data(); - if (data.x || data.y || data.z || data.a || data.b || data.c) { - pd_dprintf("Raw ] X: %d, Y: %d, Z: %d, A: %d, B: %d, C: %d\n", data.x, data.y, data.z, data.a, data.b, data.c); + if (data.x || data.y || data.z || data.twist || data.tilt_x || data.tilt_y) { + pd_dprintf("Raw ] X: %d, Y: %d, Z: %d, twist: %d, tilt X: %d, tilt Y: %d\n", data.x, data.y, data.z, data.twist, data.tilt_x, data.tilt_y); } spacemouse_module_handle_axises(&data, &mouse_report); } From a3cd5e6879cd93caa88e2a979242896e4412ba95 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Mon, 20 Nov 2023 19:43:14 -0800 Subject: [PATCH 04/10] More docs --- docs/features/pointing_device.md | 9 ++++++++- quantum/pointing_device/pointing_device_drivers.c | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/features/pointing_device.md b/docs/features/pointing_device.md index caef376ddf2..ed632b60d41 100644 --- a/docs/features/pointing_device.md +++ b/docs/features/pointing_device.md @@ -378,7 +378,12 @@ POINTING_DEVICE_DRIVER = spacemouse_module The SpaceMouse Module is a UART driven sensor, with 6 axises of motion. -While there isn't a whole lot to configure here, only the X and Y movement is enabled by default. The Z axis and the twist and turn axises are not supported out of box. These can be handled with a custom function: +| Setting (`config.h`) | Description | Default | +| ---------------------------- | ------------------------------------------------------------------------------------------- | ------------- | +| `SPACEMOUSE_USE_TILT_AXIS` | Uses the tilt axises for movement rather than the shift axises. | _not_defined_ | + + +By default, not all of the axises are utilized. If you would like to use more of them, you can do so by using this custom function, which translates the data from the SpaceMouse Module to the pointing device report. ```c void spacemouse_module_handle_axises(spacemouse_data_t *spacemouse_data, report_mouse_t* mouse_report) { @@ -386,6 +391,8 @@ void spacemouse_module_handle_axises(spacemouse_data_t *spacemouse_data, report_ mouse_report->y = CONSTRAIN_HID_XY(spacemouse_data->y); mouse_report->h = CONSTRAIN_HID(spacemouse_data->b); mouse_report->v = CONSTRAIN_HID(spacemouse_data->c); + + mouse_report->buttons = pointing_device_handle_buttons(mouse_report->buttons, (space_mouse_data->z < -10), KC_BTN1); } ``` diff --git a/quantum/pointing_device/pointing_device_drivers.c b/quantum/pointing_device/pointing_device_drivers.c index 7fe7357f1b2..d82a12a2ae8 100644 --- a/quantum/pointing_device/pointing_device_drivers.c +++ b/quantum/pointing_device/pointing_device_drivers.c @@ -497,8 +497,13 @@ const pointing_device_driver_t pointing_device_driver = { static bool spacemouse_present = false; __attribute__((weak)) void spacemouse_module_handle_axises(spacemouse_data_t *spacemouse_data, report_mouse_t* mouse_report) { +#ifdef SPACEMOUSE_USE_TILT_AXIS + mouse_report->x = CONSTRAIN_HID_XY(spacemouse_data->tilt_x); + mouse_report->y = CONSTRAIN_HID_XY(spacemouse_data->tilt_y); +#else mouse_report->x = CONSTRAIN_HID_XY(spacemouse_data->x); mouse_report->y = CONSTRAIN_HID_XY(spacemouse_data->y); +#endif } static report_mouse_t spacemouse_get_report(report_mouse_t mouse_report) { From b54db09186c669d41813f68403a3d7537532610a Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Mon, 20 Nov 2023 19:50:47 -0800 Subject: [PATCH 05/10] add datasheet pdf link --- drivers/sensors/spacemouse_module.c | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/drivers/sensors/spacemouse_module.c b/drivers/sensors/spacemouse_module.c index 4dca98f9248..800793dd858 100644 --- a/drivers/sensors/spacemouse_module.c +++ b/drivers/sensors/spacemouse_module.c @@ -5,31 +5,7 @@ #include "pointing_device_internal.h" #include "uart.h" -// REQUEST_DATA (the important part) -// Function: requests position data from the 3D-Sensor Command: 172 (0xAC) -// Returns: 16 bytes data -// Structure: B1 B2 ... B16 -// Byte 1: start-byte 0x96 (150 decimal); every data set starts with this byte Byte 2: high byte of X value -// Byte 3: low byte of X value -// Byte 4: high byte of Y value -// Byte 5: low byte of Y value -// Byte 6: high byte of Z value -// Byte 7: low byte of Z value -// Byte 8: high byte of A value (X rotation) Byte 9: low byte of A value (X rotation) Byte 10: high byte of B value (Y rotation) Byte 11: low byte of B value (Y rotation) Byte 12: high byte of C value (Z rotation) Byte 13: low byte of C value (Z rotation) Byte 14: high byte of Checksum -// Byte 15: low byte of Checksum -// Byte 16: end-byte 0x8D; every response ends with this byte -// -// X, Y, Z, A, B, C values and the Checksum are transmitted as unsigned 14-Bit values. This is due to the fact, that the MSB of payload data is always cleared (logic 0). -// Calculating a value: -// high byte (X) low byte (X) -// 14-bit value (unsigned) -// Xvalue = (high byte (X) * 128 + low byte (X)) - 8192 -// Transmitted Checksum: -// Checksumtrans = (high byte (Checksumtrans) * 128 + low byte (Checksumtrans)) -// Calculating the Checksum: -// Checksumcalc = (Byte1 + Byte2 + ... + Byte13) & 0x3FFF. -// By masking the Checksum with 0x3FFF (logic AND operation), the value is reduced to a 14-Bit value. -// The value range for X, Y, Z, A, B, C values is -350 up to +350. +// datasheet available at https://3dconnexion.com/cn/wp-content/uploads/2020/02/HW-Spec-3DX-700039_Rev001_serial.pdf #define SPACEMOUSE_INPUT_OFFSET (8192) From 8b9ada2640210817e3166129db010bb22f7e6ba4 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Mon, 20 Nov 2023 23:32:28 -0800 Subject: [PATCH 06/10] Fix lint Re-fix lint?! --- drivers/sensors/spacemouse_module.h | 16 ++++++++-------- .../pointing_device/pointing_device_drivers.c | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/sensors/spacemouse_module.h b/drivers/sensors/spacemouse_module.h index 367f52ba07a..205818851d5 100644 --- a/drivers/sensors/spacemouse_module.h +++ b/drivers/sensors/spacemouse_module.h @@ -24,12 +24,12 @@ #define SPACEMOUSE_LENGTH_PACKET (SPACEMOUSE_LENGTH_HEADER + SPACEMOUSE_LENGTH_DATA + SPACEMOUSE_LENGTH_CHECKSUM + SPACEMOUSE_LENGTH_FOOTER) enum spacemouse_commands { - SPACEMOUSE_CMD_REQUEST_DATA = 0xAC, - SPACEMOUSE_CMD_SET_ZERO_POSITION = 0xAD, - SPACEMOUSE_CMD_AUTO_DATA_ON = 0xAE, - SPACEMOUSE_CMD_AUTO_DATA_OFF = 0xAF, - SPACEMOUSE_CMD_END = 0x8D, - SPACEMOUSE_DATA_REQUEST_START = 0x96, + SPACEMOUSE_CMD_REQUEST_DATA = 0xAC, + SPACEMOUSE_CMD_SET_ZERO_POSITION = 0xAD, + SPACEMOUSE_CMD_AUTO_DATA_ON = 0xAE, + SPACEMOUSE_CMD_AUTO_DATA_OFF = 0xAF, + SPACEMOUSE_CMD_END = 0x8D, + SPACEMOUSE_DATA_REQUEST_START = 0x96, }; typedef struct { @@ -41,6 +41,6 @@ typedef struct { int16_t tilt_y; } spacemouse_data_t; -bool spacemouse_send_command(uint8_t cmd); -bool spacemouse_init(void); +bool spacemouse_send_command(uint8_t cmd); +bool spacemouse_init(void); spacemouse_data_t spacemouse_get_data(void); diff --git a/quantum/pointing_device/pointing_device_drivers.c b/quantum/pointing_device/pointing_device_drivers.c index d82a12a2ae8..4fc599f7d01 100644 --- a/quantum/pointing_device/pointing_device_drivers.c +++ b/quantum/pointing_device/pointing_device_drivers.c @@ -264,7 +264,7 @@ report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) { static uint16_t x = 0, y = 0, last_scale = 0; # if defined(CIRQUE_PINNACLE_TAP_ENABLE) - mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1); + mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1); # endif # ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE cursor_glide_t glide_report = {0}; @@ -496,14 +496,14 @@ const pointing_device_driver_t pointing_device_driver = { static bool spacemouse_present = false; -__attribute__((weak)) void spacemouse_module_handle_axises(spacemouse_data_t *spacemouse_data, report_mouse_t* mouse_report) { -#ifdef SPACEMOUSE_USE_TILT_AXIS +__attribute__((weak)) void spacemouse_module_handle_axises(spacemouse_data_t* spacemouse_data, report_mouse_t* mouse_report) { +# ifdef SPACEMOUSE_USE_TILT_AXIS mouse_report->x = CONSTRAIN_HID_XY(spacemouse_data->tilt_x); mouse_report->y = CONSTRAIN_HID_XY(spacemouse_data->tilt_y); -#else +# else mouse_report->x = CONSTRAIN_HID_XY(spacemouse_data->x); mouse_report->y = CONSTRAIN_HID_XY(spacemouse_data->y); -#endif +# endif } static report_mouse_t spacemouse_get_report(report_mouse_t mouse_report) { From bcc63f3a63f4b1d5d706ecd8b98c6ae287fa62b1 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Mon, 20 Nov 2023 23:54:25 -0800 Subject: [PATCH 07/10] Re-fix lint?! --- quantum/pointing_device/pointing_device_drivers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quantum/pointing_device/pointing_device_drivers.c b/quantum/pointing_device/pointing_device_drivers.c index 4fc599f7d01..a84c3d35d8b 100644 --- a/quantum/pointing_device/pointing_device_drivers.c +++ b/quantum/pointing_device/pointing_device_drivers.c @@ -264,7 +264,7 @@ report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) { static uint16_t x = 0, y = 0, last_scale = 0; # if defined(CIRQUE_PINNACLE_TAP_ENABLE) - mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1); + mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1); # endif # ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE cursor_glide_t glide_report = {0}; From 69f31be5c18a06da8e5769f1d21320732301c0b9 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Tue, 21 Nov 2023 03:41:05 -0800 Subject: [PATCH 08/10] Apply suggestions from code review Co-authored-by: Dasky <32983009+daskygit@users.noreply.github.com> --- docs/features/pointing_device.md | 8 ++++---- quantum/pointing_device/pointing_device_drivers.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/features/pointing_device.md b/docs/features/pointing_device.md index ed632b60d41..d429504b99d 100644 --- a/docs/features/pointing_device.md +++ b/docs/features/pointing_device.md @@ -376,17 +376,17 @@ To use the SpaceMouse module to control the pointer, add this to your `rules.mk` POINTING_DEVICE_DRIVER = spacemouse_module ``` -The SpaceMouse Module is a UART driven sensor, with 6 axises of motion. +The SpaceMouse Module is a UART driven sensor, with 6 axes of motion. | Setting (`config.h`) | Description | Default | | ---------------------------- | ------------------------------------------------------------------------------------------- | ------------- | -| `SPACEMOUSE_USE_TILT_AXIS` | Uses the tilt axises for movement rather than the shift axises. | _not_defined_ | +| `SPACEMOUSE_USE_TILT_AXIS` | Uses the tilt axes for movement rather than the shift axes. | _not_defined_ | -By default, not all of the axises are utilized. If you would like to use more of them, you can do so by using this custom function, which translates the data from the SpaceMouse Module to the pointing device report. +By default, not all of the axes are utilized. If you would like to use more of them, you can do so by using this custom function, which translates the data from the SpaceMouse Module to the pointing device report. ```c -void spacemouse_module_handle_axises(spacemouse_data_t *spacemouse_data, report_mouse_t* mouse_report) { +void spacemouse_module_handle_axes(spacemouse_data_t *spacemouse_data, report_mouse_t* mouse_report) { mouse_report->x = CONSTRAIN_HID_XY(spacemouse_data->x); mouse_report->y = CONSTRAIN_HID_XY(spacemouse_data->y); mouse_report->h = CONSTRAIN_HID(spacemouse_data->b); diff --git a/quantum/pointing_device/pointing_device_drivers.c b/quantum/pointing_device/pointing_device_drivers.c index a84c3d35d8b..992a1336e60 100644 --- a/quantum/pointing_device/pointing_device_drivers.c +++ b/quantum/pointing_device/pointing_device_drivers.c @@ -496,7 +496,7 @@ const pointing_device_driver_t pointing_device_driver = { static bool spacemouse_present = false; -__attribute__((weak)) void spacemouse_module_handle_axises(spacemouse_data_t* spacemouse_data, report_mouse_t* mouse_report) { +__attribute__((weak)) void spacemouse_module_handle_axes(spacemouse_data_t* spacemouse_data, report_mouse_t* mouse_report) { # ifdef SPACEMOUSE_USE_TILT_AXIS mouse_report->x = CONSTRAIN_HID_XY(spacemouse_data->tilt_x); mouse_report->y = CONSTRAIN_HID_XY(spacemouse_data->tilt_y); @@ -513,7 +513,7 @@ static report_mouse_t spacemouse_get_report(report_mouse_t mouse_report) { if (data.x || data.y || data.z || data.twist || data.tilt_x || data.tilt_y) { pd_dprintf("Raw ] X: %d, Y: %d, Z: %d, twist: %d, tilt X: %d, tilt Y: %d\n", data.x, data.y, data.z, data.twist, data.tilt_x, data.tilt_y); } - spacemouse_module_handle_axises(&data, &mouse_report); + spacemouse_module_handle_axes(&data, &mouse_report); } return mouse_report; } From d422ba4f38ece8d032e64605b4642f637b5aac05 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Tue, 21 Nov 2023 03:43:30 -0800 Subject: [PATCH 09/10] rejigger file locations --- drivers/sensors/spacemouse_module.c | 21 +++++++++++++++++++++ drivers/sensors/spacemouse_module.h | 26 -------------------------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/drivers/sensors/spacemouse_module.c b/drivers/sensors/spacemouse_module.c index 800793dd858..3726cac021c 100644 --- a/drivers/sensors/spacemouse_module.c +++ b/drivers/sensors/spacemouse_module.c @@ -7,8 +7,29 @@ // datasheet available at https://3dconnexion.com/cn/wp-content/uploads/2020/02/HW-Spec-3DX-700039_Rev001_serial.pdf +// Datasheet UART settings specify: +// - 38400 baud +// - 8 data bits +// - 1 stop bit +// - no parity +// - 100/s data rate + +#define SPACEMOUSE_BAUD_RATE 38400 + +#define SPACEMOUSE_AXIS_COUNT 6 #define SPACEMOUSE_INPUT_OFFSET (8192) +#define SPACEMOUSE_LENGTH_DATA (2 * SPACEMOUSE_AXIS_COUNT) + +enum spacemouse_commands { + SPACEMOUSE_CMD_REQUEST_DATA = 0xAC, + SPACEMOUSE_CMD_SET_ZERO_POSITION = 0xAD, + SPACEMOUSE_CMD_AUTO_DATA_ON = 0xAE, + SPACEMOUSE_CMD_AUTO_DATA_OFF = 0xAF, + SPACEMOUSE_CMD_END = 0x8D, + SPACEMOUSE_DATA_REQUEST_START = 0x96, +}; + bool spacemouse_send_command(uint8_t cmd) { uart_write(cmd); uint8_t buf[2]; diff --git a/drivers/sensors/spacemouse_module.h b/drivers/sensors/spacemouse_module.h index 205818851d5..c99cba5cd0b 100644 --- a/drivers/sensors/spacemouse_module.h +++ b/drivers/sensors/spacemouse_module.h @@ -6,32 +6,6 @@ #include #include -// Datasheet UART settings specify: -// - 38400 baud -// - 8 data bits -// - 1 stop bit -// - no parity -// - 100/s data rate - -#define SPACEMOUSE_BAUD_RATE 38400 - -#define SPACEMOUSE_AXIS_COUNT 6 - -#define SPACEMOUSE_LENGTH_HEADER 1 -#define SPACEMOUSE_LENGTH_DATA (2 * SPACEMOUSE_AXIS_COUNT) -#define SPACEMOUSE_LENGTH_CHECKSUM 2 -#define SPACEMOUSE_LENGTH_FOOTER 1 -#define SPACEMOUSE_LENGTH_PACKET (SPACEMOUSE_LENGTH_HEADER + SPACEMOUSE_LENGTH_DATA + SPACEMOUSE_LENGTH_CHECKSUM + SPACEMOUSE_LENGTH_FOOTER) - -enum spacemouse_commands { - SPACEMOUSE_CMD_REQUEST_DATA = 0xAC, - SPACEMOUSE_CMD_SET_ZERO_POSITION = 0xAD, - SPACEMOUSE_CMD_AUTO_DATA_ON = 0xAE, - SPACEMOUSE_CMD_AUTO_DATA_OFF = 0xAF, - SPACEMOUSE_CMD_END = 0x8D, - SPACEMOUSE_DATA_REQUEST_START = 0x96, -}; - typedef struct { int16_t x; int16_t y; From ca6caebd3f6533f41b225498436329f1094099f2 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Tue, 21 Nov 2023 03:57:55 -0800 Subject: [PATCH 10/10] Cleanup comments and commits --- drivers/sensors/spacemouse_module.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/sensors/spacemouse_module.c b/drivers/sensors/spacemouse_module.c index 3726cac021c..13e1e2f02f9 100644 --- a/drivers/sensors/spacemouse_module.c +++ b/drivers/sensors/spacemouse_module.c @@ -7,19 +7,18 @@ // datasheet available at https://3dconnexion.com/cn/wp-content/uploads/2020/02/HW-Spec-3DX-700039_Rev001_serial.pdf -// Datasheet UART settings specify: -// - 38400 baud -// - 8 data bits -// - 1 stop bit -// - no parity -// - 100/s data rate +/* Datasheet UART settings specify: + * baud rate: 38400 + * data bits: 8 + * parity: none + * stop bits: 1 + * data rate: max 100/s + */ #define SPACEMOUSE_BAUD_RATE 38400 - #define SPACEMOUSE_AXIS_COUNT 6 -#define SPACEMOUSE_INPUT_OFFSET (8192) - #define SPACEMOUSE_LENGTH_DATA (2 * SPACEMOUSE_AXIS_COUNT) +#define SPACEMOUSE_INPUT_OFFSET (8192) enum spacemouse_commands { SPACEMOUSE_CMD_REQUEST_DATA = 0xAC, @@ -49,9 +48,8 @@ bool spacemouse_cmd_set_zero_position(void) { /** * @brief Starts automatic transmission of data, at 30ms invervals - * Automatic data transmission happens at 30 ms intervals, but device can be polled at 100/s or 10ms intervals - * Since 10ms is what pointing device polling defaults to, we don't need need the stream command, but - * it is here for completeness, in case somebody wants to implement it elsewhere. + * Automatic data transmission happens at 30 ms intervals, we don't need need the stream command, + * but it is here for completeness, in case somebody wants to implement it elsewhere. * * @return true command ran successfully * @return false command failed