From de9bd767dc8578a45a195fb1e37dd4ff26ae9567 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Fri, 8 Apr 2011 05:05:05 +0000
Subject: [PATCH] Correct UC3 global interrupt functions.

Replace all calls and references to _delay_ms() in the code with the architecture-agnostic Delay_MS() function.

Improve code generation for the Delay_MS() function on the AVR8 architecture when called with a constant input.
---
 Bootloaders/DFU/BootloaderDFU.c              |  2 +-
 LUFA/Common/Common.h                         | 18 ++++++++++++++----
 LUFA/Drivers/Board/LEDs.h                    | 10 +++++-----
 LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c       |  2 +-
 LUFA/Drivers/USB/Core/UC3/Host_UC3.c         |  2 +-
 LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h |  5 +++--
 LUFA/ManPages/SoftwareBootloaderJump.txt     |  3 +--
 Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c   |  2 +-
 Projects/XPLAINBridge/XPLAINBridge.c         |  2 +-
 9 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/Bootloaders/DFU/BootloaderDFU.c b/Bootloaders/DFU/BootloaderDFU.c
index f9bc4e060..113bea748 100644
--- a/Bootloaders/DFU/BootloaderDFU.c
+++ b/Bootloaders/DFU/BootloaderDFU.c
@@ -109,7 +109,7 @@ int main(void)
 
 	/* Enable pull-up on the JTAG TCK pin so we can use it to select the mode */
 	PORTF |= (1 << 4);
-	_delay_ms(10);
+	Delay_MS(10);
 
 	/* If the TCK pin is not jumpered to ground, start the user application instead */
 	RunBootloader = (!(PINF & (1 << 4)));
diff --git a/LUFA/Common/Common.h b/LUFA/Common/Common.h
index a7e88dab5..a54512a51 100644
--- a/LUFA/Common/Common.h
+++ b/LUFA/Common/Common.h
@@ -236,18 +236,28 @@
 			/** Function to perform a blocking delay for a specified number of milliseconds. The actual delay will be
 			 *  at a minimum the specified number of milliseconds, however due to loop overhead and internal calculations
 			 *  may be slightly higher.
+			 *
+			 *  \param[in] Milliseconds  Number of milliseconds to delay
 			 */
 			static inline void Delay_MS(uint8_t Milliseconds)
 			{
+				#if (ARCH == ARCH_AVR8)
+				if (__builtin_constant_p(Milliseconds))
+				{
+					_delay_ms(Milliseconds);
+				}
+				else
+				{
+					while (Milliseconds--)
+					  _delay_ms(1);
+				}
+				#elif (ARCH == ARCH_UC3)
 				while (Milliseconds--)
 				{
-					#if (ARCH == ARCH_AVR8)
-					_delay_ms(1);
-					#elif (ARCH == ARCH_UC3)
 					__builtin_mtsr(AVR32_COUNT, 0);
 					while (__builtin_mfsr(AVR32_COUNT) < (F_CPU / 1000));				
-					#endif
 				}
+				#endif
 			}
 
 #endif
diff --git a/LUFA/Drivers/Board/LEDs.h b/LUFA/Drivers/Board/LEDs.h
index 7a135b8bc..628f2587b 100644
--- a/LUFA/Drivers/Board/LEDs.h
+++ b/LUFA/Drivers/Board/LEDs.h
@@ -79,17 +79,17 @@
  *
  *      // Turn on each of the four LEDs in turn
  *      LEDs_SetAllLEDs(LEDS_LED1); 
- *      _delay_ms(500);
+ *      Delay_MS(500);
  *      LEDs_SetAllLEDs(LEDS_LED1); 
- *      _delay_ms(500);
+ *      Delay_MS(500);
  *      LEDs_SetAllLEDs(LEDS_LED1); 
- *      _delay_ms(500);
+ *      Delay_MS(500);
  *      LEDs_SetAllLEDs(LEDS_LED1); 
- *      _delay_ms(500);
+ *      Delay_MS(500);
  *
  *      // Turn on all LEDs
  *      LEDs_SetAllLEDs(LEDS_ALL_LEDS);
- *      _delay_ms(1000);
+ *      Delay_MS(1000);
  *
  *      // Turn on LED 1, turn off LED 2, leaving LEDs 3 and 4 in their current state
  *      LEDs_ChangeLEDs((LEDS_LED1 | LEDS_LED2), LEDS_LED1);
diff --git a/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c b/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c
index 87dddd49d..6c45265d7 100644
--- a/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c
+++ b/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c
@@ -273,7 +273,7 @@ static void USB_Host_ResetDevice(void)
 			break;
 		}
 
-		_delay_ms(1);
+		Delay_MS(1);
 	}
 
 	if (HSOFIEnabled)
diff --git a/LUFA/Drivers/USB/Core/UC3/Host_UC3.c b/LUFA/Drivers/USB/Core/UC3/Host_UC3.c
index b557ff0ed..88a7df5c4 100644
--- a/LUFA/Drivers/USB/Core/UC3/Host_UC3.c
+++ b/LUFA/Drivers/USB/Core/UC3/Host_UC3.c
@@ -273,7 +273,7 @@ static void USB_Host_ResetDevice(void)
 			break;
 		}
 
-		_delay_ms(1);
+		Delay_MS(1);
 	}
 
 	if (HSOFIEnabled)
diff --git a/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h b/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h
index 95a85cf69..a9ad56611 100644
--- a/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h
+++ b/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h
@@ -87,14 +87,15 @@
 			static inline uint_reg_t USB_INT_GetGlobalEnableState(void)
 			{
 				GCC_MEMORY_BARRIER();
-				return (__builtin_mfsr(AVR32_SR) & AVR32_SR_GM);
+				return __builtin_mfsr(AVR32_SR);
 			}
 
 			static inline void USB_INT_SetGlobalEnableState(uint_reg_t GlobalIntState) ATTR_ALWAYS_INLINE;
 			static inline void USB_INT_SetGlobalEnableState(uint_reg_t GlobalIntState)
 			{
 				GCC_MEMORY_BARRIER();
-				__builtin_ssrf(AVR32_SR_GM_OFFSET, GlobalIntState);
+				if (GlobalIntState & AVR32_SR_GM)
+				  __builtin_ssrf(AVR32_SR_GM_OFFSET);
 				GCC_MEMORY_BARRIER();
 			}
 		
diff --git a/LUFA/ManPages/SoftwareBootloaderJump.txt b/LUFA/ManPages/SoftwareBootloaderJump.txt
index 049f49c8f..1fad85fb7 100644
--- a/LUFA/ManPages/SoftwareBootloaderJump.txt
+++ b/LUFA/ManPages/SoftwareBootloaderJump.txt
@@ -54,8 +54,7 @@
  *      cli();
  *
  *      // Wait two seconds for the USB detachment to register on the host
- *      for (uint8_t i = 0; i < 128; i++)
- *        _delay_ms(16);
+ *      Delay_MS(2000);
  *
  *      // Set the bootloader key to the magic value and force a reset
  *      Boot_Key = MAGIC_BOOT_KEY;
diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
index 421046b5a..ccd31f3d2 100644
--- a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
+++ b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
@@ -519,7 +519,7 @@ void ISPProtocol_SPIMulti(void)
 void ISPProtocol_DelayMS(uint8_t DelayMS)
 {
 	while (DelayMS-- && !(TimeoutExpired))
-	  _delay_ms(1);
+	  Delay_MS(1);
 }
 
 #endif
diff --git a/Projects/XPLAINBridge/XPLAINBridge.c b/Projects/XPLAINBridge/XPLAINBridge.c
index a2afbbc3c..41ebabd13 100644
--- a/Projects/XPLAINBridge/XPLAINBridge.c
+++ b/Projects/XPLAINBridge/XPLAINBridge.c
@@ -181,7 +181,7 @@ void SetupHardware(void)
 
 	/* Enable pull-up on the JTAG TDI pin so we can use it to select the mode */
 	PORTF |= (1 << 7);
-	_delay_ms(10);
+	Delay_MS(10);
 
 	/* Select the firmware mode based on the JTD pin's value */
 	CurrentFirmwareMode = (PINF & (1 << 7)) ? MODE_USART_BRIDGE : MODE_PDI_PROGRAMMER;
-- 
GitLab