From c263ea837ae7e3c0e963b798afdffd501790ce2c Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Fri, 8 Apr 2011 05:40:25 +0000
Subject: [PATCH] Move global interrupt enable/disable functions out to
 Common.h and document them.

---
 LUFA/Common/Common.h                          | 91 ++++++++++++++++++-
 LUFA/Drivers/Misc/RingBuffer.h                | 24 ++---
 LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h      |  6 +-
 .../Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c |  2 +-
 .../Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h | 31 -------
 LUFA/Drivers/USB/Core/DeviceStandardReq.c     |  6 +-
 LUFA/Drivers/USB/Core/UC3/Device_UC3.h        |  6 +-
 LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c  |  2 +-
 LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h  | 39 +-------
 LUFA/ManPages/ChangeLog.txt                   |  3 +-
 LUFA/Scheduler/Scheduler.c                    |  6 +-
 LUFA/Scheduler/Scheduler.h                    |  6 +-
 Projects/Webserver/Lib/uip/clock.c            |  9 +-
 13 files changed, 127 insertions(+), 104 deletions(-)

diff --git a/LUFA/Common/Common.h b/LUFA/Common/Common.h
index a54512a51..4e697ad18 100644
--- a/LUFA/Common/Common.h
+++ b/LUFA/Common/Common.h
@@ -97,7 +97,7 @@
 
 			typedef uint32_t uint_reg_t;
 			
-			#define  ARCH_BIG_ENDIAN
+			#define ARCH_BIG_ENDIAN
 
 			#include "Endianness.h"
 		#else
@@ -217,6 +217,22 @@
 			 */
 			#define GCC_MEMORY_BARRIER()                __asm__ __volatile__("" ::: "memory");
 
+			#if !defined(ISR) || defined(__DOXYGEN__)
+				/** Macro for the definition of interrupt service routines, so that the compiler can insert the required
+				 *  prologue and epilogue code to properly manage the interrupt routine without affecting the main thread's
+				 *  state with unintentional side-effects.
+				 *
+				 *  Interrupt handlers written using this macro may still need to be registered with the microcontroller's
+				 *  Interrupt Controller (if present) before they will properly handle incoming interrupt events.
+				 *
+				 *  \note This is supplied on some architectures where the standard library does not include a valid
+				 *        definition. If an existing definition exists, the definition here will be ignored.
+				 *
+				 *  \param Name  Unique name of the interrupt service routine.
+				 */
+				#define ISR(Name, ...)                  void Name (void) __attribute__((__interrupt__)); void Name (void)
+			#endif
+
 		/* Inline Functions: */
 			/** Function to reverse the individual bits in a byte - i.e. bit 7 is moved to bit 0, bit 6 to bit 1,
 			 *  etc.
@@ -260,6 +276,79 @@
 				#endif
 			}
 
+			/** Retrieves a mask which contains the current state of the global interrupts for the device. This
+			 *  value can be stored before altering the global interrupt enable state, before restoring the
+			 *  flag(s) back to their previous values after a critical section using \ref SetGlobalInterruptMask().
+			 *
+			 *  \return  Mask containing the current Global Interrupt Enable Mask bit(s).
+			 */
+			static inline uint_reg_t GetGlobalInterruptMask(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
+			static inline uint_reg_t GetGlobalInterruptMask(void)
+			{
+				GCC_MEMORY_BARRIER();
+
+				#if (ARCH == ARCH_AVR8)
+				return SREG;
+				#elif (ARCH == ARCH_UC3)
+				return __builtin_mfsr(AVR32_SR);				
+				#endif
+
+				GCC_MEMORY_BARRIER();
+			}
+
+			/** Sets the global interrupt enable state of the microcontroller to the mask passed into the function.
+			 *  This can be combined with \ref GetGlobalInterruptMask() to save and restore the Global Interrupt Enable
+			 *  Mask bit(s) of the device after a critical section has completed.
+			 *
+			 *  \param[in] GlobalIntState  Global Interrupt Enable Mask value to use
+			 */
+			static inline void SetGlobalInterruptMask(const uint_reg_t GlobalIntState) ATTR_ALWAYS_INLINE;
+			static inline void SetGlobalInterruptMask(const uint_reg_t GlobalIntState)
+			{
+				GCC_MEMORY_BARRIER();
+
+				#if (ARCH == ARCH_AVR8)
+				SREG = GlobalIntState;
+				#elif (ARCH == ARCH_UC3)
+				if (GlobalIntState & AVR32_SR_GM)
+				  __builtin_ssrf(AVR32_SR_GM_OFFSET);
+				else
+				  __builtin_csrf(AVR32_SR_GM_OFFSET);
+				#endif
+				
+				GCC_MEMORY_BARRIER();
+			}
+		
+			/** Enables global interrupt handling for the device, allowing interrupts to be handled. */
+			static inline void GlobalInterruptEnable(void) ATTR_ALWAYS_INLINE;
+			static inline void GlobalInterruptEnable(void)
+			{
+				GCC_MEMORY_BARRIER();
+
+				#if (ARCH == ARCH_AVR8)
+				sei();
+				#elif (ARCH == ARCH_UC3)
+				__builtin_csrf(AVR32_SR_GM_OFFSET);
+				#endif
+
+				GCC_MEMORY_BARRIER();
+			}		
+
+			/** Disabled global interrupt handling for the device, preventing interrupts from being handled. */
+			static inline void GlobalInterruptDisable(void) ATTR_ALWAYS_INLINE;
+			static inline void GlobalInterruptDisable(void)
+			{
+				GCC_MEMORY_BARRIER();
+
+				#if (ARCH == ARCH_AVR8)
+				cli();
+				#elif (ARCH == ARCH_UC3)
+				__builtin_ssrf(AVR32_SR_GM_OFFSET);
+				#endif
+
+				GCC_MEMORY_BARRIER();
+			}
+
 #endif
 
 /** @} */
diff --git a/LUFA/Drivers/Misc/RingBuffer.h b/LUFA/Drivers/Misc/RingBuffer.h
index 5c8c8403b..504029165 100644
--- a/LUFA/Drivers/Misc/RingBuffer.h
+++ b/LUFA/Drivers/Misc/RingBuffer.h
@@ -125,8 +125,8 @@
 		{
 			GCC_FORCE_POINTER_ACCESS(Buffer);
 
-			uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
-			USB_INT_GlobalDisable();
+			uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
+			GlobalInterruptDisable();
 	
 			Buffer->In     = DataPtr;
 			Buffer->Out    = DataPtr;
@@ -135,7 +135,7 @@
 			Buffer->Size   = Size;
 			Buffer->Count  = 0;
 
-			USB_INT_SetGlobalEnableState(CurrentGlobalInt);
+			SetGlobalInterruptMask(CurrentGlobalInt);
 		}
 
 		/** Retrieves the minimum number of bytes stored in a particular buffer. This value is computed
@@ -155,12 +155,12 @@
 		{
 			uint16_t Count;
 
-			uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
-			USB_INT_GlobalDisable();
+			uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
+			GlobalInterruptDisable();
 			
 			Count = Buffer->Count;
 
-			USB_INT_SetGlobalEnableState(CurrentGlobalInt);
+			SetGlobalInterruptMask(CurrentGlobalInt);
 			return Count;
 		}
 
@@ -213,12 +213,12 @@
 			if (++Buffer->In == Buffer->End)
 			  Buffer->In = Buffer->Start;
 
-			uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
-			USB_INT_GlobalDisable();
+			uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
+			GlobalInterruptDisable();
 			
 			Buffer->Count++;
 
-			USB_INT_SetGlobalEnableState(CurrentGlobalInt);
+			SetGlobalInterruptMask(CurrentGlobalInt);
 		}
 
 		/** Removes an element from the ring buffer.
@@ -240,12 +240,12 @@
 			if (++Buffer->Out == Buffer->End)
 			  Buffer->Out = Buffer->Start;
 
-			uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
-			USB_INT_GlobalDisable();
+			uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
+			GlobalInterruptDisable();
 			
 			Buffer->Count--;
 
-			USB_INT_SetGlobalEnableState(CurrentGlobalInt);
+			SetGlobalInterruptMask(CurrentGlobalInt);
 
 			return Data;
 		}
diff --git a/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h
index 77af51255..47f58b27d 100644
--- a/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h
+++ b/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h
@@ -199,8 +199,8 @@
 		
 			static inline void USB_Device_GetSerialString(uint16_t* UnicodeString)
 			{
-				uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
-				USB_INT_GlobalDisable();
+				uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
+				GlobalInterruptDisable();
 				
 				uint8_t SigReadAddress = 0x0E;
 
@@ -220,7 +220,7 @@
 															   (('A' - 10) + SerialByte) : ('0' + SerialByte));
 				}
 				
-				USB_INT_SetGlobalEnableState(CurrentGlobalInt);
+				SetGlobalInterruptMask(CurrentGlobalInt);
 			}
 		
 	#endif
diff --git a/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c b/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c
index deaa5e5fb..4939ec2ed 100644
--- a/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c
+++ b/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c
@@ -263,7 +263,7 @@ ISR(USB_COM_vect, ISR_BLOCK)
 	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
 	USB_INT_Disable(USB_INT_RXSTPI);
 
-	USB_INT_GlobalEnable();
+	GlobalInterruptEnable();
 
 	USB_Device_ProcessControlRequest();
 
diff --git a/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h
index e85b67e92..6115ec6e3 100644
--- a/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h
+++ b/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h
@@ -84,37 +84,6 @@
 			};
 
 		/* Inline Functions: */
-			static inline uint_reg_t USB_INT_GetGlobalEnableState(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
-			static inline uint_reg_t USB_INT_GetGlobalEnableState(void)
-			{
-				GCC_MEMORY_BARRIER();
-				return SREG;
-			}
-
-			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();
-				SREG = GlobalIntState;
-				GCC_MEMORY_BARRIER();
-			}
-		
-			static inline void USB_INT_GlobalEnable(void) ATTR_ALWAYS_INLINE;
-			static inline void USB_INT_GlobalEnable(void)
-			{
-				GCC_MEMORY_BARRIER();
-				sei();
-				GCC_MEMORY_BARRIER();
-			}		
-
-			static inline void USB_INT_GlobalDisable(void) ATTR_ALWAYS_INLINE;
-			static inline void USB_INT_GlobalDisable(void)
-			{
-				GCC_MEMORY_BARRIER();
-				cli();
-				GCC_MEMORY_BARRIER();
-			}
-
 			static inline void USB_INT_Enable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE;
 			static inline void USB_INT_Enable(const uint8_t Interrupt)
 			{
diff --git a/LUFA/Drivers/USB/Core/DeviceStandardReq.c b/LUFA/Drivers/USB/Core/DeviceStandardReq.c
index a502c0949..2e6d8f8c0 100644
--- a/LUFA/Drivers/USB/Core/DeviceStandardReq.c
+++ b/LUFA/Drivers/USB/Core/DeviceStandardReq.c
@@ -115,8 +115,8 @@ void USB_Device_ProcessControlRequest(void)
 static void USB_Device_SetAddress(void)
 {
 	uint8_t DeviceAddress       = (USB_ControlRequest.wValue & 0x7F);
-	uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
-	USB_INT_GlobalDisable();
+	uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
+	GlobalInterruptDisable();
 				
 	Endpoint_ClearSETUP();
 
@@ -127,7 +127,7 @@ static void USB_Device_SetAddress(void)
 	USB_Device_SetDeviceAddress(DeviceAddress);
 	USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
 	
-	USB_INT_SetGlobalEnableState(CurrentGlobalInt);
+	SetGlobalInterruptMask(CurrentGlobalInt);
 }
 
 static void USB_Device_SetConfiguration(void)
diff --git a/LUFA/Drivers/USB/Core/UC3/Device_UC3.h b/LUFA/Drivers/USB/Core/UC3/Device_UC3.h
index 150b18860..2a029bf08 100644
--- a/LUFA/Drivers/USB/Core/UC3/Device_UC3.h
+++ b/LUFA/Drivers/USB/Core/UC3/Device_UC3.h
@@ -187,8 +187,8 @@
 
 			static inline void USB_Device_GetSerialString(uint16_t* UnicodeString)
 			{
-				uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
-				USB_INT_GlobalDisable();
+				uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
+				GlobalInterruptDisable();
 				
 				uint8_t* SigReadAddress = (uint8_t*)0x80800204;
 
@@ -208,7 +208,7 @@
 															   (('A' - 10) + SerialByte) : ('0' + SerialByte));
 				}
 				
-				USB_INT_SetGlobalEnableState(CurrentGlobalInt);
+				SetGlobalInterruptMask(CurrentGlobalInt);
 			}
 	#endif
 
diff --git a/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c b/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c
index 76386649a..76f4ef022 100644
--- a/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c
+++ b/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c
@@ -49,7 +49,7 @@ void USB_INT_ClearAllInterrupts(void)
 	AVR32_USBB.udintclr = 0xFFFFFFFF;
 }
 
-LUFA_ISR(USB_GEN_vect)
+ISR(USB_GEN_vect)
 {
 	#if defined(USB_CAN_BE_DEVICE)
 	#if !defined(NO_SOF_EVENTS)
diff --git a/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h b/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h
index a9ad56611..2cebf4106 100644
--- a/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h
+++ b/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h
@@ -55,10 +55,7 @@
 		#endif
 
 	/* Private Interface - For use in library only: */
-	#if !defined(__DOXYGEN__)
-		/* Macros: */
-			#define LUFA_ISR(Name)                void Name (void) __attribute__((__interrupt__)); void Name (void)
-			
+	#if !defined(__DOXYGEN__)		
 		/* Enums: */
 			enum USB_Interrupts_t
 			{
@@ -83,38 +80,6 @@
 			};
 		
 		/* Inline Functions: */
-			static inline uint_reg_t USB_INT_GetGlobalEnableState(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
-			static inline uint_reg_t USB_INT_GetGlobalEnableState(void)
-			{
-				GCC_MEMORY_BARRIER();
-				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();
-				if (GlobalIntState & AVR32_SR_GM)
-				  __builtin_ssrf(AVR32_SR_GM_OFFSET);
-				GCC_MEMORY_BARRIER();
-			}
-		
-			static inline void USB_INT_GlobalEnable(void) ATTR_ALWAYS_INLINE;
-			static inline void USB_INT_GlobalEnable(void)
-			{
-				GCC_MEMORY_BARRIER();
-				__builtin_csrf(AVR32_SR_GM_OFFSET);
-				GCC_MEMORY_BARRIER();
-			}		
-
-			static inline void USB_INT_GlobalDisable(void) ATTR_ALWAYS_INLINE;
-			static inline void USB_INT_GlobalDisable(void)
-			{
-				GCC_MEMORY_BARRIER();
-				__builtin_ssrf(AVR32_SR_GM_OFFSET);
-				GCC_MEMORY_BARRIER();
-			}
-
 			static inline void USB_INT_Enable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE;
 			static inline void USB_INT_Enable(const uint8_t Interrupt)
 			{			
@@ -376,7 +341,7 @@
 				 */
 				void USB_GEN_vect(void);
 			#else
-				LUFA_ISR(USB_GEN_vect);
+				ISR(USB_GEN_vect);
 			#endif
 			
 	/* Disable C linkage for C++ Compilers: */
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 5d5f6db1a..97f9c3004 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -25,7 +25,8 @@
   *   - Added board driver support for the Sparkfun ATMEGA8U2 breakout board
   *   - Added TWI baud rate prescaler and bit length parameters to the TWI_Init() function (thanks to Thomas Herlinghaus)
   *   - Internal restructuring for eventual multiple architecture ports
-  *   - Added start of an AVR32 UC3 architecture port (currently incomplete/experimental)
+  *   - Added AVR32 UC3 architecture port (currently incomplete/experimental)
+  *   - Added new architecture independant functions to enable, disable, save and restore the Global Interrupt Enable flags
   *  - Library Applications:
   *   - Added ability to write protect Mass Storage disk write operations from the host OS
   *   - Added new MIDIToneGenerator project
diff --git a/LUFA/Scheduler/Scheduler.c b/LUFA/Scheduler/Scheduler.c
index 87a21491d..56e1cf41e 100644
--- a/LUFA/Scheduler/Scheduler.c
+++ b/LUFA/Scheduler/Scheduler.c
@@ -39,12 +39,12 @@ bool Scheduler_HasDelayElapsed(const uint_least16_t Delay,
 	SchedulerDelayCounter_t CurrentTickValue_LCL;
 	SchedulerDelayCounter_t DelayCounter_LCL;
 
-	uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
-	USB_INT_GlobalDisable();
+	uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
+	GlobalInterruptDisable();
 
 	CurrentTickValue_LCL = Scheduler_TickCounter;
 
-	USB_INT_SetGlobalEnableState(CurrentGlobalInt);
+	SetGlobalInterruptMask(CurrentGlobalInt);
 
 	DelayCounter_LCL = *DelayCounter;
 
diff --git a/LUFA/Scheduler/Scheduler.h b/LUFA/Scheduler/Scheduler.h
index 499a63a1b..262218683 100644
--- a/LUFA/Scheduler/Scheduler.h
+++ b/LUFA/Scheduler/Scheduler.h
@@ -219,12 +219,12 @@
 			                                        ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
 			static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter)
 			{
-				uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
-				USB_INT_GlobalDisable();
+				uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
+				GlobalInterruptDisable();
 
 				*DelayCounter = Scheduler_TickCounter;
 
-				USB_INT_SetGlobalEnableState(CurrentGlobalInt);
+				SetGlobalInterruptMask(CurrentGlobalInt);
 			}
 
 		/* Function Prototypes: */
diff --git a/Projects/Webserver/Lib/uip/clock.c b/Projects/Webserver/Lib/uip/clock.c
index 87650b6da..e71f7209d 100644
--- a/Projects/Webserver/Lib/uip/clock.c
+++ b/Projects/Webserver/Lib/uip/clock.c
@@ -1,9 +1,8 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include <avr/interrupt.h>
-#include <avr/io.h>
-#include <avr/sfr_defs.h>
+
+#include <LUFA/Common/Common.h>
 
 #include "clock.h"
 
@@ -29,9 +28,9 @@ clock_time_t clock_time()
 {
 	clock_time_t time;
 
-	USB_INT_GlobalDisable();
+	GlobalInterruptDisable();
 	time = clock_datetime;
-	USB_INT_GlobalEnable();
+	GlobalInterruptEnable();
 
 	return time;
 }
-- 
GitLab