aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common_features.mk5
-rw-r--r--docs/_summary.md1
-rw-r--r--docs/feature_digitizer.md35
-rw-r--r--keyboards/handwired/onekey/keymaps/digitizer/keymap.c38
-rw-r--r--keyboards/handwired/onekey/keymaps/digitizer/rules.mk1
-rw-r--r--quantum/digitizer.c34
-rw-r--r--quantum/digitizer.h41
-rw-r--r--tmk_core/common.mk13
-rw-r--r--tmk_core/common/host.c19
-rw-r--r--tmk_core/common/host_driver.h2
-rw-r--r--tmk_core/common/keyboard.c7
-rw-r--r--tmk_core/common/report.h14
-rw-r--r--tmk_core/protocol/chibios/main.c1
-rw-r--r--tmk_core/protocol/chibios/usb_main.c28
-rw-r--r--tmk_core/protocol/lufa/lufa.c26
-rw-r--r--tmk_core/protocol/usb_descriptor.c101
-rw-r--r--tmk_core/protocol/usb_descriptor.h27
-rw-r--r--tmk_core/protocol/vusb/vusb.c48
18 files changed, 435 insertions, 6 deletions
diff --git a/common_features.mk b/common_features.mk
index e442222ea..493aab635 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -695,6 +695,11 @@ ifeq ($(strip $(JOYSTICK_ENABLE)), digital)
695 OPT_DEFS += -DDIGITAL_JOYSTICK_ENABLE 695 OPT_DEFS += -DDIGITAL_JOYSTICK_ENABLE
696endif 696endif
697 697
698DIGITIZER_ENABLE ?= no
699ifneq ($(strip $(DIGITIZER_ENABLE)), no)
700 SRC += $(QUANTUM_DIR)/digitizer.c
701endif
702
698USBPD_ENABLE ?= no 703USBPD_ENABLE ?= no
699VALID_USBPD_DRIVER_TYPES = custom vendor 704VALID_USBPD_DRIVER_TYPES = custom vendor
700USBPD_DRIVER ?= vendor 705USBPD_DRIVER ?= vendor
diff --git a/docs/_summary.md b/docs/_summary.md
index 48115cef4..2f6309e41 100644
--- a/docs/_summary.md
+++ b/docs/_summary.md
@@ -108,6 +108,7 @@
108 * [Bluetooth](feature_bluetooth.md) 108 * [Bluetooth](feature_bluetooth.md)
109 * [Bootmagic Lite](feature_bootmagic.md) 109 * [Bootmagic Lite](feature_bootmagic.md)
110 * [Custom Matrix](custom_matrix.md) 110 * [Custom Matrix](custom_matrix.md)
111 * [Digitizer](feature_digitizer.md)
111 * [DIP Switch](feature_dip_switch.md) 112 * [DIP Switch](feature_dip_switch.md)
112 * [Encoders](feature_encoders.md) 113 * [Encoders](feature_encoders.md)
113 * [Haptic Feedback](feature_haptic_feedback.md) 114 * [Haptic Feedback](feature_haptic_feedback.md)
diff --git a/docs/feature_digitizer.md b/docs/feature_digitizer.md
new file mode 100644
index 000000000..9b6aeddba
--- /dev/null
+++ b/docs/feature_digitizer.md
@@ -0,0 +1,35 @@
1## Digitizer
2
3The digitizer HID interface allows setting the mouse cursor position at absolute coordinates, unlike the Pointing Device feature that applies relative displacements.
4
5To enable the digitizer interface, add the following line to your rules.mk:
6
7```makefile
8DIGITIZER_ENABLE = yes
9```
10
11In order to change the mouse cursor position from your keymap.c file, include the digitizer header :
12
13```c
14#include "digitizer.h"
15```
16
17This gives you access to the `digitizer` structure which members allow you to change the cursor position.
18
19The coordinates are normalized, meaning there value must be set between 0 and 1. For the `x` coordinate, the value `0` is the leftmost position, whereas the value `1` is the rightmost position.
20For the `y` coordinate, `0` is at the top and `1` at the bottom.
21
22Here is an example setting the cursor in the middle of the screen:
23
24```c
25digitizer_t digitizer;
26digitizer.x = 0.5;
27digitizer.y = 0.5;
28digitizer.tipswitch = 0;
29digitizer.inrange = 1;
30digitizer_set_report(digitizer);
31```
32
33The `tipswitch` member triggers what equates to a click when set to `1`. The `inrange` member is required for the change in coordinates to be taken. It can then be set to `0` in a new report to signal the end of the digitizer interaction, but it is not strictly required.
34
35Once all members are set to the desired value, the `status` member needs its bitmask `DZ_UPDATED` to be set so the report is sent during the next main loop iteration.
diff --git a/keyboards/handwired/onekey/keymaps/digitizer/keymap.c b/keyboards/handwired/onekey/keymaps/digitizer/keymap.c
new file mode 100644
index 000000000..6b304e86f
--- /dev/null
+++ b/keyboards/handwired/onekey/keymaps/digitizer/keymap.c
@@ -0,0 +1,38 @@
1 /* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include QMK_KEYBOARD_H
17
18#include "digitizer.h"
19
20#include "math.h"
21
22const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {LAYOUT_ortho_1x1(KC_A)};
23
24uint32_t timer = 0;
25
26void matrix_scan_user() {
27 if (timer_elapsed32(timer) < 200) {
28 return;
29 }
30
31 timer = timer_read32();
32 digitizer_t digitizer;
33 digitizer.x = 0.5 - 0.2 * cos(timer_read() / 250. / 6.28);
34 digitizer.y = 0.5 - 0.2 * sin(timer_read() / 250. / 6.28);
35 digitizer.tipswitch = 0;
36 digitizer.inrange = 1;
37 digitizer_set_report(digitizer);
38}
diff --git a/keyboards/handwired/onekey/keymaps/digitizer/rules.mk b/keyboards/handwired/onekey/keymaps/digitizer/rules.mk
new file mode 100644
index 000000000..ea9f9bd9a
--- /dev/null
+++ b/keyboards/handwired/onekey/keymaps/digitizer/rules.mk
@@ -0,0 +1 @@
DIGITIZER_ENABLE = yes \ No newline at end of file
diff --git a/quantum/digitizer.c b/quantum/digitizer.c
new file mode 100644
index 000000000..e29986742
--- /dev/null
+++ b/quantum/digitizer.c
@@ -0,0 +1,34 @@
1/* Copyright 2021
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "digitizer.h"
17
18digitizer_t digitizerReport = {.tipswitch = 0, .inrange = 0, .id = 0, .x = 0, .y = 0, .status = DZ_INITIALIZED};
19
20__attribute__((weak)) void digitizer_send(void) {
21 if (digitizerReport.status & DZ_UPDATED) {
22 host_digitizer_send(&digitizerReport);
23 digitizerReport.status &= ~DZ_UPDATED;
24 }
25}
26
27__attribute__((weak)) void digitizer_task(void) { digitizer_send(); }
28
29digitizer_t digitizer_get_report(void) { return digitizerReport; }
30
31void digitizer_set_report(digitizer_t newDigitizerReport) {
32 digitizerReport = newDigitizerReport;
33 digitizerReport.status |= DZ_UPDATED;
34} \ No newline at end of file
diff --git a/quantum/digitizer.h b/quantum/digitizer.h
new file mode 100644
index 000000000..cef551567
--- /dev/null
+++ b/quantum/digitizer.h
@@ -0,0 +1,41 @@
1/* Copyright 2021
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#include "quantum.h"
19
20#include <stdint.h>
21
22enum digitizer_status { DZ_INITIALIZED = 1, DZ_UPDATED = 2 };
23
24typedef struct {
25 int8_t tipswitch;
26 int8_t inrange;
27 uint8_t id;
28 float x;
29 float y;
30 uint8_t status : 2;
31} digitizer_t;
32
33extern digitizer_t digitizer;
34
35digitizer_t digitizer_get_report(void);
36
37void digitizer_set_report(digitizer_t newDigitizerReport);
38
39void digitizer_task(void);
40
41void host_digitizer_send(digitizer_t *digitizer);
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 6c8cf6935..fa907b47b 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -106,6 +106,19 @@ ifeq ($(strip $(NO_USB_STARTUP_CHECK)), yes)
106 TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK 106 TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK
107endif 107endif
108 108
109ifeq ($(strip $(DIGITIZER_SHARED_EP)), yes)
110 TMK_COMMON_DEFS += -DDIGITIZER_SHARED_EP
111 SHARED_EP_ENABLE = yes
112endif
113
114ifeq ($(strip $(DIGITIZER_ENABLE)), yes)
115 TMK_COMMON_DEFS += -DDIGITIZER_ENABLE
116 ifeq ($(strip $(SHARED_EP_ENABLE)), yes)
117 TMK_COMMON_DEFS += -DDIGITIZER_SHARED_EP
118 SHARED_EP_ENABLE = yes
119 endif
120endif
121
109ifeq ($(strip $(SHARED_EP_ENABLE)), yes) 122ifeq ($(strip $(SHARED_EP_ENABLE)), yes)
110 TMK_COMMON_DEFS += -DSHARED_EP_ENABLE 123 TMK_COMMON_DEFS += -DSHARED_EP_ENABLE
111endif 124endif
diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c
index a8b391e89..f0c396b18 100644
--- a/tmk_core/common/host.c
+++ b/tmk_core/common/host.c
@@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
22#include "host.h" 22#include "host.h"
23#include "util.h" 23#include "util.h"
24#include "debug.h" 24#include "debug.h"
25#include "digitizer.h"
25 26
26#ifdef NKRO_ENABLE 27#ifdef NKRO_ENABLE
27# include "keycode_config.h" 28# include "keycode_config.h"
@@ -103,6 +104,24 @@ void host_consumer_send(uint16_t report) {
103 (*driver->send_consumer)(report); 104 (*driver->send_consumer)(report);
104} 105}
105 106
107void host_digitizer_send(digitizer_t *digitizer) {
108 if (!driver) return;
109
110 report_digitizer_t report = {
111#ifdef DIGITIZER_SHARED_EP
112 .report_id = REPORT_ID_DIGITIZER,
113#endif
114 .tip = digitizer->tipswitch & 0x1,
115 .inrange = digitizer->inrange & 0x1,
116 .x = (uint16_t)(digitizer->x * 0x7FFF),
117 .y = (uint16_t)(digitizer->y * 0x7FFF),
118 };
119
120 send_digitizer(&report);
121}
122
123__attribute__((weak)) void send_digitizer(report_digitizer_t *report) {}
124
106uint16_t host_last_system_report(void) { return last_system_report; } 125uint16_t host_last_system_report(void) { return last_system_report; }
107 126
108uint16_t host_last_consumer_report(void) { return last_consumer_report; } 127uint16_t host_last_consumer_report(void) { return last_consumer_report; }
diff --git a/tmk_core/common/host_driver.h b/tmk_core/common/host_driver.h
index f34a22053..2aebca043 100644
--- a/tmk_core/common/host_driver.h
+++ b/tmk_core/common/host_driver.h
@@ -30,3 +30,5 @@ typedef struct {
30 void (*send_system)(uint16_t); 30 void (*send_system)(uint16_t);
31 void (*send_consumer)(uint16_t); 31 void (*send_consumer)(uint16_t);
32} host_driver_t; 32} host_driver_t;
33
34void send_digitizer(report_digitizer_t *report); \ No newline at end of file
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index 28fa97bc8..fcc51973f 100644
--- a/tmk_core/common/keyboard.c
+++ b/tmk_core/common/keyboard.c
@@ -106,6 +106,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
106#if defined(CRC_ENABLE) 106#if defined(CRC_ENABLE)
107# include "crc.h" 107# include "crc.h"
108#endif 108#endif
109#ifdef DIGITIZER_ENABLE
110# include "digitizer.h"
111#endif
109 112
110static uint32_t last_input_modification_time = 0; 113static uint32_t last_input_modification_time = 0;
111uint32_t last_input_activity_time(void) { return last_input_modification_time; } 114uint32_t last_input_activity_time(void) { return last_input_modification_time; }
@@ -537,6 +540,10 @@ MATRIX_LOOP_END:
537 joystick_task(); 540 joystick_task();
538#endif 541#endif
539 542
543#ifdef DIGITIZER_ENABLE
544 digitizer_task();
545#endif
546
540 // update LED 547 // update LED
541 if (led_status != host_keyboard_leds()) { 548 if (led_status != host_keyboard_leds()) {
542 led_status = host_keyboard_leds(); 549 led_status = host_keyboard_leds();
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index db6370657..f2223e806 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -30,7 +30,8 @@ enum hid_report_ids {
30 REPORT_ID_SYSTEM, 30 REPORT_ID_SYSTEM,
31 REPORT_ID_CONSUMER, 31 REPORT_ID_CONSUMER,
32 REPORT_ID_NKRO, 32 REPORT_ID_NKRO,
33 REPORT_ID_JOYSTICK 33 REPORT_ID_JOYSTICK,
34 REPORT_ID_DIGITIZER
34}; 35};
35 36
36/* Mouse buttons */ 37/* Mouse buttons */
@@ -206,6 +207,17 @@ typedef struct {
206} __attribute__((packed)) report_mouse_t; 207} __attribute__((packed)) report_mouse_t;
207 208
208typedef struct { 209typedef struct {
210#ifdef DIGITIZER_SHARED_EP
211 uint8_t report_id;
212#endif
213 uint8_t tip : 1;
214 uint8_t inrange : 1;
215 uint8_t pad2 : 6;
216 uint16_t x;
217 uint16_t y;
218} __attribute__((packed)) report_digitizer_t;
219
220typedef struct {
209#if JOYSTICK_AXES_COUNT > 0 221#if JOYSTICK_AXES_COUNT > 0
210# if JOYSTICK_AXES_RESOLUTION > 8 222# if JOYSTICK_AXES_RESOLUTION > 8
211 int16_t axes[JOYSTICK_AXES_COUNT]; 223 int16_t axes[JOYSTICK_AXES_COUNT];
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index 199741594..e41d6ff19 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -65,6 +65,7 @@ void send_keyboard(report_keyboard_t *report);
65void send_mouse(report_mouse_t *report); 65void send_mouse(report_mouse_t *report);
66void send_system(uint16_t data); 66void send_system(uint16_t data);
67void send_consumer(uint16_t data); 67void send_consumer(uint16_t data);
68void send_digitizer(report_digitizer_t *report);
68 69
69/* host struct */ 70/* host struct */
70host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer}; 71host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index e5edd74dc..cc282e6a9 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -316,6 +316,9 @@ typedef struct {
316#ifdef JOYSTICK_ENABLE 316#ifdef JOYSTICK_ENABLE
317 usb_driver_config_t joystick_driver; 317 usb_driver_config_t joystick_driver;
318#endif 318#endif
319#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
320 usb_driver_config_t digitizer_driver;
321#endif
319 }; 322 };
320 usb_driver_config_t array[0]; 323 usb_driver_config_t array[0];
321 }; 324 };
@@ -360,6 +363,14 @@ static usb_driver_configs_t drivers = {
360# define JOYSTICK_OUT_MODE USB_EP_MODE_TYPE_BULK 363# define JOYSTICK_OUT_MODE USB_EP_MODE_TYPE_BULK
361 .joystick_driver = QMK_USB_DRIVER_CONFIG(JOYSTICK, 0, false), 364 .joystick_driver = QMK_USB_DRIVER_CONFIG(JOYSTICK, 0, false),
362#endif 365#endif
366
367#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
368# define DIGITIZER_IN_CAPACITY 4
369# define DIGITIZER_OUT_CAPACITY 4
370# define DIGITIZER_IN_MODE USB_EP_MODE_TYPE_BULK
371# define DIGITIZER_OUT_MODE USB_EP_MODE_TYPE_BULK
372 .digitizer_driver = QMK_USB_DRIVER_CONFIG(DIGITIZER, 0, false),
373#endif
363}; 374};
364 375
365#define NUM_USB_DRIVERS (sizeof(drivers) / sizeof(usb_driver_config_t)) 376#define NUM_USB_DRIVERS (sizeof(drivers) / sizeof(usb_driver_config_t))
@@ -930,6 +941,23 @@ void send_consumer(uint16_t data) {
930#endif 941#endif
931} 942}
932 943
944void send_digitizer(report_digitizer_t *report) {
945#ifdef DIGITIZER_ENABLE
946# ifdef DIGITIZER_SHARED_EP
947 osalSysLock();
948 if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
949 osalSysUnlock();
950 return;
951 }
952
953 usbStartTransmitI(&USB_DRIVER, DIGITIZER_IN_EPNUM, (uint8_t *)report, sizeof(report_digitizer_t));
954 osalSysUnlock();
955# else
956 chnWrite(&drivers.digitizer_driver.driver, (uint8_t *)report, sizeof(report_digitizer_t));
957# endif
958#endif
959}
960
933/* --------------------------------------------------------- 961/* ---------------------------------------------------------
934 * Console functions 962 * Console functions
935 * --------------------------------------------------------- 963 * ---------------------------------------------------------
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 4ac079e16..8ddb8b1c4 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -142,9 +142,7 @@ static void send_keyboard(report_keyboard_t *report);
142static void send_mouse(report_mouse_t *report); 142static void send_mouse(report_mouse_t *report);
143static void send_system(uint16_t data); 143static void send_system(uint16_t data);
144static void send_consumer(uint16_t data); 144static void send_consumer(uint16_t data);
145host_driver_t lufa_driver = { 145host_driver_t lufa_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
146 keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer,
147};
148 146
149#ifdef VIRTSER_ENABLE 147#ifdef VIRTSER_ENABLE
150// clang-format off 148// clang-format off
@@ -525,6 +523,11 @@ void EVENT_USB_Device_ConfigurationChanged(void) {
525 /* Setup joystick endpoint */ 523 /* Setup joystick endpoint */
526 ConfigSuccess &= Endpoint_ConfigureEndpoint((JOYSTICK_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, JOYSTICK_EPSIZE, 1); 524 ConfigSuccess &= Endpoint_ConfigureEndpoint((JOYSTICK_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, JOYSTICK_EPSIZE, 1);
527#endif 525#endif
526
527#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
528 /* Setup digitizer endpoint */
529 ConfigSuccess &= Endpoint_ConfigureEndpoint((DIGITIZER_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, DIGITIZER_EPSIZE, 1);
530#endif
528} 531}
529 532
530/* FIXME: Expose this table in the docs somehow 533/* FIXME: Expose this table in the docs somehow
@@ -983,6 +986,23 @@ void virtser_send(const uint8_t byte) {
983} 986}
984#endif 987#endif
985 988
989void send_digitizer(report_digitizer_t *report) {
990#ifdef DIGITIZER_ENABLE
991 uint8_t timeout = 255;
992
993 if (USB_DeviceState != DEVICE_STATE_Configured) return;
994
995 Endpoint_SelectEndpoint(DIGITIZER_IN_EPNUM);
996
997 /* Check if write ready for a polling interval around 10ms */
998 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
999 if (!Endpoint_IsReadWriteAllowed()) return;
1000
1001 Endpoint_Write_Stream_LE(report, sizeof(report_digitizer_t), NULL);
1002 Endpoint_ClearIN();
1003#endif
1004}
1005
986/******************************************************************************* 1006/*******************************************************************************
987 * main 1007 * main
988 ******************************************************************************/ 1008 ******************************************************************************/
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
index 7a4a79031..099964ae5 100644
--- a/tmk_core/protocol/usb_descriptor.c
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -158,6 +158,53 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
158# endif 158# endif
159#endif 159#endif
160 160
161#ifdef DIGITIZER_ENABLE
162# ifndef DIGITIZER_SHARED_EP
163const USB_Descriptor_HIDReport_Datatype_t PROGMEM DigitizerReport[] = {
164# elif !defined(SHARED_REPORT_STARTED)
165const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
166# define SHARED_REPORT_STARTED
167# endif
168 HID_RI_USAGE_PAGE(8, 0x0D), // Digitizers
169 HID_RI_USAGE(8, 0x01), // Digitizer
170 HID_RI_COLLECTION(8, 0x01), // Application
171# ifdef DIGITIZER_SHARED_EP
172 HID_RI_REPORT_ID(8, REPORT_ID_DIGITIZER),
173# endif
174 HID_RI_USAGE(8, 0x20), // Stylus
175 HID_RI_COLLECTION(8, 0x00), // Physical
176 // Tip Switch (1 bit)
177 HID_RI_USAGE(8, 0x42), // Tip Switch
178 HID_RI_LOGICAL_MINIMUM(8, 0x00),
179 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
180 HID_RI_REPORT_SIZE(8, 0x01),
181 HID_RI_REPORT_COUNT(8, 0x01),
182 HID_RI_INPUT(8, HID_IOF_VARIABLE),
183 // In Range (1 bit)
184 HID_RI_USAGE(8, 0x32), // In Range
185 HID_RI_INPUT(8, HID_IOF_VARIABLE),
186 // Padding (6 bits)
187 HID_RI_REPORT_COUNT(8, 0x06),
188 HID_RI_INPUT(8, HID_IOF_CONSTANT | HID_IOF_VARIABLE),
189
190 // X/Y Position (4 bytes)
191 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
192 HID_RI_LOGICAL_MAXIMUM(16, 0x7FFF),
193 HID_RI_REPORT_SIZE(8, 0x10),
194 HID_RI_REPORT_COUNT(8, 0x01),
195 HID_RI_UNIT(8, 0x33), // Inch, English Linear
196 HID_RI_UNIT_EXPONENT(8, 0x0E), // -2
197 HID_RI_USAGE(8, 0x30), // X
198 HID_RI_INPUT(8, HID_IOF_VARIABLE),
199 HID_RI_USAGE(8, 0x31), // Y
200 HID_RI_INPUT(8, HID_IOF_VARIABLE),
201 HID_RI_END_COLLECTION(0),
202 HID_RI_END_COLLECTION(0),
203# ifndef DIGITIZER_SHARED_EP
204};
205# endif
206#endif
207
161#if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED) 208#if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
162const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { 209const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
163#endif 210#endif
@@ -227,6 +274,7 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
227 HID_RI_OUTPUT(8, HID_IOF_CONSTANT), 274 HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
228 HID_RI_END_COLLECTION(0), 275 HID_RI_END_COLLECTION(0),
229#endif 276#endif
277
230#ifdef SHARED_EP_ENABLE 278#ifdef SHARED_EP_ENABLE
231}; 279};
232#endif 280#endif
@@ -921,6 +969,46 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = {
921 .PollingIntervalMS = USB_POLLING_INTERVAL_MS 969 .PollingIntervalMS = USB_POLLING_INTERVAL_MS
922 } 970 }
923#endif 971#endif
972
973#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
974 /*
975 * Digitizer
976 */
977 .Digitizer_Interface = {
978 .Header = {
979 .Size = sizeof(USB_Descriptor_Interface_t),
980 .Type = DTYPE_Interface
981 },
982 .InterfaceNumber = DIGITIZER_INTERFACE,
983 .AlternateSetting = 0x00,
984 .TotalEndpoints = 1,
985 .Class = HID_CSCP_HIDClass,
986 .SubClass = HID_CSCP_NonBootSubclass,
987 .Protocol = HID_CSCP_NonBootProtocol,
988 .InterfaceStrIndex = NO_DESCRIPTOR
989 },
990 .Digitizer_HID = {
991 .Header = {
992 .Size = sizeof(USB_HID_Descriptor_HID_t),
993 .Type = HID_DTYPE_HID
994 },
995 .HIDSpec = VERSION_BCD(1, 1, 1),
996 .CountryCode = 0x00,
997 .TotalReportDescriptors = 1,
998 .HIDReportType = HID_DTYPE_Report,
999 .HIDReportLength = sizeof(DigitizerReport)
1000 },
1001 .Digitizer_INEndpoint = {
1002 .Header = {
1003 .Size = sizeof(USB_Descriptor_Endpoint_t),
1004 .Type = DTYPE_Endpoint
1005 },
1006 .EndpointAddress = (ENDPOINT_DIR_IN | DIGITIZER_IN_EPNUM),
1007 .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
1008 .EndpointSize = DIGITIZER_EPSIZE,
1009 .PollingIntervalMS = USB_POLLING_INTERVAL_MS
1010 },
1011#endif
924}; 1012};
925 1013
926/* 1014/*
@@ -1059,6 +1147,13 @@ uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const
1059 Size = sizeof(USB_HID_Descriptor_HID_t); 1147 Size = sizeof(USB_HID_Descriptor_HID_t);
1060 break; 1148 break;
1061#endif 1149#endif
1150#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
1151 case DIGITIZER_INTERFACE:
1152 Address = &ConfigurationDescriptor.Digitizer_HID;
1153 Size = sizeof(USB_HID_Descriptor_HID_t);
1154
1155 break;
1156#endif
1062 } 1157 }
1063 1158
1064 break; 1159 break;
@@ -1109,6 +1204,12 @@ uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const
1109 Size = sizeof(JoystickReport); 1204 Size = sizeof(JoystickReport);
1110 break; 1205 break;
1111#endif 1206#endif
1207#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
1208 case DIGITIZER_INTERFACE:
1209 Address = &DigitizerReport;
1210 Size = sizeof(DigitizerReport);
1211 break;
1212#endif
1112 } 1213 }
1113 1214
1114 break; 1215 break;
diff --git a/tmk_core/protocol/usb_descriptor.h b/tmk_core/protocol/usb_descriptor.h
index 867e549b4..0f0c78f66 100644
--- a/tmk_core/protocol/usb_descriptor.h
+++ b/tmk_core/protocol/usb_descriptor.h
@@ -135,6 +135,13 @@ typedef struct {
135 USB_HID_Descriptor_HID_t Joystick_HID; 135 USB_HID_Descriptor_HID_t Joystick_HID;
136 USB_Descriptor_Endpoint_t Joystick_INEndpoint; 136 USB_Descriptor_Endpoint_t Joystick_INEndpoint;
137#endif 137#endif
138
139#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
140 // Digitizer HID Interface
141 USB_Descriptor_Interface_t Digitizer_Interface;
142 USB_HID_Descriptor_HID_t Digitizer_HID;
143 USB_Descriptor_Endpoint_t Digitizer_INEndpoint;
144#endif
138} USB_Descriptor_Configuration_t; 145} USB_Descriptor_Configuration_t;
139 146
140/* 147/*
@@ -180,6 +187,10 @@ enum usb_interfaces {
180#if defined(JOYSTICK_ENABLE) 187#if defined(JOYSTICK_ENABLE)
181 JOYSTICK_INTERFACE, 188 JOYSTICK_INTERFACE,
182#endif 189#endif
190
191#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
192 DIGITIZER_INTERFACE,
193#endif
183 TOTAL_INTERFACES 194 TOTAL_INTERFACES
184}; 195};
185 196
@@ -226,7 +237,7 @@ enum usb_endpoints {
226# if STM32_USB_USE_OTG1 237# if STM32_USB_USE_OTG1
227# define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM 238# define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM
228# else 239# else
229 CONSOLE_OUT_EPNUM = NEXT_EPNUM, 240 CONSOLE_OUT_EPNUM = NEXT_EPNUM,
230# endif 241# endif
231# else 242# else
232# define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM 243# define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM
@@ -259,6 +270,19 @@ enum usb_endpoints {
259 JOYSTICK_OUT_EPNUM = NEXT_EPNUM, 270 JOYSTICK_OUT_EPNUM = NEXT_EPNUM,
260# endif 271# endif
261#endif 272#endif
273
274#ifdef DIGITIZER_ENABLE
275# if !defined(DIGITIZER_SHARED_EP)
276 DIGITIZER_IN_EPNUM = NEXT_EPNUM,
277# if STM32_USB_USE_OTG1
278 DIGITIZER_OUT_EPNUM = DIGITIZER_IN_EPNUM,
279# else
280 DIGITIZER_OUT_EPNUM = NEXT_EPNUM,
281# endif
282# else
283# define DIGITIZER_IN_EPNUM SHARED_IN_EPNUM
284# endif
285#endif
262}; 286};
263 287
264#ifdef PROTOCOL_LUFA 288#ifdef PROTOCOL_LUFA
@@ -284,5 +308,6 @@ enum usb_endpoints {
284#define CDC_NOTIFICATION_EPSIZE 8 308#define CDC_NOTIFICATION_EPSIZE 8
285#define CDC_EPSIZE 16 309#define CDC_EPSIZE 16
286#define JOYSTICK_EPSIZE 8 310#define JOYSTICK_EPSIZE 8
311#define DIGITIZER_EPSIZE 8
287 312
288uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const void** const DescriptorAddress); 313uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const void** const DescriptorAddress);
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index 98cebf601..485b20c90 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -292,6 +292,14 @@ static void send_consumer(uint16_t data) {
292#endif 292#endif
293} 293}
294 294
295void send_digitizer(report_digitizer_t *report) {
296#ifdef DIGITIZER_ENABLE
297 if (usbInterruptIsReadyShared()) {
298 usbSetInterruptShared((void *)report, sizeof(report_digitizer_t));
299 }
300#endif
301}
302
295/*------------------------------------------------------------------* 303/*------------------------------------------------------------------*
296 * Request from host * 304 * Request from host *
297 *------------------------------------------------------------------*/ 305 *------------------------------------------------------------------*/
@@ -510,8 +518,46 @@ const PROGMEM uchar shared_hid_report[] = {
510 0x95, 0x01, // Report Count (1) 518 0x95, 0x01, // Report Count (1)
511 0x75, 0x10, // Report Size (16) 519 0x75, 0x10, // Report Size (16)
512 0x81, 0x00, // Input (Data, Array, Absolute) 520 0x81, 0x00, // Input (Data, Array, Absolute)
513 0xC0 // End Collection 521 0xC0, // End Collection
522#endif
523
524#ifdef DIGITIZER_ENABLE
525 // Digitizer report descriptor
526 0x05, 0x0D, // Usage Page (Digitizers)
527 0x09, 0x01, // Usage (Digitizer)
528 0xA1, 0x01, // Collection (Application)
529 0x85, REPORT_ID_DIGITIZER, // Report ID
530 0x09, 0x22, // Usage (Finger)
531 0xA1, 0x00, // Collection (Physical)
532 // Tip Switch (1 bit)
533 0x09, 0x42, // Usage (Tip Switch)
534 0x15, 0x00, // Logical Minimum
535 0x25, 0x01, // Logical Maximum
536 0x95, 0x01, // Report Count (1)
537 0x75, 0x01, // Report Size (16)
538 0x81, 0x02, // Input (Data, Variable, Absolute)
539 // In Range (1 bit)
540 0x09, 0x32, // Usage (In Range)
541 0x81, 0x02, // Input (Data, Variable, Absolute)
542 // Padding (6 bits)
543 0x95, 0x06, // Report Count (6)
544 0x81, 0x03, // Input (Constant)
545
546 // X/Y Position (4 bytes)
547 0x05, 0x01, // Usage Page (Generic Desktop)
548 0x26, 0xFF, 0x7F, // Logical Maximum (32767)
549 0x95, 0x01, // Report Count (1)
550 0x75, 0x10, // Report Size (16)
551 0x65, 0x33, // Unit (Inch, English Linear)
552 0x55, 0x0E, // Unit Exponent (-2)
553 0x09, 0x30, // Usage (X)
554 0x81, 0x02, // Input (Data, Variable, Absolute)
555 0x09, 0x31, // Usage (Y)
556 0x81, 0x02, // Input (Data, Variable, Absolute)
557 0xC0, // End Collection
558 0xC0 // End Collection
514#endif 559#endif
560
515#ifdef SHARED_EP_ENABLE 561#ifdef SHARED_EP_ENABLE
516}; 562};
517#endif 563#endif