1 #include <AT91SAM7S64.h>
4 #define USED __attribute__((used))
5 #define USED_NAKED __attribute__((used,naked))
6 #define USED_INT(type) __attribute__((used,interrupt(#type)))
8 #define FLASH_CYCLES AT91C_MC_FWS_1FWS
10 #define FLASH_CYCLES AT91C_MC_FWS_0FWS
14 #define MAIN_OSC_FREQ 18432000
17 #if MAIN_OSC_FREQ != 18432000
18 #error Unsupported main oscilator frequency
24 #define PLL_USBDIV_EXP 1
29 #define PLL_USBDIV_EXP 1
32 #error "Unsupported main clock frequency"
35 #define PLL_FREQ ((MAIN_OSC_FREQ * PLL_MUL) / PLL_DIV)
37 #if PLL_FREQ > 180000000
38 #error "PLL frequency too high"
39 #elif PLL_FREQ < 80000000
40 #error "PLL frequency too low"
43 #if PLL_FREQ > 155000000
44 #define PLL_RANGE AT91C_CKGR_OUT_2
46 #define PLL_RANGE AT91C_CKGR_OUT_0
50 #error "PLL frequency too high for USB"
53 #define USB_FREQ (PLL_FREQ / (1<<PLL_USBDIV_EXP))
54 #if USB_FREQ > 48120000 || USB_FREQ < 47880000
55 #warning "USB frequency outside limits"
58 #if MCK * (1<<MCK_DIV_EXP) != PLL_FREQ
59 #error PLL frequency is not a the correct multiple of the main clock
76 #define SET_MODE_STACK(mode, stack_end) \
77 asm("msr CPSR_c, %0\nldr sp, =" #stack_end "\n" ::"i" ((mode)|I_Bit|F_Bit))
79 #define ENABLE_INTS() \
80 asm("mrs r0, cpsr\nand r0, %0\nmsr cpsr_c, r0\n"::"i" (~(I_Bit|F_Bit)):"r0")
83 extern void *USR_Stack_End;
84 extern void *UND_Stack_End;
85 extern void *ABT_Stack_End;
86 extern void *FIQ_Stack_End;
87 extern void *IRQ_Stack_End;
88 extern void *SVC_Stack_End;
90 extern uint8_t _data[];
91 extern uint8_t _etext[];
92 extern uint8_t _edata[];
94 extern uint8_t __bss_start[];
95 extern uint8_t __bss_end[];
98 main(
int argc,
char *argv[]);
101 copy_initialized(
void)
103 uint8_t *ram = _data;
104 uint8_t *rom = _etext;
105 while(ram < _edata) {
113 uint8_t *m = __bss_start;
114 while(m < __bss_end) {
120 Reset_handler(
void) USED_NAKED;
129 *AT91C_MC_FMR = FLASH_CYCLES | (MCK / 666666 + 1);
132 *AT91C_WDTC_WDMR = AT91C_WDTC_WDDIS;
135 *AT91C_RSTC_RMR = (0xa5<<24) | AT91C_RSTC_URSTS;
138 *AT91C_CKGR_MOR = AT91C_CKGR_MOSCEN | (6<<8);
141 while(!(*AT91C_PMC_SR & AT91C_PMC_MOSCS));
144 *AT91C_CKGR_PLLR = ((PLL_USBDIV_EXP << 28) | ((PLL_MUL-1)<<16) | PLL_RANGE
145 | (28<<8) | PLL_DIV);
148 while(!(*AT91C_PMC_SR & AT91C_PMC_LOCK));
150 *AT91C_PMC_MCKR = (MCK_DIV_EXP << 2);
151 while(!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY));
152 *AT91C_PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
153 while(!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY));
154 SET_MODE_STACK(Mode_UND, UND_Stack_End);
155 SET_MODE_STACK(Mode_ABT, ABT_Stack_End);
156 SET_MODE_STACK(Mode_FIQ, FIQ_Stack_End);
157 SET_MODE_STACK(Mode_IRQ, IRQ_Stack_End);
158 SET_MODE_STACK(Mode_SVC, SVC_Stack_End);
160 SET_MODE_STACK(Mode_SYS, USR_Stack_End);
162 SET_MODE_STACK(Mode_USR, USR_Stack_End);
167 *AT91C_AIC_SPU = (uint32_t)SPU_handler;
174 Undef_handler(
void) USED_INT(UNDEF);
182 SWI_handler(
void) USED_INT(SWI);
190 PAbt_handler(
void) USED_INT(ABORT);
198 DAbt_handler(
void) USED_INT(ABORT);
209 *AT91C_AIC_EOICR = 0;
218 asm(
"ldr pc, =Reset_handler\n");
219 asm(
"ldr pc, =Undef_handler\n");
220 asm(
"ldr pc, =SWI_handler\n");
221 asm(
"ldr pc, =PAbt_handler\n");
222 asm(
"ldr pc, =DAbt_handler\n");
224 asm(
"ldr pc,[pc,#-0xf20]\n");
225 asm(
"ldr pc,[pc,#-0xf20]\n");