Merge over core library changes from the MultiArchDemos branch.
authorDean Camera <dean@fourwalledcubicle.com>
Wed, 29 Jun 2011 05:57:29 +0000 (05:57 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Wed, 29 Jun 2011 05:57:29 +0000 (05:57 +0000)
LUFA/CodeTemplates/makefile_template.uc3
LUFA/Drivers/USB/Class/Device/HID.c
LUFA/Drivers/USB/Core/ConfigDescriptor.c
LUFA/Drivers/USB/Core/StdDescriptors.h
LUFA/Platform/UC3/ClockManagement.h [new file with mode: 0644]
LUFA/Platform/UC3/Exception.S [new file with mode: 0644]
LUFA/Platform/UC3/InterruptManagement.c [new file with mode: 0644]
LUFA/Platform/UC3/InterruptManagement.h [new file with mode: 0644]

index e29e3a4..2077ca1 100644 (file)
@@ -68,7 +68,7 @@ BOARD = ### INSERT NAME OF BOARD HERE, OR NONE IF NO BOARD DRIVERS USED ###
 F_CPU = ### INSERT PRESCALED SYSTEM CLOCK SPEED HERE, IN HZ ###\r
 \r
 \r
-# Input clock frequency.\r
+# USB controller master clock frequency.\r
 #     This will define a symbol, F_USB, in all source code files equal to the\r
 #     input clock frequency (before any prescaling is performed) in Hz. This value may\r
 #     differ from F_CPU, as the USB clock is often sourced from the same oscillator as\r
index 40351cc..3b0f87a 100644 (file)
@@ -137,7 +137,7 @@ bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfac
 {
        memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
        HIDInterfaceInfo->State.UsingReportProtocol = true;
-       HIDInterfaceInfo->State.IdleCount = 500;
+       HIDInterfaceInfo->State.IdleCount           = 500;
 
        if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber, EP_TYPE_INTERRUPT,
                                                                         ENDPOINT_DIR_IN, HIDInterfaceInfo->Config.ReportINEndpointSize,
index 35a0199..3e0cce5 100644 (file)
@@ -54,7 +54,7 @@ uint8_t USB_Host_GetDeviceConfigDescriptor(const uint8_t ConfigNumber,
        if ((ErrorCode = USB_Host_SendControlRequest(ConfigHeader)) != HOST_SENDCONTROL_Successful)
          return ErrorCode;
 
-       *ConfigSizePtr = DESCRIPTOR_PCAST(ConfigHeader, USB_Descriptor_Configuration_Header_t)->TotalConfigurationSize;
+       *ConfigSizePtr = le16_to_cpu(DESCRIPTOR_PCAST(ConfigHeader, USB_Descriptor_Configuration_Header_t)->TotalConfigurationSize);
 
        if (*ConfigSizePtr > BufferSize)
          return HOST_GETCONFIG_BuffOverflow;
index 7840bcb..864a1c4 100644 (file)
@@ -93,6 +93,9 @@
                         *  Decimal format for descriptor fields requiring BCD encoding, such as the USB version number in the
                         *  standard device descriptor.
                         *
+                        *  \note This value is automatically converted into Little Endian, suitable for direct use inside device
+                        *        descriptors on all architectures without endianness conversion macros.
+                        *
                         *  \param[in]  x  Version number to encode as a 16-bit little-endian number, as a floating point number.
                         */
                        #define VERSION_BCD(x)                    CPU_TO_LE16((((VERSION_TENS(x) << 4) | VERSION_ONES(x)) << 8) | \
                        /** String language ID for the English language. Should be used in \ref USB_Descriptor_String_t descriptors
                         *  to indicate that the English language is supported by the device in its string descriptors.
                         */
-                       #define LANGUAGE_ID_ENG                   CPU_TO_LE16(0x0409)
+                       #define LANGUAGE_ID_ENG                   0x0409
 
                        /** \name Endpoint Address Direction Masks */
                        //@{
diff --git a/LUFA/Platform/UC3/ClockManagement.h b/LUFA/Platform/UC3/ClockManagement.h
new file mode 100644 (file)
index 0000000..2b7325b
--- /dev/null
@@ -0,0 +1,181 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2011.\r
+\r
+  dean [at] fourwalledcubicle [dot] com\r
+           www.lufa-lib.org\r
+*/\r
+\r
+/*\r
+  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, distribute, and sell this\r
+  software and its documentation for any purpose is hereby granted\r
+  without fee, provided that the above copyright notice appear in\r
+  all copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#ifndef _CLOCK_MANAGEMENT_H_\r
+#define _CLOCK_MANAGEMENT_H_\r
+\r
+       /* Includes: */\r
+               #include <avr32/io.h>\r
+               #include <stdbool.h>\r
+               #include <stdint.h>\r
+\r
+               #include <LUFA/Common/Common.h>\r
+\r
+       /* Macros: */\r
+               enum Extern_OSC_ClockStartup_t\r
+               {\r
+                       EXOSC_START_0CLK         = 0,\r
+                       EXOSC_START_64CLK        = 1,\r
+                       EXOSC_START_128CLK       = 2,\r
+                       EXOSC_START_2048CLK      = 3,\r
+                       EXOSC_START_4096CLK      = 4,\r
+                       EXOSC_START_8192CLK      = 5,\r
+                       EXOSC_START_16384CLK     = 6,\r
+               };\r
+               \r
+               enum Extern_OSC_ClockMode_t\r
+               {\r
+                       EXOSC_MODE_CLOCK         = 0,\r
+                       EXOSC_MODE_900KHZ_MAX    = 1,\r
+                       EXOSC_MODE_3MHZ_MAX      = 2,\r
+                       EXOSC_MODE_8MHZ_MAX      = 3,\r
+                       EXOSC_MODE_8MHZ_OR_MORE  = 4,                   \r
+               };\r
+               \r
+               enum\r
+               {\r
+                       CLOCK_SRC_SLOW_CLK       = 0,\r
+                       CLOCK_SRC_OSC0           = 1,\r
+                       CLOCK_SRC_OSC1           = 2,\r
+                       CLOCK_SRC_PLL0           = 3,\r
+                       CLOCK_SRC_PLL1           = 4,\r
+               };\r
+\r
+       /* Inline Functions: */\r
+               static inline bool AVR32CLK_StartExternalOscillator(const uint8_t Channel,\r
+                                                                   const uint8_t Type,\r
+                                                                   const uint8_t Startup)\r
+               {\r
+                       AVR32_PM.OSCCTRL0.startup       = Startup;\r
+                       AVR32_PM.OSCCTRL0.mode          = Type;\r
+                       AVR32_PM.mcctrl                |= (1 << (AVR32_PM_MCCTRL_OSC0EN_OFFSET + Channel));\r
+\r
+                       while (!(AVR32_PM.poscsr & (1 << (AVR32_PM_POSCSR_OSC0RDY_OFFSET + Channel))));\r
+                       return true;\r
+               }\r
+\r
+               static inline void AVR32CLK_StopExternalOscillator(const uint8_t Channel)\r
+               {\r
+                       AVR32_PM.mcctrl                &= ~(1 << (AVR32_PM_MCCTRL_OSC0EN_OFFSET + Channel));\r
+               }\r
+\r
+               static inline bool AVR32CLK_StartPLL(const uint8_t Channel,\r
+                                                    const uint8_t Source,\r
+                                                    const uint32_t SourceFreq,\r
+                                                    const uint32_t Frequency)\r
+               {\r
+                       switch (Source)\r
+                       {\r
+                               case CLOCK_SRC_OSC0:\r
+                                       AVR32_PM.PLL[Channel].pllosc = 0;\r
+                                       break;\r
+                               case CLOCK_SRC_OSC1:\r
+                                       AVR32_PM.PLL[Channel].pllosc = 1;\r
+                                       break;\r
+                               default:\r
+                                       return false;\r
+                       }\r
+\r
+                       AVR32_PM.PLL[Channel].pllmul    = (Frequency / SourceFreq) ? (((Frequency / SourceFreq) - 1) / 2) : 0;\r
+                       AVR32_PM.PLL[Channel].plldiv    = 0;\r
+                       AVR32_PM.PLL[Channel].pllen     = true;\r
+\r
+                       while (!(AVR32_PM.poscsr & (1 << (AVR32_PM_POSCSR_LOCK0_OFFSET + Channel))));\r
+                       return true;\r
+               }\r
+\r
+               static inline void AVR32CLK_StopPLL(const uint8_t Channel)\r
+               {\r
+                       AVR32_PM.PLL[Channel].pllen     = false;\r
+               }\r
+               \r
+               static inline bool AVR32CLK_StartGenericClock(const uint8_t Channel,\r
+                                                             const uint8_t Source,\r
+                                                             const uint32_t SourceFreq,\r
+                                                             const uint32_t Frequency)\r
+               {\r
+                       switch (Source)\r
+                       {\r
+                               case CLOCK_SRC_OSC0:\r
+                                       AVR32_PM.GCCTRL[Channel].pllsel = 0;\r
+                                       AVR32_PM.GCCTRL[Channel].oscsel = 0;\r
+                                       break;\r
+                               case CLOCK_SRC_OSC1:\r
+                                       AVR32_PM.GCCTRL[Channel].pllsel = 0;\r
+                                       AVR32_PM.GCCTRL[Channel].oscsel = 1;\r
+                                       break;\r
+                               case CLOCK_SRC_PLL0:\r
+                                       AVR32_PM.GCCTRL[Channel].pllsel = 1;\r
+                                       AVR32_PM.GCCTRL[Channel].oscsel = 0;\r
+                                       break;\r
+                               case CLOCK_SRC_PLL1:\r
+                                       AVR32_PM.GCCTRL[Channel].pllsel = 1;\r
+                                       AVR32_PM.GCCTRL[Channel].oscsel = 1;\r
+                                       break;\r
+                               default:\r
+                                       return false;\r
+                       }\r
+\r
+                       AVR32_PM.GCCTRL[Channel].diven  = (SourceFreq > Frequency) ? true : false;\r
+                       AVR32_PM.GCCTRL[Channel].div    = (((SourceFreq / Frequency) - 1) / 2);\r
+                       AVR32_PM.GCCTRL[Channel].cen    = true;\r
+                       \r
+                       return true;\r
+               }\r
+               \r
+               static inline void AVR32CLK_StopGenericClock(const uint8_t Channel)\r
+               {\r
+                       AVR32_PM.GCCTRL[Channel].cen    = false;\r
+               }\r
+\r
+               static inline bool AVR32CLK_SetCPUClockSource(const uint8_t Source,\r
+                                                             const uint32_t SourceFreq)\r
+               {\r
+                       AVR32_FLASHC.FCR.fws            = (SourceFreq > 30000000) ? true : false;\r
+\r
+                       switch (Source)\r
+                       {\r
+                               case CLOCK_SRC_SLOW_CLK:\r
+                                       AVR32_PM.MCCTRL.mcsel   = 0;\r
+                                       break;\r
+                               case CLOCK_SRC_OSC0:\r
+                                       AVR32_PM.MCCTRL.mcsel   = 1;\r
+                                       break;\r
+                               case CLOCK_SRC_PLL0:\r
+                                       AVR32_PM.MCCTRL.mcsel   = 2;\r
+                                       break;\r
+                               default:\r
+                                       return false;\r
+                       }\r
+                       \r
+                       return true;\r
+               }\r
+\r
+#endif\r
diff --git a/LUFA/Platform/UC3/Exception.S b/LUFA/Platform/UC3/Exception.S
new file mode 100644 (file)
index 0000000..9509fd7
--- /dev/null
@@ -0,0 +1,125 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2011.\r
+\r
+  dean [at] fourwalledcubicle [dot] com\r
+           www.lufa-lib.org\r
+*/\r
+\r
+/*\r
+  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, distribute, and sell this\r
+  software and its documentation for any purpose is hereby granted\r
+  without fee, provided that the above copyright notice appear in\r
+  all copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#include <avr32/io.h>\r
+\r
+.section .exception_handlers, "ax", @progbits\r
+\r
+// ================= EXCEPTION TABLE ================\r
+.balign  0x200\r
+.global  EVBA_Table\r
+EVBA_Table:\r
+\r
+.org  0x000\r
+Exception_Unrecoverable_Exception:\r
+       rjmp $\r
+.org  0x004\r
+Exception_TLB_Multiple_Hit:\r
+       rjmp $\r
+.org  0x008\r
+Exception_Bus_Error_Data_Fetch:\r
+       rjmp $\r
+.org  0x00C\r
+Exception_Bus_Error_Instruction_Fetch:\r
+       rjmp $\r
+.org  0x010\r
+Exception_NMI:\r
+       rjmp $\r
+.org  0x014\r
+Exception_Instruction_Address:\r
+       rjmp $\r
+.org  0x018\r
+Exception_ITLB_Protection:\r
+       rjmp $\r
+.org  0x01C\r
+Exception_OCD_Breakpoint:\r
+       rjmp $\r
+.org  0x020\r
+Exception_Illegal_Opcode:\r
+       rjmp $\r
+.org  0x024\r
+Exception_Unimplemented_Instruction:\r
+       rjmp $\r
+.org  0x028\r
+Exception_Privilege_Violation:\r
+       rjmp $\r
+.org  0x02C\r
+Exception_Floating_Point:\r
+       rjmp $\r
+.org  0x030\r
+Exception_Coprocessor_Absent:\r
+       rjmp $\r
+.org  0x034\r
+Exception_Data_Address_Read:\r
+       rjmp $\r
+.org  0x038\r
+Exception_Data_Address_Write:\r
+       rjmp $\r
+.org  0x03C\r
+Exception_DTLB_Protection_Read:\r
+       rjmp $\r
+.org  0x040\r
+Exception_DTLB_Protection_Write:\r
+       rjmp $\r
+.org  0x044\r
+Exception_DTLB_Modified:\r
+       rjmp $\r
+.org  0x050\r
+Exception_ITLB_Miss:\r
+       rjmp $\r
+.org  0x060\r
+Exception_DTLB_Miss_Read:\r
+       rjmp $\r
+.org  0x070\r
+Exception_DTLB_Miss_Write:\r
+       rjmp $\r
+.org  0x100\r
+Exception_Supervisor_Call:\r
+    rjmp $\r
+// ============== END OF EXCEPTION TABLE =============\r
+\r
+// ============= GENERAL INTERRUPT HANDLER ===========\r
+.balign 4\r
+.irp    Level, 0, 1, 2, 3\r
+Exception_INT\Level:\r
+       mov     r12, \Level\r
+       call    INTC_GetInterruptHandler\r
+       mov     pc, r12\r
+.endr\r
+// ========= END OF GENERAL INTERRUPT HANDLER ========\r
+\r
+// ====== GENERAL INTERRUPT HANDLER OFFSET TABLE ======\r
+.balign 4\r
+.global Autovector_Table\r
+Autovector_Table:\r
+.irp    Level, 0, 1, 2, 3\r
+       .word ((AVR32_INTC_INT0 + \Level) << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (Exception_INT\Level - EVBA_Table)\r
+.endr\r
+// === END OF GENERAL INTERRUPT HANDLER OFFSET TABLE ===\r
diff --git a/LUFA/Platform/UC3/InterruptManagement.c b/LUFA/Platform/UC3/InterruptManagement.c
new file mode 100644 (file)
index 0000000..b1dda74
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2011.\r
+\r
+  dean [at] fourwalledcubicle [dot] com\r
+           www.lufa-lib.org\r
+*/\r
+\r
+/*\r
+  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, distribute, and sell this\r
+  software and its documentation for any purpose is hereby granted\r
+  without fee, provided that the above copyright notice appear in\r
+  all copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#include "InterruptManagement.h"\r
+\r
+/** Interrupt vector table, containing the ISR to call for each interrupt group */\r
+InterruptHandlerPtr_t InterruptHandlers[AVR32_INTC_NUM_INT_GRPS];\r
+\r
+/** ISR for unhandled interrupt groups */\r
+ISR(Unhandled_Interrupt)\r
+{\r
+       while (true);\r
+}\r
+\r
+/** Retrieves the associated interrupt handler for the interrupt currently being fired. This is\r
+ *  called directly from the exception handler routine before dispatching to the ISR.\r
+ */\r
+InterruptHandlerPtr_t INTC_GetInterruptHandler(const uint_reg_t InterruptLevel)\r
+{\r
+       return InterruptHandlers[AVR32_INTC.icr[AVR32_INTC_INT3 - InterruptLevel]];\r
+}\r
+\r
+/** Initializes the interrupt controller ready to handle interrupts. This must be called at the\r
+ *  start of the user program before any interrupts are registered or enabled.\r
+ */\r
+void INTC_Init(void)\r
+{\r
+       for (uint8_t InterruptGroup = 0; InterruptGroup < AVR32_INTC_NUM_INT_GRPS; InterruptGroup++)\r
+       {\r
+               InterruptHandlers[InterruptGroup] = Unhandled_Interrupt;\r
+               AVR32_INTC.ipr[InterruptGroup]    = Autovector_Table[AVR32_INTC_INT0];\r
+       }\r
+\r
+       __builtin_mtsr(AVR32_EVBA, (uintptr_t)&EVBA_Table);\r
+}\r
diff --git a/LUFA/Platform/UC3/InterruptManagement.h b/LUFA/Platform/UC3/InterruptManagement.h
new file mode 100644 (file)
index 0000000..fec099d
--- /dev/null
@@ -0,0 +1,83 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2011.\r
+\r
+  dean [at] fourwalledcubicle [dot] com\r
+           www.lufa-lib.org\r
+*/\r
+\r
+/*\r
+  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, distribute, and sell this\r
+  software and its documentation for any purpose is hereby granted\r
+  without fee, provided that the above copyright notice appear in\r
+  all copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#ifndef _INTERRUPT_MANAGEMENT_H_\r
+#define _INTERRUPT_MANAGEMENT_H_\r
+\r
+       /* Includes: */\r
+               #include <avr32/io.h>\r
+               #include <stdbool.h>\r
+               #include <stdint.h>\r
+\r
+               #include <LUFA/Common/Common.h>\r
+\r
+       /* Macros: */\r
+               #if !defined(ISR)\r
+                       #define ISR(Name)                 void Name (void) __attribute__((__interrupt__)); void Name (void)\r
+               #endif\r
+               \r
+               #define INTC_EnableInterrupts()   do { GCC_MEMORY_BARRIER(); __builtin_csrf(AVR32_SR_GM_OFFSET); } while (0)\r
+               #define INTC_DisableInterrupts()  do { __builtin_ssrf(AVR32_SR_GM_OFFSET); GCC_MEMORY_BARRIER(); } while (0)\r
+\r
+       /* Type Defines: */\r
+               typedef void (*InterruptHandlerPtr_t)(void);\r
+\r
+       /* External Variables: */\r
+               extern const void            EVBA_Table;\r
+               extern const uint32_t        Autovector_Table[];\r
+               extern InterruptHandlerPtr_t InterruptHandlers[AVR32_INTC_NUM_INT_GRPS];\r
+\r
+       /* Function Prototypes: */\r
+               void INTC_Init(void);\r
+\r
+       /* Inline Functions: */\r
+               /** Registers a handler for a given interrupt group. On the AVR32 UC3 devices, interrupts are grouped by\r
+                *  peripheral. To save on SRAM used, a single ISR handles all interrupt lines within a single group - to\r
+                *  determine the exact line that has interrupted within the group ISR handler, examine the module's interrupt\r
+                *  flag register bits.\r
+                *\r
+                *  If multiple interrupts with the same group are registered, the last registered handler will become the\r
+                *  handler called for interrupts raised within that group.\r
+                *\r
+                *  \param[in] InterruptRequest  Interrupt request index for the given interrupt, a AVR32_*_IRQ mask.\r
+                *  \param[in] InterruptLevel    Priority level for the specified interrupt, a AVR32_INTC_INT* mask.\r
+                *  \param[in] Handler           Address of the ISR handler for the interrupt group.\r
+                */\r
+               static inline void INTC_RegisterGroupHandler(const uint16_t InterruptRequest,\r
+                                                                                                    const uint8_t  InterruptLevel,\r
+                                                                                                    const InterruptHandlerPtr_t Handler)\r
+               {\r
+                       uint8_t InterruptGroup = (InterruptRequest >> 5);\r
+\r
+                       InterruptHandlers[InterruptGroup] = Handler;\r
+                       AVR32_INTC.ipr[InterruptGroup]    = Autovector_Table[InterruptLevel];\r
+               }\r
+\r
+#endif\r