Contiki 2.5
startup-SAM7S-arm.c
1 #include <AT91SAM7S64.h>
2 #include <stdint.h>
3 
4 #define USED __attribute__((used))
5 #define USED_NAKED __attribute__((used,naked))
6 #define USED_INT(type) __attribute__((used,interrupt(#type)))
7 #if MCK > 30000000
8 #define FLASH_CYCLES AT91C_MC_FWS_1FWS
9 #else
10 #define FLASH_CYCLES AT91C_MC_FWS_0FWS
11 #endif
12 
13 #ifndef MAIN_OSC_FREQ
14 #define MAIN_OSC_FREQ 18432000
15 #endif
16 
17 #if MAIN_OSC_FREQ != 18432000
18 #error Unsupported main oscilator frequency
19 #endif
20 
21 #if MCK == 23961600
22 #define PLL_DIV 5
23 #define PLL_MUL 26
24 #define PLL_USBDIV_EXP 1
25 #define MCK_DIV_EXP 2
26 #elif MCK == 47923200
27 #define PLL_DIV 5
28 #define PLL_MUL 26
29 #define PLL_USBDIV_EXP 1
30 #define MCK_DIV_EXP 1
31 #else
32 #error "Unsupported main clock frequency"
33 #endif
34 
35 #define PLL_FREQ ((MAIN_OSC_FREQ * PLL_MUL) / PLL_DIV)
36 
37 #if PLL_FREQ > 180000000
38 #error "PLL frequency too high"
39 #elif PLL_FREQ < 80000000
40 #error "PLL frequency too low"
41 #endif
42 
43 #if PLL_FREQ > 155000000
44 #define PLL_RANGE AT91C_CKGR_OUT_2
45 #else
46 #define PLL_RANGE AT91C_CKGR_OUT_0
47 #endif
48 
49 #if PLL_USBDIV > 2
50 #error "PLL frequency too high for USB"
51 #endif
52 
53 #define USB_FREQ (PLL_FREQ / (1<<PLL_USBDIV_EXP))
54 #if USB_FREQ > 48120000 || USB_FREQ < 47880000
55 #warning "USB frequency outside limits"
56 #endif
57 
58 #if MCK * (1<<MCK_DIV_EXP) != PLL_FREQ
59 #error PLL frequency is not a the correct multiple of the main clock
60 #endif
61 
62 /* CPU modes */
63 #define Mode_USR 0x10
64 #define Mode_FIQ 0x11
65 #define Mode_IRQ 0x12
66 #define Mode_SVC 0x13
67 #define Mode_ABT 0x17
68 #define Mode_UND 0x1B
69 #define Mode_SYS 0x1F
70 
71 /* IRQ disable bit */
72 #define I_Bit 0x80
73 /* FIQ disable bit */
74 #define F_Bit 0x40
75 
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))
78 
79 #define ENABLE_INTS() \
80 asm("mrs r0, cpsr\nand r0, %0\nmsr cpsr_c, r0\n"::"i" (~(I_Bit|F_Bit)):"r0")
81 
82 
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;
89 
90 extern uint8_t _data[];
91 extern uint8_t _etext[];
92 extern uint8_t _edata[];
93 
94 extern uint8_t __bss_start[];
95 extern uint8_t __bss_end[];
96 
97 extern int
98 main(int argc, char *argv[]);
99 
100 static void
101 copy_initialized(void)
102 {
103  uint8_t *ram = _data;
104  uint8_t *rom = _etext;
105  while(ram < _edata) {
106  *ram++ = *rom++;
107  }
108 }
109 
110 static void
111 clear_bss(void)
112 {
113  uint8_t *m = __bss_start;
114  while(m < __bss_end) {
115  *m++ = 0;
116  }
117 }
118 
119 static void
120 Reset_handler(void) USED_NAKED;
121 
122 static void
123 SPU_handler(void) __attribute__((interrupt("IRQ")));
124 
125 static void
126 Reset_handler(void)
127 {
128  /* Setup flash timing */
129  *AT91C_MC_FMR = FLASH_CYCLES | (MCK / 666666 + 1);
130 
131  /* Disable watchdog */
132  *AT91C_WDTC_WDMR = AT91C_WDTC_WDDIS;
133 
134  /* Setup reset controller */
135  *AT91C_RSTC_RMR = (0xa5<<24) | AT91C_RSTC_URSTS;
136 
137  /* Start main oscilator */
138  *AT91C_CKGR_MOR = AT91C_CKGR_MOSCEN | (6<<8);
139 
140  /* Wait for oscillator to start */
141  while(!(*AT91C_PMC_SR & AT91C_PMC_MOSCS));
142 
143  /* Setup PLL */
144  *AT91C_CKGR_PLLR = ((PLL_USBDIV_EXP << 28) | ((PLL_MUL-1)<<16) | PLL_RANGE
145  | (28<<8) | PLL_DIV);
146 
147  /* Wait for PLL to lock */
148  while(!(*AT91C_PMC_SR & AT91C_PMC_LOCK));
149 
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);
159 #ifdef RUN_AS_SYSTEM
160  SET_MODE_STACK(Mode_SYS, USR_Stack_End);
161 #else
162  SET_MODE_STACK(Mode_USR, USR_Stack_End);
163 #endif
164  copy_initialized();
165  clear_bss();
166 
167  *AT91C_AIC_SPU = (uint32_t)SPU_handler;
168  ENABLE_INTS();
169  main(0,0);
170  while(1);
171 }
172 
173 static void
174 Undef_handler(void) USED_INT(UNDEF);
175 
176 static void
177 Undef_handler(void)
178 {
179 }
180 
181 static void
182 SWI_handler(void) USED_INT(SWI);
183 
184 static void
185 SWI_handler(void)
186 {
187 }
188 
189 static void
190 PAbt_handler(void) USED_INT(ABORT);
191 
192 static void
193 PAbt_handler(void)
194 {
195 }
196 
197 static void
198 DAbt_handler(void) USED_INT(ABORT);
199 
200 static void
201 DAbt_handler(void)
202 {
203 }
204 
205 
206 static void
207 SPU_handler(void)
208 {
209  *AT91C_AIC_EOICR = 0;
210 }
211 
212 static void
213 Vectors(void) __attribute__ ((naked, section(".vectrom")));
214 
215 static void
216 Vectors(void)
217 {
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");
223  asm("nop\n");
224  asm("ldr pc,[pc,#-0xf20]\n"); /* Vector From AIC_IVR */
225  asm("ldr pc,[pc,#-0xf20]\n"); /* Vector From AIC_FVR */
226 }
227 
228 
229 
230 void foo_dummy()
231 {
232  Vectors();
233 }