Add in a new common Delay_MS() function, which provides a blocking delay for all architectures.

Remove use of avr-libc specific ATOMIC_BLOCK, replace with a new per-architecture set of inline functions to retrieve and manipulate the global interrupt enable bit for each architecture.

Add in documentation for the USB controller common interrupt routine which must be linked to the interrupt controller in the user application on the AVR32 UC3 architecture.
pull/1469/head
Dean Camera 14 years ago
parent 0c5afda7e8
commit 70284d390f

File diff suppressed because one or more lines are too long

@ -75,7 +75,6 @@
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <avr/eeprom.h> #include <avr/eeprom.h>
#include <avr/boot.h> #include <avr/boot.h>
#include <util/atomic.h>
#include <util/delay.h> #include <util/delay.h>
typedef uint8_t uint_reg_t; typedef uint8_t uint_reg_t;
@ -90,12 +89,8 @@
#include <avr32/io.h> #include <avr32/io.h>
// === TODO: Find abstracted way to handle these === // === TODO: Find abstracted way to handle these ===
#define ISR(Name) void Name (void) __attribute__((__interrupt__)); void Name (void)
#define PROGMEM const #define PROGMEM const
#define ATOMIC_BLOCK(x) if (1)
#define ATOMIC_RESTORESTATE
#define pgm_read_byte(x) *x #define pgm_read_byte(x) *x
#define _delay_ms(x)
#define memcmp_P(...) memcmp(__VA_ARGS__) #define memcmp_P(...) memcmp(__VA_ARGS__)
#define memcpy_P(...) memcpy(__VA_ARGS__) #define memcpy_P(...) memcpy(__VA_ARGS__)
// ================================================== // ==================================================
@ -238,6 +233,23 @@
return Byte; return Byte;
} }
/** Function to perform a blocking delay for a specified number of milliseconds. The actual delay will be
* at a minimum the specified number of milliseconds, however due to loop overhead and internal calculations
* may be slightly higher.
*/
static inline void Delay_MS(uint8_t Milliseconds)
{
while (Milliseconds--)
{
#if (ARCH == ARCH_AVR8)
_delay_ms(1);
#elif (ARCH == ARCH_UC3)
__builtin_mtsr(AVR32_COUNT, 0);
while (__builtin_mfsr(AVR32_COUNT) < (F_CPU / 1000));
#endif
}
}
#endif #endif
/** @} */ /** @} */

@ -125,15 +125,17 @@
{ {
GCC_FORCE_POINTER_ACCESS(Buffer); GCC_FORCE_POINTER_ACCESS(Buffer);
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
{ USB_INT_GlobalDisable();
Buffer->In = DataPtr; Buffer->In = DataPtr;
Buffer->Out = DataPtr; Buffer->Out = DataPtr;
Buffer->Start = &DataPtr[0]; Buffer->Start = &DataPtr[0];
Buffer->End = &DataPtr[Size]; Buffer->End = &DataPtr[Size];
Buffer->Size = Size; Buffer->Size = Size;
Buffer->Count = 0; Buffer->Count = 0;
}
USB_INT_SetGlobalEnableState(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
@ -153,11 +155,12 @@
{ {
uint16_t Count; uint16_t Count;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
{ USB_INT_GlobalDisable();
Count = Buffer->Count; Count = Buffer->Count;
}
USB_INT_SetGlobalEnableState(CurrentGlobalInt);
return Count; return Count;
} }
@ -210,10 +213,12 @@
if (++Buffer->In == Buffer->End) if (++Buffer->In == Buffer->End)
Buffer->In = Buffer->Start; Buffer->In = Buffer->Start;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
{ USB_INT_GlobalDisable();
Buffer->Count++; Buffer->Count++;
}
USB_INT_SetGlobalEnableState(CurrentGlobalInt);
} }
/** Removes an element from the ring buffer. /** Removes an element from the ring buffer.
@ -235,10 +240,12 @@
if (++Buffer->Out == Buffer->End) if (++Buffer->Out == Buffer->End)
Buffer->Out = Buffer->Start; Buffer->Out = Buffer->Start;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
{ USB_INT_GlobalDisable();
Buffer->Count--; Buffer->Count--;
}
USB_INT_SetGlobalEnableState(CurrentGlobalInt);
return Data; return Data;
} }

@ -199,8 +199,9 @@
static inline void USB_Device_GetSerialString(uint16_t* UnicodeString) static inline void USB_Device_GetSerialString(uint16_t* UnicodeString)
{ {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
{ USB_INT_GlobalDisable();
uint8_t SigReadAddress = 0x0E; uint8_t SigReadAddress = 0x0E;
for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++)
@ -218,7 +219,8 @@
UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ? UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ?
(('A' - 10) + SerialByte) : ('0' + SerialByte)); (('A' - 10) + SerialByte) : ('0' + SerialByte));
} }
}
USB_INT_SetGlobalEnableState(CurrentGlobalInt);
} }
#endif #endif

@ -69,7 +69,7 @@ void USB_Host_ProcessNextHostState(void)
case HOST_STATE_Powered_WaitForDeviceSettle: case HOST_STATE_Powered_WaitForDeviceSettle:
if (WaitMSRemaining--) if (WaitMSRemaining--)
{ {
_delay_ms(1); Delay_MS(1);
break; break;
} }
else else

@ -263,10 +263,9 @@ 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);
NONATOMIC_BLOCK(NONATOMIC_FORCEOFF) USB_INT_GlobalEnable();
{
USB_Device_ProcessControlRequest(); USB_Device_ProcessControlRequest();
}
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
USB_INT_Enable(USB_INT_RXSTPI); USB_INT_Enable(USB_INT_RXSTPI);

@ -84,6 +84,37 @@
}; };
/* 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,9 +115,9 @@ 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();
USB_INT_GlobalDisable();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
@ -125,9 +125,9 @@ static void USB_Device_SetAddress(void)
while (!(Endpoint_IsINReady())); while (!(Endpoint_IsINReady()));
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);
} }
static void USB_Device_SetConfiguration(void) static void USB_Device_SetConfiguration(void)

@ -187,8 +187,9 @@
static inline void USB_Device_GetSerialString(uint16_t* UnicodeString) static inline void USB_Device_GetSerialString(uint16_t* UnicodeString)
{ {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
{ USB_INT_GlobalDisable();
uint8_t* SigReadAddress = (uint8_t*)0x80800204; uint8_t* SigReadAddress = (uint8_t*)0x80800204;
for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++)
@ -206,7 +207,8 @@
UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ? UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ?
(('A' - 10) + SerialByte) : ('0' + SerialByte)); (('A' - 10) + SerialByte) : ('0' + SerialByte));
} }
}
USB_INT_SetGlobalEnableState(CurrentGlobalInt);
} }
#endif #endif

@ -69,7 +69,7 @@ void USB_Host_ProcessNextHostState(void)
case HOST_STATE_Powered_WaitForDeviceSettle: case HOST_STATE_Powered_WaitForDeviceSettle:
if (WaitMSRemaining--) if (WaitMSRemaining--)
{ {
_delay_ms(1); Delay_MS(1);
break; break;
} }
else else

@ -49,7 +49,7 @@ void USB_INT_ClearAllInterrupts(void)
AVR32_USBB.udintclr = 0xFFFFFFFF; AVR32_USBB.udintclr = 0xFFFFFFFF;
} }
ISR(USB_GEN_vect) LUFA_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)

@ -57,6 +57,9 @@
/* Private Interface - For use in library only: */ /* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__) #if !defined(__DOXYGEN__)
/* Macros: */ /* Macros: */
#define LUFA_ISR(Name) void Name (void) __attribute__((__interrupt__)); void Name (void)
/* Enums: */
enum USB_Interrupts_t enum USB_Interrupts_t
{ {
USB_INT_VBUSTI = 0, USB_INT_VBUSTI = 0,
@ -79,10 +82,38 @@
#endif #endif
}; };
/* ISR Prototypes: */
ISR(USB_GEN_vect);
/* 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) & AVR32_SR_GM);
}
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();
__builtin_ssrf(AVR32_SR_GM_OFFSET, GlobalIntState);
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)
{ {
@ -335,6 +366,18 @@
void USB_INT_DisableAllInterrupts(void); void USB_INT_DisableAllInterrupts(void);
#endif #endif
/* Public Interface - May be used in end-application: */
/* ISR Prototypes: */
#if defined(__DOXYGEN__)
/** Interrupt service routine handler for the USB controller ISR group. This interrupt routine <b>must</b> be
* linked to the entire USB controller ISR vector group inside the AVR32's interrupt controller peripheral,
* using the user application's preferred USB controller driver.
*/
void USB_GEN_vect(void);
#else
LUFA_ISR(USB_GEN_vect);
#endif
/* Disable C linkage for C++ Compilers: */ /* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus) #if defined(__cplusplus)
} }

@ -39,10 +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;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
{ USB_INT_GlobalDisable();
CurrentTickValue_LCL = Scheduler_TickCounter; CurrentTickValue_LCL = Scheduler_TickCounter;
}
USB_INT_SetGlobalEnableState(CurrentGlobalInt);
DelayCounter_LCL = *DelayCounter; DelayCounter_LCL = *DelayCounter;

@ -219,10 +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)
{ {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) uint_reg_t CurrentGlobalInt = USB_INT_GetGlobalEnableState();
{ USB_INT_GlobalDisable();
*DelayCounter = Scheduler_TickCounter; *DelayCounter = Scheduler_TickCounter;
}
USB_INT_SetGlobalEnableState(CurrentGlobalInt);
} }
/* Function Prototypes: */ /* Function Prototypes: */

@ -29,10 +29,9 @@ clock_time_t clock_time()
{ {
clock_time_t time; clock_time_t time;
ATOMIC_BLOCK(ATOMIC_FORCEON) USB_INT_GlobalDisable();
{
time = clock_datetime; time = clock_datetime;
} USB_INT_GlobalEnable();
return time; return time;
} }

Loading…
Cancel
Save