blob: 42231fb2d7878cca2565d21278b4f4cca82333e6 [file] [log] [blame]
Christina Quastb0a05702014-11-28 10:27:32 +01001/* ----------------------------------------------------------------------------
2 * ATMEL Microcontroller Software Support
3 * ----------------------------------------------------------------------------
4 * Copyright (c) 2010, Atmel Corporation
Kévin Redon432ba512018-05-21 17:13:40 +02005 * Copyright (C) 2017, Harald Welte <laforge@gnumonks.org>
Christina Quastb0a05702014-11-28 10:27:32 +01006 *
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the disclaimer below.
14 *
15 * Atmel's name may not be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
21 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * ----------------------------------------------------------------------------
29 */
30
31/*----------------------------------------------------------------------------
32 * Headers
33 *----------------------------------------------------------------------------*/
34
35#include "board.h"
36#include "board_lowlevel.h"
37
38/*----------------------------------------------------------------------------
39 * Exported variables
40 *----------------------------------------------------------------------------*/
41
42/* Stack Configuration */
43#define STACK_SIZE 0x900 /** Stack size (in DWords) */
44__attribute__ ((aligned(8),section(".stack")))
45uint32_t pdwStack[STACK_SIZE] ;
46
47/* Initialize segments */
48extern uint32_t _sfixed;
49extern uint32_t _efixed;
50extern uint32_t _etext;
51extern uint32_t _srelocate;
52extern uint32_t _erelocate;
53extern uint32_t _szero;
54extern uint32_t _ezero;
55
56
57/*----------------------------------------------------------------------------
58 * ProtoTypes
59 *----------------------------------------------------------------------------*/
Christina Quast8be71e42014-12-02 13:06:01 +010060
61/** \cond DOXYGEN_SHOULD_SKIP_THIS */
Christina Quastb0a05702014-11-28 10:27:32 +010062extern int main( void ) ;
Christina Quast8be71e42014-12-02 13:06:01 +010063/** \endcond */
Christina Quastb0a05702014-11-28 10:27:32 +010064void ResetException( void ) ;
Christina Quastb0a05702014-11-28 10:27:32 +010065
66/*------------------------------------------------------------------------------
67 * Exception Table
68 *------------------------------------------------------------------------------*/
69
70__attribute__((section(".vectors")))
71IntFunc exception_table[] = {
72
73 /* Configure Initial Stack Pointer, using linker-generated symbols */
74 (IntFunc)(&pdwStack[STACK_SIZE-1]),
75 ResetException,
76
77 NMI_Handler,
78 HardFault_Handler,
79 MemManage_Handler,
80 BusFault_Handler,
81 UsageFault_Handler,
82 0, 0, 0, 0, /* Reserved */
83 SVC_Handler,
84 DebugMon_Handler,
85 0, /* Reserved */
86 PendSV_Handler,
87 SysTick_Handler,
88
89 /* Configurable interrupts */
90 SUPC_IrqHandler, /* 0 Supply Controller */
91 RSTC_IrqHandler, /* 1 Reset Controller */
92 RTC_IrqHandler, /* 2 Real Time Clock */
93 RTT_IrqHandler, /* 3 Real Time Timer */
94 WDT_IrqHandler, /* 4 Watchdog Timer */
95 PMC_IrqHandler, /* 5 PMC */
96 EEFC_IrqHandler, /* 6 EEFC */
97 IrqHandlerNotUsed, /* 7 Reserved */
98 UART0_IrqHandler, /* 8 UART0 */
99 UART1_IrqHandler, /* 9 UART1 */
100 SMC_IrqHandler, /* 10 SMC */
101 PIOA_IrqHandler, /* 11 Parallel IO Controller A */
102 PIOB_IrqHandler, /* 12 Parallel IO Controller B */
103 PIOC_IrqHandler, /* 13 Parallel IO Controller C */
104 USART0_IrqHandler, /* 14 USART 0 */
105 USART1_IrqHandler, /* 15 USART 1 */
106 IrqHandlerNotUsed, /* 16 Reserved */
107 IrqHandlerNotUsed, /* 17 Reserved */
108 MCI_IrqHandler, /* 18 MCI */
109 TWI0_IrqHandler, /* 19 TWI 0 */
110 TWI1_IrqHandler, /* 20 TWI 1 */
111 SPI_IrqHandler, /* 21 SPI */
112 SSC_IrqHandler, /* 22 SSC */
113 TC0_IrqHandler, /* 23 Timer Counter 0 */
114 TC1_IrqHandler, /* 24 Timer Counter 1 */
115 TC2_IrqHandler, /* 25 Timer Counter 2 */
116 TC3_IrqHandler, /* 26 Timer Counter 3 */
117 TC4_IrqHandler, /* 27 Timer Counter 4 */
118 TC5_IrqHandler, /* 28 Timer Counter 5 */
119 ADC_IrqHandler, /* 29 ADC controller */
120 DAC_IrqHandler, /* 30 DAC controller */
121 PWM_IrqHandler, /* 31 PWM */
122 CRCCU_IrqHandler, /* 32 CRC Calculation Unit */
123 ACC_IrqHandler, /* 33 Analog Comparator */
124 USBD_IrqHandler, /* 34 USB Device Port */
125 IrqHandlerNotUsed /* 35 not used */
126};
127
Harald Welte0af49482017-03-02 23:18:02 +0100128#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
Harald Welted1e96342017-03-03 00:34:17 +0100129#include "usb/device/dfu/dfu.h"
Harald Welte7ed6f3b2017-02-26 17:00:43 +0100130static void BootIntoApp(void)
131{
132 unsigned int *pSrc;
133 void (*appReset)(void);
134
135 pSrc = (unsigned int *) ((unsigned char *)IFLASH_ADDR + BOARD_DFU_BOOT_SIZE);
Kévin Redon9e29a3e2018-07-07 13:48:44 +0200136 /* set vector table to application vector table (store at the beginning of the application) */
137 SCB->VTOR = (unsigned int)(pSrc);
138 /* set stack pointer to address provided in the beginning of the application (loaded into a register first) */
139 __asm__ volatile ("MSR msp,%0" : :"r"(*pSrc));
140 /* start application (by jumping to the reset function which address is stored as second entry of the vector table) */
Kévin Redon76be7c82018-05-21 19:33:50 +0200141 appReset = (void(*)(void))pSrc[1];
Harald Weltecab66412017-03-02 19:22:50 +0100142
Harald Welted1e96342017-03-03 00:34:17 +0100143 g_dfu->state = DFU_STATE_appIDLE;
Harald Weltecab66412017-03-02 19:22:50 +0100144
Harald Welte7ed6f3b2017-02-26 17:00:43 +0100145 appReset();
146}
147#endif
148
Christina Quastb0a05702014-11-28 10:27:32 +0100149/**
150 * \brief This is the code that gets called on processor reset.
151 * To initialize the device, and call the main() routine.
152 */
153void ResetException( void )
154{
155 uint32_t *pSrc, *pDest ;
156
157 /* Low level Initialize */
158 LowLevelInit() ;
159
Harald Welte0af49482017-03-02 23:18:02 +0100160
161#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
Harald Welte91fc4022017-03-03 01:05:22 +0100162 /* we are before the text segment has been relocated, so g_dfu is
163 * not initialized yet */
164 g_dfu = &_g_dfu;
Harald Welte14051002017-03-04 19:17:27 +0100165 if ((g_dfu->magic != USB_DFU_MAGIC) && !USBDFU_OverrideEnterDFU()) {
Kévin Redon80303c12018-06-17 22:35:17 +0200166 /* start application if valid
167 * the application starts with the vector table
168 * the first entry in the vector table is the initial stack pointer (SP) address
169 * the stack will be placed in RAM, which begins at 0x2000 0000
170 * there is up to 48 KB of RAM (0xc000)
171 * since the stack grown "downwards" it should start at the end of the RAM: max 0x2000 c000
172 * if the SP is not in this range (e.g. flash has been erased) there is no valid application
173 * the second entry in the vector table is the reset address, corresponding to the application start
174 */
175 if (((*((uint32_t*)(IFLASH_ADDR+BOARD_DFU_BOOT_SIZE)))&0xFFFF0000)==0x20000000) {
Kévin Redond44cb802018-07-07 14:41:11 +0200176 UART_Exit();
177 __disable_irq();
Kévin Redon80303c12018-06-17 22:35:17 +0200178 BootIntoApp();
179 /* Infinite loop */
180 while ( 1 ) ;
181 }
Harald Welted1e96342017-03-03 00:34:17 +0100182 }
Harald Welte7ed6f3b2017-02-26 17:00:43 +0100183#endif
184
Christina Quastb0a05702014-11-28 10:27:32 +0100185 /* Initialize the relocate segment */
186 pSrc = &_etext ;
187 pDest = &_srelocate ;
188
189 if ( pSrc != pDest )
190 {
191 for ( ; pDest < &_erelocate ; )
192 {
193 *pDest++ = *pSrc++ ;
194 }
195 }
196
197 /* Clear the zero segment */
198 for ( pDest = &_szero ; pDest < &_ezero ; )
199 {
200 *pDest++ = 0;
201 }
202
203 /* Set the vector table base address */
204 pSrc = (uint32_t *)&_sfixed;
205 SCB->VTOR = ( (uint32_t)pSrc & SCB_VTOR_TBLOFF_Msk ) ;
206
207 if ( ((uint32_t)pSrc >= IRAM_ADDR) && ((uint32_t)pSrc < IRAM_ADDR+IRAM_SIZE) )
208 {
209 SCB->VTOR |= 1 << SCB_VTOR_TBLBASE_Pos ;
210 }
211
Harald Welte7ed6f3b2017-02-26 17:00:43 +0100212 /* App should have disabled interrupts during the transition */
213 __enable_irq();
214
Harald Weltedb17e832017-03-02 23:19:13 +0100215 /* Branch to main function */
216 main() ;
217
Christina Quastb0a05702014-11-28 10:27:32 +0100218 /* Infinite loop */
219 while ( 1 ) ;
220}
221