Initial implementation of XAP protocol.
This commit is contained in:
parent
f4c447f2df
commit
eba91c6e28
34 changed files with 1934 additions and 4 deletions
|
|
@ -85,6 +85,10 @@ extern keymap_config_t keymap_config;
|
|||
# include "raw_hid.h"
|
||||
#endif
|
||||
|
||||
#ifdef XAP_ENABLE
|
||||
# include "xap.h"
|
||||
#endif
|
||||
|
||||
#ifdef JOYSTICK_ENABLE
|
||||
# include "joystick.h"
|
||||
#endif
|
||||
|
|
@ -249,6 +253,88 @@ static void raw_hid_task(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef XAP_ENABLE
|
||||
extern void xap_receive(xap_token_t token, const uint8_t *data, size_t length);
|
||||
|
||||
void xap_send_base(uint8_t *data, uint8_t length) {
|
||||
// TODO: implement variable size packet
|
||||
if (length != XAP_EPSIZE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: decide if we allow calls to raw_hid_send() in the middle
|
||||
// of other endpoint usage.
|
||||
uint8_t ep = Endpoint_GetCurrentEndpoint();
|
||||
|
||||
Endpoint_SelectEndpoint(XAP_IN_EPNUM);
|
||||
|
||||
// Check to see if the host is ready to accept another packet
|
||||
if (Endpoint_IsINReady()) {
|
||||
// Write data
|
||||
Endpoint_Write_Stream_LE(data, XAP_EPSIZE, NULL);
|
||||
// Finalize the stream transfer to send the last packet
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(ep);
|
||||
}
|
||||
|
||||
void xap_send(xap_token_t token, uint8_t response_flags, const void *data, size_t length) {
|
||||
uint8_t rdata[XAP_EPSIZE] = {0};
|
||||
*(xap_token_t *)&rdata[0] = token;
|
||||
if (length > (XAP_EPSIZE - 4)) response_flags &= ~(XAP_RESPONSE_FLAG_SUCCESS);
|
||||
rdata[2] = response_flags;
|
||||
if (response_flags & (XAP_RESPONSE_FLAG_SUCCESS)) {
|
||||
rdata[3] = (uint8_t)length;
|
||||
if (data != NULL) {
|
||||
memcpy(&rdata[4], data, length);
|
||||
}
|
||||
}
|
||||
xap_send_base(rdata, sizeof(rdata));
|
||||
}
|
||||
|
||||
void xap_receive_base(const void *data) {
|
||||
const uint8_t *u8data = (const uint8_t *)data;
|
||||
xap_token_t token = *(xap_token_t *)&u8data[0];
|
||||
uint8_t length = u8data[2];
|
||||
if (length <= (XAP_EPSIZE - 3)) {
|
||||
xap_receive(token, &u8data[3], length);
|
||||
}
|
||||
}
|
||||
|
||||
static void xap_task(void) {
|
||||
// Create a temporary buffer to hold the read in data from the host
|
||||
uint8_t data[XAP_EPSIZE];
|
||||
bool data_read = false;
|
||||
|
||||
// Device must be connected and configured for the task to run
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured) return;
|
||||
|
||||
Endpoint_SelectEndpoint(XAP_OUT_EPNUM);
|
||||
|
||||
// Check to see if a packet has been sent from the host
|
||||
if (Endpoint_IsOUTReceived()) {
|
||||
// Check to see if the packet contains data
|
||||
if (Endpoint_IsReadWriteAllowed()) {
|
||||
/* Read data */
|
||||
Endpoint_Read_Stream_LE(data, sizeof(data), NULL);
|
||||
data_read = true;
|
||||
}
|
||||
|
||||
// Finalize the stream transfer to receive the last packet
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
if (data_read) {
|
||||
xap_receive_base(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // XAP_ENABLE
|
||||
|
||||
/*******************************************************************************
|
||||
* Console
|
||||
******************************************************************************/
|
||||
|
|
@ -500,6 +586,12 @@ void EVENT_USB_Device_ConfigurationChanged(void) {
|
|||
ConfigSuccess &= Endpoint_ConfigureEndpoint((RAW_OUT_EPNUM | ENDPOINT_DIR_OUT), EP_TYPE_INTERRUPT, RAW_EPSIZE, 1);
|
||||
#endif
|
||||
|
||||
#ifdef XAP_ENABLE
|
||||
/* Setup XAP endpoints */
|
||||
ConfigSuccess &= Endpoint_ConfigureEndpoint((XAP_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, XAP_EPSIZE, 1);
|
||||
ConfigSuccess &= Endpoint_ConfigureEndpoint((XAP_OUT_EPNUM | ENDPOINT_DIR_OUT), EP_TYPE_INTERRUPT, XAP_EPSIZE, 1);
|
||||
#endif // XAP_ENABLE
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
/* Setup console endpoint */
|
||||
ConfigSuccess &= Endpoint_ConfigureEndpoint((CONSOLE_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, CONSOLE_EPSIZE, 1);
|
||||
|
|
@ -1102,6 +1194,10 @@ int main(void) {
|
|||
raw_hid_task();
|
||||
#endif
|
||||
|
||||
#ifdef XAP_ENABLE
|
||||
xap_task();
|
||||
#endif
|
||||
|
||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||
USB_USBTask();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
|
|||
HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
|
||||
HID_RI_END_COLLECTION(0),
|
||||
#endif
|
||||
|
||||
#ifdef SHARED_EP_ENABLE
|
||||
};
|
||||
#endif
|
||||
|
|
@ -255,6 +256,30 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef XAP_ENABLE
|
||||
const USB_Descriptor_HIDReport_Datatype_t PROGMEM XapReport[] = {
|
||||
HID_RI_USAGE_PAGE(16, 0xFF51), // Vendor Defined ('Q')
|
||||
HID_RI_USAGE(8, 0x58), // Vendor Defined ('X')
|
||||
HID_RI_COLLECTION(8, 0x01), // Application
|
||||
// Data to host
|
||||
HID_RI_USAGE(8, 0x62), // Vendor Defined
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
|
||||
HID_RI_REPORT_COUNT(8, XAP_EPSIZE),
|
||||
HID_RI_REPORT_SIZE(8, 0x08),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
||||
|
||||
// Data from host
|
||||
HID_RI_USAGE(8, 0x63), // Vendor Defined
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
|
||||
HID_RI_REPORT_COUNT(8, XAP_EPSIZE),
|
||||
HID_RI_REPORT_SIZE(8, 0x08),
|
||||
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
|
||||
HID_RI_END_COLLECTION(0),
|
||||
};
|
||||
#endif // XAP_ENABLE
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = {
|
||||
HID_RI_USAGE_PAGE(16, 0xFF31), // Vendor Defined (PJRC Teensy compatible)
|
||||
|
|
@ -492,6 +517,56 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = {
|
|||
},
|
||||
#endif
|
||||
|
||||
#ifdef XAP_ENABLE
|
||||
/*
|
||||
* QMK XAP
|
||||
*/
|
||||
.Xap_Interface = {
|
||||
.Header = {
|
||||
.Size = sizeof(USB_Descriptor_Interface_t),
|
||||
.Type = DTYPE_Interface
|
||||
},
|
||||
.InterfaceNumber = XAP_INTERFACE,
|
||||
.AlternateSetting = 0x00,
|
||||
.TotalEndpoints = 2,
|
||||
.Class = HID_CSCP_HIDClass,
|
||||
.SubClass = HID_CSCP_NonBootSubclass,
|
||||
.Protocol = HID_CSCP_NonBootProtocol,
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
.Xap_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(XapReport)
|
||||
},
|
||||
.Xap_INEndpoint = {
|
||||
.Header = {
|
||||
.Size = sizeof(USB_Descriptor_Endpoint_t),
|
||||
.Type = DTYPE_Endpoint
|
||||
},
|
||||
.EndpointAddress = (ENDPOINT_DIR_IN | XAP_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = XAP_EPSIZE,
|
||||
.PollingIntervalMS = 0x01
|
||||
},
|
||||
.Xap_OUTEndpoint = {
|
||||
.Header = {
|
||||
.Size = sizeof(USB_Descriptor_Endpoint_t),
|
||||
.Type = DTYPE_Endpoint
|
||||
},
|
||||
.EndpointAddress = (ENDPOINT_DIR_OUT | XAP_OUT_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = XAP_EPSIZE,
|
||||
.PollingIntervalMS = 0x01
|
||||
},
|
||||
#endif
|
||||
|
||||
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
|
||||
/*
|
||||
* Mouse
|
||||
|
|
@ -1046,6 +1121,14 @@ uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const
|
|||
break;
|
||||
#endif
|
||||
|
||||
#ifdef XAP_ENABLE
|
||||
case XAP_INTERFACE:
|
||||
Address = &ConfigurationDescriptor.Xap_HID;
|
||||
Size = sizeof(USB_HID_Descriptor_HID_t);
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
case CONSOLE_INTERFACE:
|
||||
Address = &ConfigurationDescriptor.Console_HID;
|
||||
|
|
@ -1096,6 +1179,14 @@ uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const
|
|||
break;
|
||||
#endif
|
||||
|
||||
#ifdef XAP_ENABLE
|
||||
case XAP_INTERFACE:
|
||||
Address = &XapReport;
|
||||
Size = sizeof(XapReport);
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
case CONSOLE_INTERFACE:
|
||||
Address = &ConsoleReport;
|
||||
|
|
|
|||
|
|
@ -75,6 +75,14 @@ typedef struct {
|
|||
USB_Descriptor_Endpoint_t Raw_OUTEndpoint;
|
||||
#endif
|
||||
|
||||
#ifdef XAP_ENABLE
|
||||
// Mouse HID Interface
|
||||
USB_Descriptor_Interface_t Xap_Interface;
|
||||
USB_HID_Descriptor_HID_t Xap_HID;
|
||||
USB_Descriptor_Endpoint_t Xap_INEndpoint;
|
||||
USB_Descriptor_Endpoint_t Xap_OUTEndpoint;
|
||||
#endif
|
||||
|
||||
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
|
||||
// Mouse HID Interface
|
||||
USB_Descriptor_Interface_t Mouse_Interface;
|
||||
|
|
@ -155,6 +163,10 @@ enum usb_interfaces {
|
|||
RAW_INTERFACE,
|
||||
#endif
|
||||
|
||||
#ifdef XAP_ENABLE
|
||||
XAP_INTERFACE,
|
||||
#endif
|
||||
|
||||
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
|
||||
MOUSE_INTERFACE,
|
||||
#endif
|
||||
|
|
@ -212,6 +224,15 @@ enum usb_endpoints {
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef XAP_ENABLE
|
||||
XAP_IN_EPNUM = NEXT_EPNUM,
|
||||
# if STM32_USB_USE_OTG1
|
||||
# define XAP_OUT_EPNUM XAP_IN_EPNUM
|
||||
# else
|
||||
XAP_OUT_EPNUM = NEXT_EPNUM,
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef SHARED_EP_ENABLE
|
||||
SHARED_IN_EPNUM = NEXT_EPNUM,
|
||||
#endif
|
||||
|
|
@ -272,7 +293,7 @@ enum usb_endpoints {
|
|||
// TODO - ARM_ATSAM
|
||||
|
||||
#if (NEXT_EPNUM - 1) > MAX_ENDPOINTS
|
||||
# error There are not enough available endpoints to support all functions. Please disable one or more of the following: Mouse Keys, Extra Keys, Console, NKRO, MIDI, Serial, Steno
|
||||
# error There are not enough available endpoints to support all functions. Please disable one or more of the following: Mouse Keys, Extra Keys, Console, NKRO, MIDI, Serial, Steno, XAP
|
||||
#endif
|
||||
|
||||
#define KEYBOARD_EPSIZE 8
|
||||
|
|
@ -284,5 +305,6 @@ enum usb_endpoints {
|
|||
#define CDC_NOTIFICATION_EPSIZE 8
|
||||
#define CDC_EPSIZE 16
|
||||
#define JOYSTICK_EPSIZE 8
|
||||
#define XAP_EPSIZE 64
|
||||
|
||||
uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const void** const DescriptorAddress);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue