Skip to content

Commit 1829d47

Browse files
committed
chore(trackpad-ptp): some code refactors / cleanup
1 parent 4d87747 commit 1829d47

File tree

3 files changed

+113
-132
lines changed

3 files changed

+113
-132
lines changed

drivers/sensors/navigator_trackpad_common.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,22 @@
7070
# define TRACKPAD_PHYSICAL_HEIGHT 157 * TRACkbPAD_DIMENSIONS_FACTOR // 1.57 inches (40mm actual size)
7171
#endif
7272

73-
// Logical coordinate range from Cirque Gen6 sensor in PTP mode (raw, no scaling)
74-
// Actual usable range is approximately 280-2018, rounded to 2048
73+
// Logical coordinate range for HID descriptor (what we report to the OS)
7574
#define TRACKPAD_LOGICAL_MAX 2048
7675

76+
// Sensor coordinate range (measured empirically from Cirque Gen6)
77+
// These define the actual usable touch area of the sensor
78+
#define SENSOR_X_MIN 281
79+
#define SENSOR_X_MAX 2018
80+
#define SENSOR_Y_MIN 276
81+
#define SENSOR_Y_MAX 2018
82+
83+
// Fixed-point multipliers for coordinate scaling (Q16 format)
84+
// Precomputed as: (TRACKPAD_LOGICAL_MAX << 16) / (SENSOR_MAX - SENSOR_MIN)
85+
// This avoids expensive division at runtime
86+
#define SENSOR_SCALE_X_MULT 77176 // 2048 * 65536 / (2018 - 281)
87+
#define SENSOR_SCALE_Y_MULT 76957 // 2048 * 65536 / (2018 - 276)
88+
7789
// Common finger structure (used by both mouse and PTP modes)
7890
typedef struct {
7991
uint8_t tip;

drivers/sensors/navigator_trackpad_ptp.c

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,21 @@ extern void send_trackpad(report_digitizer_t *report);
2121
// Defined in usb_main.c
2222
extern uint8_t get_trackpad_input_mode(void);
2323

24+
// Input mode values (set by host via HID feature report)
2425
#define TRACKPAD_INPUT_MODE_MOUSE 0
2526
#define TRACKPAD_INPUT_MODE_PTP 3
2627

28+
// PTP report structure constants
29+
#define PTP_REPORT_ID 0x01
30+
#define PTP_REPORT_SIZE 16
31+
#define PTP_FINGER0_OFFSET 1
32+
#define PTP_FINGER1_OFFSET 7
33+
#define PTP_SCAN_TIME_OFFSET 13
34+
#define PTP_COUNT_BUTTONS_OFFSET 15
35+
36+
// Button masks
37+
#define BUTTON_PRIMARY 0x01
38+
2739
// Fallback mouse configuration
2840
#ifndef TRACKPAD_MOUSE_SENSITIVITY
2941
# define TRACKPAD_MOUSE_SENSITIVITY 1.0f
@@ -38,6 +50,11 @@ extern uint8_t get_trackpad_input_mode(void);
3850
# define TRACKPAD_TAP_MOVE_THRESHOLD 30 // Maximum movement during tap (in sensor units, ~1.5% of range)
3951
#endif
4052

53+
// Per-frame movement threshold squared for tap invalidation (~4 sensor units)
54+
#ifndef TRACKPAD_TAP_FRAME_MOVE_THRESHOLD_SQ
55+
# define TRACKPAD_TAP_FRAME_MOVE_THRESHOLD_SQ 16
56+
#endif
57+
4158
#if defined(NAVIGATOR_TRACKPAD_PTP_MODE)
4259

4360
// Build a finger's 6 bytes into the report buffer
@@ -101,8 +118,8 @@ static void process_fallback_mouse(cgen6_report_t *sensor_report, bool finger_do
101118
uint8_t buttons = 0;
102119

103120
// Handle physical button (from sensor)
104-
if (sensor_report->buttons & 0x01) {
105-
buttons |= 0x01;
121+
if (sensor_report->buttons & BUTTON_PRIMARY) {
122+
buttons |= BUTTON_PRIMARY;
106123
}
107124

108125
// Handle finger down transition (start tracking)
@@ -132,7 +149,7 @@ static void process_fallback_mouse(cgen6_report_t *sensor_report, bool finger_do
132149
mouse_state.tap_pending = false;
133150
}
134151
// Also invalidate if any single-frame movement is significant
135-
if (raw_dx * raw_dx + raw_dy * raw_dy > 16) { // ~4 units of movement in one frame
152+
if (raw_dx * raw_dx + raw_dy * raw_dy > TRACKPAD_TAP_FRAME_MOVE_THRESHOLD_SQ) {
136153
mouse_state.tap_pending = false;
137154
}
138155
}
@@ -166,7 +183,7 @@ static void process_fallback_mouse(cgen6_report_t *sensor_report, bool finger_do
166183

167184
// Handle tap-generated click (button press then release after hold time)
168185
if (mouse_state.click_active) {
169-
buttons |= 0x01;
186+
buttons |= BUTTON_PRIMARY;
170187
// Release after holding for TRACKPAD_TAP_CLICK_HOLD_MS
171188
if (timer_elapsed32(mouse_state.click_release_time) >= TRACKPAD_TAP_CLICK_HOLD_MS) {
172189
mouse_state.click_active = false;
@@ -183,19 +200,18 @@ static void process_fallback_mouse(cgen6_report_t *sensor_report, bool finger_do
183200
}
184201
}
185202

186-
// Sensor coordinate range (measured empirically)
187-
#define SENSOR_X_MIN 281
188-
#define SENSOR_X_MAX 2018
189-
#define SENSOR_Y_MIN 276
190-
#define SENSOR_Y_MAX 2018
191-
192-
// Scale sensor coordinates to logical range (0 - TRACKPAD_LOGICAL_MAX)
193-
static uint16_t scale_coordinate(uint16_t raw, uint16_t sensor_min, uint16_t sensor_max) {
194-
// Clamp to sensor range
195-
if (raw < sensor_min) raw = sensor_min;
196-
if (raw > sensor_max) raw = sensor_max;
197-
// Scale to logical range
198-
return (uint32_t)(raw - sensor_min) * TRACKPAD_LOGICAL_MAX / (sensor_max - sensor_min);
203+
// Scale sensor X coordinate to logical range using fixed-point multiplication
204+
static inline uint16_t scale_x(uint16_t raw) {
205+
if (raw < SENSOR_X_MIN) raw = SENSOR_X_MIN;
206+
if (raw > SENSOR_X_MAX) raw = SENSOR_X_MAX;
207+
return ((uint32_t)(raw - SENSOR_X_MIN) * SENSOR_SCALE_X_MULT) >> 16;
208+
}
209+
210+
// Scale sensor Y coordinate to logical range using fixed-point multiplication
211+
static inline uint16_t scale_y(uint16_t raw) {
212+
if (raw < SENSOR_Y_MIN) raw = SENSOR_Y_MIN;
213+
if (raw > SENSOR_Y_MAX) raw = SENSOR_Y_MAX;
214+
return ((uint32_t)(raw - SENSOR_Y_MIN) * SENSOR_SCALE_Y_MULT) >> 16;
199215
}
200216

201217
// PTP task function - synchronous polling with timer-based throttling
@@ -240,43 +256,41 @@ static bool navigator_trackpad_ptp_task(void) {
240256
bool finger0_contact = finger0_tip || prev_finger0_tip;
241257
bool finger1_contact = finger1_tip || prev_finger1_tip;
242258

243-
uint8_t buttons = sensor_report.buttons & 0x01;
259+
uint8_t buttons = sensor_report.buttons & BUTTON_PRIMARY;
244260
bool button_changed = (buttons != prev_buttons);
245261

246262
// Contact count includes fingers that are touching OR lifting off this frame
247263
uint8_t contact_count = (finger0_contact ? 1 : 0) + (finger1_contact ? 1 : 0);
248264

249265
// Build report from sensor data using explicit byte manipulation
250-
// Report format (16 bytes): [report_id] [finger0: 6 bytes] [finger1: 6 bytes] [scan_time: 2 bytes] [count+buttons: 1 byte]
251-
uint8_t report[16] = {0};
266+
uint8_t report[PTP_REPORT_SIZE] = {0};
252267

253-
// Byte 0: Report ID
254-
report[0] = 0x01;
268+
report[0] = PTP_REPORT_ID;
255269

256-
// Bytes 1-6: Finger 0 (include if touching or lifting off)
270+
// Finger 0 (include if touching or lifting off)
257271
if (finger0_contact) {
258-
build_finger_bytes(&report[1], 0,
259-
scale_coordinate(sensor_report.fingers[0].x, SENSOR_X_MIN, SENSOR_X_MAX),
260-
scale_coordinate(sensor_report.fingers[0].y, SENSOR_Y_MIN, SENSOR_Y_MAX),
272+
build_finger_bytes(&report[PTP_FINGER0_OFFSET], 0,
273+
scale_x(sensor_report.fingers[0].x),
274+
scale_y(sensor_report.fingers[0].y),
261275
finger0_tip,
262276
sensor_report.fingers[0].confidence);
263277
}
264278

265-
// Bytes 7-12: Finger 1 (include if touching or lifting off)
279+
// Finger 1 (include if touching or lifting off)
266280
if (finger1_contact) {
267-
build_finger_bytes(&report[7], 1,
268-
scale_coordinate(sensor_report.fingers[1].x, SENSOR_X_MIN, SENSOR_X_MAX),
269-
scale_coordinate(sensor_report.fingers[1].y, SENSOR_Y_MIN, SENSOR_Y_MAX),
281+
build_finger_bytes(&report[PTP_FINGER1_OFFSET], 1,
282+
scale_x(sensor_report.fingers[1].x),
283+
scale_y(sensor_report.fingers[1].y),
270284
finger1_tip,
271285
sensor_report.fingers[1].confidence);
272286
}
273287

274-
// Bytes 13-14: Scan time
275-
report[13] = sensor_report.scan_time & 0xFF;
276-
report[14] = (sensor_report.scan_time >> 8) & 0xFF;
288+
// Scan time (2 bytes, little-endian)
289+
report[PTP_SCAN_TIME_OFFSET] = sensor_report.scan_time & 0xFF;
290+
report[PTP_SCAN_TIME_OFFSET + 1] = (sensor_report.scan_time >> 8) & 0xFF;
277291

278-
// Byte 15: Contact count (bits 0-3) + buttons (bits 4-6)
279-
report[15] = (contact_count & 0x0F) | ((buttons & 0x01) << 4);
292+
// Contact count (bits 0-3) + buttons (bits 4-6)
293+
report[PTP_COUNT_BUTTONS_OFFSET] = (contact_count & 0x0F) | ((buttons & BUTTON_PRIMARY) << 4);
280294

281295
// Get current input mode
282296
uint8_t input_mode = get_trackpad_input_mode();

tmk_core/protocol/usb_descriptor.c

Lines changed: 50 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,53 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
388388
// Include trackpad dimensions
389389
#include "drivers/sensors/navigator_trackpad_common.h"
390390

391+
// PTP finger contact collection macro - reduces duplication for multi-finger support
392+
// Each finger reports: confidence, tip switch, contact ID, X position, Y position
393+
#define PTP_FINGER_COLLECTION \
394+
HID_RI_USAGE(8, 0x22), /* Finger */ \
395+
HID_RI_COLLECTION(8, 0x00), /* Physical */ \
396+
HID_RI_PUSH(0), \
397+
HID_RI_LOGICAL_MINIMUM(8, 0x00), \
398+
HID_RI_LOGICAL_MAXIMUM(8, 0x01), \
399+
/* Tip Switch, Confidence (2 bits) */ \
400+
HID_RI_USAGE(8, 0x47), /* Confidence */ \
401+
HID_RI_USAGE(8, 0x42), /* Tip Switch */ \
402+
HID_RI_REPORT_COUNT(8, 0x02), \
403+
HID_RI_REPORT_SIZE(8, 0x01), \
404+
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \
405+
/* Padding (6 bits) */ \
406+
HID_RI_REPORT_SIZE(8, 0x01), \
407+
HID_RI_REPORT_COUNT(8, 0x06), \
408+
HID_RI_INPUT(8, HID_IOF_CONSTANT), \
409+
/* Contact identifier (3 bits) */ \
410+
HID_RI_REPORT_COUNT(8, 0x01), \
411+
HID_RI_REPORT_SIZE(8, 0x03), \
412+
HID_RI_LOGICAL_MAXIMUM(8, 0x05), \
413+
HID_RI_USAGE(8, 0x51), /* Contact identifier */ \
414+
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \
415+
/* Padding (5 bits) */ \
416+
HID_RI_REPORT_SIZE(8, 0x01), \
417+
HID_RI_REPORT_COUNT(8, 0x05), \
418+
HID_RI_INPUT(8, HID_IOF_CONSTANT), \
419+
/* X/Y Position (4 bytes) */ \
420+
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ \
421+
HID_RI_LOGICAL_MINIMUM(8, 0x0), \
422+
HID_RI_LOGICAL_MAXIMUM(16, TRACKPAD_LOGICAL_MAX), \
423+
HID_RI_REPORT_SIZE(8, 16), \
424+
HID_RI_UNIT_EXPONENT(8, 0x0E), /* -2 */ \
425+
HID_RI_UNIT(8, 0x11), /* CM, English Linear */ \
426+
HID_RI_USAGE(8, 0x30), /* X */ \
427+
HID_RI_PHYSICAL_MINIMUM(8, 0x0), \
428+
HID_RI_PHYSICAL_MAXIMUM(16, (TRACKPAD_PHYSICAL_WIDTH)), \
429+
HID_RI_REPORT_COUNT(8, 0x01), \
430+
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \
431+
HID_RI_LOGICAL_MAXIMUM(16, TRACKPAD_LOGICAL_MAX), \
432+
HID_RI_PHYSICAL_MAXIMUM(16, (TRACKPAD_PHYSICAL_HEIGHT)), \
433+
HID_RI_USAGE(8, 0x31), /* Y */ \
434+
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \
435+
HID_RI_POP(0), \
436+
HID_RI_END_COLLECTION(0)
437+
391438
// Digitizer/Touchpad HID Descriptor
392439
const USB_Descriptor_HIDReport_Datatype_t PROGMEM PrecisionTrackpadReport[] = {
393440
HID_RI_USAGE_PAGE(8, 0x0D), // Digitizers
@@ -397,103 +444,11 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM PrecisionTrackpadReport[] = {
397444
HID_RI_REPORT_ID(8, 0x01),
398445

399446
// Contact 1
400-
HID_RI_USAGE(8, 0x22), // Finger
401-
HID_RI_COLLECTION(8, 0x00), // Physical
402-
HID_RI_PUSH(0),
403-
HID_RI_LOGICAL_MINIMUM(8, 0x00),
404-
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
405-
// Tip Switch, Confidence (2 bits)
406-
HID_RI_USAGE(8, 0x47), // Confidence
407-
HID_RI_USAGE(8, 0x42), // Tip Switch
408-
HID_RI_REPORT_COUNT(8, 0x02),
409-
HID_RI_REPORT_SIZE(8, 0x01),
410-
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
411-
412-
// Padding (6 bits)
413-
HID_RI_REPORT_SIZE(8, 0x01),
414-
HID_RI_REPORT_COUNT(8, 0x06),
415-
HID_RI_INPUT(8, HID_IOF_CONSTANT),
416-
417-
// Contact identifier (3 bits)
418-
HID_RI_REPORT_COUNT(8, 0x01),
419-
HID_RI_REPORT_SIZE(8, 0x03),
420-
HID_RI_LOGICAL_MAXIMUM(8, 0x05),
421-
HID_RI_USAGE(8, 0x51), // Contact identifier
422-
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
423-
424-
// Padding (5 bits)
425-
HID_RI_REPORT_SIZE(8, 0x01),
426-
HID_RI_REPORT_COUNT(8, 0x05),
427-
HID_RI_INPUT(8, HID_IOF_CONSTANT),
428-
429-
// X/Y Position (4 bytes)
430-
HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
431-
HID_RI_LOGICAL_MINIMUM(8, 0x0),
432-
HID_RI_LOGICAL_MAXIMUM(16, TRACKPAD_LOGICAL_MAX),
433-
HID_RI_REPORT_SIZE(8, 16),
434-
HID_RI_UNIT_EXPONENT(8, 0x0E), // -2
435-
HID_RI_UNIT(8, 0x11), // CM, English Linear
436-
HID_RI_USAGE(8, 0x30), // X
437-
HID_RI_PHYSICAL_MINIMUM(8, 0x0),
438-
HID_RI_PHYSICAL_MAXIMUM(16, (TRACKPAD_PHYSICAL_WIDTH)),
439-
HID_RI_REPORT_COUNT(8, 0x01),
440-
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
441-
HID_RI_LOGICAL_MAXIMUM(16, TRACKPAD_LOGICAL_MAX),
442-
HID_RI_PHYSICAL_MAXIMUM(16, (TRACKPAD_PHYSICAL_HEIGHT)),
443-
HID_RI_USAGE(8, 0x31), // Y
444-
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
445-
HID_RI_POP(0),
446-
HID_RI_END_COLLECTION(0),
447+
PTP_FINGER_COLLECTION,
447448

448449
// Contact 2
449-
HID_RI_USAGE_PAGE(8, 0x0D), // Digitizers
450-
HID_RI_USAGE(8, 0x22), // Finger
451-
HID_RI_COLLECTION(8, 0x00), // Physical
452-
HID_RI_PUSH(0),
453-
HID_RI_LOGICAL_MINIMUM(8, 0x00),
454-
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
455-
// Tip Switch, Confidence (2 bits)
456-
HID_RI_USAGE(8, 0x47), // Confidence
457-
HID_RI_USAGE(8, 0x42), // Tip Switch
458-
HID_RI_REPORT_COUNT(8, 0x02),
459-
HID_RI_REPORT_SIZE(8, 0x01),
460-
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
461-
462-
// Padding (6 bits)
463-
HID_RI_REPORT_SIZE(8, 0x01),
464-
HID_RI_REPORT_COUNT(8, 0x06),
465-
HID_RI_INPUT(8, HID_IOF_CONSTANT),
466-
467-
// Contact identifier (3 bits)
468-
HID_RI_REPORT_COUNT(8, 0x01),
469-
HID_RI_REPORT_SIZE(8, 0x03),
470-
HID_RI_LOGICAL_MAXIMUM(8, 0x05),
471-
HID_RI_USAGE(8, 0x51), // Contact identifier
472-
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
473-
474-
// Padding (5 bits)
475-
HID_RI_REPORT_SIZE(8, 0x01),
476-
HID_RI_REPORT_COUNT(8, 0x05),
477-
HID_RI_INPUT(8, HID_IOF_CONSTANT),
478-
479-
// X/Y Position (4 bytes)
480-
HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
481-
HID_RI_LOGICAL_MINIMUM(8, 0x0),
482-
HID_RI_LOGICAL_MAXIMUM(16, TRACKPAD_LOGICAL_MAX),
483-
HID_RI_REPORT_SIZE(8, 16),
484-
HID_RI_UNIT_EXPONENT(8, 0x0E), // -2
485-
HID_RI_UNIT(8, 0x11), // CM, English Linear
486-
HID_RI_USAGE(8, 0x30), // X
487-
HID_RI_PHYSICAL_MINIMUM(8, 0x0),
488-
HID_RI_PHYSICAL_MAXIMUM(16, (TRACKPAD_PHYSICAL_WIDTH)),
489-
HID_RI_REPORT_COUNT(8, 0x01),
490-
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
491-
HID_RI_LOGICAL_MAXIMUM(16, TRACKPAD_LOGICAL_MAX),
492-
HID_RI_PHYSICAL_MAXIMUM(16, (TRACKPAD_PHYSICAL_HEIGHT)),
493-
HID_RI_USAGE(8, 0x31), // Y
494-
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
495-
HID_RI_POP(0),
496-
HID_RI_END_COLLECTION(0),
450+
HID_RI_USAGE_PAGE(8, 0x0D), // Digitizers (reset usage page after Generic Desktop)
451+
PTP_FINGER_COLLECTION,
497452

498453
// Scan Time and Contact Count
499454
HID_RI_PUSH(0),

0 commit comments

Comments
 (0)