diff options
author | Dean Camera <dean@fourwalledcubicle.com> | 2011-04-08 05:40:25 +0000 |
---|---|---|
committer | Dean Camera <dean@fourwalledcubicle.com> | 2011-04-08 05:40:25 +0000 |
commit | c263ea837ae7e3c0e963b798afdffd501790ce2c (patch) | |
tree | a899d943856b48f6889cf1fe9f5b97ccc58ca598 | |
parent | de9bd767dc8578a45a195fb1e37dd4ff26ae9567 (diff) | |
download | lufa-c263ea837ae7e3c0e963b798afdffd501790ce2c.tar.gz lufa-c263ea837ae7e3c0e963b798afdffd501790ce2c.tar.bz2 lufa-c263ea837ae7e3c0e963b798afdffd501790ce2c.zip |
Move global interrupt enable/disable functions out to Common.h and document them.
-rw-r--r-- | LUFA/Common/Common.h | 91 | ||||
-rw-r--r-- | LUFA/Drivers/Misc/RingBuffer.h | 24 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h | 6 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c | 2 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h | 31 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Core/DeviceStandardReq.c | 6 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Core/UC3/Device_UC3.h | 6 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c | 2 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h | 39 | ||||
-rw-r--r-- | LUFA/ManPages/ChangeLog.txt | 3 | ||||
-rw-r--r-- | LUFA/Scheduler/Scheduler.c | 6 | ||||
-rw-r--r-- | LUFA/Scheduler/Scheduler.h | 6 | ||||
-rw-r--r-- | 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; } |