startup-SAM7S-arm.c

00001 #include <AT91SAM7S64.h>
00002 #include <stdint.h>
00003 
00004 #define USED __attribute__((used))
00005 #define USED_NAKED __attribute__((used,naked))
00006 #define USED_INT(type) __attribute__((used,interrupt(#type)))
00007 #if MCK > 30000000
00008 #define FLASH_CYCLES AT91C_MC_FWS_1FWS
00009 #else
00010 #define FLASH_CYCLES AT91C_MC_FWS_0FWS
00011 #endif
00012 
00013 #ifndef MAIN_OSC_FREQ
00014 #define MAIN_OSC_FREQ 18432000
00015 #endif
00016 
00017 #if MAIN_OSC_FREQ != 18432000
00018 #error Unsupported main oscilator frequency
00019 #endif
00020 
00021 #if MCK == 23961600
00022 #define PLL_DIV 5
00023 #define PLL_MUL 26
00024 #define PLL_USBDIV_EXP 1
00025 #define MCK_DIV_EXP 2
00026 #elif MCK == 47923200
00027 #define PLL_DIV 5
00028 #define PLL_MUL 26
00029 #define PLL_USBDIV_EXP 1
00030 #define MCK_DIV_EXP 1
00031 #else
00032 #error "Unsupported main clock frequency"
00033 #endif
00034 
00035 #define PLL_FREQ ((MAIN_OSC_FREQ * PLL_MUL) / PLL_DIV) 
00036 
00037 #if PLL_FREQ > 180000000
00038 #error "PLL frequency too high"
00039 #elif PLL_FREQ < 80000000
00040 #error "PLL frequency too low"
00041 #endif
00042 
00043 #if PLL_FREQ > 155000000
00044 #define PLL_RANGE AT91C_CKGR_OUT_2
00045 #else
00046 #define PLL_RANGE AT91C_CKGR_OUT_0
00047 #endif
00048 
00049 #if PLL_USBDIV > 2
00050 #error "PLL frequency too high for USB"
00051 #endif
00052 
00053 #define USB_FREQ (PLL_FREQ / (1<<PLL_USBDIV_EXP))
00054 #if USB_FREQ > 48120000 || USB_FREQ < 47880000
00055 #warning "USB frequency outside limits"
00056 #endif
00057 
00058 #if MCK * (1<<MCK_DIV_EXP) != PLL_FREQ
00059 #error PLL frequency is not a the correct multiple of the main clock
00060 #endif
00061 
00062 /* CPU modes */
00063 #define Mode_USR 0x10
00064 #define Mode_FIQ 0x11
00065 #define Mode_IRQ 0x12
00066 #define Mode_SVC 0x13
00067 #define Mode_ABT 0x17
00068 #define Mode_UND 0x1B
00069 #define Mode_SYS 0x1F
00070 
00071 /* IRQ disable bit */
00072 #define I_Bit 0x80
00073 /* FIQ disable bit */
00074 #define F_Bit 0x40
00075 
00076 #define SET_MODE_STACK(mode, stack_end) \
00077 asm("msr CPSR_c, %0\nldr sp, =" #stack_end "\n" ::"i" ((mode)|I_Bit|F_Bit))
00078 
00079 #define ENABLE_INTS() \
00080 asm("mrs  r0, cpsr\nand r0, %0\nmsr cpsr_c, r0\n"::"i" (~(I_Bit|F_Bit)):"r0")
00081 
00082 
00083 extern void *USR_Stack_End;
00084 extern void *UND_Stack_End;
00085 extern void *ABT_Stack_End;
00086 extern void *FIQ_Stack_End;
00087 extern void *IRQ_Stack_End;
00088 extern void *SVC_Stack_End;
00089 
00090 extern uint8_t _data[];
00091 extern uint8_t _etext[];
00092 extern uint8_t _edata[];
00093 
00094 extern uint8_t __bss_start[];
00095 extern uint8_t __bss_end[];
00096 
00097 extern int
00098 main(int argc, char *argv[]);
00099 
00100 static void
00101 copy_initialized(void)
00102 {
00103   uint8_t *ram = _data;
00104   uint8_t *rom = _etext;
00105   while(ram < _edata) {
00106     *ram++ = *rom++;
00107   }
00108 }
00109 
00110 static void
00111 clear_bss(void)
00112 {
00113   uint8_t *m = __bss_start;
00114   while(m < __bss_end) {
00115     *m++ = 0;
00116   }
00117 }
00118 
00119 static void
00120 Reset_handler(void) USED_NAKED;
00121 
00122 static void
00123 SPU_handler(void) __attribute__((interrupt("IRQ")));
00124 
00125 static void
00126 Reset_handler(void)
00127 {
00128   /* Setup flash timing */
00129   *AT91C_MC_FMR = FLASH_CYCLES | (MCK / 666666 + 1);
00130 
00131   /* Disable watchdog */
00132   *AT91C_WDTC_WDMR = AT91C_WDTC_WDDIS;
00133 
00134   /* Setup reset controller */
00135   *AT91C_RSTC_RMR = (0xa5<<24) | AT91C_RSTC_URSTS;
00136   
00137   /* Start main oscilator */
00138   *AT91C_CKGR_MOR = AT91C_CKGR_MOSCEN | (6<<8);
00139 
00140   /* Wait for oscillator to start */
00141   while(!(*AT91C_PMC_SR & AT91C_PMC_MOSCS));
00142 
00143   /* Setup PLL */
00144   *AT91C_CKGR_PLLR = ((PLL_USBDIV_EXP << 28) | ((PLL_MUL-1)<<16) | PLL_RANGE
00145                       | (28<<8) | PLL_DIV);
00146 
00147   /* Wait for PLL to lock */
00148   while(!(*AT91C_PMC_SR & AT91C_PMC_LOCK));
00149 
00150   *AT91C_PMC_MCKR = (MCK_DIV_EXP << 2);
00151   while(!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY));
00152   *AT91C_PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
00153   while(!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY));
00154   SET_MODE_STACK(Mode_UND, UND_Stack_End);
00155   SET_MODE_STACK(Mode_ABT, ABT_Stack_End);
00156   SET_MODE_STACK(Mode_FIQ, FIQ_Stack_End);
00157   SET_MODE_STACK(Mode_IRQ, IRQ_Stack_End);
00158   SET_MODE_STACK(Mode_SVC, SVC_Stack_End);
00159 #ifdef RUN_AS_SYSTEM
00160   SET_MODE_STACK(Mode_SYS, USR_Stack_End);
00161 #else
00162   SET_MODE_STACK(Mode_USR, USR_Stack_End);
00163 #endif
00164   copy_initialized();
00165   clear_bss();
00166   
00167   *AT91C_AIC_SPU = (uint32_t)SPU_handler;
00168   ENABLE_INTS();
00169   main(0,0);
00170   while(1);
00171 }
00172 
00173 static void
00174 Undef_handler(void) USED_INT(UNDEF);
00175 
00176 static void
00177 Undef_handler(void)
00178 {
00179 }
00180 
00181 static void
00182 SWI_handler(void) USED_INT(SWI);
00183 
00184 static void
00185 SWI_handler(void)
00186 {
00187 }
00188 
00189 static void
00190 PAbt_handler(void) USED_INT(ABORT);
00191 
00192 static void
00193 PAbt_handler(void)
00194 {
00195 }
00196 
00197 static void
00198 DAbt_handler(void) USED_INT(ABORT);
00199 
00200 static void
00201 DAbt_handler(void) 
00202 {
00203 }
00204 
00205 
00206 static void
00207 SPU_handler(void)
00208 {
00209   *AT91C_AIC_EOICR = 0;
00210 }
00211 
00212 static void
00213 Vectors(void) __attribute__ ((naked, section(".vectrom")));
00214 
00215 static void
00216 Vectors(void)
00217 {
00218   asm("ldr pc, =Reset_handler\n");
00219   asm("ldr pc, =Undef_handler\n");
00220   asm("ldr pc, =SWI_handler\n");
00221   asm("ldr pc, =PAbt_handler\n");
00222   asm("ldr pc, =DAbt_handler\n");
00223   asm("nop\n");  
00224   asm("ldr pc,[pc,#-0xf20]\n"); /* Vector From AIC_IVR */
00225   asm("ldr pc,[pc,#-0xf20]\n"); /* Vector From AIC_FVR */
00226 }
00227 
00228 
00229 
00230 void foo_dummy()
00231 {
00232   Vectors();
00233 }

Generated on Mon Apr 11 14:23:34 2011 for Contiki 2.5 by  doxygen 1.6.1