diff options
Diffstat (limited to 'firmware/target/arm/at91sam/lyre_proto1/system-lyre_proto1.c')
-rw-r--r-- | firmware/target/arm/at91sam/lyre_proto1/system-lyre_proto1.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/firmware/target/arm/at91sam/lyre_proto1/system-lyre_proto1.c b/firmware/target/arm/at91sam/lyre_proto1/system-lyre_proto1.c new file mode 100644 index 0000000000..e91ef7a918 --- /dev/null +++ b/firmware/target/arm/at91sam/lyre_proto1/system-lyre_proto1.c @@ -0,0 +1,150 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * + * Copyright (C) 2009 by Jorge Pinto + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* Include Standard files */ +#include "at91sam9260.h" +#include "debug-target.h" +#include "config.h" + +/*----------------------------------------------------------------------------- + * Function Name : default_spurious_handler + * Object : default handler for spurious interrupt + *---------------------------------------------------------------------------*/ +void default_spurious_handler(void) +{ + while (1); +} + +/*----------------------------------------------------------------------------- + * Function Name : default_fiq_handler + * Object : default handler for fast interrupt + *---------------------------------------------------------------------------*/ +void default_fiq_handler(void) +{ + while (1); +} + +/*----------------------------------------------------------------------------- + * Function Name : default_irq_handler + * Object : default handler for irq + *---------------------------------------------------------------------------*/ +void default_irq_handler(void) +{ +#if defined(BOOTLOADER) + while (1); +#endif +} + +/*----------------------------------------------------------------------------- + * Function Name : lowlevel_init + * Object : This function performs very low level HW initialization + * this function can use a Stack, depending the compilation + * optimization mode + *---------------------------------------------------------------------------*/ +void lowlevel_init(void) +{ + unsigned char i = 0; + + /* void default_fiq_handler(void) + * Init PMC Step 1. Enable Main Oscillator + * Main Oscillator startup time is board specific: + * Main Oscillator Startup Time worst case (3MHz) corresponds to 15ms + * (0x40 for AT91C_CKGR_OSCOUNT field) + */ + AT91C_PMC_MOR = (((AT91C_CKGR_OSCOUNT & (0x40 << 8)) | AT91C_CKGR_MOSCEN)); + /* Wait Main Oscillator stabilization */ + while (!(AT91C_PMC_SR & AT91C_PMC_MOSCS)); + + /* Init PMC Step 2. + * Set PLLA to 198,608MHz + * PLL Startup time depends on PLL RC filter: worst case is choosen. + * + * Crystal frequency = 18.432MHz; PLLA = (18.432 * 96) / 9 = 198,608MHz. + */ + + AT91C_PMC_PLLAR = (1 << 29) | + (0x60 << 16) | /* MULA = 96 */ + (0x2 << 14) | + (0x3f << 8) | + (0x09); /* DIVA = 9 */ + + /* Wait for PLLA stabilization */ + while (!(AT91C_PMC_SR & AT91C_PMC_LOCKA)); + /* Wait until the master clock is established for the case we already */ + /* turn on the PLLA */ + while (!(AT91C_PMC_SR & AT91C_PMC_MCKRDY)); + + /* Init PMC Step 3. + * Processor Clock = 198,608MHz (PLLA); Master clock = + * (198,608MHz (PLLA))/2 = 98,304MHz. + * The PMC_MCKR register must not be programmed in a single write operation + * (see. Product Errata Sheet) + */ + AT91C_PMC_MCKR = AT91C_PMC_PRES_CLK | AT91C_PMC_MDIV_2; + /* Wait until the master clock is established */ + while (!(AT91C_PMC_SR & AT91C_PMC_MCKRDY)); + + AT91C_PMC_MCKR |= AT91C_PMC_CSS_PLLA_CLK; + /* Wait until the master clock is established */ + while (!(AT91C_PMC_SR & AT91C_PMC_MCKRDY)); + + /* Reset AIC: assign default handler for each interrupt source + */ + + /* Disable the interrupt on the interrupt controller */ + AT91C_AIC_IDCR = (1 << AT91C_ID_SYS); + + /* Assign default handler for each IRQ source */ + AT91C_AIC_SVR(AT91C_ID_FIQ) = (int) default_fiq_handler; + for (i = 1; i < 31; i++) + { + AT91C_AIC_SVR(i) = (int) default_irq_handler; + } + AT91C_AIC_SPU = (unsigned int) default_spurious_handler; + + /* Perform 8 IT acknoledge (write any value in EOICR) */ + +/* The End of Interrupt Command Register (AIC_EOICR) must be written in order +to indicate to the AIC that the current interrupt is finished. This causes the +current level to be popped from the stack, restoring the previous current level +if one exists on the stack. If another interrupt is pending, with lower or +equal priority than the old current level but with higher priority than the new +current level, the nIRQ line is re-asserted, but the interrupt sequence does +not immediately start because the āIā bit is set in the core. +SPSR_irq is restored. Finally, the saved value of the link register is restored +directly into the PC. This has the effect of returning from the interrupt to +whatever was being executed before, and of loading the CPSR with the stored +SPSR, masking or unmasking the interrupts depending on the state saved in +SPSR_irq. */ + for (i = 0; i < 8 ; i++) + { + AT91C_AIC_EOICR = 0; + } + + /* Enable the interrupt on the interrupt controller */ + AT91C_AIC_IECR = (1 << AT91C_ID_SYS); + + /* Disable Watchdog */ + AT91C_WDTC_WDMR = AT91C_WDTC_WDDIS; + + /* Remap */ + AT91C_MATRIX_MRCR = AT91C_MATRIX_RCA926I | AT91C_MATRIX_RCA926D; +} |