blob: d548a30d4d5cb6369402d0cebccdbb5993fac2f1 [file] [log] [blame]
Kévin Redon93717e42018-07-08 13:26:15 +02001/* ----------------------------------------------------------------------------
2 * ATMEL Microcontroller Software Support
3 * ----------------------------------------------------------------------------
4 * Copyright (c) 2010, Atmel Corporation
5 * Copyright (c) 2017, Harald Welte <laforge@gnumonks.org>
6 * Copyright (c) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
7 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 *
13 * - Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the disclaimer below.
15 *
16 * Atmel's name may not be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
22 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
25 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * ----------------------------------------------------------------------------
30 */
31
32/*----------------------------------------------------------------------------
33 * Headers
34 *----------------------------------------------------------------------------*/
35
36#include "board.h"
37#include "board_lowlevel.h"
38
39/*----------------------------------------------------------------------------
40 * Exported variables
41 *----------------------------------------------------------------------------*/
42
43/* Stack Configuration */
44#define STACK_SIZE 0x900 /** Stack size (in DWords) */
45__attribute__ ((aligned(8),section(".stack")))
46uint32_t pdwStack[STACK_SIZE] ;
47
48/* Initialize segments */
49extern uint32_t _sfixed;
50extern uint32_t _efixed;
51extern uint32_t _etext;
52extern uint32_t _srelocate;
53extern uint32_t _erelocate;
54extern uint32_t _szero;
55extern uint32_t _ezero;
56
57
58/*----------------------------------------------------------------------------
59 * ProtoTypes
60 *----------------------------------------------------------------------------*/
61
62/** \cond DOXYGEN_SHOULD_SKIP_THIS */
63extern int main( void ) ;
64/** \endcond */
65void ResetException( void ) ;
66
67/*------------------------------------------------------------------------------
68 * Exception Table
69 *------------------------------------------------------------------------------*/
70
71__attribute__((section(".vectors")))
72IntFunc exception_table[] = {
73
Kévin Redon33d1eb72018-07-08 13:58:12 +020074 /* Configure Initial Stack Pointer, using linker-generated symbols */
75 (IntFunc)(&pdwStack[STACK_SIZE-1]),
76 ResetException,
Kévin Redon93717e42018-07-08 13:26:15 +020077
Kévin Redon33d1eb72018-07-08 13:58:12 +020078 NMI_Handler,
79 HardFault_Handler,
80 MemManage_Handler,
81 BusFault_Handler,
82 UsageFault_Handler,
83 0, 0, 0, 0, /* Reserved */
84 SVC_Handler,
85 DebugMon_Handler,
86 0, /* Reserved */
87 PendSV_Handler,
88 SysTick_Handler,
Kévin Redon93717e42018-07-08 13:26:15 +020089
Kévin Redon33d1eb72018-07-08 13:58:12 +020090 /* Configurable interrupts */
91 SUPC_IrqHandler, /* 0 Supply Controller */
92 RSTC_IrqHandler, /* 1 Reset Controller */
93 RTC_IrqHandler, /* 2 Real Time Clock */
94 RTT_IrqHandler, /* 3 Real Time Timer */
95 WDT_IrqHandler, /* 4 Watchdog Timer */
96 PMC_IrqHandler, /* 5 PMC */
97 EEFC_IrqHandler, /* 6 EEFC */
98 IrqHandlerNotUsed, /* 7 Reserved */
99 UART0_IrqHandler, /* 8 UART0 */
100 UART1_IrqHandler, /* 9 UART1 */
101 SMC_IrqHandler, /* 10 SMC */
102 PIOA_IrqHandler, /* 11 Parallel IO Controller A */
103 PIOB_IrqHandler, /* 12 Parallel IO Controller B */
104 PIOC_IrqHandler, /* 13 Parallel IO Controller C */
105 USART0_IrqHandler, /* 14 USART 0 */
106 USART1_IrqHandler, /* 15 USART 1 */
107 IrqHandlerNotUsed, /* 16 Reserved */
108 IrqHandlerNotUsed, /* 17 Reserved */
109 MCI_IrqHandler, /* 18 MCI */
110 TWI0_IrqHandler, /* 19 TWI 0 */
111 TWI1_IrqHandler, /* 20 TWI 1 */
112 SPI_IrqHandler, /* 21 SPI */
113 SSC_IrqHandler, /* 22 SSC */
114 TC0_IrqHandler, /* 23 Timer Counter 0 */
115 TC1_IrqHandler, /* 24 Timer Counter 1 */
116 TC2_IrqHandler, /* 25 Timer Counter 2 */
117 TC3_IrqHandler, /* 26 Timer Counter 3 */
118 TC4_IrqHandler, /* 27 Timer Counter 4 */
119 TC5_IrqHandler, /* 28 Timer Counter 5 */
120 ADC_IrqHandler, /* 29 ADC controller */
121 DAC_IrqHandler, /* 30 DAC controller */
122 PWM_IrqHandler, /* 31 PWM */
123 CRCCU_IrqHandler, /* 32 CRC Calculation Unit */
124 ACC_IrqHandler, /* 33 Analog Comparator */
125 USBD_IrqHandler, /* 34 USB Device Port */
126 IrqHandlerNotUsed /* 35 not used */
Kévin Redon93717e42018-07-08 13:26:15 +0200127};
128
Kévin Redonb6e2f0f2019-12-11 17:04:21 +0100129#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu) && defined(ENVIRONMENT_flash)
Kévin Redon93717e42018-07-08 13:26:15 +0200130#include "usb/device/dfu/dfu.h"
131static void BootIntoApp(void)
132{
133 unsigned int *pSrc;
134 void (*appReset)(void);
135
136 pSrc = (unsigned int *) ((unsigned char *)IFLASH_ADDR + BOARD_DFU_BOOT_SIZE);
137 /* set vector table to application vector table (store at the beginning of the application) */
138 SCB->VTOR = (unsigned int)(pSrc);
139 /* set stack pointer to address provided in the beginning of the application (loaded into a register first) */
140 __asm__ volatile ("MSR msp,%0" : :"r"(*pSrc));
141 /* start application (by jumping to the reset function which address is stored as second entry of the vector table) */
142 appReset = (void(*)(void))pSrc[1];
143
144 g_dfu->state = DFU_STATE_appIDLE;
145
146 appReset();
147}
148#endif
149
150/**
151 * \brief This is the code that gets called on processor reset.
152 * To initialize the device, and call the main() routine.
153 */
154void ResetException( void )
155{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200156 uint32_t *pSrc, *pDest ;
Kévin Redon93717e42018-07-08 13:26:15 +0200157
Kévin Redon33d1eb72018-07-08 13:58:12 +0200158 /* Low level Initialize */
159 LowLevelInit() ;
Kévin Redon93717e42018-07-08 13:26:15 +0200160
161
Kévin Redonb6e2f0f2019-12-11 17:04:21 +0100162#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu) && defined(ENVIRONMENT_flash)
163 // boot application if there is not DFU override
164 if (!USBDFU_OverrideEnterDFU() && SCB->VTOR < IFLASH_ADDR + BOARD_DFU_BOOT_SIZE) {
Kévin Redon33d1eb72018-07-08 13:58:12 +0200165 UART_Exit();
166 __disable_irq();
167 BootIntoApp();
168 /* Infinite loop */
169 while ( 1 ) ;
170 }
Kévin Redon93717e42018-07-08 13:26:15 +0200171#endif
172
Kévin Redon33d1eb72018-07-08 13:58:12 +0200173 /* Initialize the relocate segment */
174 pSrc = &_etext ;
175 pDest = &_srelocate ;
Kévin Redon93717e42018-07-08 13:26:15 +0200176
Kévin Redon33d1eb72018-07-08 13:58:12 +0200177 if ( pSrc != pDest )
178 {
179 for ( ; pDest < &_erelocate ; )
180 {
181 *pDest++ = *pSrc++ ;
182 }
183 }
Kévin Redon93717e42018-07-08 13:26:15 +0200184
Kévin Redon33d1eb72018-07-08 13:58:12 +0200185 /* Clear the zero segment */
186 for ( pDest = &_szero ; pDest < &_ezero ; )
187 {
188 *pDest++ = 0;
189 }
Kévin Redon93717e42018-07-08 13:26:15 +0200190
Kévin Redon33d1eb72018-07-08 13:58:12 +0200191 /* Set the vector table base address */
192 pSrc = (uint32_t *)&_sfixed;
193 SCB->VTOR = ( (uint32_t)pSrc & SCB_VTOR_TBLOFF_Msk ) ;
194
195 if ( ((uint32_t)pSrc >= IRAM_ADDR) && ((uint32_t)pSrc < IRAM_ADDR+IRAM_SIZE) )
196 {
Kévin Redon93717e42018-07-08 13:26:15 +0200197 SCB->VTOR |= 1 << SCB_VTOR_TBLBASE_Pos ;
Kévin Redon33d1eb72018-07-08 13:58:12 +0200198 }
Kévin Redon93717e42018-07-08 13:26:15 +0200199
Kévin Redon33d1eb72018-07-08 13:58:12 +0200200 /* App should have disabled interrupts during the transition */
201 __enable_irq();
Kévin Redon93717e42018-07-08 13:26:15 +0200202
Kévin Redon33d1eb72018-07-08 13:58:12 +0200203 /* Branch to main function */
204 main() ;
Kévin Redon93717e42018-07-08 13:26:15 +0200205
Kévin Redon33d1eb72018-07-08 13:58:12 +0200206 /* Infinite loop */
207 while ( 1 ) ;
Kévin Redon93717e42018-07-08 13:26:15 +0200208}
209