From 64e93612988e88e70d995987588b32c99cf91e3b Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Sat, 4 Feb 2012 22:16:34 +0000
Subject: [PATCH] Minor corrections to the XMEGA USB controller implementation.

---
 LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c        | 13 ++++++++-----
 LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h        |  5 ++++-
 .../XMEGA/Template/Template_Endpoint_Control_R.c    |  2 ++
 .../XMEGA/Template/Template_Endpoint_Control_W.c    |  2 ++
 4 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c
index e73781466..f67a0ff2b 100644
--- a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c
+++ b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c
@@ -39,10 +39,10 @@
 uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
 #endif
 
-Endpoint_FIFOPair_t           USB_Endpoint_FIFOs[ENDPOINT_DETAILS_MAXEP];
+Endpoint_FIFOPair_t       USB_Endpoint_FIFOs[ENDPOINT_TOTAL_ENDPOINTS];
 
-volatile uint8_t              USB_Endpoint_SelectedEndpoint;
-volatile USB_EP_t*            USB_Endpoint_SelectedHandle;
+volatile uint8_t          USB_Endpoint_SelectedEndpoint;
+volatile USB_EP_t*        USB_Endpoint_SelectedHandle;
 volatile Endpoint_FIFO_t* USB_Endpoint_SelectedFIFO;
 
 bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Number,
@@ -66,8 +66,11 @@ bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Number,
 
 void Endpoint_ClearEndpoints(void)
 {
-	for (uint8_t EPNum = 0; EPNum < (ENDPOINT_TOTAL_ENDPOINTS * 2); EPNum++)
-	  ((USB_EP_t*)&USB_EndpointTable)[EPNum].CTRL = 0;
+	for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
+	{
+		USB_EndpointTable.Endpoints[EPNum].IN.CTRL  = 0;
+		USB_EndpointTable.Endpoints[EPNum].OUT.CTRL = 0;
+	}
 }
 
 void Endpoint_ClearStatusStage(void)
diff --git a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h
index 495aa9707..49069d8c2 100644
--- a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h
+++ b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h
@@ -391,7 +391,10 @@
 			static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
 			static inline bool Endpoint_IsReadWriteAllowed(void)
 			{
-				return (USB_Endpoint_SelectedFIFO->Position < USB_Endpoint_SelectedFIFO->Length);
+				if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN)
+				  return (USB_Endpoint_SelectedFIFO->Position < USB_Endpoint_SelectedFIFO->Length);
+				else
+				  return (USB_Endpoint_SelectedFIFO->Position > 0);
 			}
 
 			/** Determines if the currently selected endpoint is configured.
diff --git a/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_R.c b/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_R.c
index 55d137ba3..3d4151b4e 100644
--- a/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_R.c
+++ b/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_R.c
@@ -35,6 +35,8 @@ uint8_t TEMPLATE_FUNC_NAME (void* const Buffer,
 {
 	uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length));
 
+	Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN);
+
 	if (!(Length))
 	  Endpoint_ClearOUT();
 
diff --git a/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_W.c b/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_W.c
index 36685f0c4..e5180693d 100644
--- a/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_W.c
+++ b/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_W.c
@@ -36,6 +36,8 @@ uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer,
 	uint8_t* DataStream     = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length));
 	bool     LastPacketFull = false;
 
+	Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN);
+
 	if (Length > USB_ControlRequest.wLength)
 	  Length = USB_ControlRequest.wLength;
 	else if (!(Length))
-- 
GitLab