From c263ea837ae7e3c0e963b798afdffd501790ce2c Mon Sep 17 00:00:00 2001 From: Dean Camera 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 a54512a510..4e697ad187 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 5c8c8403b8..5040291655 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 77af512550..47f58b27d4 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 deaa5e5fbc..4939ec2edf 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 e85b67e925..6115ec6e3c 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 a502c09494..2e6d8f8c01 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 150b188605..2a029bf080 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 76386649ad..76f4ef022e 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 a9ad566117..2cebf41067 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 5d5f6db1af..97f9c30047 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 87a21491d8..56e1cf41e5 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 499a63a1b4..262218683a 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 87650b6daa..e71f7209d2 100644 --- a/Projects/Webserver/Lib/uip/clock.c +++ b/Projects/Webserver/Lib/uip/clock.c @@ -1,9 +1,8 @@ #include #include #include -#include -#include -#include + +#include #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; }