diff options
| -rw-r--r-- | openpcd/firmware/include/board.h | 13 | ||||
| -rw-r--r-- | openpcd/firmware/src/start/Cstartup.S | 298 | ||||
| -rw-r--r-- | openpcd/firmware/src/start/Cstartup_SAM7.c | 89 | 
3 files changed, 400 insertions, 0 deletions
| diff --git a/openpcd/firmware/include/board.h b/openpcd/firmware/include/board.h new file mode 100644 index 0000000..8dd9182 --- /dev/null +++ b/openpcd/firmware/include/board.h @@ -0,0 +1,13 @@ +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include <AT91SAM7.h> +#include <lib_AT91SAM7.h> + +/*--------------*/ +/* Master Clock */ +/*--------------*/ +#define EXT_OSC		18432000	// External Crystal Oscillator +#define MCK		47923200	// Resulting PLL CLock + +#endif/*__BOARD_H__*/ diff --git a/openpcd/firmware/src/start/Cstartup.S b/openpcd/firmware/src/start/Cstartup.S new file mode 100644 index 0000000..d13dbd8 --- /dev/null +++ b/openpcd/firmware/src/start/Cstartup.S @@ -0,0 +1,298 @@ +/*------------------------------------------------------------------------------ +//*-         ATMEL Microcontroller Software Support  -  ROUSSET  - +//*------------------------------------------------------------------------------ +//* The software is delivered "AS IS" without warranty or condition of any +//* kind, either express, implied or statutory. This includes without +//* limitation any warranty or condition with respect to merchantability or +//* fitness for any particular purpose, or against the infringements of +//* intellectual property rights of others. +//*----------------------------------------------------------------------------- +//*- File source          : Cstartup.s +//*- Object               : Generic CStartup for KEIL and GCC No Use REMAP +//*- Compilation flag     : None +//*- +//*- 1.0 18/Oct/04 JPP    : Creation +//*- 1.1 21/Feb/05 JPP    : Set Interrupt +//*- 1.1 01/Apr/05 JPP    : save SPSR  +//*-----------------------------------------------------------------------------*/ + +     .equ   IRQ_Stack_Size,     0x00000060 + +/* #include "AT91SAM7S64_inc.h"	  */ + +	.equ AIC_IVR,         (256)  +	.equ AIC_FVR,         (260)  +	.equ AIC_EOICR,       (304) +	.equ AT91C_BASE_AIC,  (0xFFFFF000) + +#;------------------------------------------------------------------------------ +#;- Section Definition +#;----------------- +#;-  Section     +#;- .internal_ram_top 	Top_Stack: used by the cstartup for vector initalisation  +#;-			management defined by ld and affect from ldscript  +#;------------------------------------------------------------------------------ +	.section 	.internal_ram_top +	.code 32 +	.align 	0 +	.global	Top_Stack +Top_Stack: +	 +/*------------------------------------------------------------------------------ +*- Area Definition +*------------------------------------------------------------------------------ +* .text is used instead of .section .text so it works with arm-aout too.  */ +        .section 	.reset +        .text +        .global _startup +        .func   _startup +_startup: +reset:  +/*------------------------------------------------------------------------------ +//*- Exception vectors  +//*-------------------- +//*- These vectors can be read at address 0 or at RAM address +//*- They ABSOLUTELY requires to be in relative addresssing mode in order to +//*- guarantee a valid jump. For the moment, all are just looping. +//*- If an exception occurs before remap, this would result in an infinite loop. +//*- To ensure if a exeption occurs before start application to infinite loop. +//*------------------------------------------------------------------------------*/ + +                B           InitReset           /* 0x00 Reset handler */ +undefvec: +                B           undefvec            /* 0x04 Undefined Instruction */ +swivec: +                B           swivec              /* 0x08 Software Interrupt */ +pabtvec: +                B           pabtvec             /* 0x0C Prefetch Abort */ +dabtvec: +                B           dabtvec             /* 0x10 Data Abort */ +rsvdvec: +                B           rsvdvec             /* 0x14 reserved  */ +irqvec: +                B           IRQ_Handler_Entry   /* 0x18 IRQ	 */ +fiqvec:               			            	/* 0x1c FIQ	*/ +/*------------------------------------------------------------------------------ +//*- Function             : FIQ_Handler_Entry +//*- Treatments           : FIQ Controller Interrupt Handler. +//*- Called Functions     : AIC_FVR[interrupt]  +//*------------------------------------------------------------------------------*/ + +FIQ_Handler_Entry: + +/*- Switch in SVC/User Mode to allow User Stack access for C code 	*/ +/* because the FIQ is not yet acknowledged*/ + +/*- Save and r0 in FIQ_Register */ +            mov         r9,r0 +	        ldr         r0 , [r8, #AIC_FVR] +            msr         CPSR_c,#I_BIT | F_BIT | ARM_MODE_SVC + +/*- Save scratch/used registers and LR in User Stack */ +            stmfd       sp!, { r1-r3, r12, lr} + +/*- Branch to the routine pointed by the AIC_FVR */ +            mov         r14, pc +            bx          r0 + +/*- Restore scratch/used registers and LR from User Stack */ +            ldmia       sp!, { r1-r3, r12, lr} + +/*- Leave Interrupts disabled and switch back in FIQ mode */ +            msr         CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ + +/*- Restore the R0 ARM_MODE_SVC register */ +            mov         r0,r9 + +/*- Restore the Program Counter using the LR_fiq directly in the PC */ +            subs        pc,lr,#4 +	.align 0 +.RAM_TOP: +	.word	Top_Stack + +InitReset: +/*------------------------------------------------------------------------------ +/*- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit +/*------------------------------------------------------------------------------*/ +            	.extern   AT91F_LowLevelInit +/*- minumum C initialization */ +/*- call  AT91F_LowLevelInit( void) */ + +            ldr     r13,.RAM_TOP            /* temporary stack in internal RAM */ +/*--Call Low level init function in ABSOLUTE through the Interworking	*/ +	        ldr	    r0,=AT91F_LowLevelInit +            mov     lr, pc +	        bx	    r0 +/*------------------------------------------------------------------------------ +//*- Stack Sizes Definition +//*------------------------ +//*- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using +//*- the vectoring. This assume that the IRQ management. +//*- The Interrupt Stack must be adjusted depending on the interrupt handlers. +//*- Fast Interrupt not requires stack If in your application it required you must +//*- be definehere. +//*- The System stack size is not defined and is limited by the free internal +//*- SRAM. +//*------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ +//*- Top of Stack Definition +//*------------------------- +//*- Interrupt and Supervisor Stack are located at the top of internal memory in  +//*- order to speed the exception handling context saving and restoring. +//*- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory. +//*------------------------------------------------------------------------------*/ + +	  .EQU		IRQ_STACK_SIZE,    (3*8*4) +          .EQU		ARM_MODE_FIQ,       0x11 +          .EQU		ARM_MODE_IRQ,       0x12 +          .EQU		ARM_MODE_SVC,       0x13 + +          .EQU		I_BIT,              0x80 +          .EQU		F_BIT,              0x40 + +/*------------------------------------------------------------------------------ +//*- Setup the stack for each mode +//*-------------------------------*/ +                mov     r0,r13 + +/*- Set up Fast Interrupt Mode and set FIQ Mode Stack*/ +                msr     CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT +/*- Init the FIQ register*/ +            	ldr     r8, =AT91C_BASE_AIC + +/*- Set up Interrupt Mode and set IRQ Mode Stack*/ +                msr     CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT +                mov     r13, r0                     /* Init stack IRQ */ +                sub     r0, r0, #IRQ_Stack_Size +/*- Set up Supervisor Mode and set Supervisor Mode Stack*/ +                msr     CPSR_c, #ARM_MODE_SVC +                mov     r13, r0                     /* Init stack Sup */ + +/*- Enable interrupt & Set up Supervisor Mode and set Supervisor Mode Stack*/ + +# Relocate .data section (Copy from ROM to RAM) +                LDR     R1, =_etext +                LDR     R2, =_data +                LDR     R3, =_edata +LoopRel:        CMP     R2, R3 +                LDRLO   R0, [R1], #4 +                STRLO   R0, [R2], #4 +                BLO     LoopRel + +# Clear .bss section (Zero init) +                MOV     R0, #0 +                LDR     R1, =__bss_start__ +                LDR     R2, =__bss_end__ +LoopZI:         CMP     R1, R2 +                STRLO   R0, [R1], #4 +                BLO     LoopZI + +		ldr	lr,=exit +		ldr	r0,=main +		bx	r0 +		 +        .size   _startup, . - _startup +        .endfunc +		 +/* "exit" dummy added by mthomas to avoid sbrk write read etc. needed +   by the newlib default "exit" */ +        .global exit +        .func   exit +exit: +        b    . +		.size   exit, . - exit +        .endfunc +		 +/*------------------------------------------------------------------------------ +//*- Manage exception +//*--------------- +//*- This module The exception must be ensure in ARM mode +//*------------------------------------------------------------------------------ +//*------------------------------------------------------------------------------ +//*- Function             : IRQ_Handler_Entry +//*- Treatments           : IRQ Controller Interrupt Handler. +//*- Called Functions     : AIC_IVR[interrupt]  +//*------------------------------------------------------------------------------*/ +        .global IRQ_Handler_Entry +        .func   IRQ_Handler_Entry + +IRQ_Handler_Entry: + +/*- Manage Exception Entry  */ +/*- Adjust and save LR_irq in IRQ stack  */ +            sub         lr, lr, #4 +            stmfd       sp!, {lr} + +/*- Save SPSR need to be saved for nested interrupt */ +            mrs         r14, SPSR +            stmfd       sp!, {r14} + +/*- Save and r0 in IRQ stack  */ +            stmfd       sp!, {r0} + +/*- Write in the IVR to support Protect Mode  */ +/*- No effect in Normal Mode  */ +/*- De-assert the NIRQ and clear the source in Protect Mode */ +            ldr         r14, =AT91C_BASE_AIC +	    ldr         r0 , [r14, #AIC_IVR] +	    str         r14, [r14, #AIC_IVR] + +/*- Enable Interrupt and Switch in Supervisor Mode */ +            msr         CPSR_c, #ARM_MODE_SVC + +/*- Save scratch/used registers and LR in User Stack */ +            stmfd       sp!, { r1-r3, r12, r14} + +/*- Branch to the routine pointed by the AIC_IVR  */ +            mov         r14, pc +            bx          r0 +/*- Restore scratch/used registers and LR from User Stack*/ +            ldmia       sp!, { r1-r3, r12, r14} + +/*- Disable Interrupt and switch back in IRQ mode */ +            msr         CPSR_c, #I_BIT | ARM_MODE_IRQ + +/*- Mark the End of Interrupt on the AIC */ +            ldr         r14, =AT91C_BASE_AIC +            str         r14, [r14, #AIC_EOICR] + +/*- Restore SPSR_irq and r0 from IRQ stack */ +            ldmia       sp!, {r0} + +/*- Restore SPSR_irq and r0 from IRQ stack */ +            ldmia       sp!, {r14} +            msr         SPSR_cxsf, r14 + +/*- Restore adjusted  LR_irq from IRQ stack directly in the PC */ +            ldmia       sp!, {pc}^ +	 +        .size   IRQ_Handler_Entry, . - IRQ_Handler_Entry +        .endfunc +/*--------------------------------------------------------------- +//* ?EXEPTION_VECTOR +//* This module is only linked if needed for closing files. +//*---------------------------------------------------------------*/ +        .global AT91F_Default_FIQ_handler +        .func   AT91F_Default_FIQ_handler +AT91F_Default_FIQ_handler: +            b     AT91F_Default_FIQ_handler +        .size   AT91F_Default_FIQ_handler, . - AT91F_Default_FIQ_handler +        .endfunc + +        .global AT91F_Default_IRQ_handler +        .func   AT91F_Default_IRQ_handler +AT91F_Default_IRQ_handler: +            b     AT91F_Default_IRQ_handler +        .size   AT91F_Default_IRQ_handler, . - AT91F_Default_IRQ_handler +        .endfunc + +        .global AT91F_Spurious_handler +        .func   AT91F_Spurious_handler +AT91F_Spurious_handler: +            b     AT91F_Spurious_handler +        .size   AT91F_Spurious_handler, . - AT91F_Spurious_handler +        .endfunc + +        .end + diff --git a/openpcd/firmware/src/start/Cstartup_SAM7.c b/openpcd/firmware/src/start/Cstartup_SAM7.c new file mode 100644 index 0000000..66dbe20 --- /dev/null +++ b/openpcd/firmware/src/start/Cstartup_SAM7.c @@ -0,0 +1,89 @@ +//*---------------------------------------------------------------------------- +//*         ATMEL Microcontroller Software Support  -  ROUSSET  - +//*---------------------------------------------------------------------------- +//* The software is delivered "AS IS" without warranty or condition of any +//* kind, either express, implied or statutory. This includes without +//* limitation any warranty or condition with respect to merchantability or +//* fitness for any particular purpose, or against the infringements of +//* intellectual property rights of others. +//*---------------------------------------------------------------------------- +//* File Name           : Cstartup_SAM7.c +//* Object              : Low level initializations written in C for GCC Tools +//* Creation            : 12/Jun/04 +//* 1.2   28/Feb/05 JPP : LIB change AT91C_WDTC_WDDIS & PLL +//* 1.3   21/Mar/05 JPP : Change PLL Wait time +//*---------------------------------------------------------------------------- + +// Include the board file description +#include <board.h> + +// The following functions must be write in ARM mode this function called directly +// by exception vector +extern void AT91F_Spurious_handler (void); +extern void AT91F_Default_IRQ_handler (void); +extern void AT91F_Default_FIQ_handler (void); + +//*---------------------------------------------------------------------------- +//* \fn    AT91F_LowLevelInit +//* \brief This function performs very low level HW initialization +//*        this function can be use a Stack, depending the compilation +//*        optimization mode +//*---------------------------------------------------------------------------- +void +AT91F_LowLevelInit (void) +{ +  int i; +  AT91PS_PMC pPMC = AT91C_BASE_PMC; +  //* Set Flash Waite sate +  //  Single Cycle Access at Up to 30 MHz, or 40 +  //  if MCK = 47923200 I have 50 Cycle for 1 usecond ( flied MC_FMR->FMCN +  AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN) & (48 << 16)) | AT91C_MC_FWS_1FWS; + +  //* Watchdog Disable +  AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; + +  //* Set MCK at 47 923 200 +  // 1 Enabling the Main Oscillator: +  // SCK = 1/32768 = 30.51 uSecond +  // Start up time = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 ms +  pPMC->PMC_MOR = ((AT91C_CKGR_OSCOUNT) & (0x06 << 8)) | AT91C_CKGR_MOSCEN; +  // Wait the startup time +  while (!(pPMC->PMC_SR & AT91C_PMC_MOSCS)); +  // 2 Checking the Main Oscillator Frequency (Optional) +  // 3 Setting PLL and divider: +  // - div by 24 Fin = 0,7680 =(18,432 / 24) +  // - Mul 125: Fout =   96,0000 =(0,7680 *125) +  // for 96 MHz the erroe is 0.16% +  // Field out NOT USED = 0 +  // PLLCOUNT pll startup time estimate at : 0.844 ms +  // PLLCOUNT 28 = 0.000844 /(1/32768) +#if 0 +  pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x05) | +		    (AT91C_CKGR_PLLCOUNT & (28 << 8)) | +		    (AT91C_CKGR_MUL & (25 << 16))); +#else +  pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 24) | +		    (AT91C_CKGR_PLLCOUNT & (28 << 8)) | +		    (AT91C_CKGR_MUL & (125 << 16))); +#endif + +  // Wait the startup time +  while (!(pPMC->PMC_SR & AT91C_PMC_LOCK)); +  while (!(pPMC->PMC_SR & AT91C_PMC_MCKRDY)); +  // 4. Selection of Master Clock and Processor Clock +  // select the PLL clock divided by 2 +  pPMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2; +  while (!(pPMC->PMC_SR & AT91C_PMC_MCKRDY)); + +  pPMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK; +  while (!(pPMC->PMC_SR & AT91C_PMC_MCKRDY)); + +  // Set up the default interrupts handler vectors +  AT91C_BASE_AIC->AIC_SVR[0] = (int) AT91F_Default_FIQ_handler; +  for (i = 1; i < 31; i++) +    { +      AT91C_BASE_AIC->AIC_SVR[i] = (int) AT91F_Default_IRQ_handler; +    } +  AT91C_BASE_AIC->AIC_SPU = (int) AT91F_Spurious_handler; + +} | 
