source: rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/startup.c@ 224

Last change on this file since 224 was 224, checked in by ertl-honda, 8 years ago

1.7.10のファイルに更新

File size: 15.9 KB
Line 
1/*
2 Arduino.h - Main include file for the Arduino SDK
3 Copyright (c) 2014 Arduino Team. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20#include "sam.h"
21#include "variant.h"
22
23/* Initialize segments */
24extern uint32_t __etext ;
25extern uint32_t __data_start__ ;
26extern uint32_t __data_end__ ;
27extern uint32_t __bss_start__ ;
28extern uint32_t __bss_end__ ;
29extern uint32_t __StackTop;
30
31extern int main( void ) ;
32extern void __libc_init_array(void);
33
34/* Default empty handler */
35void Dummy_Handler(void);
36
37/* Cortex-M0+ core handlers */
38#if defined DEBUG
39void NMI_Handler( void )
40{
41 while ( 1 )
42 {
43 }
44}
45
46void HardFault_Handler( void )
47{
48 while ( 1 )
49 {
50 }
51}
52
53void SVC_Handler( void )
54{
55 while ( 1 )
56 {
57 }
58}
59
60void PendSV_Handler( void )
61{
62 while ( 1 )
63 {
64 }
65}
66
67void SysTick_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
68#else
69void NMI_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
70void HardFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
71void SVC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
72void PendSV_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
73void SysTick_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
74#endif //DEBUG
75
76/* Peripherals handlers */
77void PM_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
78void SYSCTRL_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
79void WDT_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
80void RTC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
81void EIC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
82void NVMCTRL_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
83void DMAC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
84void USB_Handler ( void ) __attribute__ ((weak));
85void EVSYS_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
86void SERCOM0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
87void SERCOM1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
88void SERCOM2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
89void SERCOM3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
90void SERCOM4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
91void SERCOM5_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
92void TCC0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
93void TCC1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
94void TCC2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
95void TC3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
96void TC4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
97void TC5_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
98void TC6_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
99void TC7_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
100void ADC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
101void AC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
102void DAC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
103void PTC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
104void I2S_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
105
106/* Exception Table */
107__attribute__ ((section(".isr_vector")))
108const DeviceVectors exception_table=
109{
110 /* Configure Initial Stack Pointer, using linker-generated symbols */
111 (void*) (&__StackTop),
112
113 (void*) Reset_Handler,
114 (void*) NMI_Handler,
115 (void*) HardFault_Handler,
116 (void*) (0UL), /* Reserved */
117 (void*) (0UL), /* Reserved */
118 (void*) (0UL), /* Reserved */
119 (void*) (0UL), /* Reserved */
120 (void*) (0UL), /* Reserved */
121 (void*) (0UL), /* Reserved */
122 (void*) (0UL), /* Reserved */
123 (void*) SVC_Handler,
124 (void*) (0UL), /* Reserved */
125 (void*) (0UL), /* Reserved */
126 (void*) PendSV_Handler,
127 (void*) SysTick_Handler,
128
129 /* Configurable interrupts */
130 (void*) PM_Handler, /* 0 Power Manager */
131 (void*) SYSCTRL_Handler, /* 1 System Control */
132 (void*) WDT_Handler, /* 2 Watchdog Timer */
133 (void*) RTC_Handler, /* 3 Real-Time Counter */
134 (void*) EIC_Handler, /* 4 External Interrupt Controller */
135 (void*) NVMCTRL_Handler, /* 5 Non-Volatile Memory Controller */
136 (void*) DMAC_Handler, /* 6 Direct Memory Access Controller */
137 (void*) USB_Handler, /* 7 Universal Serial Bus */
138 (void*) EVSYS_Handler, /* 8 Event System Interface */
139 (void*) SERCOM0_Handler, /* 9 Serial Communication Interface 0 */
140 (void*) SERCOM1_Handler, /* 10 Serial Communication Interface 1 */
141 (void*) SERCOM2_Handler, /* 11 Serial Communication Interface 2 */
142 (void*) SERCOM3_Handler, /* 12 Serial Communication Interface 3 */
143 (void*) SERCOM4_Handler, /* 13 Serial Communication Interface 4 */
144 (void*) SERCOM5_Handler, /* 14 Serial Communication Interface 5 */
145 (void*) TCC0_Handler, /* 15 Timer Counter Control 0 */
146 (void*) TCC1_Handler, /* 16 Timer Counter Control 1 */
147 (void*) TCC2_Handler, /* 17 Timer Counter Control 2 */
148 (void*) TC3_Handler, /* 18 Basic Timer Counter 0 */
149 (void*) TC4_Handler, /* 19 Basic Timer Counter 1 */
150 (void*) TC5_Handler, /* 20 Basic Timer Counter 2 */
151 (void*) TC6_Handler, /* 21 Basic Timer Counter 3 */
152 (void*) TC7_Handler, /* 22 Basic Timer Counter 4 */
153 (void*) ADC_Handler, /* 23 Analog Digital Converter */
154 (void*) AC_Handler, /* 24 Analog Comparators */
155 (void*) DAC_Handler, /* 25 Digital Analog Converter */
156 (void*) PTC_Handler, /* 26 Peripheral Touch Controller */
157 (void*) I2S_Handler /* 27 Inter-IC Sound Interface */
158} ;
159
160/**
161 * \brief This is the code that gets called on processor reset.
162 * It configures the needed clocks and according Flash Read Wait States.
163 * At reset:
164 * - OSC8M clock source is enabled with a divider by 8 (1MHz).
165 * - Generic Clock Generator 0 (GCLKMAIN) is using OSC8M as source.
166 * We need to:
167 * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator), will be used as DFLL48M reference.
168 * 2) Put XOSC32K as source of Generic Clock Generator 1
169 * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference)
170 * 4) Enable DFLL48M clock
171 * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz.
172 * 6) Modify PRESCaler value of OSCM to have 8MHz
173 * 7) Put OSC8M as source for Generic Clock Generator 3
174 */
175// Constants for Clock generators
176#define GENERIC_CLOCK_GENERATOR_MAIN (0u)
177#define GENERIC_CLOCK_GENERATOR_XOSC32K (1u)
178#define GENERIC_CLOCK_GENERATOR_OSCULP32K (2u) /* Initialized at reset for WDT */
179#define GENERIC_CLOCK_GENERATOR_OSC8M (3u)
180// Constants for Clock multiplexers
181#define GENERIC_CLOCK_MULTIPLEXER_DFLL48M (0u)
182
183void SystemInit( void )
184{
185 //----- Tx & Rx led blinking during transmission (pin declaration) ----- begin ----
186 PORT->Group[1].DIRSET.reg=0x00000008; //PB03 as output (RX_LED)
187 PORT->Group[1].OUTSET.reg=0x00000008; //PB03 as output (RX_LED)
188
189 PORT->Group[0].DIRSET.reg=0x08000000; //PB03 as output (TX_LED)
190 PORT->Group[0].OUTSET.reg=0x08000000; //PB03 as output (TX_LED)
191 //----- Tx & Rx led blinking during transmission (pin declaration) ----- end ----
192
193 /* Set 1 Flash Wait State for 48MHz, cf tables 20.9 and 35.27 in SAMD21 Datasheet */
194 NVMCTRL->CTRLB.bit.RWS = NVMCTRL_CTRLB_RWS_HALF_Val ;
195
196 /* Turn on the digital interface clock */
197 PM->APBAMASK.reg |= PM_APBAMASK_GCLK ;
198
199 /* ----------------------------------------------------------------------------------------------
200 * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator)
201 */
202 SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP( 0x6u ) | /* cf table 15.10 of product datasheet in chapter 15.8.6 */
203 SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_EN32K ;
204 SYSCTRL->XOSC32K.bit.ENABLE = 1 ; /* separate call, as described in chapter 15.6.3 */
205
206 while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_XOSC32KRDY) == 0 )
207 {
208 /* Wait for oscillator stabilization */
209 }
210
211 /* Software reset the module to ensure it is re-initialized correctly */
212 /* Note: Due to synchronization, there is a delay from writing CTRL.SWRST until the reset is complete.
213 * CTRL.SWRST and STATUS.SYNCBUSY will both be cleared when the reset is complete, as described in chapter 13.8.1
214 */
215 GCLK->CTRL.reg = GCLK_CTRL_SWRST ;
216
217 while ( (GCLK->CTRL.reg & GCLK_CTRL_SWRST) && (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) )
218 {
219 /* Wait for reset to complete */
220 }
221
222 /* ----------------------------------------------------------------------------------------------
223 * 2) Put XOSC32K as source of Generic Clock Generator 1
224 */
225 GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ) ; // Generic Clock Generator 1
226
227 while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
228 {
229 /* Wait for synchronization */
230 }
231
232 /* Write Generic Clock Generator 1 configuration */
233 GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ) | // Generic Clock Generator 1
234 GCLK_GENCTRL_SRC_XOSC32K | // Selected source is External 32KHz Oscillator
235// GCLK_GENCTRL_OE | // Output clock to a pin for tests
236 GCLK_GENCTRL_GENEN ;
237
238 while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
239 {
240 /* Wait for synchronization */
241 }
242
243 /* ----------------------------------------------------------------------------------------------
244 * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference)
245 */
246 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GENERIC_CLOCK_MULTIPLEXER_DFLL48M ) | // Generic Clock Multiplexer 0
247 GCLK_CLKCTRL_GEN_GCLK1 | // Generic Clock Generator 1 is source
248 GCLK_CLKCTRL_CLKEN ;
249
250 while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
251 {
252 /* Wait for synchronization */
253 }
254
255 /* ----------------------------------------------------------------------------------------------
256 * 4) Enable DFLL48M clock
257 */
258
259 /* DFLL Configuration in Closed Loop mode, cf product datasheet chapter 15.6.7.1 - Closed-Loop Operation */
260
261 /* Remove the OnDemand mode, Bug http://avr32.icgroup.norway.atmel.com/bugzilla/show_bug.cgi?id=9905 */
262 SYSCTRL->DFLLCTRL.bit.ONDEMAND = 0 ;
263
264 while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
265 {
266 /* Wait for synchronization */
267 }
268
269 SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 31 ) | // Coarse step is 31, half of the max value
270 SYSCTRL_DFLLMUL_FSTEP( 511 ) | // Fine step is 511, half of the max value
271 SYSCTRL_DFLLMUL_MUL( (VARIANT_MCK/VARIANT_MAINOSC) ) ; // External 32KHz is the reference
272
273 while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
274 {
275 /* Wait for synchronization */
276 }
277
278 /* Write full configuration to DFLL control register */
279 SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | /* Enable the closed loop mode */
280 SYSCTRL_DFLLCTRL_WAITLOCK |
281 SYSCTRL_DFLLCTRL_QLDIS ; /* Disable Quick lock */
282
283 while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
284 {
285 /* Wait for synchronization */
286 }
287
288 /* Enable the DFLL */
289 SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_ENABLE ;
290
291 while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKC) == 0 ||
292 (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKF) == 0 )
293 {
294 /* Wait for locks flags */
295 }
296
297 while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
298 {
299 /* Wait for synchronization */
300 }
301
302 /* ----------------------------------------------------------------------------------------------
303 * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz.
304 */
305 GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_MAIN ) ; // Generic Clock Generator 0
306
307 while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
308 {
309 /* Wait for synchronization */
310 }
311
312 /* Write Generic Clock Generator 0 configuration */
313 GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_MAIN ) | // Generic Clock Generator 0
314 GCLK_GENCTRL_SRC_DFLL48M | // Selected source is DFLL 48MHz
315// GCLK_GENCTRL_OE | // Output clock to a pin for tests
316 GCLK_GENCTRL_IDC | // Set 50/50 duty cycle
317 GCLK_GENCTRL_GENEN ;
318
319 while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
320 {
321 /* Wait for synchronization */
322 }
323
324 /* ----------------------------------------------------------------------------------------------
325 * 6) Modify PRESCaler value of OSC8M to have 8MHz
326 */
327 SYSCTRL->OSC8M.bit.PRESC = SYSCTRL_OSC8M_PRESC_0_Val ;
328 SYSCTRL->OSC8M.bit.ONDEMAND = 0 ;
329
330 /* ----------------------------------------------------------------------------------------------
331 * 7) Put OSC8M as source for Generic Clock Generator 3
332 */
333 GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) ; // Generic Clock Generator 3
334
335 /* Write Generic Clock Generator 3 configuration */
336 GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) | // Generic Clock Generator 3
337 GCLK_GENCTRL_SRC_OSC8M | // Selected source is RC OSC 8MHz (already enabled at reset)
338// GCLK_GENCTRL_OE | // Output clock to a pin for tests
339 GCLK_GENCTRL_GENEN ;
340
341 while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
342 {
343 /* Wait for synchronization */
344 }
345
346 /*
347 * Now that all system clocks are configured, we can set CPU and APBx BUS clocks.
348 * There values are normally the one present after Reset.
349 */
350 PM->CPUSEL.reg = PM_CPUSEL_CPUDIV_DIV1 ;
351 PM->APBASEL.reg = PM_APBASEL_APBADIV_DIV1_Val ;
352 PM->APBBSEL.reg = PM_APBBSEL_APBBDIV_DIV1_Val ;
353 PM->APBCSEL.reg = PM_APBCSEL_APBCDIV_DIV1_Val ;
354
355 SystemCoreClock=VARIANT_MCK ;
356}
357
358/**
359 * \brief This is the code that gets called on processor reset.
360 * To initialize the device, and call the main() routine.
361 */
362void Reset_Handler( void )
363{
364 uint32_t *pSrc, *pDest;
365
366 /* Initialize the initialized data section */
367 pSrc = &__etext;
368 pDest = &__data_start__;
369
370 if ( (&__data_start__ != &__data_end__) && (pSrc != pDest) )
371 {
372 for (; pDest < &__data_end__ ; pDest++, pSrc++ )
373 {
374 *pDest = *pSrc ;
375 }
376 }
377
378 /* Clear the zero section */
379 if ( (&__data_start__ != &__data_end__) && (pSrc != pDest) )
380 {
381 for ( pDest = &__bss_start__ ; pDest < &__bss_end__ ; pDest++ )
382 {
383 *pDest = 0 ;
384 }
385 }
386
387 /* Initialize the C library */
388 __libc_init_array();
389
390 SystemInit() ;
391
392 /* Branch to main function */
393 main() ;
394
395 /* Infinite loop */
396 while ( 1 )
397 {
398 }
399}
400
401/**
402 * \brief Default interrupt handler for unused IRQs.
403 */
404void Dummy_Handler( void )
405{
406 while ( 1 )
407 {
408 }
409}
410
411static void (*usb_isr)(void) = NULL;
412
413void USB_Handler(void)
414{
415 if (usb_isr)
416 usb_isr();
417}
418
419void USB_SetHandler(void (*new_usb_isr)(void))
420{
421 usb_isr = new_usb_isr;
422}
423
Note: See TracBrowser for help on using the repository browser.