From 3851c3dea620a672d266e798f2262f4709136fb7 Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Fri, 15 Feb 2019 13:52:35 -0500
Subject: Disable Pluggable USB

Not compatible with XInput, which requires a static descriptor
---
 cores/arduino/USBDesc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/USBDesc.h b/cores/arduino/USBDesc.h
index c0dce07..cc00a21 100644
--- a/cores/arduino/USBDesc.h
+++ b/cores/arduino/USBDesc.h
@@ -16,7 +16,7 @@
    SOFTWARE.
  */
 
-#define PLUGGABLE_USB_ENABLED
+// #define PLUGGABLE_USB_ENABLED  // Not compatible with XInput
 
 #if defined(EPRST6)
 #define USB_ENDPOINTS 7 // AtMegaxxU4
-- 
cgit v1.2.3-18-g5258


From fbad822c99b957b513b018cb135b41051f93cc11 Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Fri, 15 Feb 2019 13:54:21 -0500
Subject: Fix warning related to disabling Pluggable HID

Unused if pluggable USB is not enabled. Should submit a PR to fix this in the main repo...
---
 cores/arduino/USBCore.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index 81f689d..b5a2be3 100644
--- a/cores/arduino/USBCore.cpp
+++ b/cores/arduino/USBCore.cpp
@@ -496,14 +496,13 @@ bool SendConfiguration(int maxlen)
 static
 bool SendDescriptor(USBSetup& setup)
 {
-	int ret;
 	u8 t = setup.wValueH;
 	if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t)
 		return SendConfiguration(setup.wLength);
 
 	InitControl(setup.wLength);
 #ifdef PLUGGABLE_USB_ENABLED
-	ret = PluggableUSB().getDescriptor(setup);
+	int ret = PluggableUSB().getDescriptor(setup);
 	if (ret != 0) {
 		return (ret > 0 ? true : false);
 	}
-- 
cgit v1.2.3-18-g5258


From 2307486942f246aca947d770849b5d05822d7d17 Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Fri, 15 Feb 2019 14:27:49 -0500
Subject: Replace Serial with null

Allows sketches using Serial to compile but discards all data
---
 cores/arduino/CDC.cpp  | 134 -------------------------------------------------
 cores/arduino/USBAPI.h |  46 ++++++++---------
 2 files changed, 20 insertions(+), 160 deletions(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp
index 142f8f6..9fea948 100644
--- a/cores/arduino/CDC.cpp
+++ b/cores/arduino/CDC.cpp
@@ -163,140 +163,6 @@ bool CDC_Setup(USBSetup& setup)
 	return false;
 }
 
-
-void Serial_::begin(unsigned long /* baud_count */)
-{
-	peek_buffer = -1;
-}
-
-void Serial_::begin(unsigned long /* baud_count */, byte /* config */)
-{
-	peek_buffer = -1;
-}
-
-void Serial_::end(void)
-{
-}
-
-int Serial_::available(void)
-{
-	if (peek_buffer >= 0) {
-		return 1 + USB_Available(CDC_RX);
-	}
-	return USB_Available(CDC_RX);
-}
-
-int Serial_::peek(void)
-{
-	if (peek_buffer < 0)
-		peek_buffer = USB_Recv(CDC_RX);
-	return peek_buffer;
-}
-
-int Serial_::read(void)
-{
-	if (peek_buffer >= 0) {
-		int c = peek_buffer;
-		peek_buffer = -1;
-		return c;
-	}
-	return USB_Recv(CDC_RX);
-}
-
-int Serial_::availableForWrite(void)
-{
-	return USB_SendSpace(CDC_TX);
-}
-
-void Serial_::flush(void)
-{
-	USB_Flush(CDC_TX);
-}
-
-size_t Serial_::write(uint8_t c)
-{
-	return write(&c, 1);
-}
-
-size_t Serial_::write(const uint8_t *buffer, size_t size)
-{
-	/* only try to send bytes if the high-level CDC connection itself 
-	 is open (not just the pipe) - the OS should set lineState when the port
-	 is opened and clear lineState when the port is closed.
-	 bytes sent before the user opens the connection or after
-	 the connection is closed are lost - just like with a UART. */
-	
-	// TODO - ZE - check behavior on different OSes and test what happens if an
-	// open connection isn't broken cleanly (cable is yanked out, host dies
-	// or locks up, or host virtual serial port hangs)
-	if (_usbLineInfo.lineState > 0)	{
-		int r = USB_Send(CDC_TX,buffer,size);
-		if (r > 0) {
-			return r;
-		} else {
-			setWriteError();
-			return 0;
-		}
-	}
-	setWriteError();
-	return 0;
-}
-
-// This operator is a convenient way for a sketch to check whether the
-// port has actually been configured and opened by the host (as opposed
-// to just being connected to the host).  It can be used, for example, in 
-// setup() before printing to ensure that an application on the host is
-// actually ready to receive and display the data.
-// We add a short delay before returning to fix a bug observed by Federico
-// where the port is configured (lineState != 0) but not quite opened.
-Serial_::operator bool() {
-	bool result = false;
-	if (_usbLineInfo.lineState > 0) 
-		result = true;
-	delay(10);
-	return result;
-}
-
-unsigned long Serial_::baud() {
-	// Disable interrupts while reading a multi-byte value
-	uint32_t baudrate;
-	ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
-		baudrate =  _usbLineInfo.dwDTERate;
-	}
-	return baudrate;
-}
-
-uint8_t Serial_::stopbits() {
-	return _usbLineInfo.bCharFormat;
-}
-
-uint8_t Serial_::paritytype() {
-	return _usbLineInfo.bParityType;
-}
-
-uint8_t Serial_::numbits() {
-	return _usbLineInfo.bDataBits;
-}
-
-bool Serial_::dtr() {
-	return _usbLineInfo.lineState & 0x1;
-}
-
-bool Serial_::rts() {
-	return _usbLineInfo.lineState & 0x2;
-}
-
-int32_t Serial_::readBreak() {
-	int32_t ret;
-	// Disable IRQs while reading and clearing breakValue to make
-	// sure we don't overwrite a value just set by the ISR.
-	ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
-		ret = breakValue;
-		breakValue = -1;
-	}
-	return ret;
-}
-
 Serial_ Serial;
 
 #endif /* if defined(USBCON) */
diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h
index 479ced9..06dd737 100644
--- a/cores/arduino/USBAPI.h
+++ b/cores/arduino/USBAPI.h
@@ -87,27 +87,21 @@ struct ring_buffer;
 
 class Serial_ : public Stream
 {
-private:
-	int peek_buffer;
 public:
-	Serial_() { peek_buffer = -1; };
-	void begin(unsigned long);
-	void begin(unsigned long, uint8_t);
-	void end(void);
-
-	virtual int available(void);
-	virtual int peek(void);
-	virtual int read(void);
-	virtual int availableForWrite(void);
-	virtual void flush(void);
-	virtual size_t write(uint8_t);
-	virtual size_t write(const uint8_t*, size_t);
+	Serial_() {};
+	void begin(unsigned long) {}
+	void begin(unsigned long, uint8_t) {}
+	void end(void) {}
+
+	virtual int available(void) { return -1; }
+	virtual int peek(void) { return -1; }
+	virtual int read(void) { return -1; }
+	virtual int availableForWrite(void) { return 0; }
+	virtual void flush(void) {}
+	virtual size_t write(uint8_t) { return 1; }
+	virtual size_t write(const uint8_t*, size_t n) { return n; }
 	using Print::write; // pull in write(str) and write(buf, size) from Print
-	operator bool();
-
-	volatile uint8_t _rx_buffer_head;
-	volatile uint8_t _rx_buffer_tail;
-	unsigned char _rx_buffer[SERIAL_BUFFER_SIZE];
+	operator bool() { return true; }
 
 	// This method allows processing "SEND_BREAK" requests sent by
 	// the USB host. Those requests indicate that the host wants to
@@ -124,17 +118,17 @@ public:
 	// first request is lost.
 	// Note that the value returned is a long, so it can return
 	// 0-0xffff as well as -1.
-	int32_t readBreak();
+	int32_t readBreak() { return -1; };
 
 	// These return the settings specified by the USB host for the
 	// serial port. These aren't really used, but are offered here
 	// in case a sketch wants to act on these settings.
-	uint32_t baud();
-	uint8_t stopbits();
-	uint8_t paritytype();
-	uint8_t numbits();
-	bool dtr();
-	bool rts();
+	uint32_t baud() { return 0; }
+	uint8_t stopbits() { return 1; }
+	uint8_t paritytype() { return 0; }
+	uint8_t numbits() { return 8; }
+	bool dtr() { return true; }
+	bool rts() { return true; }
 	enum {
 		ONE_STOP_BIT = 0,
 		ONE_AND_HALF_STOP_BIT = 1,
-- 
cgit v1.2.3-18-g5258


From 3364c6f736a77e60f26273af0bb021f4507dd1b9 Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Fri, 15 Feb 2019 14:44:45 -0500
Subject: Removed USB CDC Serial

This will compile but will NOT enumerate properly without a config descriptor. You've been warned...
---
 cores/arduino/CDC.cpp     | 143 ----------------------------------------------
 cores/arduino/USBAPI.h    |  17 ------
 cores/arduino/USBCore.cpp |  54 +++--------------
 cores/arduino/USBCore.h   | 107 ----------------------------------
 cores/arduino/USBDesc.h   |  17 ------
 5 files changed, 7 insertions(+), 331 deletions(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp
index 9fea948..a6bce17 100644
--- a/cores/arduino/CDC.cpp
+++ b/cores/arduino/CDC.cpp
@@ -17,152 +17,9 @@
 */
 
 #include "USBAPI.h"
-#include <avr/wdt.h>
-#include <util/atomic.h>
 
 #if defined(USBCON)
 
-typedef struct
-{
-	u32	dwDTERate;
-	u8	bCharFormat;
-	u8 	bParityType;
-	u8 	bDataBits;
-	u8	lineState;
-} LineInfo;
-
-static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
-static volatile int32_t breakValue = -1;
-
-static u8 wdtcsr_save;
-
-#define WEAK __attribute__ ((weak))
-
-extern const CDCDescriptor _cdcInterface PROGMEM;
-const CDCDescriptor _cdcInterface =
-{
-	D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1),
-
-	//	CDC communication interface
-	D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),
-	D_CDCCS(CDC_HEADER,0x10,0x01),								// Header (1.10 bcd)
-	D_CDCCS(CDC_CALL_MANAGEMENT,1,1),							// Device handles call management (not)
-	D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6),				// SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
-	D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE),	// Communication interface is master, data interface is slave 0
-	D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40),
-
-	//	CDC data interface
-	D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
-	D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0),
-	D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0)
-};
-
-bool isLUFAbootloader()
-{
-	return pgm_read_word(FLASHEND - 1) == NEW_LUFA_SIGNATURE;
-}
-
-int CDC_GetInterface(u8* interfaceNum)
-{
-	interfaceNum[0] += 2;	// uses 2
-	return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface));
-}
-
-bool CDC_Setup(USBSetup& setup)
-{
-	u8 r = setup.bRequest;
-	u8 requestType = setup.bmRequestType;
-
-	if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
-	{
-		if (CDC_GET_LINE_CODING == r)
-		{
-			USB_SendControl(0,(void*)&_usbLineInfo,7);
-			return true;
-		}
-	}
-
-	if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
-	{
-		if (CDC_SEND_BREAK == r)
-		{
-			breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
-		}
-
-		if (CDC_SET_LINE_CODING == r)
-		{
-			USB_RecvControl((void*)&_usbLineInfo,7);
-		}
-
-		if (CDC_SET_CONTROL_LINE_STATE == r)
-		{
-			_usbLineInfo.lineState = setup.wValueL;
-
-			// auto-reset into the bootloader is triggered when the port, already 
-			// open at 1200 bps, is closed.  this is the signal to start the watchdog
-			// with a relatively long period so it can finish housekeeping tasks
-			// like servicing endpoints before the sketch ends
-
-			uint16_t magic_key_pos = MAGIC_KEY_POS;
-
-// If we don't use the new RAMEND directly, check manually if we have a newer bootloader.
-// This is used to keep compatible with the old leonardo bootloaders.
-// You are still able to set the magic key position manually to RAMEND-1 to save a few bytes for this check.
-#if MAGIC_KEY_POS != (RAMEND-1)
-			// For future boards save the key in the inproblematic RAMEND
-			// Which is reserved for the main() return value (which will never return)
-			if (isLUFAbootloader()) {
-				// horray, we got a new bootloader!
-				magic_key_pos = (RAMEND-1);
-			}
-#endif
-
-			// We check DTR state to determine if host port is open (bit 0 of lineState).
-			if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
-			{
-#if MAGIC_KEY_POS != (RAMEND-1)
-				// Backup ram value if its not a newer bootloader and it hasn't already been saved.
-				// This should avoid memory corruption at least a bit, not fully
-				if (magic_key_pos != (RAMEND-1) && *(uint16_t *)magic_key_pos != MAGIC_KEY) {
-					*(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos;
-				}
-#endif
-				// Store boot key
-				*(uint16_t *)magic_key_pos = MAGIC_KEY;
-				// Save the watchdog state in case the reset is aborted.
-				wdtcsr_save = WDTCSR;
-				wdt_enable(WDTO_120MS);
-			}
-			else if (*(uint16_t *)magic_key_pos == MAGIC_KEY)
-			{
-				// Most OSs do some intermediate steps when configuring ports and DTR can
-				// twiggle more than once before stabilizing.
-				// To avoid spurious resets we set the watchdog to 120ms and eventually
-				// cancel if DTR goes back high.
-				// Cancellation is only done if an auto-reset was started, which is
-				// indicated by the magic key having been set.
-
-				wdt_reset();
-				// Restore the watchdog state in case the sketch was using it.
-				WDTCSR |= (1<<WDCE) | (1<<WDE);
-				WDTCSR = wdtcsr_save;
-#if MAGIC_KEY_POS != (RAMEND-1)
-				// Restore backed up (old bootloader) magic key data
-				if (magic_key_pos != (RAMEND-1)) {
-					*(uint16_t *)magic_key_pos = *(uint16_t *)(RAMEND-1);
-				} else
-#endif
-				{
-				// Clean up RAMEND key
-					*(uint16_t *)magic_key_pos = 0x0000;
-				}
-			}
-		}
-		return true;
-	}
-	return false;
-}
-
 Serial_ Serial;
 
 #endif /* if defined(USBCON) */
diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h
index 06dd737..04e3dd9 100644
--- a/cores/arduino/USBAPI.h
+++ b/cores/arduino/USBAPI.h
@@ -161,23 +161,6 @@ typedef struct
 	uint16_t wLength;
 } USBSetup;
 
-//================================================================================
-//================================================================================
-//	MSC 'Driver'
-
-int		MSC_GetInterface(uint8_t* interfaceNum);
-int		MSC_GetDescriptor(int i);
-bool	MSC_Setup(USBSetup& setup);
-bool	MSC_Data(uint8_t rx,uint8_t tx);
-
-//================================================================================
-//================================================================================
-//	CSC 'Driver'
-
-int		CDC_GetInterface(uint8_t* interfaceNum);
-int		CDC_GetDescriptor(int i);
-bool	CDC_Setup(USBSetup& setup);
-
 //================================================================================
 //================================================================================
 
diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index b5a2be3..6146954 100644
--- a/cores/arduino/USBCore.cpp
+++ b/cores/arduino/USBCore.cpp
@@ -327,12 +327,10 @@ int USB_Send(u8 ep, const void* d, int len)
 
 u8 _initEndpoints[USB_ENDPOINTS] =
 {
-	0,                      // Control Endpoint
-	
-	EP_TYPE_INTERRUPT_IN,   // CDC_ENDPOINT_ACM
-	EP_TYPE_BULK_OUT,       // CDC_ENDPOINT_OUT
-	EP_TYPE_BULK_IN,        // CDC_ENDPOINT_IN
-
+	0,                         // Control Endpoint
+	// EP_TYPE_INTERRUPT_IN,   // CDC_ENDPOINT_ACM
+	// EP_TYPE_BULK_OUT,       // CDC_ENDPOINT_OUT
+	// EP_TYPE_BULK_IN,        // CDC_ENDPOINT_IN
 	// Following endpoints are automatically initialized to 0
 };
 
@@ -369,21 +367,6 @@ void InitEndpoints()
 	UERST = 0;
 }
 
-//	Handle CLASS_INTERFACE requests
-static
-bool ClassInterfaceRequest(USBSetup& setup)
-{
-	u8 i = setup.wIndex;
-
-	if (CDC_ACM_INTERFACE == i)
-		return CDC_Setup(setup);
-
-#ifdef PLUGGABLE_USB_ENABLED
-	return PluggableUSB().setup(setup);
-#endif
-	return false;
-}
-
 static int _cmark;
 static int _cend;
 void InitControl(int end)
@@ -462,34 +445,14 @@ int USB_RecvControl(void* d, int len)
 	return len;
 }
 
-static u8 SendInterfaces()
-{
-	u8 interfaces = 0;
-
-	CDC_GetInterface(&interfaces);
-
-#ifdef PLUGGABLE_USB_ENABLED
-	PluggableUSB().getInterface(&interfaces);
-#endif
-
-	return interfaces;
-}
-
 //	Construct a dynamic configuration descriptor
 //	This really needs dynamic endpoint allocation etc
 //	TODO
 static
 bool SendConfiguration(int maxlen)
 {
-	//	Count and measure interfaces
-	InitControl(0);
-	u8 interfaces = SendInterfaces();
-	ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
-
-	//	Now send them
-	InitControl(maxlen);
-	USB_SendControl(0,&config,sizeof(ConfigDescriptor));
-	SendInterfaces();
+	// InitControl(maxlen);
+	// USB_SendControl( * Config Descriptor Here * );
 	return true;
 }
 
@@ -632,8 +595,7 @@ ISR(USB_COM_vect)
 	}
 	else
 	{
-		InitControl(setup.wLength);		//	Max length of transfer
-		ok = ClassInterfaceRequest(setup);
+		ok = true;
 	}
 
 	if (ok)
@@ -754,8 +716,6 @@ ISR(USB_GEN_vect)
 	//	Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too
 	if (udint & (1<<SOFI))
 	{
-		USB_Flush(CDC_TX);				// Send a tx frame if found
-		
 		// check whether the one-shot period has elapsed.  if so, turn off the LED
 		if (TxLEDPulse && !(--TxLEDPulse))
 			TXLED0;
diff --git a/cores/arduino/USBCore.h b/cores/arduino/USBCore.h
index 4210ced..eafdbe5 100644
--- a/cores/arduino/USBCore.h
+++ b/cores/arduino/USBCore.h
@@ -53,16 +53,6 @@
 #define REQUEST_HOSTTODEVICE_CLASS_INTERFACE    (REQUEST_HOSTTODEVICE | REQUEST_CLASS | REQUEST_INTERFACE)
 #define REQUEST_DEVICETOHOST_STANDARD_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_INTERFACE)
 
-//	Class requests
-
-#define CDC_SET_LINE_CODING			0x20
-#define CDC_GET_LINE_CODING			0x21
-#define CDC_SET_CONTROL_LINE_STATE	0x22
-#define CDC_SEND_BREAK				0x23
-
-#define MSC_RESET					0xFF
-#define MSC_GET_MAX_LUN				0xFE
-
 //	Descriptors
 
 #define USB_DEVICE_DESC_SIZE 18
@@ -111,21 +101,6 @@
 
 #define TOBYTES(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
 
-#define CDC_V1_10                               0x0110
-#define CDC_COMMUNICATION_INTERFACE_CLASS       0x02
-
-#define CDC_CALL_MANAGEMENT                     0x01
-#define CDC_ABSTRACT_CONTROL_MODEL              0x02
-#define CDC_HEADER                              0x00
-#define CDC_ABSTRACT_CONTROL_MANAGEMENT         0x02
-#define CDC_UNION                               0x06
-#define CDC_CS_INTERFACE                        0x24
-#define CDC_CS_ENDPOINT                         0x25
-#define CDC_DATA_INTERFACE_CLASS                0x0A
-
-#define MSC_SUBCLASS_SCSI						0x06 
-#define MSC_PROTOCOL_BULK_ONLY					0x50 
-
 #ifndef USB_VERSION
 #define USB_VERSION 0x200
 #endif
@@ -187,82 +162,6 @@ typedef struct
 	u8 interval;
 } EndpointDescriptor;
 
-// Interface Association Descriptor
-// Used to bind 2 interfaces together in CDC compostite device
-typedef struct
-{
-	u8 len;				// 8
-	u8 dtype;			// 11
-	u8 firstInterface;
-	u8 interfaceCount;
-	u8 functionClass;
-	u8 funtionSubClass;
-	u8 functionProtocol;
-	u8 iInterface;
-} IADDescriptor;
-
-//	CDC CS interface descriptor
-typedef struct
-{
-	u8 len;		// 5
-	u8 dtype;	// 0x24
-	u8 subtype;
-	u8 d0;
-	u8 d1;
-} CDCCSInterfaceDescriptor;
-
-typedef struct
-{
-	u8 len;		// 4
-	u8 dtype;	// 0x24
-	u8 subtype;
-	u8 d0;
-} CDCCSInterfaceDescriptor4;
-
-typedef struct 
-{
-    u8	len;
-    u8 	dtype;		// 0x24
-    u8 	subtype;	// 1
-    u8 	bmCapabilities;
-    u8 	bDataInterface;
-} CMFunctionalDescriptor;
-	
-typedef struct 
-{
-    u8	len;
-    u8 	dtype;		// 0x24
-    u8 	subtype;	// 1
-    u8 	bmCapabilities;
-} ACMFunctionalDescriptor;
-
-typedef struct 
-{
-	//	IAD
-	IADDescriptor				iad;	// Only needed on compound device
-
-	//	Control
-	InterfaceDescriptor			cif;	// 
-	CDCCSInterfaceDescriptor	header;
-	CMFunctionalDescriptor		callManagement;			// Call Management
-	ACMFunctionalDescriptor		controlManagement;		// ACM
-	CDCCSInterfaceDescriptor	functionalDescriptor;	// CDC_UNION
-	EndpointDescriptor			cifin;
-
-	//	Data
-	InterfaceDescriptor			dif;
-	EndpointDescriptor			in;
-	EndpointDescriptor			out;
-} CDCDescriptor;
-
-typedef struct 
-{
-	InterfaceDescriptor			msc;
-	EndpointDescriptor			in;
-	EndpointDescriptor			out;
-} MSCDescriptor;
-
-
 #define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \
 	{ 18, 1, USB_VERSION, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs }
 
@@ -275,12 +174,6 @@ typedef struct
 #define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \
 	{ 7, 5, _addr,_attr,_packetSize, _interval }
 
-#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \
-	{ 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 }
-
-#define D_CDCCS(_subtype,_d0,_d1)	{ 5, 0x24, _subtype, _d0, _d1 }
-#define D_CDCCS4(_subtype,_d0)		{ 4, 0x24, _subtype, _d0 }
-
 // Bootloader related fields
 // Old Caterina bootloader places the MAGIC key into unsafe RAM locations (it can be rewritten
 // by the running sketch before to actual reboot).
diff --git a/cores/arduino/USBDesc.h b/cores/arduino/USBDesc.h
index cc00a21..fe1af92 100644
--- a/cores/arduino/USBDesc.h
+++ b/cores/arduino/USBDesc.h
@@ -24,23 +24,6 @@
 #define USB_ENDPOINTS 5 // AtMegaxxU2
 #endif
 
-#define ISERIAL_MAX_LEN     20
-
-#define CDC_INTERFACE_COUNT	2
-#define CDC_ENPOINT_COUNT	3
-
-#define CDC_ACM_INTERFACE	0	// CDC ACM
-#define CDC_DATA_INTERFACE	1	// CDC Data
-#define CDC_FIRST_ENDPOINT	1
-#define CDC_ENDPOINT_ACM	(CDC_FIRST_ENDPOINT)							// CDC First
-#define CDC_ENDPOINT_OUT	(CDC_FIRST_ENDPOINT+1)
-#define CDC_ENDPOINT_IN		(CDC_FIRST_ENDPOINT+2)
-
-#define INTERFACE_COUNT		(MSC_INTERFACE + MSC_INTERFACE_COUNT)
-
-#define CDC_RX CDC_ENDPOINT_OUT
-#define CDC_TX CDC_ENDPOINT_IN
-
 #define IMANUFACTURER   1
 #define IPRODUCT        2
 #define ISERIAL         3
\ No newline at end of file
-- 
cgit v1.2.3-18-g5258


From 60b8a6df837a31bc9783cf34a98bcda9917b7ba6 Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Sun, 17 Feb 2019 14:18:23 -0500
Subject: Add XInput device and config descriptors

---
 cores/arduino/USBAPI.h                          |   1 +
 cores/arduino/USBCore.cpp                       |  14 +-
 cores/arduino/xinput/USB_XInput_Descriptors.cpp | 207 ++++++++++++++++++++++++
 cores/arduino/xinput/USB_XInput_Descriptors.h   |  46 ++++++
 4 files changed, 257 insertions(+), 11 deletions(-)
 create mode 100644 cores/arduino/xinput/USB_XInput_Descriptors.cpp
 create mode 100644 cores/arduino/xinput/USB_XInput_Descriptors.h

(limited to 'cores/arduino')

diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h
index 04e3dd9..86713dd 100644
--- a/cores/arduino/USBAPI.h
+++ b/cores/arduino/USBAPI.h
@@ -42,6 +42,7 @@ typedef unsigned long u32;
 
 #include "USBDesc.h"
 #include "USBCore.h"
+#include "xinput/USB_XInput_Descriptors.h"
 
 //================================================================================
 //================================================================================
diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index 6146954..f2f5540 100644
--- a/cores/arduino/USBCore.cpp
+++ b/cores/arduino/USBCore.cpp
@@ -34,7 +34,6 @@ volatile u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
 extern const u16 STRING_LANGUAGE[] PROGMEM;
 extern const u8 STRING_PRODUCT[] PROGMEM;
 extern const u8 STRING_MANUFACTURER[] PROGMEM;
-extern const DeviceDescriptor USB_DeviceDescriptorIAD PROGMEM;
 
 const u16 STRING_LANGUAGE[2] = {
 	(3<<8) | (2+2),
@@ -65,13 +64,6 @@ const u8 STRING_PRODUCT[] PROGMEM = USB_PRODUCT;
 
 const u8 STRING_MANUFACTURER[] PROGMEM = USB_MANUFACTURER;
 
-
-#define DEVICE_CLASS 0x02
-
-//	DEVICE DESCRIPTOR
-const DeviceDescriptor USB_DeviceDescriptorIAD =
-	D_DEVICE(0xEF,0x02,0x01,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,ISERIAL,1);
-
 //==================================================================
 //==================================================================
 
@@ -451,8 +443,8 @@ int USB_RecvControl(void* d, int len)
 static
 bool SendConfiguration(int maxlen)
 {
-	// InitControl(maxlen);
-	// USB_SendControl( * Config Descriptor Here * );
+	InitControl(maxlen);
+	USB_SendControl(TRANSFER_PGM, &USB_ConfigDescriptor, USB_ConfigDescriptorSize);
 	return true;
 }
 
@@ -474,7 +466,7 @@ bool SendDescriptor(USBSetup& setup)
 	const u8* desc_addr = 0;
 	if (USB_DEVICE_DESCRIPTOR_TYPE == t)
 	{
-		desc_addr = (const u8*)&USB_DeviceDescriptorIAD;
+		desc_addr = (const u8*) &USB_DeviceDescriptor;
 	}
 	else if (USB_STRING_DESCRIPTOR_TYPE == t)
 	{
diff --git a/cores/arduino/xinput/USB_XInput_Descriptors.cpp b/cores/arduino/xinput/USB_XInput_Descriptors.cpp
new file mode 100644
index 0000000..c9acd02
--- /dev/null
+++ b/cores/arduino/xinput/USB_XInput_Descriptors.cpp
@@ -0,0 +1,207 @@
+/*
+ *  Project     Arduino XInput - AVR Core
+ *  @author     David Madison
+ *  @link       github.com/dmadison/ArduinoXInput_AVR
+ *  @license    MIT - Copyright (c) 2019 David Madison
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "USB_XInput_Descriptors.h"
+
+#if defined(USBCON)
+
+const DeviceDescriptor USB_DeviceDescriptor = {
+	0x12,           // bLength (18)
+	0x01,           // bDescriptorType (DEVICE)
+	USB_VERSION,    // bcdUSB (2.0)
+	0xFF,           // bDeviceClass
+	0xFF,           // bDeviceSubClass
+	0xFF,           // bDeviceProtocol
+	0x40,           // bMaxPacketSize0
+	USB_VID,        // idEVendor
+	USB_PID,        // idProduct
+	0x114,          // bcdDevice
+	IMANUFACTURER,  // iManufacturer
+	IPRODUCT,       // iProduct
+	ISERIAL,        // iSerialNumber
+	0x01,           // bNumConfigurations
+};
+
+const u8 USB_ConfigDescriptor[] = {
+	// Configuration Descriptor
+	0x09,        // bLength
+	0x02,        // bDescriptorType (CONFIGURATION)
+	0x99, 0x00,  // wTotalLength (153)
+	0x04,        // bNumInterfaces
+	0x01,        // bConfigurationValue
+	0x00,        // iConfiguration
+	0xA0,        // bmAttributes
+	0xFA,        // bMaxPower
+
+	/* ---------------------------------------------------- */
+	// Interface 0: Control Data
+	0x09,        // bLength
+	0x04,        // bDescriptorType (INTERFACE)
+	0x00,        // bInterfaceNumber
+	0x00,        // bAlternateSetting
+	0x02,        // bNumEndpoints
+	0xFF,        // bInterfaceClass
+	0x5D,        // bInterfaceSubClass
+	0x01,        // bInterfaceProtocol
+	0x00,        // iInterface
+
+	// Unknown Descriptor (If0)
+	0x11,        // bLength
+	0x21,        // bDescriptorType
+	0x00, 0x01, 0x01, 0x25,  // ???
+	0x81,        // bEndpointAddress (IN, 1)
+	0x14,        // bMaxDataSize
+	0x00, 0x00, 0x00, 0x00, 0x13,  // ???
+	0x01,        // bEndpointAddress (OUT, 1)
+	0x08,        // bMaxDataSize
+	0x00, 0x00,  // ???
+
+	// Endpoint 1: Control Data Out
+	0x07,        // bLength
+	0x05,        // bDescriptorType (ENDPOINT)
+	0x81,        // bEndpointAddress (IN, 1)
+	0x03,        // bmAttributes
+	0x20, 0x00,  // wMaxPacketSize
+	0x04,        // bInterval
+
+	// Endpoint 1: Control Data In
+	0x07,        // bLength
+	0x05,        // bDescriptorType (ENDPOINT)
+	0x01,        // bEndpointAddress (OUT, 1)
+	0x03,        // bmAttributes
+	0x20, 0x00,  // wMaxPacketSize
+	0x08,        // bInterval
+
+	/* ---------------------------------------------------- */
+	// Interface 1: Headset (and Expansion Port?)
+	0x09,        // bLength
+	0x04,        // bDescriptorType (INTERFACE)
+	0x01,        // bInterfaceNumber
+	0x00,        // bAlternateSetting
+	0x04,        // bNumEndpoints
+	0xFF,        // bInterfaceClass
+	0x5D,        // bInterfaceSubClass
+	0x03,        // bInterfaceProtocol
+	0x00,        // iInterface
+
+	// Unknown Descriptor (If1)
+	0x1B,        // bLength
+	0x21,        // bDescriptorType
+	0x00, 0x01, 0x01, 0x01,  // ???
+	0x82,        // bEndpointAddress (IN, 2)
+	0x40,        // bMaxDataSize
+	0x01,        // ???
+	0x02,        // bEndpointAddress (OUT, 2)
+	0x20,        // bMaxDataSize
+	0x16,        // ???
+	0x83,        // bEndpointAddress (IN, 3)
+	0x00,        // bMaxDataSize
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x16,  // ???
+	0x03,        // bEndpointAddress (OUT, 3)
+	0x00,        // bMaxDataSize
+	0x00, 0x00, 0x00, 0x00, 0x00,  // ???
+
+	// Endpoint 2: Microphone Data Out
+	0x07,        // bLength
+	0x05,        // bDescriptorType (ENDPOINT)
+	0x82,        // bEndpointAddress (IN, 2)
+	0x03,        // bmAttributes
+	0x20, 0x00,  // wMaxPacketSize
+	0x02,        // bInterval
+
+	// Endpoint 2: Headset Audio In
+	0x07,        // bLength
+	0x05,        // bDescriptorType (ENDPOINT)
+	0x02,        // bEndpointAddress (OUT, 2)
+	0x03,        // bmAttributes
+	0x20, 0x00,  // wMaxPacketSize
+	0x04,        // bInterval
+
+	// Endpoint 3: Unknown, Out
+	0x07,        // bLength
+	0x05,        // bDescriptorType (ENDPOINT)
+	0x83,        // bEndpointAddress (IN, 3)
+	0x03,        // bmAttributes
+	0x20, 0x00,  // wMaxPacketSize
+	0x40,        // bInterval
+
+	// Endpoint 3: Unknown, In
+	0x07,        // bLength
+	0x05,        // bDescriptorType (ENDPOINT)
+	0x03,        // bEndpointAddress (OUT, 3)
+	0x03,        // bmAttributes
+	0x20, 0x00,  // wMaxPacketSize
+	0x10,        // bInterval
+
+	/* ---------------------------------------------------- */
+	// Interface 2: Unknown
+	0x09,        // bLength
+	0x04,        // bDescriptorType (INTERFACE)
+	0x02,        // bInterfaceNumber
+	0x00,        // bAlternateSetting
+	0x01,        // bNumEndpoints
+	0xFF,        // bInterfaceClass
+	0x5D,        // bInterfaceSubClass
+	0x02,        // bInterfaceProtocol
+	0x00,        // iInterface
+
+	// Unknown Descriptor (If2)
+	0x09,        // bLength
+	0x21,        // bDescriptorType
+	0x00, 0x01, 0x01, 0x22,  // ???
+	0x84,        // bEndpointAddress (IN, 4)
+	0x07,        // bMaxDataSize
+	0x00,        // ???
+
+	// Endpoint 4: Unknown, Out
+	0x07,        // bLength
+	0x05,        // bDescriptorType (ENDPOINT)
+	0x84,        // bEndpointAddress (IN, 4)
+	0x03,        // bmAttributes
+	0x20, 0x00,  // wMaxPacketSize
+	0x10,        // bInterval
+
+	/* ---------------------------------------------------- */
+	// Interface 3: Security Method
+	0x09,        // bLength
+	0x04,        // bDescriptorType (INTERFACE)
+	0x03,        // bInterfaceNumber
+	0x00,        // bAlternateSetting
+	0x00,        // bNumEndpoints
+	0xFF,        // bInterfaceClass
+	0xFD,        // bInterfaceSubClass
+	0x13,        // bInterfaceProtocol
+	0x04,        // iInterface
+
+	// Unknown Descriptor (If3)
+	0x06,        // bLength
+	0x41,        // bDescriptorType
+	0x00, 0x01, 0x01, 0x03,  // ???
+};
+
+const u16 USB_ConfigDescriptorSize = sizeof(USB_ConfigDescriptor);
+
+#endif /* if defined(USBCON) */
diff --git a/cores/arduino/xinput/USB_XInput_Descriptors.h b/cores/arduino/xinput/USB_XInput_Descriptors.h
new file mode 100644
index 0000000..e8c3c24
--- /dev/null
+++ b/cores/arduino/xinput/USB_XInput_Descriptors.h
@@ -0,0 +1,46 @@
+/*
+ *  Project     Arduino XInput - AVR Core
+ *  @author     David Madison
+ *  @link       github.com/dmadison/ArduinoXInput_AVR
+ *  @license    MIT - Copyright (c) 2019 David Madison
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "USBAPI.h"
+
+#ifndef USB_XINPUT_DESCRIPTORS_H
+#define USB_XINPUT_DESCRIPTORS_H
+
+#if defined(USBCON)
+
+extern const DeviceDescriptor USB_DeviceDescriptor PROGMEM;
+extern const u8  USB_ConfigDescriptor[] PROGMEM;
+extern const u16 USB_ConfigDescriptorSize PROGMEM;
+
+#undef USB_VID
+#define USB_VID 0x045E
+
+#undef USB_PID
+#define USB_PID 0x028E
+
+#endif /* if defined(USBCON) */
+
+#endif /* ifndef USB_XINPUT_DESCRIPTORS_H */
-- 
cgit v1.2.3-18-g5258


From a326a6ed8ee990acd8452adb2733a7c5f8a9963c Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Sun, 17 Feb 2019 17:05:16 -0500
Subject: Add XInput string descriptors

---
 cores/arduino/USBCore.cpp                       | 5 +++++
 cores/arduino/xinput/USB_XInput_Descriptors.cpp | 3 +++
 cores/arduino/xinput/USB_XInput_Descriptors.h   | 9 +++++++++
 3 files changed, 17 insertions(+)

(limited to 'cores/arduino')

diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index f2f5540..f239999 100644
--- a/cores/arduino/USBCore.cpp
+++ b/cores/arduino/USBCore.cpp
@@ -484,8 +484,13 @@ bool SendDescriptor(USBSetup& setup)
 			char name[ISERIAL_MAX_LEN];
 			PluggableUSB().getShortName(name);
 			return USB_SendStringDescriptor((uint8_t*)name, strlen(name), 0);
+#else
+			return USB_SendStringDescriptor(STRING_SERIAL, strlen((char*)STRING_SERIAL), TRANSFER_PGM);
 #endif
 		}
+		else if (setup.wValueL == ISECURITY) {
+			return USB_SendStringDescriptor(STRING_SECURITY, strlen((char*)STRING_SECURITY), TRANSFER_PGM);
+		}
 		else
 			return false;
 	}
diff --git a/cores/arduino/xinput/USB_XInput_Descriptors.cpp b/cores/arduino/xinput/USB_XInput_Descriptors.cpp
index c9acd02..af8b573 100644
--- a/cores/arduino/xinput/USB_XInput_Descriptors.cpp
+++ b/cores/arduino/xinput/USB_XInput_Descriptors.cpp
@@ -204,4 +204,7 @@ const u8 USB_ConfigDescriptor[] = {
 
 const u16 USB_ConfigDescriptorSize = sizeof(USB_ConfigDescriptor);
 
+const u8 STRING_SERIAL[] = "Arduino XInput AVR";
+const u8 STRING_SECURITY[] = "Xbox Security Method 3, Version 1.00, \xA9 2005 Microsoft Corporation. All rights reserved.";
+
 #endif /* if defined(USBCON) */
diff --git a/cores/arduino/xinput/USB_XInput_Descriptors.h b/cores/arduino/xinput/USB_XInput_Descriptors.h
index e8c3c24..8cb19df 100644
--- a/cores/arduino/xinput/USB_XInput_Descriptors.h
+++ b/cores/arduino/xinput/USB_XInput_Descriptors.h
@@ -31,10 +31,19 @@
 
 #if defined(USBCON)
 
+// Device Descriptor
 extern const DeviceDescriptor USB_DeviceDescriptor PROGMEM;
+
+// Config Descriptor
 extern const u8  USB_ConfigDescriptor[] PROGMEM;
 extern const u16 USB_ConfigDescriptorSize PROGMEM;
 
+// String Descriptors
+extern const u8 STRING_SERIAL[] PROGMEM;
+extern const u8 STRING_SECURITY[] PROGMEM;
+
+#define ISECURITY 4
+
 #undef USB_VID
 #define USB_VID 0x045E
 
-- 
cgit v1.2.3-18-g5258


From 5b5ddcf165f8dfa601abd28af1c73a6fcfedae98 Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Sun, 17 Feb 2019 22:47:15 -0500
Subject: Modify endpoint numbers to be sequential

Easier for the AVR to deal with the memory if the in/out numbers aren't paired.
---
 cores/arduino/xinput/USB_XInput_Descriptors.cpp | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/xinput/USB_XInput_Descriptors.cpp b/cores/arduino/xinput/USB_XInput_Descriptors.cpp
index af8b573..ef9b9d8 100644
--- a/cores/arduino/xinput/USB_XInput_Descriptors.cpp
+++ b/cores/arduino/xinput/USB_XInput_Descriptors.cpp
@@ -75,7 +75,7 @@ const u8 USB_ConfigDescriptor[] = {
 	0x81,        // bEndpointAddress (IN, 1)
 	0x14,        // bMaxDataSize
 	0x00, 0x00, 0x00, 0x00, 0x13,  // ???
-	0x01,        // bEndpointAddress (OUT, 1)
+	0x02,        // bEndpointAddress (OUT, 2)
 	0x08,        // bMaxDataSize
 	0x00, 0x00,  // ???
 
@@ -90,7 +90,7 @@ const u8 USB_ConfigDescriptor[] = {
 	// Endpoint 1: Control Data In
 	0x07,        // bLength
 	0x05,        // bDescriptorType (ENDPOINT)
-	0x01,        // bEndpointAddress (OUT, 1)
+	0x02,        // bEndpointAddress (OUT, 2)
 	0x03,        // bmAttributes
 	0x20, 0x00,  // wMaxPacketSize
 	0x08,        // bInterval
@@ -111,23 +111,23 @@ const u8 USB_ConfigDescriptor[] = {
 	0x1B,        // bLength
 	0x21,        // bDescriptorType
 	0x00, 0x01, 0x01, 0x01,  // ???
-	0x82,        // bEndpointAddress (IN, 2)
+	0x83,        // bEndpointAddress (IN, 3)
 	0x40,        // bMaxDataSize
 	0x01,        // ???
-	0x02,        // bEndpointAddress (OUT, 2)
+	0x04,        // bEndpointAddress (OUT, 4)
 	0x20,        // bMaxDataSize
 	0x16,        // ???
-	0x83,        // bEndpointAddress (IN, 3)
+	0x85,        // bEndpointAddress (IN, 5)
 	0x00,        // bMaxDataSize
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x16,  // ???
-	0x03,        // bEndpointAddress (OUT, 3)
+	0x05,        // bEndpointAddress (OUT, 5)
 	0x00,        // bMaxDataSize
 	0x00, 0x00, 0x00, 0x00, 0x00,  // ???
 
 	// Endpoint 2: Microphone Data Out
 	0x07,        // bLength
 	0x05,        // bDescriptorType (ENDPOINT)
-	0x82,        // bEndpointAddress (IN, 2)
+	0x83,        // bEndpointAddress (IN, 3)
 	0x03,        // bmAttributes
 	0x20, 0x00,  // wMaxPacketSize
 	0x02,        // bInterval
@@ -135,7 +135,7 @@ const u8 USB_ConfigDescriptor[] = {
 	// Endpoint 2: Headset Audio In
 	0x07,        // bLength
 	0x05,        // bDescriptorType (ENDPOINT)
-	0x02,        // bEndpointAddress (OUT, 2)
+	0x04,        // bEndpointAddress (OUT, 4)
 	0x03,        // bmAttributes
 	0x20, 0x00,  // wMaxPacketSize
 	0x04,        // bInterval
@@ -143,7 +143,7 @@ const u8 USB_ConfigDescriptor[] = {
 	// Endpoint 3: Unknown, Out
 	0x07,        // bLength
 	0x05,        // bDescriptorType (ENDPOINT)
-	0x83,        // bEndpointAddress (IN, 3)
+	0x85,        // bEndpointAddress (IN, 5)
 	0x03,        // bmAttributes
 	0x20, 0x00,  // wMaxPacketSize
 	0x40,        // bInterval
@@ -151,7 +151,7 @@ const u8 USB_ConfigDescriptor[] = {
 	// Endpoint 3: Unknown, In
 	0x07,        // bLength
 	0x05,        // bDescriptorType (ENDPOINT)
-	0x03,        // bEndpointAddress (OUT, 3)
+	0x05,        // bEndpointAddress (OUT, 5)
 	0x03,        // bmAttributes
 	0x20, 0x00,  // wMaxPacketSize
 	0x10,        // bInterval
@@ -172,14 +172,14 @@ const u8 USB_ConfigDescriptor[] = {
 	0x09,        // bLength
 	0x21,        // bDescriptorType
 	0x00, 0x01, 0x01, 0x22,  // ???
-	0x84,        // bEndpointAddress (IN, 4)
+	0x86,        // bEndpointAddress (IN, 6)
 	0x07,        // bMaxDataSize
 	0x00,        // ???
 
 	// Endpoint 4: Unknown, Out
 	0x07,        // bLength
 	0x05,        // bDescriptorType (ENDPOINT)
-	0x84,        // bEndpointAddress (IN, 4)
+	0x86,        // bEndpointAddress (IN, 6)
 	0x03,        // bmAttributes
 	0x20, 0x00,  // wMaxPacketSize
 	0x10,        // bInterval
-- 
cgit v1.2.3-18-g5258


From 905158b7844c5e346439d18f856a7a9a59f467ab Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Sun, 17 Feb 2019 22:58:02 -0500
Subject: Allocate XInput endpoint memory

---
 cores/arduino/USBCore.cpp | 61 +++++++++++++++++++++++++----------------------
 1 file changed, 32 insertions(+), 29 deletions(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index f239999..8794250 100644
--- a/cores/arduino/USBCore.cpp
+++ b/cores/arduino/USBCore.cpp
@@ -317,46 +317,49 @@ int USB_Send(u8 ep, const void* d, int len)
 	return r;
 }
 
-u8 _initEndpoints[USB_ENDPOINTS] =
-{
-	0,                         // Control Endpoint
-	// EP_TYPE_INTERRUPT_IN,   // CDC_ENDPOINT_ACM
-	// EP_TYPE_BULK_OUT,       // CDC_ENDPOINT_OUT
-	// EP_TYPE_BULK_IN,        // CDC_ENDPOINT_IN
-	// Following endpoints are automatically initialized to 0
-};
-
 #define EP_SINGLE_64 0x32	// EP0
 #define EP_DOUBLE_64 0x36	// Other endpoints
 #define EP_SINGLE_16 0x12
 
-static
+static inline
+u8 BankSizeMask(const uint8_t nbytes)
+{
+	uint8_t mask = 0;
+	for (uint8_t size = 8; size < 64; size <<= 1) {
+		if (nbytes <= size) break;
+		mask++;
+	}
+
+	return (mask << EPSIZE0);
+}
+
+static inline
 void InitEP(u8 index, u8 type, u8 size)
 {
-	UENUM = index;
-	UECONX = (1<<EPEN);
-	UECFG0X = type;
-	UECFG1X = size;
+	UENUM = index;       // Select endpoint
+	UECONX = (1<<EPEN);  // Enable endpoint
+	UECFG0X = type;      // Direction and transmission type
+	UECFG1X = size;      // Memory allocation, # of data banks, and bank size
+}
+
+static inline
+bool InitEPSize(const u8 index, const u8 type, const u8 nbanks, const u8 banksize)
+{
+	if (index >= USB_ENDPOINTS) return false;
+	uint8_t size = ((1 << ALLOC) | ((nbanks > 1) ? (1 << EPBK0) : 0) | BankSizeMask(banksize));
+	InitEP(index, type, size);
+	return UESTA0X & (1 << CFGOK);  // Success
 }
 
 static
 void InitEndpoints()
 {
-	for (u8 i = 1; i < sizeof(_initEndpoints) && _initEndpoints[i] != 0; i++)
-	{
-		UENUM = i;
-		UECONX = (1<<EPEN);
-		UECFG0X = _initEndpoints[i];
-#if USB_EP_SIZE == 16
-		UECFG1X = EP_SINGLE_16;
-#elif USB_EP_SIZE == 64
-		UECFG1X = EP_DOUBLE_64;
-#else
-#error Unsupported value for USB_EP_SIZE
-#endif
-	}
-	UERST = 0x7E;	// And reset them
-	UERST = 0;
+	InitEPSize(1, EP_TYPE_INTERRUPT_IN,  1, 32);  // Control Data Send
+	InitEPSize(2, EP_TYPE_INTERRUPT_OUT, 1, 32);  // Control Data Receive
+	InitEPSize(5, EP_TYPE_INTERRUPT_IN,  1, 32);  // Expansion Interface NACK (avoid config reset)
+
+	UERST = 0x7E;  // Reset endpoints
+	UERST = 0;     // End reset
 }
 
 static int _cmark;
-- 
cgit v1.2.3-18-g5258


From 697a840e1b23a06f595bc2dbd75bcaacb9a1a8ad Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Tue, 19 Feb 2019 12:41:46 -0500
Subject: Add XInput endpoint number defines

---
 cores/arduino/xinput/USB_XInput_Descriptors.h | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'cores/arduino')

diff --git a/cores/arduino/xinput/USB_XInput_Descriptors.h b/cores/arduino/xinput/USB_XInput_Descriptors.h
index 8cb19df..21697fb 100644
--- a/cores/arduino/xinput/USB_XInput_Descriptors.h
+++ b/cores/arduino/xinput/USB_XInput_Descriptors.h
@@ -44,6 +44,10 @@ extern const u8 STRING_SECURITY[] PROGMEM;
 
 #define ISECURITY 4
 
+// Endpoint Numbers
+#define XINPUT_TX_ENDPOINT	1
+#define XINPUT_RX_ENDPOINT	2
+
 #undef USB_VID
 #define USB_VID 0x045E
 
-- 
cgit v1.2.3-18-g5258


From 058af1724d130745167f670272630ed2811d1317 Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Tue, 19 Feb 2019 12:50:10 -0500
Subject: Change VID and PID in boards.txt

Better to set these where intended so they can be easily overridden if need be.
---
 cores/arduino/xinput/USB_XInput_Descriptors.h | 6 ------
 1 file changed, 6 deletions(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/xinput/USB_XInput_Descriptors.h b/cores/arduino/xinput/USB_XInput_Descriptors.h
index 21697fb..976fe56 100644
--- a/cores/arduino/xinput/USB_XInput_Descriptors.h
+++ b/cores/arduino/xinput/USB_XInput_Descriptors.h
@@ -48,12 +48,6 @@ extern const u8 STRING_SECURITY[] PROGMEM;
 #define XINPUT_TX_ENDPOINT	1
 #define XINPUT_RX_ENDPOINT	2
 
-#undef USB_VID
-#define USB_VID 0x045E
-
-#undef USB_PID
-#define USB_PID 0x028E
-
 #endif /* if defined(USBCON) */
 
 #endif /* ifndef USB_XINPUT_DESCRIPTORS_H */
-- 
cgit v1.2.3-18-g5258


From a7b370bf9657dccc9038d6611ea289d996b53621 Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Thu, 21 Feb 2019 10:55:11 -0500
Subject: Add XInput USB API

---
 cores/arduino/USBAPI.h                  |  2 ++
 cores/arduino/xinput/USB_XInput_API.cpp | 57 +++++++++++++++++++++++++++++++++
 cores/arduino/xinput/USB_XInput_API.h   | 51 +++++++++++++++++++++++++++++
 3 files changed, 110 insertions(+)
 create mode 100644 cores/arduino/xinput/USB_XInput_API.cpp
 create mode 100644 cores/arduino/xinput/USB_XInput_API.h

(limited to 'cores/arduino')

diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h
index 86713dd..0f7d171 100644
--- a/cores/arduino/USBAPI.h
+++ b/cores/arduino/USBAPI.h
@@ -180,6 +180,8 @@ int USB_Recv(uint8_t ep, void* data, int len);		// non-blocking
 int USB_Recv(uint8_t ep);							// non-blocking
 void USB_Flush(uint8_t ep);
 
+#include "xinput/USB_XInput_API.h"
+
 #endif
 
 #endif /* if defined(USBCON) */
diff --git a/cores/arduino/xinput/USB_XInput_API.cpp b/cores/arduino/xinput/USB_XInput_API.cpp
new file mode 100644
index 0000000..27a6670
--- /dev/null
+++ b/cores/arduino/xinput/USB_XInput_API.cpp
@@ -0,0 +1,57 @@
+/*
+ *  Project     Arduino XInput - AVR Core
+ *  @author     David Madison
+ *  @link       github.com/dmadison/ArduinoXInput_AVR
+ *  @license    MIT - Copyright (c) 2019 David Madison
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "USB_XInput_API.h"
+
+#ifdef USB_XINPUT
+
+void (*XInputUSB::RecvCallback)(void) = nullptr;
+
+boolean XInputUSB::connected() {
+	return true;  // Need to implement
+}
+
+int XInputUSB::available() {
+	return USB_Available(XINPUT_RX_ENDPOINT);
+}
+
+int XInputUSB::recv(void *buffer, uint8_t nbytes) {
+	return USB_Recv(XINPUT_RX_ENDPOINT, buffer, nbytes);
+}
+
+int XInputUSB::send(const void *buffer, uint8_t nbytes) {
+	int result = USB_Send(XINPUT_TX_ENDPOINT, buffer, nbytes);
+	if (result > 0) {
+		USB_Flush(XINPUT_TX_ENDPOINT);
+	}
+	return result;
+}
+
+void XInputUSB::setRecvCallback(void(*callback)(void)) {
+	XInputUSB::RecvCallback = callback;
+}
+
+#endif /* ifdef USB_XINPUT */
diff --git a/cores/arduino/xinput/USB_XInput_API.h b/cores/arduino/xinput/USB_XInput_API.h
new file mode 100644
index 0000000..0a8fa43
--- /dev/null
+++ b/cores/arduino/xinput/USB_XInput_API.h
@@ -0,0 +1,51 @@
+/*
+ *  Project     Arduino XInput - AVR Core
+ *  @author     David Madison
+ *  @link       github.com/dmadison/ArduinoXInput_AVR
+ *  @license    MIT - Copyright (c) 2019 David Madison
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "USBAPI.h"
+
+#ifndef USB_XINPUT_API_H
+#define USB_XINPUT_API_H
+
+#ifdef USBCON
+
+#define USB_XINPUT
+
+class XInputUSB {
+public:
+	// API
+	static bool connected(void);
+	static int  available(void);
+	static int  recv(void *buffer, uint8_t nbytes);
+	static int  send(const void *buffer, uint8_t nbytes);
+	static void setRecvCallback(void(*callback)(void));
+
+	// Non-API Data
+	static void (*RecvCallback)(void);
+};
+
+#endif /* if defined(USBCON) */
+
+#endif /* ifndef USB_XINPUT_API_H */
-- 
cgit v1.2.3-18-g5258


From 49456f49d0d18d023e5617dc87ff4a5192a1f497 Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Thu, 21 Feb 2019 11:42:06 -0500
Subject: Add USB receive callback to USB ISR

Using the OUT endpoint interrupt
---
 cores/arduino/USBCore.cpp | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index 8794250..f2a2365 100644
--- a/cores/arduino/USBCore.cpp
+++ b/cores/arduino/USBCore.cpp
@@ -360,6 +360,9 @@ void InitEndpoints()
 
 	UERST = 0x7E;  // Reset endpoints
 	UERST = 0;     // End reset
+
+	SetEP(XINPUT_RX_ENDPOINT);  // Select XInput RX endpoint (OUT)
+	UEIENX |= (1 << RXOUTE);  // Enable received "OUT" interrupt
 }
 
 static int _cmark;
@@ -506,9 +509,17 @@ bool SendDescriptor(USBSetup& setup)
 	return true;
 }
 
-//	Endpoint 0 interrupt
+//	Endpoint interrupt
 ISR(USB_COM_vect)
 {
+	SetEP(XINPUT_RX_ENDPOINT);  // Select XInput RX endpoint (OUT)
+	if (UEINTX & (1 << RXOUTI)) {  // If data received...
+		UEINTX &= ~(1 << RXOUTI);  // Clear interrupt flag
+		if (XInputUSB::RecvCallback != nullptr) {
+			XInputUSB::RecvCallback();  // Call callback function if it exists
+		}
+	}
+
     SetEP(0);
 	if (!ReceivedSetupInt())
 		return;
-- 
cgit v1.2.3-18-g5258


From a4453c563cedb1c57dd10d189aa792b8e84d3feb Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Thu, 21 Feb 2019 13:24:07 -0500
Subject: Use endpoint number defines for ep allocation

---
 cores/arduino/USBCore.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index f2a2365..aa52243 100644
--- a/cores/arduino/USBCore.cpp
+++ b/cores/arduino/USBCore.cpp
@@ -354,8 +354,8 @@ bool InitEPSize(const u8 index, const u8 type, const u8 nbanks, const u8 banksiz
 static
 void InitEndpoints()
 {
-	InitEPSize(1, EP_TYPE_INTERRUPT_IN,  1, 32);  // Control Data Send
-	InitEPSize(2, EP_TYPE_INTERRUPT_OUT, 1, 32);  // Control Data Receive
+	InitEPSize(XINPUT_TX_ENDPOINT, EP_TYPE_INTERRUPT_IN,  1, 32);  // Control Data Send
+	InitEPSize(XINPUT_RX_ENDPOINT, EP_TYPE_INTERRUPT_OUT, 1, 32);  // Control Data Receive
 	InitEPSize(5, EP_TYPE_INTERRUPT_IN,  1, 32);  // Expansion Interface NACK (avoid config reset)
 
 	UERST = 0x7E;  // Reset endpoints
-- 
cgit v1.2.3-18-g5258


From fc18d5330ee7f3b7dc3ebc3f7e12a876464182ad Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Thu, 21 Feb 2019 13:27:40 -0500
Subject: Change receive endpoint to double-banked

No reason not to take advantage of this feature, although with the interrupt in place I doubt it will be useful.
---
 cores/arduino/USBCore.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index aa52243..6e820a1 100644
--- a/cores/arduino/USBCore.cpp
+++ b/cores/arduino/USBCore.cpp
@@ -355,7 +355,7 @@ static
 void InitEndpoints()
 {
 	InitEPSize(XINPUT_TX_ENDPOINT, EP_TYPE_INTERRUPT_IN,  1, 32);  // Control Data Send
-	InitEPSize(XINPUT_RX_ENDPOINT, EP_TYPE_INTERRUPT_OUT, 1, 32);  // Control Data Receive
+	InitEPSize(XINPUT_RX_ENDPOINT, EP_TYPE_INTERRUPT_OUT, 2, 32);  // Control Data Receive
 	InitEPSize(5, EP_TYPE_INTERRUPT_IN,  1, 32);  // Expansion Interface NACK (avoid config reset)
 
 	UERST = 0x7E;  // Reset endpoints
-- 
cgit v1.2.3-18-g5258


From 1580d392e9662b25161c88681e1e274526109921 Mon Sep 17 00:00:00 2001
From: David Madison <dmadison@users.noreply.github.com>
Date: Thu, 21 Feb 2019 15:07:53 -0500
Subject: Add USB connected API support

Returns true if the device USB is configured. Although will still return true if the device has been configured and the USB data pins disconnected...
---
 cores/arduino/xinput/USB_XInput_API.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/xinput/USB_XInput_API.cpp b/cores/arduino/xinput/USB_XInput_API.cpp
index 27a6670..678692d 100644
--- a/cores/arduino/xinput/USB_XInput_API.cpp
+++ b/cores/arduino/xinput/USB_XInput_API.cpp
@@ -31,7 +31,7 @@
 void (*XInputUSB::RecvCallback)(void) = nullptr;
 
 boolean XInputUSB::connected() {
-	return true;  // Need to implement
+	return USBDevice.configured();
 }
 
 int XInputUSB::available() {
-- 
cgit v1.2.3-18-g5258