typedef uint32_t uint_reg_t;
- #define ARCH_BIG_ENDIAN
+ #define ARCH_BIG_ENDIAN
#include "Endianness.h"
#else
*/
#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.
#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
/** @} */
{\r
GCC_FORCE_POINTER_ACCESS(Buffer);\r
\r
- uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();\r
- USB_INT_GlobalDisable();\r
+ uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();\r
+ GlobalInterruptDisable();\r
\r
Buffer->In = DataPtr;\r
Buffer->Out = DataPtr;\r
Buffer->Size = Size;\r
Buffer->Count = 0;\r
\r
- USB_INT_SetGlobalEnableState(CurrentGlobalInt);\r
+ SetGlobalInterruptMask(CurrentGlobalInt);\r
}\r
\r
/** Retrieves the minimum number of bytes stored in a particular buffer. This value is computed\r
{\r
uint16_t Count;\r
\r
- uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();\r
- USB_INT_GlobalDisable();\r
+ uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();\r
+ GlobalInterruptDisable();\r
\r
Count = Buffer->Count;\r
\r
- USB_INT_SetGlobalEnableState(CurrentGlobalInt);\r
+ SetGlobalInterruptMask(CurrentGlobalInt);\r
return Count;\r
}\r
\r
if (++Buffer->In == Buffer->End)\r
Buffer->In = Buffer->Start;\r
\r
- uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();\r
- USB_INT_GlobalDisable();\r
+ uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();\r
+ GlobalInterruptDisable();\r
\r
Buffer->Count++;\r
\r
- USB_INT_SetGlobalEnableState(CurrentGlobalInt);\r
+ SetGlobalInterruptMask(CurrentGlobalInt);\r
}\r
\r
/** Removes an element from the ring buffer.\r
if (++Buffer->Out == Buffer->End)\r
Buffer->Out = Buffer->Start;\r
\r
- uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();\r
- USB_INT_GlobalDisable();\r
+ uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();\r
+ GlobalInterruptDisable();\r
\r
Buffer->Count--;\r
\r
- USB_INT_SetGlobalEnableState(CurrentGlobalInt);\r
+ SetGlobalInterruptMask(CurrentGlobalInt);\r
\r
return Data;\r
}\r
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;
(('A' - 10) + SerialByte) : ('0' + SerialByte));
}
- USB_INT_SetGlobalEnableState(CurrentGlobalInt);
+ SetGlobalInterruptMask(CurrentGlobalInt);
}
#endif
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
USB_INT_Disable(USB_INT_RXSTPI);
- USB_INT_GlobalEnable();
+ GlobalInterruptEnable();
USB_Device_ProcessControlRequest();
};
/* 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)
{
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();
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)
\r
static inline void USB_Device_GetSerialString(uint16_t* UnicodeString)\r
{\r
- uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();\r
- USB_INT_GlobalDisable();\r
+ uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();\r
+ GlobalInterruptDisable();\r
\r
uint8_t* SigReadAddress = (uint8_t*)0x80800204;\r
\r
(('A' - 10) + SerialByte) : ('0' + SerialByte));\r
}\r
\r
- USB_INT_SetGlobalEnableState(CurrentGlobalInt);\r
+ SetGlobalInterruptMask(CurrentGlobalInt);\r
}\r
#endif\r
\r
AVR32_USBB.udintclr = 0xFFFFFFFF;\r
}\r
\r
-LUFA_ISR(USB_GEN_vect)\r
+ISR(USB_GEN_vect)\r
{\r
#if defined(USB_CAN_BE_DEVICE)\r
#if !defined(NO_SOF_EVENTS)\r
#endif\r
\r
/* Private Interface - For use in library only: */\r
- #if !defined(__DOXYGEN__)\r
- /* Macros: */\r
- #define LUFA_ISR(Name) void Name (void) __attribute__((__interrupt__)); void Name (void)\r
- \r
+ #if !defined(__DOXYGEN__) \r
/* Enums: */\r
enum USB_Interrupts_t\r
{\r
};\r
\r
/* Inline Functions: */\r
- static inline uint_reg_t USB_INT_GetGlobalEnableState(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;\r
- static inline uint_reg_t USB_INT_GetGlobalEnableState(void)\r
- {\r
- GCC_MEMORY_BARRIER();\r
- return __builtin_mfsr(AVR32_SR);\r
- }\r
-\r
- static inline void USB_INT_SetGlobalEnableState(uint_reg_t GlobalIntState) ATTR_ALWAYS_INLINE;\r
- static inline void USB_INT_SetGlobalEnableState(uint_reg_t GlobalIntState)\r
- {\r
- GCC_MEMORY_BARRIER();\r
- if (GlobalIntState & AVR32_SR_GM)\r
- __builtin_ssrf(AVR32_SR_GM_OFFSET);\r
- GCC_MEMORY_BARRIER();\r
- }\r
- \r
- static inline void USB_INT_GlobalEnable(void) ATTR_ALWAYS_INLINE;\r
- static inline void USB_INT_GlobalEnable(void)\r
- {\r
- GCC_MEMORY_BARRIER();\r
- __builtin_csrf(AVR32_SR_GM_OFFSET);\r
- GCC_MEMORY_BARRIER();\r
- } \r
-\r
- static inline void USB_INT_GlobalDisable(void) ATTR_ALWAYS_INLINE;\r
- static inline void USB_INT_GlobalDisable(void)\r
- {\r
- GCC_MEMORY_BARRIER();\r
- __builtin_ssrf(AVR32_SR_GM_OFFSET);\r
- GCC_MEMORY_BARRIER();\r
- }\r
-\r
static inline void USB_INT_Enable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE;\r
static inline void USB_INT_Enable(const uint8_t Interrupt)\r
{ \r
*/\r
void USB_GEN_vect(void);\r
#else\r
- LUFA_ISR(USB_GEN_vect);\r
+ ISR(USB_GEN_vect);\r
#endif\r
\r
/* Disable C linkage for C++ Compilers: */\r
* - 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
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;
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: */
#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"
{
clock_time_t time;
- USB_INT_GlobalDisable();
+ GlobalInterruptDisable();
time = clock_datetime;
- USB_INT_GlobalEnable();
+ GlobalInterruptEnable();
return time;
}