forked from mirrors/qmk_userspace
		
	Digitizer HID interface : absolute coordinates for mouse cursor (#12851)
* Add digitizer HID interface for setting the mouse cursor position at absolute screen coordinates. Tested on Pro Micro, Proton C and Blackpill. * Update docs/feature_digitizer.md Co-authored-by: Ryan <fauxpark@gmail.com> * Update tmk_core/protocol/usb_descriptor.c Co-authored-by: Ryan <fauxpark@gmail.com> * Add missing copyrights Add V-USB support * Add support for digitizer dedicated endpoint for lufa and chibios. Fix formatting issues Move digitizer_task definition to the feature's base implementation file * Run cformat on modified files * Change digitizer report usage to Digitizer instead of Pen to avoid pointer disappearing on Windows. * Update tmk_core/protocol/vusb/vusb.c Co-authored-by: Ryan <fauxpark@gmail.com> * Run cformat from docker image * Remove send_digitizer from host_driver_t and instead rely on the declaration being the interface to the implementation in each HW-specific usb implementation. * Fix build : send_digitizer shouldn't be static in vusb and add weak-linkage implementation for tests without usb implementation * Change digitizer user interface to match pointing device's * Update documentation with new API Co-authored-by: a-chol <nothing@none.com> Co-authored-by: Ryan <fauxpark@gmail.com>
This commit is contained in:
		
					parent
					
						
							
								7794e97f32
							
						
					
				
			
			
				commit
				
					
						75b49aff56
					
				
			
		
					 18 changed files with 435 additions and 6 deletions
				
			
		| 
						 | 
					@ -695,6 +695,11 @@ ifeq ($(strip $(JOYSTICK_ENABLE)), digital)
 | 
				
			||||||
    OPT_DEFS += -DDIGITAL_JOYSTICK_ENABLE
 | 
					    OPT_DEFS += -DDIGITAL_JOYSTICK_ENABLE
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DIGITIZER_ENABLE ?= no
 | 
				
			||||||
 | 
					ifneq ($(strip $(DIGITIZER_ENABLE)), no)
 | 
				
			||||||
 | 
					    SRC += $(QUANTUM_DIR)/digitizer.c
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
USBPD_ENABLE ?= no
 | 
					USBPD_ENABLE ?= no
 | 
				
			||||||
VALID_USBPD_DRIVER_TYPES = custom vendor
 | 
					VALID_USBPD_DRIVER_TYPES = custom vendor
 | 
				
			||||||
USBPD_DRIVER ?= vendor
 | 
					USBPD_DRIVER ?= vendor
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,6 +108,7 @@
 | 
				
			||||||
    * [Bluetooth](feature_bluetooth.md)
 | 
					    * [Bluetooth](feature_bluetooth.md)
 | 
				
			||||||
    * [Bootmagic Lite](feature_bootmagic.md)
 | 
					    * [Bootmagic Lite](feature_bootmagic.md)
 | 
				
			||||||
    * [Custom Matrix](custom_matrix.md)
 | 
					    * [Custom Matrix](custom_matrix.md)
 | 
				
			||||||
 | 
					    * [Digitizer](feature_digitizer.md)
 | 
				
			||||||
    * [DIP Switch](feature_dip_switch.md)
 | 
					    * [DIP Switch](feature_dip_switch.md)
 | 
				
			||||||
    * [Encoders](feature_encoders.md)
 | 
					    * [Encoders](feature_encoders.md)
 | 
				
			||||||
    * [Haptic Feedback](feature_haptic_feedback.md)
 | 
					    * [Haptic Feedback](feature_haptic_feedback.md)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										35
									
								
								docs/feature_digitizer.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								docs/feature_digitizer.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					## Digitizer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The digitizer HID interface allows setting the mouse cursor position at absolute coordinates, unlike the Pointing Device feature that applies relative displacements.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To enable the digitizer interface, add the following line to your rules.mk: 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```makefile
 | 
				
			||||||
 | 
					DIGITIZER_ENABLE = yes
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In order to change the mouse cursor position from your keymap.c file, include the digitizer header : 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```c
 | 
				
			||||||
 | 
					#include "digitizer.h"
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This gives you access to the `digitizer` structure which members allow you to change the cursor position.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The 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.
 | 
				
			||||||
 | 
					For the `y` coordinate, `0` is at the top and `1` at the bottom.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Here is an example setting the cursor in the middle of the screen:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```c
 | 
				
			||||||
 | 
					digitizer_t digitizer;
 | 
				
			||||||
 | 
					digitizer.x = 0.5;
 | 
				
			||||||
 | 
					digitizer.y = 0.5;
 | 
				
			||||||
 | 
					digitizer.tipswitch = 0;
 | 
				
			||||||
 | 
					digitizer.inrange = 1;
 | 
				
			||||||
 | 
					digitizer_set_report(digitizer);
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Once 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.
 | 
				
			||||||
							
								
								
									
										38
									
								
								keyboards/handwired/onekey/keymaps/digitizer/keymap.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								keyboards/handwired/onekey/keymaps/digitizer/keymap.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					 /* Copyright 2021 QMK 
 | 
				
			||||||
 | 
					  * 
 | 
				
			||||||
 | 
					  * This program is free software: you can redistribute it and/or modify 
 | 
				
			||||||
 | 
					  * it under the terms of the GNU General Public License as published by 
 | 
				
			||||||
 | 
					  * the Free Software Foundation, either version 2 of the License, or 
 | 
				
			||||||
 | 
					  * (at your option) any later version. 
 | 
				
			||||||
 | 
					  * 
 | 
				
			||||||
 | 
					  * This program is distributed in the hope that it will be useful, 
 | 
				
			||||||
 | 
					  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 | 
				
			||||||
 | 
					  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 | 
				
			||||||
 | 
					  * GNU General Public License for more details. 
 | 
				
			||||||
 | 
					  * 
 | 
				
			||||||
 | 
					  * You should have received a copy of the GNU General Public License 
 | 
				
			||||||
 | 
					  * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 | 
				
			||||||
 | 
					  */ 
 | 
				
			||||||
 | 
					#include QMK_KEYBOARD_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "digitizer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "math.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {LAYOUT_ortho_1x1(KC_A)};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t timer = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void matrix_scan_user() {
 | 
				
			||||||
 | 
					    if (timer_elapsed32(timer) < 200) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    timer               = timer_read32();
 | 
				
			||||||
 | 
					    digitizer_t digitizer;
 | 
				
			||||||
 | 
					    digitizer.x         = 0.5 - 0.2 * cos(timer_read() / 250. / 6.28);
 | 
				
			||||||
 | 
					    digitizer.y         = 0.5 - 0.2 * sin(timer_read() / 250. / 6.28);
 | 
				
			||||||
 | 
					    digitizer.tipswitch = 0;
 | 
				
			||||||
 | 
					    digitizer.inrange   = 1;
 | 
				
			||||||
 | 
					    digitizer_set_report(digitizer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1
									
								
								keyboards/handwired/onekey/keymaps/digitizer/rules.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								keyboards/handwired/onekey/keymaps/digitizer/rules.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					DIGITIZER_ENABLE = yes
 | 
				
			||||||
							
								
								
									
										34
									
								
								quantum/digitizer.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								quantum/digitizer.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,34 @@
 | 
				
			||||||
 | 
					/* Copyright 2021
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 2 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "digitizer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					digitizer_t digitizerReport = {.tipswitch = 0, .inrange = 0, .id = 0, .x = 0, .y = 0, .status = DZ_INITIALIZED};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__attribute__((weak)) void digitizer_send(void) {
 | 
				
			||||||
 | 
					    if (digitizerReport.status & DZ_UPDATED) {
 | 
				
			||||||
 | 
					        host_digitizer_send(&digitizerReport);
 | 
				
			||||||
 | 
					        digitizerReport.status &= ~DZ_UPDATED;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__attribute__((weak)) void digitizer_task(void) { digitizer_send(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					digitizer_t digitizer_get_report(void) { return digitizerReport; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void digitizer_set_report(digitizer_t newDigitizerReport) {
 | 
				
			||||||
 | 
					    digitizerReport = newDigitizerReport;
 | 
				
			||||||
 | 
					    digitizerReport.status |= DZ_UPDATED;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										41
									
								
								quantum/digitizer.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								quantum/digitizer.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,41 @@
 | 
				
			||||||
 | 
					/* Copyright 2021
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 2 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "quantum.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum digitizer_status { DZ_INITIALIZED = 1, DZ_UPDATED = 2 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    int8_t  tipswitch;
 | 
				
			||||||
 | 
					    int8_t  inrange;
 | 
				
			||||||
 | 
					    uint8_t id;
 | 
				
			||||||
 | 
					    float   x;
 | 
				
			||||||
 | 
					    float   y;
 | 
				
			||||||
 | 
					    uint8_t status : 2;
 | 
				
			||||||
 | 
					} digitizer_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern digitizer_t digitizer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					digitizer_t digitizer_get_report(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void digitizer_set_report(digitizer_t newDigitizerReport);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void digitizer_task(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void host_digitizer_send(digitizer_t *digitizer);
 | 
				
			||||||
| 
						 | 
					@ -106,6 +106,19 @@ ifeq ($(strip $(NO_USB_STARTUP_CHECK)), yes)
 | 
				
			||||||
    TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK
 | 
					    TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifeq ($(strip $(DIGITIZER_SHARED_EP)), yes)
 | 
				
			||||||
 | 
					    TMK_COMMON_DEFS += -DDIGITIZER_SHARED_EP
 | 
				
			||||||
 | 
					    SHARED_EP_ENABLE = yes
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifeq ($(strip $(DIGITIZER_ENABLE)), yes)
 | 
				
			||||||
 | 
					    TMK_COMMON_DEFS += -DDIGITIZER_ENABLE
 | 
				
			||||||
 | 
					    ifeq ($(strip $(SHARED_EP_ENABLE)), yes)
 | 
				
			||||||
 | 
					        TMK_COMMON_DEFS += -DDIGITIZER_SHARED_EP
 | 
				
			||||||
 | 
					        SHARED_EP_ENABLE = yes
 | 
				
			||||||
 | 
					    endif
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(strip $(SHARED_EP_ENABLE)), yes)
 | 
					ifeq ($(strip $(SHARED_EP_ENABLE)), yes)
 | 
				
			||||||
    TMK_COMMON_DEFS += -DSHARED_EP_ENABLE
 | 
					    TMK_COMMON_DEFS += -DSHARED_EP_ENABLE
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
#include "host.h"
 | 
					#include "host.h"
 | 
				
			||||||
#include "util.h"
 | 
					#include "util.h"
 | 
				
			||||||
#include "debug.h"
 | 
					#include "debug.h"
 | 
				
			||||||
 | 
					#include "digitizer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef NKRO_ENABLE
 | 
					#ifdef NKRO_ENABLE
 | 
				
			||||||
#    include "keycode_config.h"
 | 
					#    include "keycode_config.h"
 | 
				
			||||||
| 
						 | 
					@ -103,6 +104,24 @@ void host_consumer_send(uint16_t report) {
 | 
				
			||||||
    (*driver->send_consumer)(report);
 | 
					    (*driver->send_consumer)(report);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void host_digitizer_send(digitizer_t *digitizer) {
 | 
				
			||||||
 | 
					    if (!driver) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    report_digitizer_t report = {
 | 
				
			||||||
 | 
					#ifdef DIGITIZER_SHARED_EP
 | 
				
			||||||
 | 
					        .report_id = REPORT_ID_DIGITIZER,
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        .tip     = digitizer->tipswitch & 0x1,
 | 
				
			||||||
 | 
					        .inrange = digitizer->inrange & 0x1,
 | 
				
			||||||
 | 
					        .x       = (uint16_t)(digitizer->x * 0x7FFF),
 | 
				
			||||||
 | 
					        .y       = (uint16_t)(digitizer->y * 0x7FFF),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    send_digitizer(&report);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__attribute__((weak)) void send_digitizer(report_digitizer_t *report) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t host_last_system_report(void) { return last_system_report; }
 | 
					uint16_t host_last_system_report(void) { return last_system_report; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t host_last_consumer_report(void) { return last_consumer_report; }
 | 
					uint16_t host_last_consumer_report(void) { return last_consumer_report; }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,3 +30,5 @@ typedef struct {
 | 
				
			||||||
    void (*send_system)(uint16_t);
 | 
					    void (*send_system)(uint16_t);
 | 
				
			||||||
    void (*send_consumer)(uint16_t);
 | 
					    void (*send_consumer)(uint16_t);
 | 
				
			||||||
} host_driver_t;
 | 
					} host_driver_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void send_digitizer(report_digitizer_t *report);
 | 
				
			||||||
| 
						 | 
					@ -106,6 +106,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
#if defined(CRC_ENABLE)
 | 
					#if defined(CRC_ENABLE)
 | 
				
			||||||
#    include "crc.h"
 | 
					#    include "crc.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef DIGITIZER_ENABLE
 | 
				
			||||||
 | 
					#    include "digitizer.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint32_t last_input_modification_time = 0;
 | 
					static uint32_t last_input_modification_time = 0;
 | 
				
			||||||
uint32_t        last_input_activity_time(void) { return last_input_modification_time; }
 | 
					uint32_t        last_input_activity_time(void) { return last_input_modification_time; }
 | 
				
			||||||
| 
						 | 
					@ -537,6 +540,10 @@ MATRIX_LOOP_END:
 | 
				
			||||||
    joystick_task();
 | 
					    joystick_task();
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DIGITIZER_ENABLE
 | 
				
			||||||
 | 
					    digitizer_task();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // update LED
 | 
					    // update LED
 | 
				
			||||||
    if (led_status != host_keyboard_leds()) {
 | 
					    if (led_status != host_keyboard_leds()) {
 | 
				
			||||||
        led_status = host_keyboard_leds();
 | 
					        led_status = host_keyboard_leds();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,8 @@ enum hid_report_ids {
 | 
				
			||||||
    REPORT_ID_SYSTEM,
 | 
					    REPORT_ID_SYSTEM,
 | 
				
			||||||
    REPORT_ID_CONSUMER,
 | 
					    REPORT_ID_CONSUMER,
 | 
				
			||||||
    REPORT_ID_NKRO,
 | 
					    REPORT_ID_NKRO,
 | 
				
			||||||
    REPORT_ID_JOYSTICK
 | 
					    REPORT_ID_JOYSTICK,
 | 
				
			||||||
 | 
					    REPORT_ID_DIGITIZER
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Mouse buttons */
 | 
					/* Mouse buttons */
 | 
				
			||||||
| 
						 | 
					@ -205,6 +206,17 @@ typedef struct {
 | 
				
			||||||
    int8_t  h;
 | 
					    int8_t  h;
 | 
				
			||||||
} __attribute__((packed)) report_mouse_t;
 | 
					} __attribute__((packed)) report_mouse_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					#ifdef DIGITIZER_SHARED_EP
 | 
				
			||||||
 | 
					    uint8_t report_id;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    uint8_t  tip : 1;
 | 
				
			||||||
 | 
					    uint8_t  inrange : 1;
 | 
				
			||||||
 | 
					    uint8_t  pad2 : 6;
 | 
				
			||||||
 | 
					    uint16_t x;
 | 
				
			||||||
 | 
					    uint16_t y;
 | 
				
			||||||
 | 
					} __attribute__((packed)) report_digitizer_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
#if JOYSTICK_AXES_COUNT > 0
 | 
					#if JOYSTICK_AXES_COUNT > 0
 | 
				
			||||||
#    if JOYSTICK_AXES_RESOLUTION > 8
 | 
					#    if JOYSTICK_AXES_RESOLUTION > 8
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,6 +65,7 @@ void    send_keyboard(report_keyboard_t *report);
 | 
				
			||||||
void    send_mouse(report_mouse_t *report);
 | 
					void    send_mouse(report_mouse_t *report);
 | 
				
			||||||
void    send_system(uint16_t data);
 | 
					void    send_system(uint16_t data);
 | 
				
			||||||
void    send_consumer(uint16_t data);
 | 
					void    send_consumer(uint16_t data);
 | 
				
			||||||
 | 
					void    send_digitizer(report_digitizer_t *report);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* host struct */
 | 
					/* host struct */
 | 
				
			||||||
host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
 | 
					host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -315,6 +315,9 @@ typedef struct {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifdef JOYSTICK_ENABLE
 | 
					#ifdef JOYSTICK_ENABLE
 | 
				
			||||||
            usb_driver_config_t joystick_driver;
 | 
					            usb_driver_config_t joystick_driver;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
 | 
				
			||||||
 | 
					            usb_driver_config_t digitizer_driver;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        usb_driver_config_t array[0];
 | 
					        usb_driver_config_t array[0];
 | 
				
			||||||
| 
						 | 
					@ -360,6 +363,14 @@ static usb_driver_configs_t drivers = {
 | 
				
			||||||
#    define JOYSTICK_OUT_MODE USB_EP_MODE_TYPE_BULK
 | 
					#    define JOYSTICK_OUT_MODE USB_EP_MODE_TYPE_BULK
 | 
				
			||||||
    .joystick_driver = QMK_USB_DRIVER_CONFIG(JOYSTICK, 0, false),
 | 
					    .joystick_driver = QMK_USB_DRIVER_CONFIG(JOYSTICK, 0, false),
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
 | 
				
			||||||
 | 
					#    define DIGITIZER_IN_CAPACITY 4
 | 
				
			||||||
 | 
					#    define DIGITIZER_OUT_CAPACITY 4
 | 
				
			||||||
 | 
					#    define DIGITIZER_IN_MODE USB_EP_MODE_TYPE_BULK
 | 
				
			||||||
 | 
					#    define DIGITIZER_OUT_MODE USB_EP_MODE_TYPE_BULK
 | 
				
			||||||
 | 
					    .digitizer_driver = QMK_USB_DRIVER_CONFIG(DIGITIZER, 0, false),
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NUM_USB_DRIVERS (sizeof(drivers) / sizeof(usb_driver_config_t))
 | 
					#define NUM_USB_DRIVERS (sizeof(drivers) / sizeof(usb_driver_config_t))
 | 
				
			||||||
| 
						 | 
					@ -930,6 +941,23 @@ void send_consumer(uint16_t data) {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void send_digitizer(report_digitizer_t *report) {
 | 
				
			||||||
 | 
					#ifdef DIGITIZER_ENABLE
 | 
				
			||||||
 | 
					#    ifdef DIGITIZER_SHARED_EP
 | 
				
			||||||
 | 
					    osalSysLock();
 | 
				
			||||||
 | 
					    if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
 | 
				
			||||||
 | 
					        osalSysUnlock();
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    usbStartTransmitI(&USB_DRIVER, DIGITIZER_IN_EPNUM, (uint8_t *)report, sizeof(report_digitizer_t));
 | 
				
			||||||
 | 
					    osalSysUnlock();
 | 
				
			||||||
 | 
					#    else
 | 
				
			||||||
 | 
					    chnWrite(&drivers.digitizer_driver.driver, (uint8_t *)report, sizeof(report_digitizer_t));
 | 
				
			||||||
 | 
					#    endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ---------------------------------------------------------
 | 
					/* ---------------------------------------------------------
 | 
				
			||||||
 *                   Console functions
 | 
					 *                   Console functions
 | 
				
			||||||
 * ---------------------------------------------------------
 | 
					 * ---------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,9 +142,7 @@ static void    send_keyboard(report_keyboard_t *report);
 | 
				
			||||||
static void    send_mouse(report_mouse_t *report);
 | 
					static void    send_mouse(report_mouse_t *report);
 | 
				
			||||||
static void    send_system(uint16_t data);
 | 
					static void    send_system(uint16_t data);
 | 
				
			||||||
static void    send_consumer(uint16_t data);
 | 
					static void    send_consumer(uint16_t data);
 | 
				
			||||||
host_driver_t  lufa_driver = {
 | 
					host_driver_t  lufa_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
 | 
				
			||||||
    keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef VIRTSER_ENABLE
 | 
					#ifdef VIRTSER_ENABLE
 | 
				
			||||||
// clang-format off
 | 
					// clang-format off
 | 
				
			||||||
| 
						 | 
					@ -525,6 +523,11 @@ void EVENT_USB_Device_ConfigurationChanged(void) {
 | 
				
			||||||
    /* Setup joystick endpoint */
 | 
					    /* Setup joystick endpoint */
 | 
				
			||||||
    ConfigSuccess &= Endpoint_ConfigureEndpoint((JOYSTICK_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, JOYSTICK_EPSIZE, 1);
 | 
					    ConfigSuccess &= Endpoint_ConfigureEndpoint((JOYSTICK_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, JOYSTICK_EPSIZE, 1);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
 | 
				
			||||||
 | 
					    /* Setup digitizer endpoint */
 | 
				
			||||||
 | 
					    ConfigSuccess &= Endpoint_ConfigureEndpoint((DIGITIZER_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, DIGITIZER_EPSIZE, 1);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* FIXME: Expose this table in the docs somehow
 | 
					/* FIXME: Expose this table in the docs somehow
 | 
				
			||||||
| 
						 | 
					@ -983,6 +986,23 @@ void virtser_send(const uint8_t byte) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void send_digitizer(report_digitizer_t *report) {
 | 
				
			||||||
 | 
					#ifdef DIGITIZER_ENABLE
 | 
				
			||||||
 | 
					    uint8_t timeout = 255;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (USB_DeviceState != DEVICE_STATE_Configured) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Endpoint_SelectEndpoint(DIGITIZER_IN_EPNUM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Check if write ready for a polling interval around 10ms */
 | 
				
			||||||
 | 
					    while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
 | 
				
			||||||
 | 
					    if (!Endpoint_IsReadWriteAllowed()) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Endpoint_Write_Stream_LE(report, sizeof(report_digitizer_t), NULL);
 | 
				
			||||||
 | 
					    Endpoint_ClearIN();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*******************************************************************************
 | 
					/*******************************************************************************
 | 
				
			||||||
 * main
 | 
					 * main
 | 
				
			||||||
 ******************************************************************************/
 | 
					 ******************************************************************************/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -158,6 +158,53 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
 | 
				
			||||||
#    endif
 | 
					#    endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DIGITIZER_ENABLE
 | 
				
			||||||
 | 
					#    ifndef DIGITIZER_SHARED_EP
 | 
				
			||||||
 | 
					const USB_Descriptor_HIDReport_Datatype_t PROGMEM DigitizerReport[] = {
 | 
				
			||||||
 | 
					#    elif !defined(SHARED_REPORT_STARTED)
 | 
				
			||||||
 | 
					const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
 | 
				
			||||||
 | 
					#        define SHARED_REPORT_STARTED
 | 
				
			||||||
 | 
					#    endif
 | 
				
			||||||
 | 
					    HID_RI_USAGE_PAGE(8, 0x0D),      // Digitizers
 | 
				
			||||||
 | 
					    HID_RI_USAGE(8, 0x01),           // Digitizer
 | 
				
			||||||
 | 
					    HID_RI_COLLECTION(8, 0x01),      // Application
 | 
				
			||||||
 | 
					#    ifdef DIGITIZER_SHARED_EP
 | 
				
			||||||
 | 
					        HID_RI_REPORT_ID(8, REPORT_ID_DIGITIZER),
 | 
				
			||||||
 | 
					#    endif
 | 
				
			||||||
 | 
					        HID_RI_USAGE(8, 0x20),       // Stylus
 | 
				
			||||||
 | 
					        HID_RI_COLLECTION(8, 0x00),  // Physical
 | 
				
			||||||
 | 
					            // Tip Switch (1 bit)
 | 
				
			||||||
 | 
					            HID_RI_USAGE(8, 0x42),   // Tip Switch
 | 
				
			||||||
 | 
					            HID_RI_LOGICAL_MINIMUM(8, 0x00),
 | 
				
			||||||
 | 
					            HID_RI_LOGICAL_MAXIMUM(8, 0x01),
 | 
				
			||||||
 | 
					            HID_RI_REPORT_SIZE(8, 0x01),
 | 
				
			||||||
 | 
					            HID_RI_REPORT_COUNT(8, 0x01),
 | 
				
			||||||
 | 
					            HID_RI_INPUT(8, HID_IOF_VARIABLE),
 | 
				
			||||||
 | 
					            // In Range (1 bit)
 | 
				
			||||||
 | 
					            HID_RI_USAGE(8, 0x32),  // In Range
 | 
				
			||||||
 | 
					            HID_RI_INPUT(8, HID_IOF_VARIABLE),
 | 
				
			||||||
 | 
					            // Padding (6 bits)
 | 
				
			||||||
 | 
					            HID_RI_REPORT_COUNT(8, 0x06),
 | 
				
			||||||
 | 
					            HID_RI_INPUT(8, HID_IOF_CONSTANT | HID_IOF_VARIABLE),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // X/Y Position (4 bytes)
 | 
				
			||||||
 | 
					            HID_RI_USAGE_PAGE(8, 0x01),     // Generic Desktop
 | 
				
			||||||
 | 
					            HID_RI_LOGICAL_MAXIMUM(16, 0x7FFF),
 | 
				
			||||||
 | 
					            HID_RI_REPORT_SIZE(8, 0x10),
 | 
				
			||||||
 | 
					            HID_RI_REPORT_COUNT(8, 0x01),
 | 
				
			||||||
 | 
					            HID_RI_UNIT(8, 0x33),           // Inch, English Linear
 | 
				
			||||||
 | 
					            HID_RI_UNIT_EXPONENT(8, 0x0E),  // -2
 | 
				
			||||||
 | 
					            HID_RI_USAGE(8, 0x30),          // X
 | 
				
			||||||
 | 
					            HID_RI_INPUT(8, HID_IOF_VARIABLE),
 | 
				
			||||||
 | 
					            HID_RI_USAGE(8, 0x31),          // Y
 | 
				
			||||||
 | 
					            HID_RI_INPUT(8, HID_IOF_VARIABLE),
 | 
				
			||||||
 | 
					        HID_RI_END_COLLECTION(0),
 | 
				
			||||||
 | 
					    HID_RI_END_COLLECTION(0),
 | 
				
			||||||
 | 
					#    ifndef DIGITIZER_SHARED_EP
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#    endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
 | 
					#if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
 | 
				
			||||||
const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
 | 
					const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -227,6 +274,7 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
 | 
				
			||||||
        HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
 | 
					        HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
 | 
				
			||||||
    HID_RI_END_COLLECTION(0),
 | 
					    HID_RI_END_COLLECTION(0),
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef SHARED_EP_ENABLE
 | 
					#ifdef SHARED_EP_ENABLE
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -921,6 +969,46 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = {
 | 
				
			||||||
        .PollingIntervalMS      = USB_POLLING_INTERVAL_MS
 | 
					        .PollingIntervalMS      = USB_POLLING_INTERVAL_MS
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Digitizer
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    .Digitizer_Interface  = {
 | 
				
			||||||
 | 
					        .Header = {
 | 
				
			||||||
 | 
					            .Size               = sizeof(USB_Descriptor_Interface_t),
 | 
				
			||||||
 | 
					            .Type               = DTYPE_Interface
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        .InterfaceNumber        = DIGITIZER_INTERFACE,
 | 
				
			||||||
 | 
					        .AlternateSetting       = 0x00,
 | 
				
			||||||
 | 
					        .TotalEndpoints         = 1,
 | 
				
			||||||
 | 
					        .Class                  = HID_CSCP_HIDClass,
 | 
				
			||||||
 | 
					        .SubClass               = HID_CSCP_NonBootSubclass,
 | 
				
			||||||
 | 
					        .Protocol               = HID_CSCP_NonBootProtocol,
 | 
				
			||||||
 | 
					        .InterfaceStrIndex      = NO_DESCRIPTOR
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    .Digitizer_HID = {
 | 
				
			||||||
 | 
					        .Header = {
 | 
				
			||||||
 | 
					            .Size               = sizeof(USB_HID_Descriptor_HID_t),
 | 
				
			||||||
 | 
					            .Type               = HID_DTYPE_HID
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        .HIDSpec                = VERSION_BCD(1, 1, 1),
 | 
				
			||||||
 | 
					        .CountryCode            = 0x00,
 | 
				
			||||||
 | 
					        .TotalReportDescriptors = 1,
 | 
				
			||||||
 | 
					        .HIDReportType          = HID_DTYPE_Report,
 | 
				
			||||||
 | 
					        .HIDReportLength        = sizeof(DigitizerReport)
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    .Digitizer_INEndpoint = {
 | 
				
			||||||
 | 
					        .Header = {
 | 
				
			||||||
 | 
					            .Size               = sizeof(USB_Descriptor_Endpoint_t),
 | 
				
			||||||
 | 
					            .Type               = DTYPE_Endpoint
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        .EndpointAddress        = (ENDPOINT_DIR_IN | DIGITIZER_IN_EPNUM),
 | 
				
			||||||
 | 
					        .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
 | 
				
			||||||
 | 
					        .EndpointSize           = DIGITIZER_EPSIZE,
 | 
				
			||||||
 | 
					        .PollingIntervalMS      = USB_POLLING_INTERVAL_MS
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -1059,6 +1147,13 @@ uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const
 | 
				
			||||||
                    Size    = sizeof(USB_HID_Descriptor_HID_t);
 | 
					                    Size    = sizeof(USB_HID_Descriptor_HID_t);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
 | 
				
			||||||
 | 
					                case DIGITIZER_INTERFACE:
 | 
				
			||||||
 | 
					                    Address = &ConfigurationDescriptor.Digitizer_HID;
 | 
				
			||||||
 | 
					                    Size    = sizeof(USB_HID_Descriptor_HID_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
| 
						 | 
					@ -1108,6 +1203,12 @@ uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const
 | 
				
			||||||
                    Address = &JoystickReport;
 | 
					                    Address = &JoystickReport;
 | 
				
			||||||
                    Size    = sizeof(JoystickReport);
 | 
					                    Size    = sizeof(JoystickReport);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
 | 
				
			||||||
 | 
					                case DIGITIZER_INTERFACE:
 | 
				
			||||||
 | 
					                    Address = &DigitizerReport;
 | 
				
			||||||
 | 
					                    Size    = sizeof(DigitizerReport);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -135,6 +135,13 @@ typedef struct {
 | 
				
			||||||
    USB_HID_Descriptor_HID_t   Joystick_HID;
 | 
					    USB_HID_Descriptor_HID_t   Joystick_HID;
 | 
				
			||||||
    USB_Descriptor_Endpoint_t  Joystick_INEndpoint;
 | 
					    USB_Descriptor_Endpoint_t  Joystick_INEndpoint;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
 | 
				
			||||||
 | 
					    // Digitizer HID Interface
 | 
				
			||||||
 | 
					    USB_Descriptor_Interface_t Digitizer_Interface;
 | 
				
			||||||
 | 
					    USB_HID_Descriptor_HID_t   Digitizer_HID;
 | 
				
			||||||
 | 
					    USB_Descriptor_Endpoint_t  Digitizer_INEndpoint;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
} USB_Descriptor_Configuration_t;
 | 
					} USB_Descriptor_Configuration_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -180,6 +187,10 @@ enum usb_interfaces {
 | 
				
			||||||
#if defined(JOYSTICK_ENABLE)
 | 
					#if defined(JOYSTICK_ENABLE)
 | 
				
			||||||
    JOYSTICK_INTERFACE,
 | 
					    JOYSTICK_INTERFACE,
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
 | 
				
			||||||
 | 
					    DIGITIZER_INTERFACE,
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    TOTAL_INTERFACES
 | 
					    TOTAL_INTERFACES
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -226,7 +237,7 @@ enum usb_endpoints {
 | 
				
			||||||
#        if STM32_USB_USE_OTG1
 | 
					#        if STM32_USB_USE_OTG1
 | 
				
			||||||
#            define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM
 | 
					#            define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM
 | 
				
			||||||
#        else
 | 
					#        else
 | 
				
			||||||
    CONSOLE_OUT_EPNUM = NEXT_EPNUM,
 | 
					    CONSOLE_OUT_EPNUM   = NEXT_EPNUM,
 | 
				
			||||||
#        endif
 | 
					#        endif
 | 
				
			||||||
#    else
 | 
					#    else
 | 
				
			||||||
#        define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM
 | 
					#        define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM
 | 
				
			||||||
| 
						 | 
					@ -259,6 +270,19 @@ enum usb_endpoints {
 | 
				
			||||||
    JOYSTICK_OUT_EPNUM    = NEXT_EPNUM,
 | 
					    JOYSTICK_OUT_EPNUM    = NEXT_EPNUM,
 | 
				
			||||||
#    endif
 | 
					#    endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DIGITIZER_ENABLE
 | 
				
			||||||
 | 
					#    if !defined(DIGITIZER_SHARED_EP)
 | 
				
			||||||
 | 
					    DIGITIZER_IN_EPNUM = NEXT_EPNUM,
 | 
				
			||||||
 | 
					#        if STM32_USB_USE_OTG1
 | 
				
			||||||
 | 
					    DIGITIZER_OUT_EPNUM = DIGITIZER_IN_EPNUM,
 | 
				
			||||||
 | 
					#        else
 | 
				
			||||||
 | 
					    DIGITIZER_OUT_EPNUM = NEXT_EPNUM,
 | 
				
			||||||
 | 
					#        endif
 | 
				
			||||||
 | 
					#    else
 | 
				
			||||||
 | 
					#        define DIGITIZER_IN_EPNUM SHARED_IN_EPNUM
 | 
				
			||||||
 | 
					#    endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef PROTOCOL_LUFA
 | 
					#ifdef PROTOCOL_LUFA
 | 
				
			||||||
| 
						 | 
					@ -284,5 +308,6 @@ enum usb_endpoints {
 | 
				
			||||||
#define CDC_NOTIFICATION_EPSIZE 8
 | 
					#define CDC_NOTIFICATION_EPSIZE 8
 | 
				
			||||||
#define CDC_EPSIZE 16
 | 
					#define CDC_EPSIZE 16
 | 
				
			||||||
#define JOYSTICK_EPSIZE 8
 | 
					#define JOYSTICK_EPSIZE 8
 | 
				
			||||||
 | 
					#define DIGITIZER_EPSIZE 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const void** const DescriptorAddress);
 | 
					uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const void** const DescriptorAddress);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -292,6 +292,14 @@ static void send_consumer(uint16_t data) {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void send_digitizer(report_digitizer_t *report) {
 | 
				
			||||||
 | 
					#ifdef DIGITIZER_ENABLE
 | 
				
			||||||
 | 
					    if (usbInterruptIsReadyShared()) {
 | 
				
			||||||
 | 
					        usbSetInterruptShared((void *)report, sizeof(report_digitizer_t));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*------------------------------------------------------------------*
 | 
					/*------------------------------------------------------------------*
 | 
				
			||||||
 * Request from host                                                *
 | 
					 * Request from host                                                *
 | 
				
			||||||
 *------------------------------------------------------------------*/
 | 
					 *------------------------------------------------------------------*/
 | 
				
			||||||
| 
						 | 
					@ -510,8 +518,46 @@ const PROGMEM uchar shared_hid_report[] = {
 | 
				
			||||||
    0x95, 0x01,                //   Report Count (1)
 | 
					    0x95, 0x01,                //   Report Count (1)
 | 
				
			||||||
    0x75, 0x10,                //   Report Size (16)
 | 
					    0x75, 0x10,                //   Report Size (16)
 | 
				
			||||||
    0x81, 0x00,                //   Input (Data, Array, Absolute)
 | 
					    0x81, 0x00,                //   Input (Data, Array, Absolute)
 | 
				
			||||||
    0xC0                       // End Collection
 | 
					    0xC0,                      // End Collection
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DIGITIZER_ENABLE
 | 
				
			||||||
 | 
					    // Digitizer report descriptor
 | 
				
			||||||
 | 
					    0x05, 0x0D,                 // Usage Page (Digitizers)
 | 
				
			||||||
 | 
					    0x09, 0x01,                 // Usage (Digitizer)
 | 
				
			||||||
 | 
					    0xA1, 0x01,                 // Collection (Application)
 | 
				
			||||||
 | 
					    0x85, REPORT_ID_DIGITIZER,  //   Report ID
 | 
				
			||||||
 | 
					    0x09, 0x22,                 //   Usage (Finger)
 | 
				
			||||||
 | 
					    0xA1, 0x00,                 //   Collection (Physical)
 | 
				
			||||||
 | 
					    // Tip Switch (1 bit)
 | 
				
			||||||
 | 
					    0x09, 0x42,  //     Usage (Tip Switch)
 | 
				
			||||||
 | 
					    0x15, 0x00,  //     Logical Minimum
 | 
				
			||||||
 | 
					    0x25, 0x01,  //     Logical Maximum
 | 
				
			||||||
 | 
					    0x95, 0x01,  //     Report Count (1)
 | 
				
			||||||
 | 
					    0x75, 0x01,  //     Report Size (16)
 | 
				
			||||||
 | 
					    0x81, 0x02,  //     Input (Data, Variable, Absolute)
 | 
				
			||||||
 | 
					    // In Range (1 bit)
 | 
				
			||||||
 | 
					    0x09, 0x32,  //     Usage (In Range)
 | 
				
			||||||
 | 
					    0x81, 0x02,  //     Input (Data, Variable, Absolute)
 | 
				
			||||||
 | 
					    // Padding (6 bits)
 | 
				
			||||||
 | 
					    0x95, 0x06,  //     Report Count (6)
 | 
				
			||||||
 | 
					    0x81, 0x03,  //     Input (Constant)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // X/Y Position (4 bytes)
 | 
				
			||||||
 | 
					    0x05, 0x01,        //     Usage Page (Generic Desktop)
 | 
				
			||||||
 | 
					    0x26, 0xFF, 0x7F,  //     Logical Maximum (32767)
 | 
				
			||||||
 | 
					    0x95, 0x01,        //     Report Count (1)
 | 
				
			||||||
 | 
					    0x75, 0x10,        //     Report Size (16)
 | 
				
			||||||
 | 
					    0x65, 0x33,        //     Unit (Inch, English Linear)
 | 
				
			||||||
 | 
					    0x55, 0x0E,        //     Unit Exponent (-2)
 | 
				
			||||||
 | 
					    0x09, 0x30,        //     Usage (X)
 | 
				
			||||||
 | 
					    0x81, 0x02,        //     Input (Data, Variable, Absolute)
 | 
				
			||||||
 | 
					    0x09, 0x31,        //     Usage (Y)
 | 
				
			||||||
 | 
					    0x81, 0x02,        //     Input (Data, Variable, Absolute)
 | 
				
			||||||
 | 
					    0xC0,              //   End Collection
 | 
				
			||||||
 | 
					    0xC0               // End Collection
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef SHARED_EP_ENABLE
 | 
					#ifdef SHARED_EP_ENABLE
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue