Commit c263ea83 authored by Dean Camera's avatar Dean Camera

Move global interrupt enable/disable functions out to Common.h and document them.

parent de9bd767
...@@ -97,7 +97,7 @@ ...@@ -97,7 +97,7 @@
typedef uint32_t uint_reg_t; typedef uint32_t uint_reg_t;
#define ARCH_BIG_ENDIAN #define ARCH_BIG_ENDIAN
#include "Endianness.h" #include "Endianness.h"
#else #else
...@@ -217,6 +217,22 @@ ...@@ -217,6 +217,22 @@
*/ */
#define GCC_MEMORY_BARRIER() __asm__ __volatile__("" ::: "memory"); #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: */ /* 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, /** Function to reverse the individual bits in a byte - i.e. bit 7 is moved to bit 0, bit 6 to bit 1,
* etc. * etc.
...@@ -260,6 +276,79 @@ ...@@ -260,6 +276,79 @@
#endif #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 #endif
/** @} */ /** @} */
......
...@@ -125,8 +125,8 @@ ...@@ -125,8 +125,8 @@
{ {
GCC_FORCE_POINTER_ACCESS(Buffer); GCC_FORCE_POINTER_ACCESS(Buffer);
uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState(); uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
USB_INT_GlobalDisable(); GlobalInterruptDisable();
Buffer->In = DataPtr; Buffer->In = DataPtr;
Buffer->Out = DataPtr; Buffer->Out = DataPtr;
...@@ -135,7 +135,7 @@ ...@@ -135,7 +135,7 @@
Buffer->Size = Size; Buffer->Size = Size;
Buffer->Count = 0; Buffer->Count = 0;
USB_INT_SetGlobalEnableState(CurrentGlobalInt); SetGlobalInterruptMask(CurrentGlobalInt);
} }
/** Retrieves the minimum number of bytes stored in a particular buffer. This value is computed /** Retrieves the minimum number of bytes stored in a particular buffer. This value is computed
...@@ -155,12 +155,12 @@ ...@@ -155,12 +155,12 @@
{ {
uint16_t Count; uint16_t Count;
uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState(); uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
USB_INT_GlobalDisable(); GlobalInterruptDisable();
Count = Buffer->Count; Count = Buffer->Count;
USB_INT_SetGlobalEnableState(CurrentGlobalInt); SetGlobalInterruptMask(CurrentGlobalInt);
return Count; return Count;
} }
...@@ -213,12 +213,12 @@ ...@@ -213,12 +213,12 @@
if (++Buffer->In == Buffer->End) if (++Buffer->In == Buffer->End)
Buffer->In = Buffer->Start; Buffer->In = Buffer->Start;
uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState(); uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
USB_INT_GlobalDisable(); GlobalInterruptDisable();
Buffer->Count++; Buffer->Count++;
USB_INT_SetGlobalEnableState(CurrentGlobalInt); SetGlobalInterruptMask(CurrentGlobalInt);
} }
/** Removes an element from the ring buffer. /** Removes an element from the ring buffer.
...@@ -240,12 +240,12 @@ ...@@ -240,12 +240,12 @@
if (++Buffer->Out == Buffer->End) if (++Buffer->Out == Buffer->End)
Buffer->Out = Buffer->Start; Buffer->Out = Buffer->Start;
uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState(); uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
USB_INT_GlobalDisable(); GlobalInterruptDisable();
Buffer->Count--; Buffer->Count--;
USB_INT_SetGlobalEnableState(CurrentGlobalInt); SetGlobalInterruptMask(CurrentGlobalInt);
return Data; return Data;
} }
......
...@@ -199,8 +199,8 @@ ...@@ -199,8 +199,8 @@
static inline void USB_Device_GetSerialString(uint16_t* UnicodeString) static inline void USB_Device_GetSerialString(uint16_t* UnicodeString)
{ {
uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState(); uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
USB_INT_GlobalDisable(); GlobalInterruptDisable();
uint8_t SigReadAddress = 0x0E; uint8_t SigReadAddress = 0x0E;
...@@ -220,7 +220,7 @@ ...@@ -220,7 +220,7 @@
(('A' - 10) + SerialByte) : ('0' + SerialByte)); (('A' - 10) + SerialByte) : ('0' + SerialByte));
} }
USB_INT_SetGlobalEnableState(CurrentGlobalInt); SetGlobalInterruptMask(CurrentGlobalInt);
} }
#endif #endif
......
...@@ -263,7 +263,7 @@ ISR(USB_COM_vect, ISR_BLOCK) ...@@ -263,7 +263,7 @@ ISR(USB_COM_vect, ISR_BLOCK)
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
USB_INT_Disable(USB_INT_RXSTPI); USB_INT_Disable(USB_INT_RXSTPI);
USB_INT_GlobalEnable(); GlobalInterruptEnable();
USB_Device_ProcessControlRequest(); USB_Device_ProcessControlRequest();
......
...@@ -84,37 +84,6 @@ ...@@ -84,37 +84,6 @@
}; };
/* Inline Functions: */ /* 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) ATTR_ALWAYS_INLINE;
static inline void USB_INT_Enable(const uint8_t Interrupt) static inline void USB_INT_Enable(const uint8_t Interrupt)
{ {
......
...@@ -115,8 +115,8 @@ void USB_Device_ProcessControlRequest(void) ...@@ -115,8 +115,8 @@ void USB_Device_ProcessControlRequest(void)
static void USB_Device_SetAddress(void) static void USB_Device_SetAddress(void)
{ {
uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F); uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F);
uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState(); uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
USB_INT_GlobalDisable(); GlobalInterruptDisable();
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
...@@ -127,7 +127,7 @@ static void USB_Device_SetAddress(void) ...@@ -127,7 +127,7 @@ static void USB_Device_SetAddress(void)
USB_Device_SetDeviceAddress(DeviceAddress); USB_Device_SetDeviceAddress(DeviceAddress);
USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default; USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
USB_INT_SetGlobalEnableState(CurrentGlobalInt); SetGlobalInterruptMask(CurrentGlobalInt);
} }
static void USB_Device_SetConfiguration(void) static void USB_Device_SetConfiguration(void)
......
...@@ -187,8 +187,8 @@ ...@@ -187,8 +187,8 @@
static inline void USB_Device_GetSerialString(uint16_t* UnicodeString) static inline void USB_Device_GetSerialString(uint16_t* UnicodeString)
{ {
uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState(); uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
USB_INT_GlobalDisable(); GlobalInterruptDisable();
uint8_t* SigReadAddress = (uint8_t*)0x80800204; uint8_t* SigReadAddress = (uint8_t*)0x80800204;
...@@ -208,7 +208,7 @@ ...@@ -208,7 +208,7 @@
(('A' - 10) + SerialByte) : ('0' + SerialByte)); (('A' - 10) + SerialByte) : ('0' + SerialByte));
} }
USB_INT_SetGlobalEnableState(CurrentGlobalInt); SetGlobalInterruptMask(CurrentGlobalInt);
} }
#endif #endif
......
...@@ -49,7 +49,7 @@ void USB_INT_ClearAllInterrupts(void) ...@@ -49,7 +49,7 @@ void USB_INT_ClearAllInterrupts(void)
AVR32_USBB.udintclr = 0xFFFFFFFF; AVR32_USBB.udintclr = 0xFFFFFFFF;
} }
LUFA_ISR(USB_GEN_vect) ISR(USB_GEN_vect)
{ {
#if defined(USB_CAN_BE_DEVICE) #if defined(USB_CAN_BE_DEVICE)
#if !defined(NO_SOF_EVENTS) #if !defined(NO_SOF_EVENTS)
......
...@@ -55,10 +55,7 @@ ...@@ -55,10 +55,7 @@
#endif #endif
/* Private Interface - For use in library only: */ /* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__) #if !defined(__DOXYGEN__)
/* Macros: */
#define LUFA_ISR(Name) void Name (void) __attribute__((__interrupt__)); void Name (void)
/* Enums: */ /* Enums: */
enum USB_Interrupts_t enum USB_Interrupts_t
{ {
...@@ -83,38 +80,6 @@ ...@@ -83,38 +80,6 @@
}; };
/* Inline Functions: */ /* 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) ATTR_ALWAYS_INLINE;
static inline void USB_INT_Enable(const uint8_t Interrupt) static inline void USB_INT_Enable(const uint8_t Interrupt)
{ {
...@@ -376,7 +341,7 @@ ...@@ -376,7 +341,7 @@
*/ */
void USB_GEN_vect(void); void USB_GEN_vect(void);
#else #else
LUFA_ISR(USB_GEN_vect); ISR(USB_GEN_vect);
#endif #endif
/* Disable C linkage for C++ Compilers: */ /* Disable C linkage for C++ Compilers: */
......
...@@ -25,7 +25,8 @@ ...@@ -25,7 +25,8 @@
* - Added board driver support for the Sparkfun ATMEGA8U2 breakout board * - 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) * - 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 * - 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: * - Library Applications:
* - Added ability to write protect Mass Storage disk write operations from the host OS * - Added ability to write protect Mass Storage disk write operations from the host OS
* - Added new MIDIToneGenerator project * - Added new MIDIToneGenerator project
......
...@@ -39,12 +39,12 @@ bool Scheduler_HasDelayElapsed(const uint_least16_t Delay, ...@@ -39,12 +39,12 @@ bool Scheduler_HasDelayElapsed(const uint_least16_t Delay,
SchedulerDelayCounter_t CurrentTickValue_LCL; SchedulerDelayCounter_t CurrentTickValue_LCL;
SchedulerDelayCounter_t DelayCounter_LCL; SchedulerDelayCounter_t DelayCounter_LCL;
uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState(); uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
USB_INT_GlobalDisable(); GlobalInterruptDisable();
CurrentTickValue_LCL = Scheduler_TickCounter; CurrentTickValue_LCL = Scheduler_TickCounter;
USB_INT_SetGlobalEnableState(CurrentGlobalInt); SetGlobalInterruptMask(CurrentGlobalInt);
DelayCounter_LCL = *DelayCounter; DelayCounter_LCL = *DelayCounter;
......
...@@ -219,12 +219,12 @@ ...@@ -219,12 +219,12 @@
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter) static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter)
{ {
uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState(); uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
USB_INT_GlobalDisable(); GlobalInterruptDisable();
*DelayCounter = Scheduler_TickCounter; *DelayCounter = Scheduler_TickCounter;
USB_INT_SetGlobalEnableState(CurrentGlobalInt); SetGlobalInterruptMask(CurrentGlobalInt);
} }
/* Function Prototypes: */ /* Function Prototypes: */
......
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <avr/interrupt.h>
#include <avr/io.h> #include <LUFA/Common/Common.h>
#include <avr/sfr_defs.h>
#include "clock.h" #include "clock.h"
...@@ -29,9 +28,9 @@ clock_time_t clock_time() ...@@ -29,9 +28,9 @@ clock_time_t clock_time()
{ {
clock_time_t time; clock_time_t time;
USB_INT_GlobalDisable(); GlobalInterruptDisable();
time = clock_datetime; time = clock_datetime;
USB_INT_GlobalEnable(); GlobalInterruptEnable();
return time; return time;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment