diff --git a/Sensor Watch Starter Project/linker/saml22j18.ld b/Sensor Watch Starter Project/linker/saml22j18.ld index a68c3b1..a980150 100755 --- a/Sensor Watch Starter Project/linker/saml22j18.ld +++ b/Sensor Watch Starter Project/linker/saml22j18.ld @@ -1,82 +1,145 @@ -/* - * Copyright (c) 2014-2016, Alex Taradov - * All rights reserved. +/** + * \file * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * \brief Linker script for running in internal FLASH on the SAML22J18A * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ MEMORY { - flash (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* 256k */ - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000 /* 32k */ + rom (rx) : ORIGIN = 0x2000, LENGTH = 0x00040000-0x2000 + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } -__top_flash = ORIGIN(flash) + LENGTH(flash); -__top_ram = ORIGIN(ram) + LENGTH(ram); +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; -ENTRY(irq_handler_reset) +ENTRY(Reset_Handler) +/* Section Definitions */ SECTIONS { - .text : ALIGN(4) - { - FILL(0xff) - KEEP(*(.vectors)) - *(.text*) - *(.rodata) - *(.rodata.*) + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + . = ALIGN(4); - } > flash + _etext = .; - . = ALIGN(4); - _etext = .; + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram - .uninit_RESERVED : ALIGN(4) - { - KEEP(*(.bss.$RESERVED*)) - } > ram + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram - .data : ALIGN(4) - { - FILL(0xff) - _data = .; - *(.ramfunc .ramfunc.*); - *(vtable) - *(.data*) . = ALIGN(4); - _edata = .; - } > ram AT > flash - - .bss : ALIGN(4) - { - _bss = .; - *(.bss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - PROVIDE(_end = .); - } > ram - - PROVIDE(_stack_top = __top_ram - 0); + _end = . ; } diff --git a/Sensor Watch Starter Project/main.c b/Sensor Watch Starter Project/main.c index 5c0aade..2ced056 100755 --- a/Sensor Watch Starter Project/main.c +++ b/Sensor Watch Starter Project/main.c @@ -36,139 +36,69 @@ #include "hal_gpio.h" //----------------------------------------------------------------------------- -#define PERIOD_FAST 100 -#define PERIOD_SLOW 500 - HAL_GPIO_PIN(LED, A, 21) -HAL_GPIO_PIN(BUTTON, A, 30) HAL_GPIO_PIN(UART_TX, B, 0) HAL_GPIO_PIN(UART_RX, B, 2) //----------------------------------------------------------------------------- -static void timer_set_period(uint16_t i) -{ - TC3->COUNT16.CC[0].reg = (F_CPU / 1000ul / 256) * i; - TC3->COUNT16.COUNT.reg = 0; +static void uart_init(uint32_t baud) { + uint64_t br = (uint64_t)65536 * (F_CPU - 16 * baud) / F_CPU; + + HAL_GPIO_UART_TX_out(); + HAL_GPIO_UART_TX_pmuxen(HAL_GPIO_PMUX_C); + HAL_GPIO_UART_RX_in(); + HAL_GPIO_UART_RX_pmuxen(HAL_GPIO_PMUX_C); + + MCLK->APBCMASK.reg |= MCLK_APBCMASK_SERCOM3; + + GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN(0) | GCLK_PCHCTRL_CHEN; + while (0 == (GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg & GCLK_PCHCTRL_CHEN)); + + SERCOM3->USART.CTRLA.reg = + SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE(1/*USART_INT_CLK*/) | + SERCOM_USART_CTRLA_RXPO(0/*PAD0*/) | SERCOM_USART_CTRLA_TXPO(1/*PAD2*/); + + SERCOM3->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | + SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/); + + SERCOM3->USART.BAUD.reg = (uint16_t)br; + + SERCOM3->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE; } //----------------------------------------------------------------------------- -void irq_handler_tc3(void) -{ - if (TC3->COUNT16.INTFLAG.reg & TC_INTFLAG_MC(1)) - { - HAL_GPIO_LED_toggle(); - TC3->COUNT16.INTFLAG.reg = TC_INTFLAG_MC(1); - } +static void uart_putc(char c) { + while (!(SERCOM3->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE)); + SERCOM3->USART.DATA.reg = c; } //----------------------------------------------------------------------------- -static void timer_init(void) -{ - MCLK->APBCMASK.reg |= MCLK_APBCMASK_TC3; - - GCLK->PCHCTRL[TC3_GCLK_ID].reg = GCLK_PCHCTRL_GEN(0) | GCLK_PCHCTRL_CHEN; - while (0 == (GCLK->PCHCTRL[TC3_GCLK_ID].reg & GCLK_PCHCTRL_CHEN)); - - TC3->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | TC_CTRLA_PRESCALER(6/*DIV256*/) | - TC_CTRLA_PRESCSYNC_RESYNC; - - TC3->COUNT16.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ; - - TC3->COUNT16.COUNT.reg = 0; - - timer_set_period(PERIOD_SLOW); - - TC3->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE; - - TC3->COUNT16.INTENSET.reg = TC_INTENSET_MC(1); - NVIC_EnableIRQ(TC3_IRQn); +static void uart_puts(char *s) { + while (*s) uart_putc(*s++); } //----------------------------------------------------------------------------- -static void uart_init(uint32_t baud) -{ - uint64_t br = (uint64_t)65536 * (F_CPU - 16 * baud) / F_CPU; - - HAL_GPIO_UART_TX_out(); - HAL_GPIO_UART_TX_pmuxen(HAL_GPIO_PMUX_C); - HAL_GPIO_UART_RX_in(); - HAL_GPIO_UART_RX_pmuxen(HAL_GPIO_PMUX_C); - - MCLK->APBCMASK.reg |= MCLK_APBCMASK_SERCOM3; - - GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN(0) | GCLK_PCHCTRL_CHEN; - while (0 == (GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg & GCLK_PCHCTRL_CHEN)); - - SERCOM3->USART.CTRLA.reg = - SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE(1/*USART_INT_CLK*/) | - SERCOM_USART_CTRLA_RXPO(0/*PAD0*/) | SERCOM_USART_CTRLA_TXPO(1/*PAD2*/); - - SERCOM3->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | - SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/); - - SERCOM3->USART.BAUD.reg = (uint16_t)br; - - SERCOM3->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE; +static void sys_init(void) { + // Switch to 16MHz clock (disable prescaler) + OSCCTRL->OSC16MCTRL.reg = OSCCTRL_OSC16MCTRL_ENABLE | OSCCTRL_OSC16MCTRL_FSEL_16; + // Switch to the highest performance level + PM->INTFLAG.reg = PM_INTFLAG_PLRDY; + PM->PLCFG.reg = PM_PLCFG_PLSEL_PL2_Val; + while (!PM->INTFLAG.reg); } //----------------------------------------------------------------------------- -static void uart_putc(char c) -{ - while (!(SERCOM3->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE)); - SERCOM3->USART.DATA.reg = c; -} +int main(void) { + sys_init(); + uart_init(115200); + HAL_GPIO_LED_out(); + HAL_GPIO_LED_set(); -//----------------------------------------------------------------------------- -static void uart_puts(char *s) -{ - while (*s) - uart_putc(*s++); -} + uart_puts("\r\nHello, world!\r\n"); -//----------------------------------------------------------------------------- -static void sys_init(void) -{ - // Switch to 16MHz clock (disable prescaler) - OSCCTRL->OSC16MCTRL.reg = OSCCTRL_OSC16MCTRL_ENABLE | OSCCTRL_OSC16MCTRL_FSEL_16; - - // Switch to the highest performance level - PM->INTFLAG.reg = PM_INTFLAG_PLRDY; - PM->PLCFG.reg = PM_PLCFG_PLSEL_PL2_Val; - while (!PM->INTFLAG.reg); -} - -//----------------------------------------------------------------------------- -int main(void) -{ - uint32_t cnt = 0; - bool fast = false; - - sys_init(); - timer_init(); - uart_init(115200); - - uart_puts("\r\nHello, world!\r\n"); - - HAL_GPIO_LED_out(); - HAL_GPIO_LED_clr(); - - HAL_GPIO_BUTTON_in(); - HAL_GPIO_BUTTON_pullup(); - - while (1) - { - if (HAL_GPIO_BUTTON_read()) - cnt = 0; - else if (cnt < 5001) - cnt++; - - if (5000 == cnt) - { - fast = !fast; - timer_set_period(fast ? PERIOD_FAST : PERIOD_SLOW); - uart_putc('.'); + while (1) { + uart_putc('.'); } - } - return 0; + return 0; } diff --git a/Sensor Watch Starter Project/startup_saml22.c b/Sensor Watch Starter Project/startup_saml22.c index 4414b38..f498256 100755 --- a/Sensor Watch Starter Project/startup_saml22.c +++ b/Sensor Watch Starter Project/startup_saml22.c @@ -1,156 +1,225 @@ -/* - * Copyright (c) 2014-2017, Alex Taradov - * All rights reserved. +/** + * \file * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * \brief gcc starttup file for SAML22 * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ -//----------------------------------------------------------------------------- #include "saml22.h" -//----------------------------------------------------------------------------- -#define DUMMY __attribute__ ((weak, alias ("irq_handler_dummy"))) +/* Initialize segments */ +extern uint32_t _sfixed; +extern uint32_t _efixed; +extern uint32_t _etext; +extern uint32_t _srelocate; +extern uint32_t _erelocate; +extern uint32_t _szero; +extern uint32_t _ezero; +extern uint32_t _sstack; +extern uint32_t _estack; -//----------------------------------------------------------------------------- -void irq_handler_reset(void); -DUMMY void irq_handler_nmi(void); -DUMMY void irq_handler_hard_fault(void); -DUMMY void irq_handler_sv_call(void); -DUMMY void irq_handler_pend_sv(void); -DUMMY void irq_handler_sys_tick(void); +/** \cond DOXYGEN_SHOULD_SKIP_THIS */ +int main(void); +/** \endcond */ -DUMMY void irq_handler_system(void); -DUMMY void irq_handler_wdt(void); -DUMMY void irq_handler_rtc(void); -DUMMY void irq_handler_eic(void); -DUMMY void irq_handler_freqm(void); -DUMMY void irq_handler_usb(void); -DUMMY void irq_handler_nvmctrl(void); -DUMMY void irq_handler_dmac(void); -DUMMY void irq_handler_evsys(void); -DUMMY void irq_handler_sercom0(void); -DUMMY void irq_handler_sercom1(void); -DUMMY void irq_handler_sercom2(void); -DUMMY void irq_handler_sercom3(void); -DUMMY void irq_handler_sercom4(void); -DUMMY void irq_handler_sercom5(void); -DUMMY void irq_handler_tcc0(void); -DUMMY void irq_handler_tc0(void); -DUMMY void irq_handler_tc1(void); -DUMMY void irq_handler_tc2(void); -DUMMY void irq_handler_tc3(void); -DUMMY void irq_handler_adc(void); -DUMMY void irq_handler_ac(void); -DUMMY void irq_handler_ptc(void); -DUMMY void irq_handler_slcd(void); -DUMMY void irq_handler_aes(void); -DUMMY void irq_handler_trng(void); +void __libc_init_array(void); -extern int main(void); +/* Default empty handler */ +void Dummy_Handler(void); -extern void _stack_top(void); -extern unsigned int _etext; -extern unsigned int _data; -extern unsigned int _edata; -extern unsigned int _bss; -extern unsigned int _ebss; +/* Cortex-M0+ core handlers */ +void NonMaskableInt_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void HardFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SVCall_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PendSV_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SysTick_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -//----------------------------------------------------------------------------- -__attribute__ ((used, section(".vectors"))) -void (* const vectors[])(void) = -{ - &_stack_top, // 0 - Initial Stack Pointer Value +/* Peripherals handlers */ +void SYSTEM_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); /* MCLK, OSC32KCTRL, OSCCTRL, PAC, PM, SUPC, TAL */ +void WDT_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void RTC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void FREQM_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#ifdef ID_USB +void USB_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +void NVMCTRL_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DMAC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EVSYS_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#ifdef ID_SERCOM3 +void SERCOM3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +#ifdef ID_SERCOM4 +void SERCOM4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +#ifdef ID_SERCOM5 +void SERCOM5_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +void TCC0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void ADC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void AC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#ifdef ID_PTC +void PTC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +void SLCD_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#ifdef ID_AES +void AES_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +#ifdef ID_TRNG +void TRNG_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif - // Cortex-M0+ handlers - irq_handler_reset, // 1 - Reset - irq_handler_nmi, // 2 - NMI - irq_handler_hard_fault, // 3 - Hard Fault - 0, // 4 - Reserved - 0, // 5 - Reserved - 0, // 6 - Reserved - 0, // 7 - Reserved - 0, // 8 - Reserved - 0, // 9 - Reserved - 0, // 10 - Reserved - irq_handler_sv_call, // 11 - SVCall - 0, // 12 - Reserved - 0, // 13 - Reserved - irq_handler_pend_sv, // 14 - PendSV - irq_handler_sys_tick, // 15 - SysTick +/* Exception Table */ +__attribute__ ((section(".vectors"))) +const DeviceVectors exception_table = { - // Peripheral handlers - irq_handler_system, // 0 - System Controller - irq_handler_wdt, // 1 - Watchdog Timer - irq_handler_rtc, // 2 - Real-Time Counter - irq_handler_eic, // 3 - External Interrupt Controller - irq_handler_freqm, // 4 - External Interrupt Controller - irq_handler_usb, // 5 - Universal Serial Bus Controller - irq_handler_nvmctrl, // 6 - Non-Volatile Memory Controller - irq_handler_dmac, // 7 - Direct Memory Access Controller - irq_handler_evsys, // 8 - Event System - irq_handler_sercom0, // 9 - Serial Communication Interface 0 - irq_handler_sercom1, // 10 - Serial Communication Interface 1 - irq_handler_sercom2, // 11 - Serial Communication Interface 2 - irq_handler_sercom3, // 12 - Serial Communication Interface 3 - irq_handler_sercom4, // 13 - Serial Communication Interface 4 - irq_handler_sercom5, // 14 - Serial Communication Interface 5 - irq_handler_tcc0, // 15 - Timer/Counter for Control 0 - irq_handler_tc0, // 16 - Timer/Counter 0 - irq_handler_tc1, // 17 - Timer/Counter 1 - irq_handler_tc2, // 18 - Timer/Counter 2 - irq_handler_tc3, // 19 - Timer/Counter 3 - irq_handler_adc, // 20 - Analog-to-Digital Converter - irq_handler_ac, // 21 - Analog Comparator - irq_handler_ptc, // 22 - Peripheral Touch Controller - irq_handler_slcd, // 23 - Segment Liquid Crystal Display Controller - irq_handler_aes, // 24 - Advanced Encryption Standard - irq_handler_trng, // 25 - True Random Number Generator + /* Configure Initial Stack Pointer, using linker-generated symbols */ + .pvStack = (void*) (&_estack), + + .pfnReset_Handler = (void*) Reset_Handler, + .pfnNonMaskableInt_Handler = (void*) NonMaskableInt_Handler, + .pfnHardFault_Handler = (void*) HardFault_Handler, + .pvReservedM12 = (void*) (0UL), /* Reserved */ + .pvReservedM11 = (void*) (0UL), /* Reserved */ + .pvReservedM10 = (void*) (0UL), /* Reserved */ + .pvReservedM9 = (void*) (0UL), /* Reserved */ + .pvReservedM8 = (void*) (0UL), /* Reserved */ + .pvReservedM7 = (void*) (0UL), /* Reserved */ + .pvReservedM6 = (void*) (0UL), /* Reserved */ + .pfnSVCall_Handler = (void*) SVCall_Handler, + .pvReservedM4 = (void*) (0UL), /* Reserved */ + .pvReservedM3 = (void*) (0UL), /* Reserved */ + .pfnPendSV_Handler = (void*) PendSV_Handler, + .pfnSysTick_Handler = (void*) SysTick_Handler, + + /* Configurable interrupts */ + .pfnSYSTEM_Handler = (void*) SYSTEM_Handler, /* 0 Main Clock, 32k Oscillators Control, Oscillators Control, Peripheral Access Controller, Power Manager, Supply Controller, Trigger Allocator */ + .pfnWDT_Handler = (void*) WDT_Handler, /* 1 Watchdog Timer */ + .pfnRTC_Handler = (void*) RTC_Handler, /* 2 Real-Time Counter */ + .pfnEIC_Handler = (void*) EIC_Handler, /* 3 External Interrupt Controller */ + .pfnFREQM_Handler = (void*) FREQM_Handler, /* 4 Frequency Meter */ +#ifdef ID_USB + .pfnUSB_Handler = (void*) USB_Handler, /* 5 Universal Serial Bus */ +#else + .pvReserved5 = (void*) (0UL), /* 5 Reserved */ +#endif + .pfnNVMCTRL_Handler = (void*) NVMCTRL_Handler, /* 6 Non-Volatile Memory Controller */ + .pfnDMAC_Handler = (void*) DMAC_Handler, /* 7 Direct Memory Access Controller */ + .pfnEVSYS_Handler = (void*) EVSYS_Handler, /* 8 Event System Interface */ + .pfnSERCOM0_Handler = (void*) SERCOM0_Handler, /* 9 Serial Communication Interface 0 */ + .pfnSERCOM1_Handler = (void*) SERCOM1_Handler, /* 10 Serial Communication Interface 1 */ + .pfnSERCOM2_Handler = (void*) SERCOM2_Handler, /* 11 Serial Communication Interface 2 */ +#ifdef ID_SERCOM3 + .pfnSERCOM3_Handler = (void*) SERCOM3_Handler, /* 12 Serial Communication Interface 3 */ +#else + .pvReserved12 = (void*) (0UL), /* 12 Reserved */ +#endif +#ifdef ID_SERCOM4 + .pfnSERCOM4_Handler = (void*) SERCOM4_Handler, /* 13 Serial Communication Interface 4 */ +#else + .pvReserved13 = (void*) (0UL), /* 13 Reserved */ +#endif +#ifdef ID_SERCOM5 + .pfnSERCOM5_Handler = (void*) SERCOM5_Handler, /* 14 Serial Communication Interface 5 */ +#else + .pvReserved14 = (void*) (0UL), /* 14 Reserved */ +#endif + .pfnTCC0_Handler = (void*) TCC0_Handler, /* 15 Timer Counter Control */ + .pfnTC0_Handler = (void*) TC0_Handler, /* 16 Basic Timer Counter 0 */ + .pfnTC1_Handler = (void*) TC1_Handler, /* 17 Basic Timer Counter 1 */ + .pfnTC2_Handler = (void*) TC2_Handler, /* 18 Basic Timer Counter 2 */ + .pfnTC3_Handler = (void*) TC3_Handler, /* 19 Basic Timer Counter 3 */ + .pfnADC_Handler = (void*) ADC_Handler, /* 20 Analog Digital Converter */ + .pfnAC_Handler = (void*) AC_Handler, /* 21 Analog Comparators */ +#ifdef ID_PTC + .pfnPTC_Handler = (void*) PTC_Handler, /* 22 Peripheral Touch Controller */ +#else + .pvReserved22 = (void*) (0UL), /* 22 Reserved */ +#endif + .pfnSLCD_Handler = (void*) SLCD_Handler, /* 23 Segment Liquid Crystal Display Controller */ +#ifdef ID_AES + .pfnAES_Handler = (void*) AES_Handler, /* 24 Advanced Encryption Standard */ +#else + .pvReserved24 = (void*) (0UL), /* 24 Reserved */ +#endif +#ifdef ID_TRNG + .pfnTRNG_Handler = (void*) TRNG_Handler /* 25 True Random Generator */ +#else + .pvReserved25 = (void*) (0UL) /* 25 Reserved */ +#endif }; -//----------------------------------------------------------------------------- -void irq_handler_reset(void) +/** + * \brief This is the code that gets called on processor reset. + * To initialize the device, and call the main() routine. + */ +void Reset_Handler(void) { - unsigned int *src, *dst; + uint32_t *pSrc, *pDest; - src = &_etext; - dst = &_data; - while (dst < &_edata) - *dst++ = *src++; + /* Initialize the relocate segment */ + pSrc = &_etext; + pDest = &_srelocate; - dst = &_bss; - while (dst < &_ebss) - *dst++ = 0; + if (pSrc != pDest) { + for (; pDest < &_erelocate;) { + *pDest++ = *pSrc++; + } + } - SCB->VTOR = (uint32_t)vectors; + /* Clear the zero segment */ + for (pDest = &_szero; pDest < &_ezero;) { + *pDest++ = 0; + } - main(); + /* Set the vector table base address */ + pSrc = (uint32_t *) & _sfixed; + SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk); - while (1); + /* Initialize the C library */ + __libc_init_array(); + + /* Branch to main function */ + main(); + + /* Infinite loop */ + while (1); } -//----------------------------------------------------------------------------- -void irq_handler_dummy(void) +/** + * \brief Default interrupt handler for unused IRQs. + */ +void Dummy_Handler(void) { - while (1); + while (1) { + } }