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
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
00072 #define I_Bit 0x80
00073
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
00129 *AT91C_MC_FMR = FLASH_CYCLES | (MCK / 666666 + 1);
00130
00131
00132 *AT91C_WDTC_WDMR = AT91C_WDTC_WDDIS;
00133
00134
00135 *AT91C_RSTC_RMR = (0xa5<<24) | AT91C_RSTC_URSTS;
00136
00137
00138 *AT91C_CKGR_MOR = AT91C_CKGR_MOSCEN | (6<<8);
00139
00140
00141 while(!(*AT91C_PMC_SR & AT91C_PMC_MOSCS));
00142
00143
00144 *AT91C_CKGR_PLLR = ((PLL_USBDIV_EXP << 28) | ((PLL_MUL-1)<<16) | PLL_RANGE
00145 | (28<<8) | PLL_DIV);
00146
00147
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");
00225 asm("ldr pc,[pc,#-0xf20]\n");
00226 }
00227
00228
00229
00230 void foo_dummy()
00231 {
00232 Vectors();
00233 }