2015-04-10 01:32:04 +09:00
/*
Copyright 2011 Jun Wako <wakojun@gmail.com>
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 <stdint.h>
2020-06-10 06:30:37 +10:00
#include <avr/wdt.h>
2020-05-30 13:14:59 -07:00
#include <usbdrv/usbdrv.h>
2020-06-10 06:30:37 +10:00
2015-04-10 01:32:04 +09:00
#include "usbconfig.h"
#include "host.h"
#include "report.h"
#include "host_driver.h"
#include "vusb.h"
2020-05-03 01:25:39 +01:00
#include "print.h"
#include "debug.h"
2020-06-10 06:30:37 +10:00
#include "wait.h"
2020-05-21 20:31:42 +10:00
#include "usb_descriptor_common.h"
2015-04-10 01:32:04 +09:00
2020-04-06 08:25:07 +10:00
#ifdef RAW_ENABLE
2020-03-31 05:15:05 +09:00
# include "raw_hid.h"
#endif
2020-05-03 01:25:39 +01:00
#if defined(CONSOLE_ENABLE)
# define RBUF_SIZE 128
# include "ring_buffer.h"
#endif
#define NEXT_INTERFACE __COUNTER__
/*
* Interface indexes
*/
enum usb_interfaces {
2021-01-11 19:46:30 +11:00
#ifndef KEYBOARD_SHARED_EP
2020-05-03 01:25:39 +01:00
KEYBOARD_INTERFACE = NEXT_INTERFACE ,
2021-01-11 19:46:30 +11:00
#else
SHARED_INTERFACE = NEXT_INTERFACE ,
# define KEYBOARD_INTERFACE SHARED_INTERFACE
#endif
2020-05-14 01:24:18 +01:00
// It is important that the Raw HID interface is at a constant
// interface number, to support Linux/OSX platforms and chrome.hid
// If Raw HID is enabled, let it be always 1.
2020-05-03 01:25:39 +01:00
#ifdef RAW_ENABLE
RAW_INTERFACE = NEXT_INTERFACE ,
#endif
2021-01-11 19:46:30 +11:00
#if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
SHARED_INTERFACE = NEXT_INTERFACE ,
2020-05-14 01:24:18 +01:00
#endif
2021-01-11 19:46:30 +11:00
2020-05-03 01:25:39 +01:00
#ifdef CONSOLE_ENABLE
CONSOLE_INTERFACE = NEXT_INTERFACE ,
#endif
2021-01-11 19:46:30 +11:00
2020-06-10 06:30:37 +10:00
TOTAL_INTERFACES = NEXT_INTERFACE
2020-05-03 01:25:39 +01:00
};
2020-08-19 02:16:35 +01:00
#define MAX_INTERFACES 3
2020-05-03 01:25:39 +01:00
#if (NEXT_INTERFACE - 1) > MAX_INTERFACES
# error There are not enough available interfaces to support all functions. Please disable one or more of the following: Mouse Keys, Extra Keys, Raw HID, Console
2020-03-31 05:15:05 +09:00
#endif
2020-08-19 02:16:35 +01:00
#if (defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)) && CONSOLE_ENABLE
# error Mouse/Extra Keys share an endpoint with Console. Please disable one of the two.
#endif
2020-06-07 15:00:21 +10:00
static uint8_t keyboard_led_state = 0 ;
2019-08-30 11:19:03 -07:00
static uint8_t vusb_idle_rate = 0 ;
2015-04-10 01:32:04 +09:00
/* Keyboard report send buffer */
#define KBUF_SIZE 16
static report_keyboard_t kbuf [ KBUF_SIZE ];
2019-08-30 11:19:03 -07:00
static uint8_t kbuf_head = 0 ;
static uint8_t kbuf_tail = 0 ;
2015-04-10 01:32:04 +09:00
2020-06-07 15:00:21 +10:00
static report_keyboard_t keyboard_report_sent ;
2015-04-10 01:32:04 +09:00
2018-04-08 00:07:26 +03:00
#define VUSB_TRANSFER_KEYBOARD_MAX_TRIES 10
2015-04-10 01:32:04 +09:00
/* transfer keyboard report from buffer */
2019-08-30 11:19:03 -07:00
void vusb_transfer_keyboard ( void ) {
2018-04-08 00:07:26 +03:00
for ( int i = 0 ; i < VUSB_TRANSFER_KEYBOARD_MAX_TRIES ; i ++ ) {
if ( usbInterruptIsReady ()) {
if ( kbuf_head != kbuf_tail ) {
2021-01-11 19:46:30 +11:00
#ifndef KEYBOARD_SHARED_EP
2018-04-08 00:07:26 +03:00
usbSetInterrupt (( void * ) & kbuf [ kbuf_tail ], sizeof ( report_keyboard_t ));
2021-01-11 19:46:30 +11:00
#else
// Ugly hack! :(
usbSetInterrupt (( void * ) & kbuf [ kbuf_tail ], sizeof ( report_keyboard_t ) - 1 );
while ( ! usbInterruptIsReady ()) {
usbPoll ();
}
usbSetInterrupt (( void * )( & ( kbuf [ kbuf_tail ]. keys [ 5 ])), 1 );
#endif
2018-04-08 00:07:26 +03:00
kbuf_tail = ( kbuf_tail + 1 ) % KBUF_SIZE ;
if ( debug_keyboard ) {
2020-06-10 06:30:37 +10:00
dprintf ( "V-USB: kbuf[%d->%d](%02X) \n " , kbuf_tail , kbuf_head , ( kbuf_head < kbuf_tail ) ? ( KBUF_SIZE - kbuf_tail + kbuf_head ) : ( kbuf_head - kbuf_tail ));
2018-04-08 00:07:26 +03:00
}
2015-04-10 01:32:04 +09:00
}
2018-04-08 00:07:26 +03:00
break ;
2015-04-10 01:32:04 +09:00
}
2018-04-08 00:07:26 +03:00
usbPoll ();
2020-06-10 06:30:37 +10:00
wait_ms ( 1 );
2015-04-10 01:32:04 +09:00
}
}
2020-03-31 05:15:05 +09:00
/*------------------------------------------------------------------*
* RAW HID
*------------------------------------------------------------------*/
#ifdef RAW_ENABLE
# define RAW_BUFFER_SIZE 32
# define RAW_EPSIZE 8
static uint8_t raw_output_buffer [ RAW_BUFFER_SIZE ];
static uint8_t raw_output_received_bytes = 0 ;
void raw_hid_send ( uint8_t * data , uint8_t length ) {
if ( length != RAW_BUFFER_SIZE ) {
return ;
}
uint8_t * temp = data ;
for ( uint8_t i = 0 ; i < 4 ; i ++ ) {
2020-08-19 02:16:35 +01:00
while ( ! usbInterruptIsReady4 ()) {
2020-03-31 05:15:05 +09:00
usbPoll ();
}
2020-08-19 02:16:35 +01:00
usbSetInterrupt4 ( temp , 8 );
2020-03-31 05:15:05 +09:00
temp += 8 ;
}
2020-08-19 02:16:35 +01:00
while ( ! usbInterruptIsReady4 ()) {
2020-03-31 05:15:05 +09:00
usbPoll ();
}
2020-08-19 02:16:35 +01:00
usbSetInterrupt4 ( 0 , 0 );
2020-03-31 05:15:05 +09:00
}
__attribute__ (( weak )) void raw_hid_receive ( uint8_t * data , uint8_t length ) {
// Users should #include "raw_hid.h" in their own code
// and implement this function there. Leave this as weak linkage
// so users can opt to not handle data coming in.
}
void raw_hid_task ( void ) {
if ( raw_output_received_bytes == RAW_BUFFER_SIZE ) {
raw_hid_receive ( raw_output_buffer , RAW_BUFFER_SIZE );
raw_output_received_bytes = 0 ;
}
}
2020-05-03 01:25:39 +01:00
#endif
2020-03-31 05:15:05 +09:00
2020-05-03 01:25:39 +01:00
/*------------------------------------------------------------------*
* Console
*------------------------------------------------------------------*/
#ifdef CONSOLE_ENABLE
# define CONSOLE_BUFFER_SIZE 32
# define CONSOLE_EPSIZE 8
int8_t sendchar ( uint8_t c ) {
rbuf_enqueue ( c );
return 0 ;
}
static inline bool usbSendData3 ( char * data , uint8_t len ) {
uint8_t retries = 5 ;
while ( ! usbInterruptIsReady3 ()) {
if ( ! ( retries -- )) {
return false ;
}
usbPoll ();
}
usbSetInterrupt3 (( unsigned char * ) data , len );
return true ;
}
void console_task ( void ) {
if ( ! usbConfiguration ) {
return ;
}
if ( ! rbuf_has_data ()) {
return ;
}
// Send in chunks of 8 padded to 32
char send_buf [ CONSOLE_BUFFER_SIZE ] = { 0 };
uint8_t send_buf_count = 0 ;
while ( rbuf_has_data () && send_buf_count < CONSOLE_EPSIZE ) {
send_buf [ send_buf_count ++ ] = rbuf_dequeue ();
}
char * temp = send_buf ;
for ( uint8_t i = 0 ; i < 4 ; i ++ ) {
if ( ! usbSendData3 ( temp , 8 )) {
break ;
}
temp += 8 ;
}
usbSendData3 ( 0 , 0 );
usbPoll ();
}
2020-03-31 05:15:05 +09:00
#endif
2015-04-10 01:32:04 +09:00
/*------------------------------------------------------------------*
* Host driver
*------------------------------------------------------------------*/
static uint8_t keyboard_leds ( void );
2019-08-30 11:19:03 -07:00
static void send_keyboard ( report_keyboard_t * report );
static void send_mouse ( report_mouse_t * report );
static void send_system ( uint16_t data );
static void send_consumer ( uint16_t data );
2021-09-15 17:40:22 +02:00
static void send_programmable_button ( uint32_t data );
2015-04-10 01:32:04 +09:00
2021-09-15 17:40:22 +02:00
static host_driver_t driver = { keyboard_leds , send_keyboard , send_mouse , send_system , send_consumer , send_programmable_button };
2015-04-10 01:32:04 +09:00
2022-02-12 10:29:31 -08:00
host_driver_t * vusb_driver ( void ) {
return & driver ;
}
2015-04-10 01:32:04 +09:00
2022-02-12 10:29:31 -08:00
static uint8_t keyboard_leds ( void ) {
return keyboard_led_state ;
}
2015-04-10 01:32:04 +09:00
2019-08-30 11:19:03 -07:00
static void send_keyboard ( report_keyboard_t * report ) {
2015-04-10 01:32:04 +09:00
uint8_t next = ( kbuf_head + 1 ) % KBUF_SIZE ;
if ( next != kbuf_tail ) {
kbuf [ kbuf_head ] = * report ;
2019-08-30 11:19:03 -07:00
kbuf_head = next ;
2015-04-10 01:32:04 +09:00
} else {
2020-06-10 06:30:37 +10:00
dprint ( "kbuf: full \n " );
2015-04-10 01:32:04 +09:00
}
// NOTE: send key strokes of Macro
usbPoll ();
vusb_transfer_keyboard ();
2020-06-07 15:00:21 +10:00
keyboard_report_sent = * report ;
2015-04-10 01:32:04 +09:00
}
2021-01-11 19:46:30 +11:00
#ifndef KEYBOARD_SHARED_EP
# define usbInterruptIsReadyShared usbInterruptIsReady3
# define usbSetInterruptShared usbSetInterrupt3
#else
# define usbInterruptIsReadyShared usbInterruptIsReady
# define usbSetInterruptShared usbSetInterrupt
#endif
2015-04-10 01:32:04 +09:00
2019-08-30 11:19:03 -07:00
static void send_mouse ( report_mouse_t * report ) {
2020-04-06 08:25:07 +10:00
#ifdef MOUSE_ENABLE
2021-01-11 19:46:30 +11:00
if ( usbInterruptIsReadyShared ()) {
usbSetInterruptShared (( void * ) report , sizeof ( report_mouse_t ));
2015-04-10 01:32:04 +09:00
}
2020-04-01 21:06:22 +01:00
#endif
2015-04-10 01:32:04 +09:00
}
2020-02-12 17:19:39 +11:00
#ifdef EXTRAKEY_ENABLE
2020-02-03 07:17:05 +11:00
static void send_extra ( uint8_t report_id , uint16_t data ) {
2020-02-02 20:47:40 +00:00
static uint8_t last_id = 0 ;
2015-04-10 01:32:04 +09:00
static uint16_t last_data = 0 ;
2020-02-03 07:17:05 +11:00
if (( report_id == last_id ) && ( data == last_data )) return ;
2020-02-02 20:47:40 +00:00
last_id = report_id ;
2015-04-10 01:32:04 +09:00
last_data = data ;
2021-06-07 07:16:55 +02:00
static report_extra_t report ;
report = ( report_extra_t ){. report_id = report_id , . usage = data };
2021-01-11 19:46:30 +11:00
if ( usbInterruptIsReadyShared ()) {
usbSetInterruptShared (( void * ) & report , sizeof ( report_extra_t ));
2015-04-10 01:32:04 +09:00
}
}
2020-02-12 17:19:39 +11:00
#endif
2015-04-10 01:32:04 +09:00
2020-02-12 17:19:39 +11:00
static void send_system ( uint16_t data ) {
#ifdef EXTRAKEY_ENABLE
2020-02-25 12:18:11 +11:00
send_extra ( REPORT_ID_SYSTEM , data );
2020-02-12 17:19:39 +11:00
#endif
}
2015-04-10 01:32:04 +09:00
2020-02-12 17:19:39 +11:00
static void send_consumer ( uint16_t data ) {
#ifdef EXTRAKEY_ENABLE
send_extra ( REPORT_ID_CONSUMER , data );
#endif
}
2015-04-10 01:32:04 +09:00
2021-08-17 20:52:44 +02:00
void send_digitizer ( report_digitizer_t * report ) {
#ifdef DIGITIZER_ENABLE
if ( usbInterruptIsReadyShared ()) {
usbSetInterruptShared (( void * ) report , sizeof ( report_digitizer_t ));
2021-11-01 18:57:37 +00:00
}
2021-09-15 17:40:22 +02:00
#endif
}
static void send_programmable_button ( uint32_t data ) {
#ifdef PROGRAMMABLE_BUTTON_ENABLE
static report_programmable_button_t report = {
. report_id = REPORT_ID_PROGRAMMABLE_BUTTON ,
};
report . usage = data ;
if ( usbInterruptIsReadyShared ()) {
usbSetInterruptShared (( void * ) & report , sizeof ( report ));
2021-08-17 20:52:44 +02:00
}
#endif
}
2015-04-10 01:32:04 +09:00
/*------------------------------------------------------------------*
* Request from host *
*------------------------------------------------------------------*/
static struct {
2019-08-30 11:19:03 -07:00
uint16_t len ;
2019-11-25 20:33:02 +00:00
enum { NONE , SET_LED } kind ;
2015-04-10 01:32:04 +09:00
} last_req ;
2019-08-30 11:19:03 -07:00
usbMsgLen_t usbFunctionSetup ( uchar data [ 8 ]) {
usbRequest_t * rq = ( void * ) data ;
2015-04-10 01:32:04 +09:00
2019-08-30 11:19:03 -07:00
if (( rq -> bmRequestType & USBRQ_TYPE_MASK ) == USBRQ_TYPE_CLASS ) { /* class request type */
if ( rq -> bRequest == USBRQ_HID_GET_REPORT ) {
2020-06-10 06:30:37 +10:00
dprint ( "GET_REPORT:" );
2020-06-07 15:00:21 +10:00
if ( rq -> wIndex . word == KEYBOARD_INTERFACE ) {
usbMsgPtr = ( usbMsgPtr_t ) & keyboard_report_sent ;
return sizeof ( keyboard_report_sent );
}
2019-08-30 11:19:03 -07:00
} else if ( rq -> bRequest == USBRQ_HID_GET_IDLE ) {
2020-06-10 06:30:37 +10:00
dprint ( "GET_IDLE:" );
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) & vusb_idle_rate ;
2015-04-10 01:32:04 +09:00
return 1 ;
2019-08-30 11:19:03 -07:00
} else if ( rq -> bRequest == USBRQ_HID_SET_IDLE ) {
2015-04-10 01:32:04 +09:00
vusb_idle_rate = rq -> wValue . bytes [ 1 ];
2020-06-10 06:30:37 +10:00
dprintf ( "SET_IDLE: %02X" , vusb_idle_rate );
2019-08-30 11:19:03 -07:00
} else if ( rq -> bRequest == USBRQ_HID_SET_REPORT ) {
2020-06-10 06:30:37 +10:00
dprint ( "SET_REPORT:" );
2015-04-10 01:32:04 +09:00
// Report Type: 0x02(Out)/ReportID: 0x00(none) && Interface: 0(keyboard)
2020-06-07 15:00:21 +10:00
if ( rq -> wValue . word == 0x0200 && rq -> wIndex . word == KEYBOARD_INTERFACE ) {
2020-06-10 06:30:37 +10:00
dprint ( "SET_LED:" );
2015-04-10 01:32:04 +09:00
last_req . kind = SET_LED ;
2019-08-30 11:19:03 -07:00
last_req . len = rq -> wLength . word ;
2015-04-10 01:32:04 +09:00
}
2022-02-12 10:29:31 -08:00
return USB_NO_MSG ; // to get data in usbFunctionWrite
2015-04-10 01:32:04 +09:00
} else {
2020-06-10 06:30:37 +10:00
dprint ( "UNKNOWN:" );
2015-04-10 01:32:04 +09:00
}
2019-08-30 11:19:03 -07:00
} else {
2020-06-10 06:30:37 +10:00
dprint ( "VENDOR:" );
2015-04-10 01:32:04 +09:00
/* no vendor specific requests implemented */
}
2020-06-10 06:30:37 +10:00
dprint ( " \n " );
2019-08-30 11:19:03 -07:00
return 0 ; /* default for not implemented requests: return no data back to host */
2015-04-10 01:32:04 +09:00
}
2019-08-30 11:19:03 -07:00
uchar usbFunctionWrite ( uchar * data , uchar len ) {
2015-04-10 01:32:04 +09:00
if ( last_req . len == 0 ) {
return - 1 ;
}
switch ( last_req . kind ) {
case SET_LED :
2020-06-10 06:30:37 +10:00
dprintf ( "SET_LED: %02X \n " , data [ 0 ]);
2020-06-07 15:00:21 +10:00
keyboard_led_state = data [ 0 ];
2019-08-30 11:19:03 -07:00
last_req . len = 0 ;
2015-04-10 01:32:04 +09:00
return 1 ;
break ;
case NONE :
default :
return - 1 ;
break ;
}
return 1 ;
}
2020-03-31 05:15:05 +09:00
void usbFunctionWriteOut ( uchar * data , uchar len ) {
#ifdef RAW_ENABLE
// Data from host must be divided every 8bytes
if ( len != 8 ) {
2020-06-10 06:30:37 +10:00
dprint ( "RAW: invalid length \n " );
2020-03-31 05:15:05 +09:00
raw_output_received_bytes = 0 ;
return ;
}
if ( raw_output_received_bytes + len > RAW_BUFFER_SIZE ) {
2020-06-10 06:30:37 +10:00
dprint ( "RAW: buffer full \n " );
2020-03-31 05:15:05 +09:00
raw_output_received_bytes = 0 ;
} else {
for ( uint8_t i = 0 ; i < 8 ; i ++ ) {
raw_output_buffer [ raw_output_received_bytes + i ] = data [ i ];
}
raw_output_received_bytes += len ;
}
#endif
}
2015-04-10 01:32:04 +09:00
/*------------------------------------------------------------------*
* Descriptors *
*------------------------------------------------------------------*/
2021-01-11 19:46:30 +11:00
#ifdef KEYBOARD_SHARED_EP
const PROGMEM uchar shared_hid_report [] = {
# define SHARED_REPORT_STARTED
#else
2015-04-10 01:32:04 +09:00
const PROGMEM uchar keyboard_hid_report [] = {
2021-01-11 19:46:30 +11:00
#endif
2022-02-12 10:29:31 -08:00
0x05 , 0x01 , // Usage Page (Generic Desktop)
0x09 , 0x06 , // Usage (Keyboard)
0xA1 , 0x01 , // Collection (Application)
2021-01-11 19:46:30 +11:00
#ifdef KEYBOARD_SHARED_EP
2022-02-12 10:29:31 -08:00
0x85 , REPORT_ID_KEYBOARD , // Report ID
2021-01-11 19:46:30 +11:00
#endif
2020-02-12 17:19:39 +11:00
// Modifiers (8 bits)
2022-02-12 10:29:31 -08:00
0x05 , 0x07 , // Usage Page (Keyboard/Keypad)
0x19 , 0xE0 , // Usage Minimum (Keyboard Left Control)
0x29 , 0xE7 , // Usage Maximum (Keyboard Right GUI)
0x15 , 0x00 , // Logical Minimum (0)
0x25 , 0x01 , // Logical Maximum (1)
0x95 , 0x08 , // Report Count (8)
0x75 , 0x01 , // Report Size (1)
0x81 , 0x02 , // Input (Data, Variable, Absolute)
2020-02-12 17:19:39 +11:00
// Reserved (1 byte)
2022-02-12 10:29:31 -08:00
0x95 , 0x01 , // Report Count (1)
0x75 , 0x08 , // Report Size (8)
0x81 , 0x03 , // Input (Constant)
2020-02-12 17:19:39 +11:00
// Keycodes (6 bytes)
2022-02-12 10:29:31 -08:00
0x05 , 0x07 , // Usage Page (Keyboard/Keypad)
0x19 , 0x00 , // Usage Minimum (0)
0x29 , 0xFF , // Usage Maximum (255)
0x15 , 0x00 , // Logical Minimum (0)
0x26 , 0xFF , 0x00 , // Logical Maximum (255)
0x95 , 0x06 , // Report Count (6)
0x75 , 0x08 , // Report Size (8)
0x81 , 0x00 , // Input (Data, Array, Absolute)
2020-02-12 17:19:39 +11:00
// Status LEDs (5 bits)
2022-02-12 10:29:31 -08:00
0x05 , 0x08 , // Usage Page (LED)
0x19 , 0x01 , // Usage Minimum (Num Lock)
0x29 , 0x05 , // Usage Maximum (Kana)
0x95 , 0x05 , // Report Count (5)
0x75 , 0x01 , // Report Size (1)
0x91 , 0x02 , // Output (Data, Variable, Absolute)
2020-02-12 17:19:39 +11:00
// LED padding (3 bits)
2022-02-12 10:29:31 -08:00
0x95 , 0x01 , // Report Count (1)
0x75 , 0x03 , // Report Size (3)
0x91 , 0x03 , // Output (Constant)
0xC0 , // End Collection
2021-01-11 19:46:30 +11:00
#ifndef KEYBOARD_SHARED_EP
2015-04-10 01:32:04 +09:00
};
2021-01-11 19:46:30 +11:00
#endif
2015-04-10 01:32:04 +09:00
2021-01-11 19:46:30 +11:00
#if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
const PROGMEM uchar shared_hid_report [] = {
# define SHARED_REPORT_STARTED
#endif
#ifdef MOUSE_ENABLE
2020-02-12 17:19:39 +11:00
// Mouse report descriptor
2022-02-12 10:29:31 -08:00
0x05 , 0x01 , // Usage Page (Generic Desktop)
0x09 , 0x02 , // Usage (Mouse)
0xA1 , 0x01 , // Collection (Application)
0x85 , REPORT_ID_MOUSE , // Report ID
0x09 , 0x01 , // Usage (Pointer)
0xA1 , 0x00 , // Collection (Physical)
2021-01-27 09:38:34 -08:00
// Buttons (8 bits)
2022-02-12 10:29:31 -08:00
0x05 , 0x09 , // Usage Page (Button)
0x19 , 0x01 , // Usage Minimum (Button 1)
0x29 , 0x08 , // Usage Maximum (Button 8)
0x15 , 0x00 , // Logical Minimum (0)
0x25 , 0x01 , // Logical Maximum (1)
0x95 , 0x08 , // Report Count (8)
0x75 , 0x01 , // Report Size (1)
0x81 , 0x02 , // Input (Data, Variable, Absolute)
2020-02-12 17:19:39 +11:00
// X/Y position (2 bytes)
2022-02-12 10:29:31 -08:00
0x05 , 0x01 , // Usage Page (Generic Desktop)
0x09 , 0x30 , // Usage (X)
0x09 , 0x31 , // Usage (Y)
0x15 , 0x81 , // Logical Minimum (-127)
0x25 , 0x7F , // Logical Maximum (127)
0x95 , 0x02 , // Report Count (2)
0x75 , 0x08 , // Report Size (8)
0x81 , 0x06 , // Input (Data, Variable, Relative)
2020-02-12 17:19:39 +11:00
// Vertical wheel (1 byte)
2022-02-12 10:29:31 -08:00
0x09 , 0x38 , // Usage (Wheel)
0x15 , 0x81 , // Logical Minimum (-127)
0x25 , 0x7F , // Logical Maximum (127)
0x95 , 0x01 , // Report Count (1)
0x75 , 0x08 , // Report Size (8)
0x81 , 0x06 , // Input (Data, Variable, Relative)
2020-02-12 17:19:39 +11:00
// Horizontal wheel (1 byte)
2022-02-12 10:29:31 -08:00
0x05 , 0x0C , // Usage Page (Consumer)
0x0A , 0x38 , 0x02 , // Usage (AC Pan)
0x15 , 0x81 , // Logical Minimum (-127)
0x25 , 0x7F , // Logical Maximum (127)
0x95 , 0x01 , // Report Count (1)
0x75 , 0x08 , // Report Size (8)
0x81 , 0x06 , // Input (Data, Variable, Relative)
0xC0 , // End Collection
0xC0 , // End Collection
2021-01-11 19:46:30 +11:00
#endif
2020-02-12 17:19:39 +11:00
2021-01-11 19:46:30 +11:00
#ifdef EXTRAKEY_ENABLE
2020-02-12 17:19:39 +11:00
// Extrakeys report descriptor
2022-02-12 10:29:31 -08:00
0x05 , 0x01 , // Usage Page (Generic Desktop)
0x09 , 0x80 , // Usage (System Control)
0xA1 , 0x01 , // Collection (Application)
0x85 , REPORT_ID_SYSTEM , // Report ID
0x19 , 0x01 , // Usage Minimum (Pointer)
0x2A , 0xB7 , 0x00 , // Usage Maximum (System Display LCD Autoscale)
0x15 , 0x01 , // Logical Minimum
0x26 , 0xB7 , 0x00 , // Logical Maximum
0x95 , 0x01 , // Report Count (1)
0x75 , 0x10 , // Report Size (16)
0x81 , 0x00 , // Input (Data, Array, Absolute)
0xC0 , // End Collection
2020-02-12 17:19:39 +11:00
2022-02-12 10:29:31 -08:00
0x05 , 0x0C , // Usage Page (Consumer)
0x09 , 0x01 , // Usage (Consumer Control)
0xA1 , 0x01 , // Collection (Application)
0x85 , REPORT_ID_CONSUMER , // Report ID
0x19 , 0x01 , // Usage Minimum (Consumer Control)
0x2A , 0xA0 , 0x02 , // Usage Maximum (AC Desktop Show All Applications)
0x15 , 0x01 , // Logical Minimum
0x26 , 0xA0 , 0x02 , // Logical Maximum
0x95 , 0x01 , // Report Count (1)
0x75 , 0x10 , // Report Size (16)
0x81 , 0x00 , // Input (Data, Array, Absolute)
0xC0 , // End Collection
2021-01-11 19:46:30 +11:00
#endif
2021-08-17 20:52:44 +02:00
#ifdef DIGITIZER_ENABLE
// Digitizer report descriptor
2022-02-12 10:29:31 -08:00
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)
2021-08-17 20:52:44 +02:00
// Tip Switch (1 bit)
2022-02-12 10:29:31 -08:00
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)
2021-08-17 20:52:44 +02:00
// In Range (1 bit)
2022-02-12 10:29:31 -08:00
0x09 , 0x32 , // Usage (In Range)
0x81 , 0x02 , // Input (Data, Variable, Absolute)
2021-08-17 20:52:44 +02:00
// Padding (6 bits)
2022-02-12 10:29:31 -08:00
0x95 , 0x06 , // Report Count (6)
0x81 , 0x03 , // Input (Constant)
2021-08-17 20:52:44 +02:00
// X/Y Position (4 bytes)
2022-02-12 10:29:31 -08:00
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
2021-08-17 20:52:44 +02:00
#endif
2021-09-15 17:40:22 +02:00
#ifdef PROGRAMMABLE_BUTTON_ENABLE
// Programmable buttons report descriptor
2022-02-12 10:29:31 -08:00
0x05 , 0x0C , // Usage Page (Consumer)
0x09 , 0x01 , // Usage (Consumer Control)
0xA1 , 0x01 , // Collection (Application)
0x85 , REPORT_ID_PROGRAMMABLE_BUTTON , // Report ID
0x09 , 0x03 , // Usage (Programmable Buttons)
0xA1 , 0x04 , // Collection (Named Array)
0x05 , 0x09 , // Usage Page (Button)
0x19 , 0x01 , // Usage Minimum (Button 1)
0x29 , 0x20 , // Usage Maximum (Button 32)
0x15 , 0x00 , // Logical Minimum (0)
0x25 , 0x01 , // Logical Maximum (1)
0x95 , 0x20 , // Report Count (32)
0x75 , 0x01 , // Report Size (1)
0x81 , 0x02 , // Input (Data, Variable, Absolute)
0xC0 , // End Collection
0xC0 , // End Collection
2021-09-15 17:40:22 +02:00
#endif
2021-01-11 19:46:30 +11:00
#ifdef SHARED_EP_ENABLE
2015-04-10 01:32:04 +09:00
};
2020-02-25 12:18:11 +11:00
#endif
2015-04-10 01:32:04 +09:00
2020-06-10 06:30:37 +10:00
#ifdef RAW_ENABLE
const PROGMEM uchar raw_hid_report [] = {
2022-02-12 10:29:31 -08:00
0x06 , RAW_USAGE_PAGE_LO , RAW_USAGE_PAGE_HI , // Usage Page (Vendor Defined)
0x09 , RAW_USAGE_ID , // Usage (Vendor Defined)
0xA1 , 0x01 , // Collection (Application)
2020-06-10 06:30:37 +10:00
// Data to host
2022-02-12 10:29:31 -08:00
0x09 , 0x62 , // Usage (Vendor Defined)
0x15 , 0x00 , // Logical Minimum (0)
0x26 , 0xFF , 0x00 , // Logical Maximum (255)
0x95 , RAW_BUFFER_SIZE , // Report Count
0x75 , 0x08 , // Report Size (8)
0x81 , 0x02 , // Input (Data, Variable, Absolute)
2020-06-10 06:30:37 +10:00
// Data from host
2022-02-12 10:29:31 -08:00
0x09 , 0x63 , // Usage (Vendor Defined)
0x15 , 0x00 , // Logical Minimum (0)
0x26 , 0xFF , 0x00 , // Logical Maximum (255)
0x95 , RAW_BUFFER_SIZE , // Report Count
0x75 , 0x08 , // Report Size (8)
0x91 , 0x02 , // Output (Data, Variable, Absolute)
0xC0 // End Collection
2020-06-10 06:30:37 +10:00
};
#endif
2020-05-03 01:25:39 +01:00
#if defined(CONSOLE_ENABLE)
const PROGMEM uchar console_hid_report [] = {
2022-02-12 10:29:31 -08:00
0x06 , 0x31 , 0xFF , // Usage Page (Vendor Defined - PJRC Teensy compatible)
0x09 , 0x74 , // Usage (Vendor Defined - PJRC Teensy compatible)
0xA1 , 0x01 , // Collection (Application)
2020-05-03 01:25:39 +01:00
// Data to host
2022-02-12 10:29:31 -08:00
0x09 , 0x75 , // Usage (Vendor Defined)
0x15 , 0x00 , // Logical Minimum (0x00)
0x26 , 0xFF , 0x00 , // Logical Maximum (0x00FF)
0x95 , CONSOLE_BUFFER_SIZE , // Report Count
0x75 , 0x08 , // Report Size (8)
0x81 , 0x02 , // Input (Data, Variable, Absolute)
2020-05-03 01:25:39 +01:00
// Data from host
2022-02-12 10:29:31 -08:00
0x09 , 0x76 , // Usage (Vendor Defined)
0x15 , 0x00 , // Logical Minimum (0x00)
0x26 , 0xFF , 0x00 , // Logical Maximum (0x00FF)
0x95 , CONSOLE_BUFFER_SIZE , // Report Count
0x75 , 0x08 , // Report Size (8)
0x91 , 0x02 , // Output (Data)
0xC0 // End Collection
2020-03-31 05:15:05 +09:00
};
#endif
2019-11-15 10:21:22 +11:00
#ifndef USB_MAX_POWER_CONSUMPTION
# define USB_MAX_POWER_CONSUMPTION 500
#endif
#ifndef USB_POLLING_INTERVAL_MS
# define USB_POLLING_INTERVAL_MS 1
#endif
2020-03-27 00:11:32 +11:00
// clang-format off
2020-03-28 13:02:25 +11:00
const PROGMEM usbStringDescriptor_t usbStringDescriptorZero = {
2020-03-27 00:11:32 +11:00
. header = {
2020-03-28 13:02:25 +11:00
. bLength = USB_STRING_LEN ( 1 ),
2020-03-27 00:11:32 +11:00
. bDescriptorType = USBDESCR_STRING
},
2020-03-28 13:02:25 +11:00
. bString = { 0x0409 } // US English
2020-03-27 00:11:32 +11:00
};
2020-03-28 13:02:25 +11:00
const PROGMEM usbStringDescriptor_t usbStringDescriptorManufacturer = {
2020-03-27 00:11:32 +11:00
. header = {
2020-03-28 13:02:25 +11:00
. bLength = USB_STRING_LEN ( sizeof ( STR ( MANUFACTURER )) - 1 ),
2020-03-27 00:11:32 +11:00
. bDescriptorType = USBDESCR_STRING
},
2020-03-28 13:02:25 +11:00
. bString = LSTR ( MANUFACTURER )
2020-03-27 00:11:32 +11:00
};
2020-03-28 13:02:25 +11:00
const PROGMEM usbStringDescriptor_t usbStringDescriptorProduct = {
2020-03-27 00:11:32 +11:00
. header = {
2020-03-28 13:02:25 +11:00
. bLength = USB_STRING_LEN ( sizeof ( STR ( PRODUCT )) - 1 ),
2020-03-27 00:11:32 +11:00
. bDescriptorType = USBDESCR_STRING
},
2020-03-28 13:02:25 +11:00
. bString = LSTR ( PRODUCT )
2020-03-27 00:11:32 +11:00
};
2020-12-05 21:14:19 +11:00
#if defined(SERIAL_NUMBER)
2020-03-28 13:02:25 +11:00
const PROGMEM usbStringDescriptor_t usbStringDescriptorSerial = {
2020-03-27 00:11:32 +11:00
. header = {
2021-07-16 19:43:18 +10:00
. bLength = USB_STRING_LEN ( sizeof ( SERIAL_NUMBER ) - 1 ),
2020-03-27 00:11:32 +11:00
. bDescriptorType = USBDESCR_STRING
},
2021-07-16 19:43:18 +10:00
. bString = USBSTR ( SERIAL_NUMBER )
2020-03-27 00:11:32 +11:00
};
2020-12-05 21:14:19 +11:00
#endif
2020-03-27 00:11:32 +11:00
2019-08-30 11:19:03 -07:00
/*
2020-03-28 13:02:25 +11:00
* Device descriptor
2015-04-10 01:32:04 +09:00
*/
2020-03-28 13:02:25 +11:00
const PROGMEM usbDeviceDescriptor_t usbDeviceDescriptor = {
. header = {
. bLength = sizeof ( usbDeviceDescriptor_t ),
. bDescriptorType = USBDESCR_DEVICE
},
. bcdUSB = 0x0110 ,
2020-04-06 08:25:07 +10:00
. bDeviceClass = 0x00 ,
. bDeviceSubClass = 0x00 ,
2020-03-28 13:02:25 +11:00
. bDeviceProtocol = 0x00 ,
. bMaxPacketSize0 = 8 ,
. idVendor = VENDOR_ID ,
. idProduct = PRODUCT_ID ,
. bcdDevice = DEVICE_VER ,
. iManufacturer = 0x01 ,
. iProduct = 0x02 ,
2020-12-05 21:14:19 +11:00
#if defined(SERIAL_NUMBER)
2020-03-28 13:02:25 +11:00
. iSerialNumber = 0x03 ,
2020-12-05 21:14:19 +11:00
#else
. iSerialNumber = 0x00 ,
#endif
2020-03-28 13:02:25 +11:00
. bNumConfigurations = 1
};
/*
* Configuration descriptors
*/
const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
. header = {
. header = {
. bLength = sizeof ( usbConfigurationDescriptorHeader_t ),
. bDescriptorType = USBDESCR_CONFIG
},
. wTotalLength = sizeof ( usbConfigurationDescriptor_t ),
2020-05-03 01:25:39 +01:00
. bNumInterfaces = TOTAL_INTERFACES ,
2020-03-28 13:02:25 +11:00
. bConfigurationValue = 0x01 ,
. iConfiguration = 0x00 ,
2020-04-05 01:18:19 -07:00
. bmAttributes = ( 1 << 7 ) | USBATTR_REMOTEWAKE ,
2020-03-28 13:02:25 +11:00
. bMaxPower = USB_MAX_POWER_CONSUMPTION / 2
},
2015-04-10 01:32:04 +09:00
2021-01-11 19:46:30 +11:00
# ifndef KEYBOARD_SHARED_EP
2015-04-10 01:32:04 +09:00
/*
2020-03-28 13:02:25 +11:00
* Keyboard
2015-04-10 01:32:04 +09:00
*/
2020-03-28 13:02:25 +11:00
. keyboardInterface = {
. header = {
. bLength = sizeof ( usbInterfaceDescriptor_t ),
. bDescriptorType = USBDESCR_INTERFACE
},
2020-05-03 01:25:39 +01:00
. bInterfaceNumber = KEYBOARD_INTERFACE ,
2020-03-28 13:02:25 +11:00
. bAlternateSetting = 0x00 ,
2020-04-06 08:25:07 +10:00
. bNumEndpoints = 1 ,
. bInterfaceClass = 0x03 ,
. bInterfaceSubClass = 0x01 ,
. bInterfaceProtocol = 0x01 ,
2020-03-28 13:02:25 +11:00
. iInterface = 0x00
},
. keyboardHID = {
. header = {
. bLength = sizeof ( usbHIDDescriptor_t ),
. bDescriptorType = USBDESCR_HID
},
. bcdHID = 0x0101 ,
. bCountryCode = 0x00 ,
. bNumDescriptors = 1 ,
. bDescriptorType = USBDESCR_HID_REPORT ,
. wDescriptorLength = sizeof ( keyboard_hid_report )
},
. keyboardINEndpoint = {
. header = {
. bLength = sizeof ( usbEndpointDescriptor_t ),
. bDescriptorType = USBDESCR_ENDPOINT
},
. bEndpointAddress = ( USBRQ_DIR_DEVICE_TO_HOST | 1 ),
. bmAttributes = 0x03 ,
. wMaxPacketSize = 8 ,
. bInterval = USB_POLLING_INTERVAL_MS
},
2021-01-11 19:46:30 +11:00
# endif
2015-04-10 01:32:04 +09:00
2020-05-03 01:25:39 +01:00
# if defined(RAW_ENABLE)
2020-05-14 01:24:18 +01:00
/*
* RAW HID
*/
2020-03-31 05:15:05 +09:00
. rawInterface = {
. header = {
. bLength = sizeof ( usbInterfaceDescriptor_t ),
. bDescriptorType = USBDESCR_INTERFACE
},
2020-05-03 01:25:39 +01:00
. bInterfaceNumber = RAW_INTERFACE ,
2020-03-31 05:15:05 +09:00
. bAlternateSetting = 0x00 ,
. bNumEndpoints = 2 ,
. bInterfaceClass = 0x03 ,
. bInterfaceSubClass = 0x00 ,
. bInterfaceProtocol = 0x00 ,
. iInterface = 0x00
},
. rawHID = {
. header = {
. bLength = sizeof ( usbHIDDescriptor_t ),
. bDescriptorType = USBDESCR_HID
},
. bcdHID = 0x0101 ,
. bCountryCode = 0x00 ,
2020-12-21 13:12:07 +11:00
. bNumDescriptors = 1 ,
2020-03-31 05:15:05 +09:00
. bDescriptorType = USBDESCR_HID_REPORT ,
. wDescriptorLength = sizeof ( raw_hid_report )
},
. rawINEndpoint = {
. header = {
. bLength = sizeof ( usbEndpointDescriptor_t ),
. bDescriptorType = USBDESCR_ENDPOINT
},
2020-08-19 02:16:35 +01:00
. bEndpointAddress = ( USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP4_NUMBER ),
2020-03-31 05:15:05 +09:00
. bmAttributes = 0x03 ,
. wMaxPacketSize = RAW_EPSIZE ,
. bInterval = USB_POLLING_INTERVAL_MS
},
. rawOUTEndpoint = {
. header = {
. bLength = sizeof ( usbEndpointDescriptor_t ),
. bDescriptorType = USBDESCR_ENDPOINT
},
2020-08-19 02:16:35 +01:00
. bEndpointAddress = ( USBRQ_DIR_HOST_TO_DEVICE | USB_CFG_EP4_NUMBER ),
2020-03-31 05:15:05 +09:00
. bmAttributes = 0x03 ,
. wMaxPacketSize = RAW_EPSIZE ,
. bInterval = USB_POLLING_INTERVAL_MS
2020-05-03 01:25:39 +01:00
},
# endif
2021-01-11 19:46:30 +11:00
# ifdef SHARED_EP_ENABLE
2020-05-14 01:24:18 +01:00
/*
2021-01-11 19:46:30 +11:00
* Shared
2020-05-14 01:24:18 +01:00
*/
2021-01-11 19:46:30 +11:00
. sharedInterface = {
2020-05-14 01:24:18 +01:00
. header = {
. bLength = sizeof ( usbInterfaceDescriptor_t ),
. bDescriptorType = USBDESCR_INTERFACE
},
2021-01-11 19:46:30 +11:00
. bInterfaceNumber = SHARED_INTERFACE ,
2020-05-14 01:24:18 +01:00
. bAlternateSetting = 0x00 ,
. bNumEndpoints = 1 ,
. bInterfaceClass = 0x03 ,
2021-01-11 19:46:30 +11:00
# ifdef KEYBOARD_SHARED_EP
. bInterfaceSubClass = 0x01 ,
. bInterfaceProtocol = 0x01 ,
# else
2020-05-14 01:24:18 +01:00
. bInterfaceSubClass = 0x00 ,
. bInterfaceProtocol = 0x00 ,
2021-01-11 19:46:30 +11:00
# endif
2020-05-14 01:24:18 +01:00
. iInterface = 0x00
},
2021-01-11 19:46:30 +11:00
. sharedHID = {
2020-05-14 01:24:18 +01:00
. header = {
. bLength = sizeof ( usbHIDDescriptor_t ),
. bDescriptorType = USBDESCR_HID
},
. bcdHID = 0x0101 ,
. bCountryCode = 0x00 ,
. bNumDescriptors = 1 ,
. bDescriptorType = USBDESCR_HID_REPORT ,
2021-01-11 19:46:30 +11:00
. wDescriptorLength = sizeof ( shared_hid_report )
2020-05-14 01:24:18 +01:00
},
2021-01-11 19:46:30 +11:00
. sharedINEndpoint = {
2020-05-14 01:24:18 +01:00
. header = {
. bLength = sizeof ( usbEndpointDescriptor_t ),
. bDescriptorType = USBDESCR_ENDPOINT
},
2021-01-11 19:46:30 +11:00
# ifdef KEYBOARD_SHARED_EP
. bEndpointAddress = ( USBRQ_DIR_DEVICE_TO_HOST | 1 ),
# else
2020-05-14 01:24:18 +01:00
. bEndpointAddress = ( USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER ),
2021-01-11 19:46:30 +11:00
# endif
2020-05-14 01:24:18 +01:00
. bmAttributes = 0x03 ,
. wMaxPacketSize = 8 ,
. bInterval = USB_POLLING_INTERVAL_MS
},
# endif
2021-01-11 19:46:30 +11:00
2020-05-03 01:25:39 +01:00
# if defined(CONSOLE_ENABLE)
/*
* Console
*/
. consoleInterface = {
. header = {
. bLength = sizeof ( usbInterfaceDescriptor_t ),
. bDescriptorType = USBDESCR_INTERFACE
},
. bInterfaceNumber = CONSOLE_INTERFACE ,
. bAlternateSetting = 0x00 ,
. bNumEndpoints = 2 ,
. bInterfaceClass = 0x03 ,
. bInterfaceSubClass = 0x00 ,
. bInterfaceProtocol = 0x00 ,
. iInterface = 0x00
},
. consoleHID = {
. header = {
. bLength = sizeof ( usbHIDDescriptor_t ),
. bDescriptorType = USBDESCR_HID
},
. bcdHID = 0x0111 ,
. bCountryCode = 0x00 ,
. bNumDescriptors = 1 ,
. bDescriptorType = USBDESCR_HID_REPORT ,
. wDescriptorLength = sizeof ( console_hid_report )
},
. consoleINEndpoint = {
. header = {
. bLength = sizeof ( usbEndpointDescriptor_t ),
. bDescriptorType = USBDESCR_ENDPOINT
},
. bEndpointAddress = ( USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER ),
. bmAttributes = 0x03 ,
. wMaxPacketSize = CONSOLE_EPSIZE ,
. bInterval = 0x01
},
. consoleOUTEndpoint = {
. header = {
. bLength = sizeof ( usbEndpointDescriptor_t ),
. bDescriptorType = USBDESCR_ENDPOINT
},
. bEndpointAddress = ( USBRQ_DIR_HOST_TO_DEVICE | USB_CFG_EP3_NUMBER ),
. bmAttributes = 0x03 ,
. wMaxPacketSize = CONSOLE_EPSIZE ,
. bInterval = 0x01
2021-01-11 19:46:30 +11:00
}
2019-08-30 11:19:03 -07:00
# endif
2015-04-10 01:32:04 +09:00
};
2020-03-28 13:02:25 +11:00
// clang-format on
2019-08-30 11:19:03 -07:00
USB_PUBLIC usbMsgLen_t usbFunctionDescriptor ( struct usbRequest * rq ) {
2015-04-10 01:32:04 +09:00
usbMsgLen_t len = 0 ;
switch ( rq -> wValue . bytes [ 1 ]) {
2020-03-28 13:02:25 +11:00
case USBDESCR_DEVICE :
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) & usbDeviceDescriptor ;
2020-03-28 13:02:25 +11:00
len = sizeof ( usbDeviceDescriptor_t );
break ;
2015-04-10 01:32:04 +09:00
case USBDESCR_CONFIG :
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) & usbConfigurationDescriptor ;
2020-03-28 13:02:25 +11:00
len = sizeof ( usbConfigurationDescriptor_t );
2015-04-10 01:32:04 +09:00
break ;
2020-03-27 00:11:32 +11:00
case USBDESCR_STRING :
switch ( rq -> wValue . bytes [ 0 ]) {
case 0 :
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) & usbStringDescriptorZero ;
2020-03-28 13:02:25 +11:00
len = usbStringDescriptorZero . header . bLength ;
2020-03-27 00:11:32 +11:00
break ;
2022-02-12 10:29:31 -08:00
case 1 : // iManufacturer
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) & usbStringDescriptorManufacturer ;
2020-03-28 13:02:25 +11:00
len = usbStringDescriptorManufacturer . header . bLength ;
2020-03-27 00:11:32 +11:00
break ;
2022-02-12 10:29:31 -08:00
case 2 : // iProduct
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) & usbStringDescriptorProduct ;
2020-03-28 13:02:25 +11:00
len = usbStringDescriptorProduct . header . bLength ;
2020-03-27 00:11:32 +11:00
break ;
2020-12-05 21:14:19 +11:00
#if defined(SERIAL_NUMBER)
2022-02-12 10:29:31 -08:00
case 3 : // iSerialNumber
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) & usbStringDescriptorSerial ;
2020-03-28 13:02:25 +11:00
len = usbStringDescriptorSerial . header . bLength ;
2020-03-27 00:11:32 +11:00
break ;
2020-12-05 21:14:19 +11:00
#endif
2020-03-27 00:11:32 +11:00
}
break ;
2015-04-10 01:32:04 +09:00
case USBDESCR_HID :
switch ( rq -> wValue . bytes [ 0 ]) {
2021-01-11 19:46:30 +11:00
#ifndef KEYBOARD_SHARED_EP
2020-05-03 01:25:39 +01:00
case KEYBOARD_INTERFACE :
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) & usbConfigurationDescriptor . keyboardHID ;
2020-03-28 13:02:25 +11:00
len = sizeof ( usbHIDDescriptor_t );
2015-04-10 01:32:04 +09:00
break ;
2021-01-11 19:46:30 +11:00
#endif
2020-05-03 01:25:39 +01:00
#if defined(RAW_ENABLE)
case RAW_INTERFACE :
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) & usbConfigurationDescriptor . rawHID ;
2020-03-31 05:15:05 +09:00
len = sizeof ( usbHIDDescriptor_t );
break ;
2020-05-03 01:25:39 +01:00
#endif
2021-01-11 19:46:30 +11:00
#ifdef SHARED_EP_ENABLE
case SHARED_INTERFACE :
usbMsgPtr = ( usbMsgPtr_t ) & usbConfigurationDescriptor . sharedHID ;
2020-05-14 01:24:18 +01:00
len = sizeof ( usbHIDDescriptor_t );
break ;
#endif
2021-01-11 19:46:30 +11:00
2020-05-03 01:25:39 +01:00
#if defined(CONSOLE_ENABLE)
case CONSOLE_INTERFACE :
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) & usbConfigurationDescriptor . consoleHID ;
2020-05-03 01:25:39 +01:00
len = sizeof ( usbHIDDescriptor_t );
break ;
2020-02-25 12:18:11 +11:00
#endif
2015-04-10 01:32:04 +09:00
}
break ;
case USBDESCR_HID_REPORT :
/* interface index */
switch ( rq -> wIndex . word ) {
2021-01-11 19:46:30 +11:00
#ifndef KEYBOARD_SHARED_EP
2020-05-03 01:25:39 +01:00
case KEYBOARD_INTERFACE :
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) keyboard_hid_report ;
2019-08-30 11:19:03 -07:00
len = sizeof ( keyboard_hid_report );
2015-04-10 01:32:04 +09:00
break ;
2021-01-11 19:46:30 +11:00
#endif
2020-05-03 01:25:39 +01:00
#if defined(RAW_ENABLE)
case RAW_INTERFACE :
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) raw_hid_report ;
2020-03-31 05:15:05 +09:00
len = sizeof ( raw_hid_report );
break ;
2020-05-03 01:25:39 +01:00
#endif
2021-01-11 19:46:30 +11:00
#ifdef SHARED_EP_ENABLE
case SHARED_INTERFACE :
usbMsgPtr = ( usbMsgPtr_t ) shared_hid_report ;
len = sizeof ( shared_hid_report );
2020-05-14 01:24:18 +01:00
break ;
#endif
2021-01-11 19:46:30 +11:00
2020-05-03 01:25:39 +01:00
#if defined(CONSOLE_ENABLE)
case CONSOLE_INTERFACE :
2020-05-30 13:14:59 -07:00
usbMsgPtr = ( usbMsgPtr_t ) console_hid_report ;
2020-05-03 01:25:39 +01:00
len = sizeof ( console_hid_report );
break ;
2020-02-25 12:18:11 +11:00
#endif
2015-04-10 01:32:04 +09:00
}
break ;
}
return len ;
}