From c6a7a028bd1f6a41195ed95e3c6b4291105ef448 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Wed, 29 Jun 2011 05:57:29 +0000 Subject: Merge over core library changes from the MultiArchDemos branch. --- LUFA/Platform/UC3/ClockManagement.h | 181 ++++++++++++++++++++++++++++++++ LUFA/Platform/UC3/Exception.S | 125 ++++++++++++++++++++++ LUFA/Platform/UC3/InterruptManagement.c | 62 +++++++++++ LUFA/Platform/UC3/InterruptManagement.h | 83 +++++++++++++++ 4 files changed, 451 insertions(+) create mode 100644 LUFA/Platform/UC3/ClockManagement.h create mode 100644 LUFA/Platform/UC3/Exception.S create mode 100644 LUFA/Platform/UC3/InterruptManagement.c create mode 100644 LUFA/Platform/UC3/InterruptManagement.h (limited to 'LUFA/Platform') diff --git a/LUFA/Platform/UC3/ClockManagement.h b/LUFA/Platform/UC3/ClockManagement.h new file mode 100644 index 000000000..2b7325ba8 --- /dev/null +++ b/LUFA/Platform/UC3/ClockManagement.h @@ -0,0 +1,181 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2011. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#ifndef _CLOCK_MANAGEMENT_H_ +#define _CLOCK_MANAGEMENT_H_ + + /* Includes: */ + #include + #include + #include + + #include + + /* Macros: */ + enum Extern_OSC_ClockStartup_t + { + EXOSC_START_0CLK = 0, + EXOSC_START_64CLK = 1, + EXOSC_START_128CLK = 2, + EXOSC_START_2048CLK = 3, + EXOSC_START_4096CLK = 4, + EXOSC_START_8192CLK = 5, + EXOSC_START_16384CLK = 6, + }; + + enum Extern_OSC_ClockMode_t + { + EXOSC_MODE_CLOCK = 0, + EXOSC_MODE_900KHZ_MAX = 1, + EXOSC_MODE_3MHZ_MAX = 2, + EXOSC_MODE_8MHZ_MAX = 3, + EXOSC_MODE_8MHZ_OR_MORE = 4, + }; + + enum + { + CLOCK_SRC_SLOW_CLK = 0, + CLOCK_SRC_OSC0 = 1, + CLOCK_SRC_OSC1 = 2, + CLOCK_SRC_PLL0 = 3, + CLOCK_SRC_PLL1 = 4, + }; + + /* Inline Functions: */ + static inline bool AVR32CLK_StartExternalOscillator(const uint8_t Channel, + const uint8_t Type, + const uint8_t Startup) + { + AVR32_PM.OSCCTRL0.startup = Startup; + AVR32_PM.OSCCTRL0.mode = Type; + AVR32_PM.mcctrl |= (1 << (AVR32_PM_MCCTRL_OSC0EN_OFFSET + Channel)); + + while (!(AVR32_PM.poscsr & (1 << (AVR32_PM_POSCSR_OSC0RDY_OFFSET + Channel)))); + return true; + } + + static inline void AVR32CLK_StopExternalOscillator(const uint8_t Channel) + { + AVR32_PM.mcctrl &= ~(1 << (AVR32_PM_MCCTRL_OSC0EN_OFFSET + Channel)); + } + + static inline bool AVR32CLK_StartPLL(const uint8_t Channel, + const uint8_t Source, + const uint32_t SourceFreq, + const uint32_t Frequency) + { + switch (Source) + { + case CLOCK_SRC_OSC0: + AVR32_PM.PLL[Channel].pllosc = 0; + break; + case CLOCK_SRC_OSC1: + AVR32_PM.PLL[Channel].pllosc = 1; + break; + default: + return false; + } + + AVR32_PM.PLL[Channel].pllmul = (Frequency / SourceFreq) ? (((Frequency / SourceFreq) - 1) / 2) : 0; + AVR32_PM.PLL[Channel].plldiv = 0; + AVR32_PM.PLL[Channel].pllen = true; + + while (!(AVR32_PM.poscsr & (1 << (AVR32_PM_POSCSR_LOCK0_OFFSET + Channel)))); + return true; + } + + static inline void AVR32CLK_StopPLL(const uint8_t Channel) + { + AVR32_PM.PLL[Channel].pllen = false; + } + + static inline bool AVR32CLK_StartGenericClock(const uint8_t Channel, + const uint8_t Source, + const uint32_t SourceFreq, + const uint32_t Frequency) + { + switch (Source) + { + case CLOCK_SRC_OSC0: + AVR32_PM.GCCTRL[Channel].pllsel = 0; + AVR32_PM.GCCTRL[Channel].oscsel = 0; + break; + case CLOCK_SRC_OSC1: + AVR32_PM.GCCTRL[Channel].pllsel = 0; + AVR32_PM.GCCTRL[Channel].oscsel = 1; + break; + case CLOCK_SRC_PLL0: + AVR32_PM.GCCTRL[Channel].pllsel = 1; + AVR32_PM.GCCTRL[Channel].oscsel = 0; + break; + case CLOCK_SRC_PLL1: + AVR32_PM.GCCTRL[Channel].pllsel = 1; + AVR32_PM.GCCTRL[Channel].oscsel = 1; + break; + default: + return false; + } + + AVR32_PM.GCCTRL[Channel].diven = (SourceFreq > Frequency) ? true : false; + AVR32_PM.GCCTRL[Channel].div = (((SourceFreq / Frequency) - 1) / 2); + AVR32_PM.GCCTRL[Channel].cen = true; + + return true; + } + + static inline void AVR32CLK_StopGenericClock(const uint8_t Channel) + { + AVR32_PM.GCCTRL[Channel].cen = false; + } + + static inline bool AVR32CLK_SetCPUClockSource(const uint8_t Source, + const uint32_t SourceFreq) + { + AVR32_FLASHC.FCR.fws = (SourceFreq > 30000000) ? true : false; + + switch (Source) + { + case CLOCK_SRC_SLOW_CLK: + AVR32_PM.MCCTRL.mcsel = 0; + break; + case CLOCK_SRC_OSC0: + AVR32_PM.MCCTRL.mcsel = 1; + break; + case CLOCK_SRC_PLL0: + AVR32_PM.MCCTRL.mcsel = 2; + break; + default: + return false; + } + + return true; + } + +#endif diff --git a/LUFA/Platform/UC3/Exception.S b/LUFA/Platform/UC3/Exception.S new file mode 100644 index 000000000..9509fd7f2 --- /dev/null +++ b/LUFA/Platform/UC3/Exception.S @@ -0,0 +1,125 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2011. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include + +.section .exception_handlers, "ax", @progbits + +// ================= EXCEPTION TABLE ================ +.balign 0x200 +.global EVBA_Table +EVBA_Table: + +.org 0x000 +Exception_Unrecoverable_Exception: + rjmp $ +.org 0x004 +Exception_TLB_Multiple_Hit: + rjmp $ +.org 0x008 +Exception_Bus_Error_Data_Fetch: + rjmp $ +.org 0x00C +Exception_Bus_Error_Instruction_Fetch: + rjmp $ +.org 0x010 +Exception_NMI: + rjmp $ +.org 0x014 +Exception_Instruction_Address: + rjmp $ +.org 0x018 +Exception_ITLB_Protection: + rjmp $ +.org 0x01C +Exception_OCD_Breakpoint: + rjmp $ +.org 0x020 +Exception_Illegal_Opcode: + rjmp $ +.org 0x024 +Exception_Unimplemented_Instruction: + rjmp $ +.org 0x028 +Exception_Privilege_Violation: + rjmp $ +.org 0x02C +Exception_Floating_Point: + rjmp $ +.org 0x030 +Exception_Coprocessor_Absent: + rjmp $ +.org 0x034 +Exception_Data_Address_Read: + rjmp $ +.org 0x038 +Exception_Data_Address_Write: + rjmp $ +.org 0x03C +Exception_DTLB_Protection_Read: + rjmp $ +.org 0x040 +Exception_DTLB_Protection_Write: + rjmp $ +.org 0x044 +Exception_DTLB_Modified: + rjmp $ +.org 0x050 +Exception_ITLB_Miss: + rjmp $ +.org 0x060 +Exception_DTLB_Miss_Read: + rjmp $ +.org 0x070 +Exception_DTLB_Miss_Write: + rjmp $ +.org 0x100 +Exception_Supervisor_Call: + rjmp $ +// ============== END OF EXCEPTION TABLE ============= + +// ============= GENERAL INTERRUPT HANDLER =========== +.balign 4 +.irp Level, 0, 1, 2, 3 +Exception_INT\Level: + mov r12, \Level + call INTC_GetInterruptHandler + mov pc, r12 +.endr +// ========= END OF GENERAL INTERRUPT HANDLER ======== + +// ====== GENERAL INTERRUPT HANDLER OFFSET TABLE ====== +.balign 4 +.global Autovector_Table +Autovector_Table: +.irp Level, 0, 1, 2, 3 + .word ((AVR32_INTC_INT0 + \Level) << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (Exception_INT\Level - EVBA_Table) +.endr +// === END OF GENERAL INTERRUPT HANDLER OFFSET TABLE === diff --git a/LUFA/Platform/UC3/InterruptManagement.c b/LUFA/Platform/UC3/InterruptManagement.c new file mode 100644 index 000000000..b1dda745c --- /dev/null +++ b/LUFA/Platform/UC3/InterruptManagement.c @@ -0,0 +1,62 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2011. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "InterruptManagement.h" + +/** Interrupt vector table, containing the ISR to call for each interrupt group */ +InterruptHandlerPtr_t InterruptHandlers[AVR32_INTC_NUM_INT_GRPS]; + +/** ISR for unhandled interrupt groups */ +ISR(Unhandled_Interrupt) +{ + while (true); +} + +/** Retrieves the associated interrupt handler for the interrupt currently being fired. This is + * called directly from the exception handler routine before dispatching to the ISR. + */ +InterruptHandlerPtr_t INTC_GetInterruptHandler(const uint_reg_t InterruptLevel) +{ + return InterruptHandlers[AVR32_INTC.icr[AVR32_INTC_INT3 - InterruptLevel]]; +} + +/** Initializes the interrupt controller ready to handle interrupts. This must be called at the + * start of the user program before any interrupts are registered or enabled. + */ +void INTC_Init(void) +{ + for (uint8_t InterruptGroup = 0; InterruptGroup < AVR32_INTC_NUM_INT_GRPS; InterruptGroup++) + { + InterruptHandlers[InterruptGroup] = Unhandled_Interrupt; + AVR32_INTC.ipr[InterruptGroup] = Autovector_Table[AVR32_INTC_INT0]; + } + + __builtin_mtsr(AVR32_EVBA, (uintptr_t)&EVBA_Table); +} diff --git a/LUFA/Platform/UC3/InterruptManagement.h b/LUFA/Platform/UC3/InterruptManagement.h new file mode 100644 index 000000000..fec099dba --- /dev/null +++ b/LUFA/Platform/UC3/InterruptManagement.h @@ -0,0 +1,83 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2011. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#ifndef _INTERRUPT_MANAGEMENT_H_ +#define _INTERRUPT_MANAGEMENT_H_ + + /* Includes: */ + #include + #include + #include + + #include + + /* Macros: */ + #if !defined(ISR) + #define ISR(Name) void Name (void) __attribute__((__interrupt__)); void Name (void) + #endif + + #define INTC_EnableInterrupts() do { GCC_MEMORY_BARRIER(); __builtin_csrf(AVR32_SR_GM_OFFSET); } while (0) + #define INTC_DisableInterrupts() do { __builtin_ssrf(AVR32_SR_GM_OFFSET); GCC_MEMORY_BARRIER(); } while (0) + + /* Type Defines: */ + typedef void (*InterruptHandlerPtr_t)(void); + + /* External Variables: */ + extern const void EVBA_Table; + extern const uint32_t Autovector_Table[]; + extern InterruptHandlerPtr_t InterruptHandlers[AVR32_INTC_NUM_INT_GRPS]; + + /* Function Prototypes: */ + void INTC_Init(void); + + /* Inline Functions: */ + /** Registers a handler for a given interrupt group. On the AVR32 UC3 devices, interrupts are grouped by + * peripheral. To save on SRAM used, a single ISR handles all interrupt lines within a single group - to + * determine the exact line that has interrupted within the group ISR handler, examine the module's interrupt + * flag register bits. + * + * If multiple interrupts with the same group are registered, the last registered handler will become the + * handler called for interrupts raised within that group. + * + * \param[in] InterruptRequest Interrupt request index for the given interrupt, a AVR32_*_IRQ mask. + * \param[in] InterruptLevel Priority level for the specified interrupt, a AVR32_INTC_INT* mask. + * \param[in] Handler Address of the ISR handler for the interrupt group. + */ + static inline void INTC_RegisterGroupHandler(const uint16_t InterruptRequest, + const uint8_t InterruptLevel, + const InterruptHandlerPtr_t Handler) + { + uint8_t InterruptGroup = (InterruptRequest >> 5); + + InterruptHandlers[InterruptGroup] = Handler; + AVR32_INTC.ipr[InterruptGroup] = Autovector_Table[InterruptLevel]; + } + +#endif -- cgit v1.2.3