From bfa622d27e95f391a4e7ea256a5162075dac18e0 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Fri, 24 Dec 2010 18:06:55 +0000
Subject: [PATCH] Much more efficient algorithm for the Endpoint/Pipe
 configuration routine of unordered endpoints/pipes - only reconfigure the
 endpoints and pipes above the newly configured endpoint/pipe, and don't cache
 existing endpoint/pipe configuration before use to save SRAM.

---
 LUFA/Drivers/USB/LowLevel/Endpoint.c | 63 ++++++++++-----------
 LUFA/Drivers/USB/LowLevel/Pipe.c     | 85 +++++++++++++---------------
 2 files changed, 69 insertions(+), 79 deletions(-)

diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.c b/LUFA/Drivers/USB/LowLevel/Endpoint.c
index 56c73fc48..9d13eadb9 100644
--- a/LUFA/Drivers/USB/LowLevel/Endpoint.c
+++ b/LUFA/Drivers/USB/LowLevel/Endpoint.c
@@ -52,46 +52,41 @@ bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
 	UECFG1X = UECFG1XData;
 
 	return Endpoint_IsConfigured();
-#else
-	uint8_t UECFG0XTemp[ENDPOINT_TOTAL_ENDPOINTS];
-	uint8_t UECFG1XTemp[ENDPOINT_TOTAL_ENDPOINTS];
-	uint8_t UEIENXTemp[ENDPOINT_TOTAL_ENDPOINTS];
-	
-	for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
+#else	
+	for (uint8_t EPNum = Number; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
 	{
+		uint8_t UECFG0XTemp;
+		uint8_t UECFG1XTemp;
+		uint8_t UEIENXTemp;
+
 		Endpoint_SelectEndpoint(EPNum);
-		UECFG0XTemp[EPNum] = UECFG0X;
-		UECFG1XTemp[EPNum] = UECFG1X;
-		UEIENXTemp[EPNum]  = UEIENX;
-	}
-	
-	UECFG0XTemp[Number] = UECFG0XData;
-	UECFG1XTemp[Number] = UECFG1XData;
-	UEIENXTemp[Number]  = 0;
-	
-	for (uint8_t EPNum = 1; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
-	{
-		Endpoint_SelectEndpoint(EPNum);	
-		UEIENX  = 0;
-		UEINTX  = 0;
-		UECFG1X = 0;
-		Endpoint_DisableEndpoint();
-	}
+		
+		if (EPNum == Number)
+		{
+			UECFG0XTemp = UECFG0XData;
+			UECFG1XTemp = UECFG1XData;
+			UEIENXTemp  = 0;
+		}
+		else
+		{
+			UECFG0XTemp = UECFG0X;
+			UECFG1XTemp = UECFG1X;
+			UEIENXTemp  = UEIENX;
+		}
 
-	for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
-	{
-		if (!(UECFG1XTemp[EPNum] & (1 << ALLOC)))
+		if (!(UECFG1XTemp & (1 << ALLOC)))
 		  continue;
-		
-		Endpoint_SelectEndpoint(EPNum);		
-		Endpoint_EnableEndpoint();
 
-		UECFG0X = UECFG0XTemp[EPNum];
-		UECFG1X = UECFG1XTemp[EPNum];
-		UEIENX  = UEIENXTemp[EPNum];
-		
+		Endpoint_DisableEndpoint();
+		UECFG1X &= (1 << ALLOC);
+
+		Endpoint_EnableEndpoint();
+		UECFG0X = UECFG0XTemp;
+		UECFG1X = UECFG1XTemp;
+		UEIENX  = UEIENXTemp;
+			
 		if (!(Endpoint_IsConfigured()))
-		  return false;
+		  return false;			
 	}
 	
 	Endpoint_SelectEndpoint(Number);
diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.c b/LUFA/Drivers/USB/LowLevel/Pipe.c
index fc50060be..9f2b007b7 100644
--- a/LUFA/Drivers/USB/LowLevel/Pipe.c
+++ b/LUFA/Drivers/USB/LowLevel/Pipe.c
@@ -56,58 +56,53 @@ bool Pipe_ConfigurePipe(const uint8_t Number,
 	Pipe_SetInfiniteINRequests();
 
 	return Pipe_IsConfigured();
-#else
-	uint8_t UPCFG0XTemp[PIPE_TOTAL_PIPES];
-	uint8_t UPCFG1XTemp[PIPE_TOTAL_PIPES];
-	uint8_t UPCFG2XTemp[PIPE_TOTAL_PIPES];
-	uint8_t UPCONXTemp[PIPE_TOTAL_PIPES];
-	uint8_t UPINRQXTemp[PIPE_TOTAL_PIPES];
-	uint8_t UPIENXTemp[PIPE_TOTAL_PIPES];
-	
-	for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
-	{
-		Pipe_SelectPipe(PNum);
-		UPCFG0XTemp[PNum] = UPCFG0X;
-		UPCFG1XTemp[PNum] = UPCFG1X;
-		UPCFG2XTemp[PNum] = UPCFG2X;
-		UPCONXTemp[PNum]  = UPCONX;
-		UPINRQXTemp[PNum] = UPINRQX;
-		UPIENXTemp[PNum]  = UPIENX;
-	}
-	
-	UPCFG0XTemp[Number] = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0));
-	UPCFG1XTemp[Number] = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size));
-	UPCFG2XTemp[Number] = 0;
-	UPCONXTemp[Number]  = (1 << INMODE);
-	UPINRQXTemp[Number] = 0;
-	UPIENXTemp[Number]  = 0;
-	
-	for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
+#else	
+	for (uint8_t PNum = Number; PNum < PIPE_TOTAL_PIPES; PNum++)
 	{
+		uint8_t UPCFG0XTemp;
+		uint8_t UPCFG1XTemp;
+		uint8_t UPCFG2XTemp;
+		uint8_t UPCONXTemp;
+		uint8_t UPINRQXTemp;
+		uint8_t UPIENXTemp;
+
 		Pipe_SelectPipe(PNum);
-		UPIENX  = 0;
-		UPINTX  = 0;
-		UPCFG1X = 0;
-		Pipe_DisablePipe();
-	}
+		
+		if (PNum == Number)
+		{
+			UPCFG0XTemp = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0));
+			UPCFG1XTemp = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size));
+			UPCFG2XTemp = 0;
+			UPCONXTemp  = ((1 << PEN) | (1 << INMODE));
+			UPINRQXTemp = 0;
+			UPIENXTemp  = 0;
+		}
+		else
+		{
+			UPCFG0XTemp = UPCFG0X;
+			UPCFG1XTemp = UPCFG1X;
+			UPCFG2XTemp = UPCFG2X;
+			UPCONXTemp  = UPCONX;
+			UPINRQXTemp = UPINRQX;
+			UPIENXTemp  = UPIENX;
+		}
 
-	for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
-	{
-		if (!(UPCFG1XTemp[PNum] & (1 << ALLOC)))
+		if (!(UPCFG1XTemp & (1 << ALLOC)))
 		  continue;
-		
-		Pipe_SelectPipe(PNum);		
-		Pipe_EnablePipe();
+		  
+		Pipe_DisablePipe();
+		UPCFG1X &= (1 << ALLOC);
 
-		UPCFG0X  = UPCFG0XTemp[PNum];
-		UPCFG1X  = UPCFG1XTemp[PNum];
-		UPCFG2X  = UPCFG2XTemp[PNum];
-		UPCONX  |= UPCONXTemp[PNum];
-		UPINRQX  = UPINRQXTemp[PNum];
-		UPIENX   = UPIENXTemp[PNum];
+		Pipe_EnablePipe();
+		UPCFG0X = UPCFG0XTemp;
+		UPCFG1X = UPCFG1XTemp;
+		UPCFG2X = UPCFG2XTemp;
+		UPCONX  = UPCONXTemp;
+		UPINRQX = UPINRQXTemp;
+		UPIENX  = UPIENXTemp;
 
 		if (!(Pipe_IsConfigured()))
-		  return false;
+		  return false;		
 	}
 		
 	Pipe_SelectPipe(Number);	
-- 
GitLab