2 * Copyright © 2019 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
18 /* Interrupt functions */
20 void samd21_halt_isr(void)
22 ao_panic(AO_PANIC_CRASH);
25 void samd21_ignore_isr(void)
30 samd21_flash_size(void)
32 uint32_t nvmp = (samd21_nvmctrl.param >> SAMD21_NVMCTRL_PARAM_NVMP) & SAMD21_NVMCTRL_PARAM_NVMP_MASK;
33 uint32_t psz = (samd21_nvmctrl.param >> SAMD21_NVMCTRL_PARAM_PSZ) & SAMD21_NVMCTRL_PARAM_PSZ_MASK;
35 /* page size is 2**(3 + psz) */
36 return nvmp << (3 + psz);
39 #define STRINGIFY(x) #x
42 void __attribute__ ((weak)) samd21_ ## name ## _isr(void); \
43 _Pragma(STRINGIFY(weak samd21_ ## name ## _isr = samd21_ignore_isr))
45 #define isr_halt(name) \
46 void __attribute__ ((weak)) samd21_ ## name ## _isr(void); \
47 _Pragma(STRINGIFY(weak samd21_ ## name ## _isr = samd21_halt_isr))
92 #define i(addr,name) [(addr)/4] = samd21_ ## name ## _isr
94 extern char __stack[];
95 void _start(void) __attribute__((__noreturn__));
96 void main(void) __attribute__((__noreturn__));
98 __attribute__ ((section(".init")))
99 void (*const __interrupt_vector[])(void) __attribute((aligned(128))) = {
100 [0] = (void *) __stack,
109 i(0x40, pm), /* IRQ0 */
141 extern char __data_source[];
142 extern char __data_start[];
143 extern char __data_size[];
144 extern char __bss_start[];
145 extern char __bss_size[];
149 memcpy(__data_start, __data_source, (uintptr_t) __data_size);
150 memset(__bss_start, '\0', (uintptr_t) __bss_size);
153 if (ao_boot_check_chain()) {
155 if (ao_boot_check_pin())
158 ao_boot_chain(AO_BOOT_APPLICATION_BASE);
163 /* Turn on sysctrl */
164 samd21_pm.apbamask |= (1 << SAMD21_PM_APBAMASK_SYSCTRL);
165 /* Set interrupt vector */
166 samd21_scb.vtor = (uint32_t) &__interrupt_vector;