diff --git a/cpu/sam0_common/Makefile.include b/cpu/sam0_common/Makefile.include index dd1db86930..db869d12e1 100644 --- a/cpu/sam0_common/Makefile.include +++ b/cpu/sam0_common/Makefile.include @@ -10,6 +10,10 @@ ifneq (,$(filter saml10e16a saml11e16a,$(CPU_MODEL))) ROM_LEN ?= 64K RAM_LEN ?= 16K endif +ifneq (,$(filter samd51j20a same54p20a,$(CPU_MODEL))) + ROM_LEN ?= 1024K + RAM_LEN ?= 256K +endif ROM_START_ADDR ?= 0x00000000 RAM_START_ADDR ?= 0x20000000 diff --git a/cpu/sam0_common/include/cpu_conf.h b/cpu/sam0_common/include/cpu_conf.h index 563eccda45..a35a866042 100644 --- a/cpu/sam0_common/include/cpu_conf.h +++ b/cpu/sam0_common/include/cpu_conf.h @@ -24,6 +24,8 @@ #include "cpu_conf_common.h" #if defined(CPU_SAML1X) #include "vendor/sam23.h" +#elif defined(CPU_SAMD5X) +#include "vendor/samd5x.h" #else #include "vendor/sam0.h" #endif @@ -52,11 +54,22 @@ extern "C" { * @{ */ /* a flashpage in RIOT is mapped to a flash row on the SAM0s */ -#define FLASHPAGE_SIZE (256U) +#if defined(NVMCTRL_ROW_SIZE) +#define FLASHPAGE_SIZE (NVMCTRL_ROW_SIZE) +#elif defined(NVMCTRL_BLOCK_SIZE) +#define FLASHPAGE_SIZE (NVMCTRL_BLOCK_SIZE) +#elif defined(NVMCTRL_PAGE_SIZE) +/* saml1x: The NVM is organized into rows, where each row contains four pages, +as shown in the NVM Row Organization figure. */ +#define FLASHPAGE_SIZE (4 * NVMCTRL_PAGE_SIZE) +#else +#error "Unsupported Device" +#endif + /* one SAM0 row contains 4 SAM0 pages, so 4 SAM0 pages contain * the amount of a RIOT flashpage */ -#define FLASHPAGE_PAGES_PER_ROW (4) +#define FLASHPAGE_PAGES_PER_ROW (FLASHPAGE_SIZE/FLASH_PAGE_SIZE) /* number of RIOT flashpages on device */ #define FLASHPAGE_NUMOF (FLASH_NB_OF_PAGES / FLASHPAGE_PAGES_PER_ROW) /* The minimum block size which can be written is 16B. However, the erase diff --git a/cpu/sam0_common/include/periph_cpu_common.h b/cpu/sam0_common/include/periph_cpu_common.h index 8039b83109..d47bf93021 100644 --- a/cpu/sam0_common/include/periph_cpu_common.h +++ b/cpu/sam0_common/include/periph_cpu_common.h @@ -82,6 +82,7 @@ enum { PA = 0, /**< port A */ PB = 1, /**< port B */ PC = 2, /**< port C */ + PD = 3, /**< port D */ }; /** @@ -368,11 +369,20 @@ static inline int sercom_id(const void *sercom) */ static inline void sercom_clk_en(void *sercom) { + const uint8_t id = sercom_id(sercom); #if defined(CPU_FAM_SAMD21) - PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << sercom_id(sercom)); + PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << id); +#elif defined (CPU_FAM_SAMD5X) + if (id < 2) { + MCLK->APBAMASK.reg |= (1 << (id + 12)); + } else if (id < 4) { + MCLK->APBBMASK.reg |= (1 << (id + 7)); + } else { + MCLK->APBDMASK.reg |= (1 << (id - 4)); + } #else - if (sercom_id(sercom) < 5) { - MCLK->APBCMASK.reg |= (MCLK_APBCMASK_SERCOM0 << sercom_id(sercom)); + if (id < 5) { + MCLK->APBCMASK.reg |= (MCLK_APBCMASK_SERCOM0 << id); } #if defined(CPU_FAM_SAML21) else { @@ -389,11 +399,20 @@ static inline void sercom_clk_en(void *sercom) */ static inline void sercom_clk_dis(void *sercom) { + const uint8_t id = sercom_id(sercom); #if defined(CPU_FAM_SAMD21) - PM->APBCMASK.reg &= ~(PM_APBCMASK_SERCOM0 << sercom_id(sercom)); + PM->APBCMASK.reg &= ~(PM_APBCMASK_SERCOM0 << id); +#elif defined (CPU_FAM_SAMD5X) + if (id < 2) { + MCLK->APBAMASK.reg &= ~(1 << (id + 12)); + } else if (id < 4) { + MCLK->APBBMASK.reg &= ~(1 << (id + 7)); + } else { + MCLK->APBDMASK.reg &= ~(1 << (id - 4)); + } #else - if (sercom_id(sercom) < 5) { - MCLK->APBCMASK.reg &= ~(MCLK_APBCMASK_SERCOM0 << sercom_id(sercom)); + if (id < 5) { + MCLK->APBCMASK.reg &= ~(MCLK_APBCMASK_SERCOM0 << id); } #if defined (CPU_FAM_SAML21) else { @@ -403,6 +422,17 @@ static inline void sercom_clk_dis(void *sercom) #endif } +#ifdef CPU_FAM_SAMD5X +static inline uint8_t _sercom_gclk_id_core(uint8_t sercom_id) { + if (sercom_id < 2) + return sercom_id + 7; + if (sercom_id < 4) + return sercom_id + 21; + else + return sercom_id + 30; +} +#endif + /** * @brief Configure generator clock for given SERCOM device * @@ -411,19 +441,20 @@ static inline void sercom_clk_dis(void *sercom) */ static inline void sercom_set_gen(void *sercom, uint32_t gclk) { + const uint8_t id = sercom_id(sercom); #if defined(CPU_FAM_SAMD21) GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | gclk | - (SERCOM0_GCLK_ID_CORE + sercom_id(sercom))); + (SERCOM0_GCLK_ID_CORE + id)); while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} +#elif defined(CPU_FAM_SAMD5X) + GCLK->PCHCTRL[_sercom_gclk_id_core(id)].reg = (GCLK_PCHCTRL_CHEN | gclk); #else - if (sercom_id(sercom) < 5) { - GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE + sercom_id(sercom)].reg = - (GCLK_PCHCTRL_CHEN | gclk); + if (id < 5) { + GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE + id].reg = (GCLK_PCHCTRL_CHEN | gclk); } #if defined(CPU_FAM_SAML21) else { - GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = - (GCLK_PCHCTRL_CHEN | gclk); + GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = (GCLK_PCHCTRL_CHEN | gclk); } #endif /* CPU_FAM_SAML21 */ #endif diff --git a/cpu/sam0_common/periph/cpuid.c b/cpu/sam0_common/periph/cpuid.c index 3423f67072..50dfdf280a 100644 --- a/cpu/sam0_common/periph/cpuid.c +++ b/cpu/sam0_common/periph/cpuid.c @@ -25,11 +25,17 @@ #include "periph/cpuid.h" +#ifdef CPU_SAMD5X +#define WORD0 (*(volatile uint32_t *)0x008061FC) +#define WORD1 (*(volatile uint32_t *)0x00806010) +#define WORD2 (*(volatile uint32_t *)0x00806014) +#define WORD3 (*(volatile uint32_t *)0x00806018) +#else #define WORD0 (*(volatile uint32_t *)0x0080A00C) #define WORD1 (*(volatile uint32_t *)0x0080A040) #define WORD2 (*(volatile uint32_t *)0x0080A044) #define WORD3 (*(volatile uint32_t *)0x0080A048) - +#endif void cpuid_get(void *id) { diff --git a/cpu/sam0_common/periph/flashpage.c b/cpu/sam0_common/periph/flashpage.c index 43be85fdd3..d82df64b50 100644 --- a/cpu/sam0_common/periph/flashpage.c +++ b/cpu/sam0_common/periph/flashpage.c @@ -47,7 +47,7 @@ static inline void wait_nvm_is_ready(void) __attribute__((always_inline)); static inline void wait_nvm_is_ready(void) { -#ifdef CPU_SAML1X +#if defined(CPU_SAML1X) || defined(CPU_SAMD5X) while (!_NVMCTRL->STATUS.bit.READY) {} #else while (!_NVMCTRL->INTFLAG.bit.READY) {} @@ -57,7 +57,7 @@ static inline void wait_nvm_is_ready(void) static void _unlock(void) { /* remove peripheral access lock for the NVMCTRL peripheral */ -#if defined(CPU_FAM_SAML21) || defined(CPU_SAML1X) +#ifdef REG_PAC_WRCTRL PAC->WRCTRL.reg = (PAC_WRCTRL_KEY_CLR | ID_NVMCTRL); #else if (PAC1->WPSET.reg & NVMCTRL_PAC_BIT) { @@ -69,7 +69,7 @@ static void _unlock(void) static void _lock(void) { /* put peripheral access lock for the NVMCTRL peripheral */ -#if defined(CPU_FAM_SAML21) || defined(CPU_SAML1X) +#ifdef REG_PAC_WRCTRL PAC->WRCTRL.reg = (PAC_WRCTRL_KEY_SET | ID_NVMCTRL); #else if (PAC1->WPCLR.reg & NVMCTRL_PAC_BIT) { @@ -113,7 +113,11 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len) len /= 4; _unlock(); +#ifdef NVMCTRL_CTRLB_CMDEX_KEY + _NVMCTRL->CTRLB.reg = (NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_PBC); +#else _NVMCTRL->CTRLA.reg = (NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_PBC); +#endif wait_nvm_is_ready(); for (unsigned i = 0; i < len; i++) { *dst++ = *data_addr++; @@ -128,7 +132,11 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len) #endif } else { #endif +#ifdef NVMCTRL_CTRLB_CMDEX_KEY + _NVMCTRL->CTRLB.reg = (NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_WP); +#else _NVMCTRL->CTRLA.reg = (NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_WP); +#endif #ifdef FLASHPAGE_RWWEE_NUMOF } #endif @@ -156,7 +164,7 @@ void flashpage_write(int page, const void *data) /* erase given page (the ADDR register uses 16-bit addresses) */ _unlock(); -#ifdef CPU_SAML1X +#if defined(CPU_SAML1X) || defined(CPU_SAMD5X) /* Ensure address alignment */ _NVMCTRL->ADDR.reg = (((uint32_t)page_addr) & 0xfffffffe); #else @@ -172,7 +180,11 @@ void flashpage_write(int page, const void *data) #endif } else { #endif +#ifdef NVMCTRL_CTRLB_CMDEX_KEY + _NVMCTRL->CTRLB.reg = (NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_EB); +#else _NVMCTRL->CTRLA.reg = (NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_ER); +#endif #ifdef FLASHPAGE_RWWEE_NUMOF } #endif diff --git a/cpu/sam0_common/periph/gpio.c b/cpu/sam0_common/periph/gpio.c index e88d4f8fe5..874ceb7018 100644 --- a/cpu/sam0_common/periph/gpio.c +++ b/cpu/sam0_common/periph/gpio.c @@ -205,6 +205,8 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, #ifdef CPU_SAML1X /* EXTI[4..7] are binded to EIC_OTHER_IRQn */ NVIC_EnableIRQ((exti > 3 )? EIC_OTHER_IRQn : (EIC_0_IRQn + exti)); +#elif defined(CPU_SAMD5X) + NVIC_EnableIRQ(EIC_0_IRQn + exti); #else NVIC_EnableIRQ(EIC_IRQn); #endif @@ -253,31 +255,34 @@ void isr_eic(void) cortexm_isr_end(); } -#ifdef CPU_SAML1X -void isr_eic0(void) -{ - isr_eic(); +#if defined(CPU_SAML1X) || defined(CPU_SAMD5X) + +#define ISR_EICn(n) \ +void isr_eic ## n (void) \ +{ \ + isr_eic(); \ } -void isr_eic1(void) -{ - isr_eic(); -} - -void isr_eic2(void) -{ - isr_eic(); -} - -void isr_eic3(void) -{ - isr_eic(); -} - -void isr_eic_other(void) -{ - isr_eic(); -} +ISR_EICn(0) +ISR_EICn(1) +ISR_EICn(2) +ISR_EICn(3) +#if defined(CPU_SAMD5X) +ISR_EICn(4) +ISR_EICn(5) +ISR_EICn(6) +ISR_EICn(7) +ISR_EICn(8) +ISR_EICn(9) +ISR_EICn(10) +ISR_EICn(11) +ISR_EICn(12) +ISR_EICn(13) +ISR_EICn(14) +ISR_EICn(15) +#else +ISR_EICn(_other) #endif /* CPU_SAML1X */ +#endif /* CPU_SAML1X || CPU_SAMD5X */ #endif /* MODULE_PERIPH_GPIO_IRQ */ diff --git a/cpu/sam0_common/periph/i2c.c b/cpu/sam0_common/periph/i2c.c index 806301e0a2..e7c62470b1 100644 --- a/cpu/sam0_common/periph/i2c.c +++ b/cpu/sam0_common/periph/i2c.c @@ -44,7 +44,7 @@ #define BUSSTATE_OWNER SERCOM_I2CM_STATUS_BUSSTATE(2) #define BUSSTATE_BUSY SERCOM_I2CM_STATUS_BUSSTATE(3) -#if defined(CPU_SAML21) || defined(CPU_SAML1X) +#if defined(CPU_SAML21) || defined(CPU_SAML1X) || defined(CPU_SAMD5X) #define SERCOM_I2CM_CTRLA_MODE_I2C_MASTER SERCOM_I2CM_CTRLA_MODE(5) #endif diff --git a/cpu/sam0_common/periph/uart.c b/cpu/sam0_common/periph/uart.c index 7ebf2c0ca2..68de304485 100644 --- a/cpu/sam0_common/periph/uart.c +++ b/cpu/sam0_common/periph/uart.c @@ -99,7 +99,7 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) if ((rx_cb) && (uart_config[uart].rx_pin != GPIO_UNDEF)) { uart_ctx[uart].rx_cb = rx_cb; uart_ctx[uart].arg = arg; -#if defined (CPU_SAML1X) +#if defined (CPU_SAML1X) || defined (CPU_SAMD5X) NVIC_EnableIRQ(SERCOM0_2_IRQn + (sercom_id(dev(uart)) * 4)); #else NVIC_EnableIRQ(SERCOM0_IRQn + sercom_id(dev(uart))); diff --git a/cpu/sam0_common/periph/usbdev.c b/cpu/sam0_common/periph/usbdev.c index 649c0503a0..ae0ea271d8 100644 --- a/cpu/sam0_common/periph/usbdev.c +++ b/cpu/sam0_common/periph/usbdev.c @@ -229,17 +229,24 @@ static bool _syncbusy_swrst(sam0_common_usb_t *dev) static inline void _poweron(void) { -#if defined(CPU_FAM_SAMD21) +#if defined(MCLK) + MCLK->AHBMASK.reg |= MCLK_AHBMASK_USB; + MCLK->APBBMASK.reg |= MCLK_APBBMASK_USB; +#else PM->AHBMASK.reg |= PM_AHBMASK_USB; PM->APBBMASK.reg |= PM_APBBMASK_USB; +#endif + +#if defined(CPU_FAM_SAMD21) GCLK->CLKCTRL.reg = (uint32_t)(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | (GCLK_CLKCTRL_ID(USB_GCLK_ID))); #elif defined(CPU_FAM_SAML21) - MCLK->AHBMASK.reg |= MCLK_AHBMASK_USB; - MCLK->APBBMASK.reg |= MCLK_APBBMASK_USB; GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK0; +#elif defined(CPU_FAM_SAMD5X) + GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | + GCLK_PCHCTRL_GEN_GCLK6; #else #error "Unknown CPU family for sam0 common usbdev driver" #endif @@ -356,7 +363,14 @@ static void _usbdev_init(usbdev_t *dev) _block_pm(); usbdev->usbdev.cb(&usbdev->usbdev, USBDEV_EVENT_HOST_CONNECT); /* Interrupt configuration */ +#ifdef CPU_FAM_SAMD5X + NVIC_EnableIRQ(USB_0_IRQn); + NVIC_EnableIRQ(USB_1_IRQn); + NVIC_EnableIRQ(USB_2_IRQn); + NVIC_EnableIRQ(USB_3_IRQn); +#else NVIC_EnableIRQ(USB_IRQn); +#endif } static void usb_attach(sam0_common_usb_t *dev) @@ -504,6 +518,24 @@ void isr_usb(void) cortexm_isr_end(); } +void isr_usb0(void) +{ + isr_usb(); +} + +void isr_usb1(void) +{ + isr_usb(); +} +void isr_usb2(void) +{ + isr_usb(); +} +void isr_usb3(void) +{ + isr_usb(); +} + static void _usbdev_esr(usbdev_t *dev) { sam0_common_usb_t *usbdev = (sam0_common_usb_t *)dev; diff --git a/cpu/samd5x/Makefile b/cpu/samd5x/Makefile new file mode 100644 index 0000000000..8794dfbc47 --- /dev/null +++ b/cpu/samd5x/Makefile @@ -0,0 +1,10 @@ +# define the module that is build +MODULE = cpu + +# add a list of subdirectories, that should also be build +DIRS = periph $(RIOTCPU)/cortexm_common $(RIOTCPU)/sam0_common + +# (file triggers compiler bug. see #5775) +SRC_NOLTO += vectors.c + +include $(RIOTBASE)/Makefile.base diff --git a/cpu/samd5x/Makefile.features b/cpu/samd5x/Makefile.features new file mode 100644 index 0000000000..52f4483551 --- /dev/null +++ b/cpu/samd5x/Makefile.features @@ -0,0 +1 @@ +include $(RIOTCPU)/sam0_common/Makefile.features diff --git a/cpu/samd5x/Makefile.include b/cpu/samd5x/Makefile.include new file mode 100644 index 0000000000..afb1ffd149 --- /dev/null +++ b/cpu/samd5x/Makefile.include @@ -0,0 +1,12 @@ +export CPU_ARCH = cortex-m4f +export CPU_FAM = samd5x + +# Slot size is determined by "((total_flash_size - RIOTBOOT_LEN) / 2)". +# If RIOTBOOT_LEN uses an uneven number of flashpages, the remainder of the +# flash cannot be divided by two slots while staying FLASHPAGE_SIZE aligned. +RIOTBOOT_LEN ?= 0x2000 + +USEMODULE += pm_layered + +include $(RIOTCPU)/sam0_common/Makefile.include +include $(RIOTMAKE)/arch/cortexm.inc.mk diff --git a/cpu/samd5x/cpu.c b/cpu/samd5x/cpu.c new file mode 100644 index 0000000000..551c158dc6 --- /dev/null +++ b/cpu/samd5x/cpu.c @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2019 ML!PA Consulting GmbH + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_samd5x + * @{ + * + * @file cpu.c + * @brief Implementation of the CPU initialization for Microchip SAMD5x/SAME5x MCUs + * + * @author Benjamin Valentin + * @} + */ + +#include "cpu.h" +#include "periph_conf.h" +#include "periph/init.h" + +static void xosc32k_init(void) +{ + OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE | OSC32KCTRL_XOSC32K_XTALEN + | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_RUNSTDBY + | OSC32KCTRL_XOSC32K_STARTUP(7); + + while (!OSC32KCTRL->STATUS.bit.XOSC32KRDY) {} +} + +#ifdef MODULE_PERIPH_USBDEV +static void dfll_init(void) +{ + uint32_t reg = OSCCTRL_DFLLCTRLB_QLDIS +#ifdef OSCCTRL_DFLLCTRLB_WAITLOCK + | OSCCTRL_DFLLCTRLB_WAITLOCK +#endif + ; + + OSCCTRL->DFLLCTRLB.reg = reg; + OSCCTRL->DFLLCTRLA.reg = OSCCTRL_DFLLCTRLA_ENABLE; +} +#endif + +static void fdpll0_init(uint32_t f_cpu) +{ + const uint32_t LDR = ((f_cpu << 5) / 32768); + + GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = GCLK_PCHCTRL_GEN(1) | GCLK_PCHCTRL_CHEN; + + OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(LDR & 0x1F) + | OSCCTRL_DPLLRATIO_LDR((LDR >> 5) - 1); + + OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK + | OSCCTRL_DPLLCTRLB_WUF + | OSCCTRL_DPLLCTRLB_LBYPASS; + + OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE; + + while (!(OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY && + OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK)) {} +} + +static void gclk_connect(uint8_t id, uint8_t src, uint32_t flags) { + GCLK->GENCTRL[id].reg = GCLK_GENCTRL_SRC(src) | GCLK_GENCTRL_GENEN | flags | GCLK_GENCTRL_IDC; +} + +/** + * @brief Initialize the CPU, set IRQ priorities, clocks + */ +void cpu_init(void) +{ + /* initialize the Cortex-M core */ + cortexm_init(); + + /* turn on only needed APB peripherals */ + MCLK->APBAMASK.reg = MCLK_APBAMASK_MCLK + | MCLK_APBAMASK_OSCCTRL + | MCLK_APBAMASK_OSC32KCTRL + | MCLK_APBAMASK_GCLK +#ifdef MODULE_PERIPH_GPIO_IRQ + | MCLK_APBAMASK_EIC +#endif + ; +#ifdef MODULE_PERIPH_GPIO + MCLK->APBBMASK.reg = MCLK_APBBMASK_PORT; +#endif + + /* enable the Cortex M Cache Controller */ + CMCC->CTRL.bit.CEN = 1; + + /* Software reset the GCLK module to ensure it is re-initialized correctly */ + GCLK->CTRLA.reg = GCLK_CTRLA_SWRST; + while (GCLK->CTRLA.reg & GCLK_CTRLA_SWRST) {} + while (GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_SWRST) {} + + xosc32k_init(); + gclk_connect(1, GCLK_SOURCE_XOSC32K, 0); + + fdpll0_init(CLOCK_CORECLOCK); + + /* main clock */ + gclk_connect(0, GCLK_SOURCE_DPLL0, 0); + + /* clock used by xtimer */ + gclk_connect(5, GCLK_SOURCE_DPLL0, GCLK_GENCTRL_DIV(CLOCK_CORECLOCK / 8000000)); + +#ifdef MODULE_PERIPH_USBDEV + dfll_init(); + gclk_connect(6, GCLK_SOURCE_DFLL, 0); +#endif + + while (GCLK->SYNCBUSY.reg) {} + +#ifdef MODULE_PERIPH_PM + /* enable power managemet module */ + MCLK->APBAMASK.reg |= MCLK_APBAMASK_PM; +#endif +#ifdef MODULE_PERIPH_FLASHPAGE + MCLK->APBBMASK.reg |= MCLK_APBBMASK_NVMCTRL; +#endif + + /* trigger static peripheral initialization */ + periph_init(); +} diff --git a/cpu/samd5x/doc.txt b/cpu/samd5x/doc.txt new file mode 100644 index 0000000000..452cc8b73a --- /dev/null +++ b/cpu/samd5x/doc.txt @@ -0,0 +1,9 @@ +/** + * @defgroup cpu_samd5x Microchip SAMD5x/SAME5x + * @ingroup cpu + * @brief Microchip SAMD5x/SAME5x Cortex-M4F MCU specific implementation. + * + * This module contains Microchip SAMD5x/SAME5x specific code and definition. + * + * @see cpu_sam0_common + */ diff --git a/cpu/samd5x/include/periph_cpu.h b/cpu/samd5x/include/periph_cpu.h new file mode 100644 index 0000000000..544ade187b --- /dev/null +++ b/cpu/samd5x/include/periph_cpu.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2019 ML!PA Consulting GmbH + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_samd5x + * @brief CPU specific definitions for internal peripheral handling + * @{ + * + * @file + * @brief CPU specific definitions for internal peripheral handling + * + * @author Benjamin Valentin + */ + +#ifndef PERIPH_CPU_H +#define PERIPH_CPU_H + +#include + +#include "periph_cpu_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Mapping of pins to EXTI lines, -1 means not EXTI possible + */ +static const int8_t exti_config[4][32] = { +#ifdef CPU_MODEL_SAMD51J20A + { 0, 1, 2, 3, 4, 5, 6, 7, -1, 9, 10, 11, 12, 13, 14, 15, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, 11, -1, -1, 14, 15 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 1, -1, -1, -1, -1, 6, 7, -1, -1, -1, -1, -1, -1, 14, 15 }, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +#elif CPU_MODEL_SAME54P20A + { 0, 1, 2, 3, 4, 5, 6, 7, -1, 9, 10, 11, 12, 13, 14, 15, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, 11, -1, -1, 14, 15 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 14, 15 }, + { 0, 1, 2, 3, 4, 5, 6, 9, -1, -1, 10, 11, 12, 13, 14, 15, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, 14, 15 }, + { 0, 1, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, -1, -1, -1, + -1, -1, -1, -1, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } +#else + #error Please define a proper CPU_MODEL. +#endif +}; + +/** + * @brief Override SPI hardware chip select macro + * + * As of now, we do not support HW CS, so we always set it to a fixed value + */ +#define SPI_HWCS(x) (UINT_MAX - 1) + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CPU_H */ +/** @} */ diff --git a/cpu/samd5x/periph/Makefile b/cpu/samd5x/periph/Makefile new file mode 100644 index 0000000000..a36df249ac --- /dev/null +++ b/cpu/samd5x/periph/Makefile @@ -0,0 +1 @@ +include $(RIOTMAKE)/periph.mk diff --git a/cpu/samd5x/periph/pm.c b/cpu/samd5x/periph/pm.c new file mode 100644 index 0000000000..f0ef4ea23e --- /dev/null +++ b/cpu/samd5x/periph/pm.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2019 ML!PA Consulting GmbH + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_samd5x + * @ingroup drivers_periph_pm + * @{ + * + * @file + * @brief Implementation of the kernels power management interface + * + * @author Benjamin Valentin + * + * @} + */ + +#include "periph/pm.h" + +#define ENABLE_DEBUG (0) + +#if ENABLE_DEBUG +#define DEBUG(s) puts(s) +#else +#define DEBUG(s) +#endif + +void pm_set(unsigned mode) +{ + bool deep = 0; + uint32_t _mode; + + switch (mode) { + case 0: + DEBUG("pm_set(): setting BACKUP mode."); + _mode = PM_SLEEPCFG_SLEEPMODE_BACKUP; + deep = 1; + break; + case 1: + DEBUG("pm_set(): setting HIBERNATE mode."); + _mode = PM_SLEEPCFG_SLEEPMODE_HIBERNATE; + deep = 1; + break; + case 2: + DEBUG("pm_set(): setting STANDBY mode."); + _mode = PM_SLEEPCFG_SLEEPMODE_STANDBY; + deep = 1; + break; + default: /* Falls through */ + case 3: + DEBUG("pm_set(): setting IDLE2 mode."); + _mode = PM_SLEEPCFG_SLEEPMODE_IDLE2; + break; + } + + /* write sleep configuration */ + PM->SLEEPCFG.bit.SLEEPMODE = _mode; + /* make sure value has been set */ + while (PM->SLEEPCFG.bit.SLEEPMODE != _mode) {} + + cortexm_sleep(deep); +} diff --git a/cpu/samd5x/vectors.c b/cpu/samd5x/vectors.c new file mode 100644 index 0000000000..ad62d8be4d --- /dev/null +++ b/cpu/samd5x/vectors.c @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2019 ML!PA Consulting GmbH + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_samd5x + * @{ + * + * @file + * @brief Startup code and interrupt vector definition + * + * @author Benjamin Valentin + * + * @} + */ + +#include +#include "vectors_cortexm.h" + +/* define a local dummy handler as it needs to be in the same compilation unit + * as the alias definition */ +void dummy_handler(void) { + dummy_handler_default(); +} + +/* SAME54 specific interrupt vector */ +WEAK_DEFAULT void isr_pm ( void ); +WEAK_DEFAULT void isr_mclk ( void ); +WEAK_DEFAULT void isr_oscctrl0 ( void ); +WEAK_DEFAULT void isr_oscctrl1 ( void ); +WEAK_DEFAULT void isr_oscctrl2 ( void ); +WEAK_DEFAULT void isr_oscctrl3 ( void ); +WEAK_DEFAULT void isr_oscctrl4 ( void ); +WEAK_DEFAULT void isr_osc32kctrl ( void ); +WEAK_DEFAULT void isr_supc0 ( void ); +WEAK_DEFAULT void isr_supc1 ( void ); +WEAK_DEFAULT void isr_wdt ( void ); +WEAK_DEFAULT void isr_rtc ( void ); +WEAK_DEFAULT void isr_eic0 ( void ); +WEAK_DEFAULT void isr_eic1 ( void ); +WEAK_DEFAULT void isr_eic2 ( void ); +WEAK_DEFAULT void isr_eic3 ( void ); +WEAK_DEFAULT void isr_eic4 ( void ); +WEAK_DEFAULT void isr_eic5 ( void ); +WEAK_DEFAULT void isr_eic6 ( void ); +WEAK_DEFAULT void isr_eic7 ( void ); +WEAK_DEFAULT void isr_eic8 ( void ); +WEAK_DEFAULT void isr_eic9 ( void ); +WEAK_DEFAULT void isr_eic10 ( void ); +WEAK_DEFAULT void isr_eic11 ( void ); +WEAK_DEFAULT void isr_eic12 ( void ); +WEAK_DEFAULT void isr_eic13 ( void ); +WEAK_DEFAULT void isr_eic14 ( void ); +WEAK_DEFAULT void isr_eic15 ( void ); +WEAK_DEFAULT void irq_freqm ( void ); +WEAK_DEFAULT void isr_nvmctrl0 ( void ); +WEAK_DEFAULT void isr_nvmctrl1 ( void ); +WEAK_DEFAULT void isr_dmac0 ( void ); +WEAK_DEFAULT void isr_dmac1 ( void ); +WEAK_DEFAULT void isr_dmac2 ( void ); +WEAK_DEFAULT void isr_dmac3 ( void ); +WEAK_DEFAULT void isr_dmac4 ( void ); +WEAK_DEFAULT void isr_evsys0 ( void ); +WEAK_DEFAULT void isr_evsys1 ( void ); +WEAK_DEFAULT void isr_evsys2 ( void ); +WEAK_DEFAULT void isr_evsys3 ( void ); +WEAK_DEFAULT void isr_evsys4 ( void ); +WEAK_DEFAULT void isr_pac ( void ); +WEAK_DEFAULT void irq_ramecc ( void ); +WEAK_DEFAULT void isr_sercom0_0 ( void ); +WEAK_DEFAULT void isr_sercom0_1 ( void ); +WEAK_DEFAULT void isr_sercom0_2 ( void ); +WEAK_DEFAULT void isr_sercom0_3 ( void ); +WEAK_DEFAULT void isr_sercom1_0 ( void ); +WEAK_DEFAULT void isr_sercom1_1 ( void ); +WEAK_DEFAULT void isr_sercom1_2 ( void ); +WEAK_DEFAULT void isr_sercom1_3 ( void ); +WEAK_DEFAULT void isr_sercom2_0 ( void ); +WEAK_DEFAULT void isr_sercom2_1 ( void ); +WEAK_DEFAULT void isr_sercom2_2 ( void ); +WEAK_DEFAULT void isr_sercom2_3 ( void ); +WEAK_DEFAULT void isr_sercom3_0 ( void ); +WEAK_DEFAULT void isr_sercom3_1 ( void ); +WEAK_DEFAULT void isr_sercom3_2 ( void ); +WEAK_DEFAULT void isr_sercom3_3 ( void ); +WEAK_DEFAULT void isr_sercom4_0 ( void ); +WEAK_DEFAULT void isr_sercom4_1 ( void ); +WEAK_DEFAULT void isr_sercom4_2 ( void ); +WEAK_DEFAULT void isr_sercom4_3 ( void ); +WEAK_DEFAULT void isr_sercom5_0 ( void ); +WEAK_DEFAULT void isr_sercom5_1 ( void ); +WEAK_DEFAULT void isr_sercom5_2 ( void ); +WEAK_DEFAULT void isr_sercom5_3 ( void ); +WEAK_DEFAULT void isr_sercom6_0 ( void ); +WEAK_DEFAULT void isr_sercom6_1 ( void ); +WEAK_DEFAULT void isr_sercom6_2 ( void ); +WEAK_DEFAULT void isr_sercom6_3 ( void ); +WEAK_DEFAULT void isr_sercom7_0 ( void ); +WEAK_DEFAULT void isr_sercom7_1 ( void ); +WEAK_DEFAULT void isr_sercom7_2 ( void ); +WEAK_DEFAULT void isr_sercom7_3 ( void ); +WEAK_DEFAULT void isr_can0 ( void ); +WEAK_DEFAULT void isr_can1 ( void ); +WEAK_DEFAULT void isr_usb0 ( void ); +WEAK_DEFAULT void isr_usb1 ( void ); +WEAK_DEFAULT void isr_usb2 ( void ); +WEAK_DEFAULT void isr_usb3 ( void ); +WEAK_DEFAULT void isr_gmac ( void ); +WEAK_DEFAULT void isr_tcc0_0 ( void ); +WEAK_DEFAULT void isr_tcc0_1 ( void ); +WEAK_DEFAULT void isr_tcc0_2 ( void ); +WEAK_DEFAULT void isr_tcc0_3 ( void ); +WEAK_DEFAULT void isr_tcc0_4 ( void ); +WEAK_DEFAULT void isr_tcc0_5 ( void ); +WEAK_DEFAULT void isr_tcc0_6 ( void ); +WEAK_DEFAULT void isr_tcc1_0 ( void ); +WEAK_DEFAULT void isr_tcc1_1 ( void ); +WEAK_DEFAULT void isr_tcc1_2 ( void ); +WEAK_DEFAULT void isr_tcc1_3 ( void ); +WEAK_DEFAULT void isr_tcc1_4 ( void ); +WEAK_DEFAULT void isr_tcc2_0 ( void ); +WEAK_DEFAULT void isr_tcc2_1 ( void ); +WEAK_DEFAULT void isr_tcc2_2 ( void ); +WEAK_DEFAULT void isr_tcc2_3 ( void ); +WEAK_DEFAULT void isr_tcc3_0 ( void ); +WEAK_DEFAULT void isr_tcc3_1 ( void ); +WEAK_DEFAULT void isr_tcc3_2 ( void ); +WEAK_DEFAULT void isr_tcc4_0 ( void ); +WEAK_DEFAULT void isr_tcc4_1 ( void ); +WEAK_DEFAULT void isr_tcc4_2 ( void ); +WEAK_DEFAULT void isr_tc0 ( void ); +WEAK_DEFAULT void isr_tc1 ( void ); +WEAK_DEFAULT void isr_tc2 ( void ); +WEAK_DEFAULT void isr_tc3 ( void ); +WEAK_DEFAULT void isr_tc4 ( void ); +WEAK_DEFAULT void isr_tc5 ( void ); +WEAK_DEFAULT void isr_tc6 ( void ); +WEAK_DEFAULT void isr_tc7 ( void ); +WEAK_DEFAULT void isr_pdec0 ( void ); +WEAK_DEFAULT void isr_pdec1 ( void ); +WEAK_DEFAULT void isr_pdec2 ( void ); +WEAK_DEFAULT void isr_adc0_0 ( void ); +WEAK_DEFAULT void isr_adc0_1 ( void ); +WEAK_DEFAULT void isr_adc1_0 ( void ); +WEAK_DEFAULT void isr_adc1_1 ( void ); +WEAK_DEFAULT void isr_ac ( void ); +WEAK_DEFAULT void isr_dac0 ( void ); +WEAK_DEFAULT void isr_dac1 ( void ); +WEAK_DEFAULT void isr_dac2 ( void ); +WEAK_DEFAULT void isr_dac3 ( void ); +WEAK_DEFAULT void isr_dac4 ( void ); +WEAK_DEFAULT void isr_i2s ( void ); +WEAK_DEFAULT void isr_pcc ( void ); +WEAK_DEFAULT void isr_aes ( void ); +WEAK_DEFAULT void isr_trng ( void ); +WEAK_DEFAULT void isr_icm ( void ); +WEAK_DEFAULT void isr_pukcc ( void ); +WEAK_DEFAULT void isq_qspi ( void ); +WEAK_DEFAULT void isr_sdhc0 ( void ); +WEAK_DEFAULT void isr_sdhc1 ( void ); + +/* CPU specific interrupt vector table */ +ISR_VECTOR(1) const isr_t vector_cpu[CPU_IRQ_NUMOF] = { + isr_pm, /* 0 Power Manager */ + isr_mclk, /* 1 Main Clock */ + isr_oscctrl0, /* 2 Oscillators Control IRQ 0 */ + isr_oscctrl1, /* 3 Oscillators Control IRQ 1 */ + isr_oscctrl2, /* 4 Oscillators Control IRQ 2 */ + isr_oscctrl3, /* 5 Oscillators Control IRQ 3 */ + isr_oscctrl4, /* 6 Oscillators Control IRQ 4 */ + isr_osc32kctrl, /* 7 32kHz Oscillators Control */ + isr_supc0, /* 8 Supply Controller IRQ 0 */ + isr_supc1, /* 9 Supply Controller IRQ 1 */ + isr_wdt, /* 10 Watchdog Timer */ + isr_rtc, /* 11 Real-Time Counter */ + isr_eic0, /* 12 External Interrupt Controller IRQ 0 */ + isr_eic1, /* 13 External Interrupt Controller IRQ 1 */ + isr_eic2, /* 14 External Interrupt Controller IRQ 2 */ + isr_eic3, /* 15 External Interrupt Controller IRQ 3 */ + isr_eic4, /* 16 External Interrupt Controller IRQ 4 */ + isr_eic5, /* 17 External Interrupt Controller IRQ 5 */ + isr_eic6, /* 18 External Interrupt Controller IRQ 6 */ + isr_eic7, /* 19 External Interrupt Controller IRQ 7 */ + isr_eic8, /* 20 External Interrupt Controller IRQ 8 */ + isr_eic9, /* 21 External Interrupt Controller IRQ 9 */ + isr_eic10, /* 22 External Interrupt Controller IRQ 10 */ + isr_eic11, /* 23 External Interrupt Controller IRQ 11 */ + isr_eic12, /* 24 External Interrupt Controller IRQ 12 */ + isr_eic13, /* 25 External Interrupt Controller IRQ 13 */ + isr_eic14, /* 26 External Interrupt Controller IRQ 14 */ + isr_eic15, /* 27 External Interrupt Controller IRQ 15 */ + irq_freqm, /* 28 Frequency Meter */ + isr_nvmctrl0, /* 29 Non-Volatile Memory Controller IRQ 0 */ + isr_nvmctrl1, /* 30 Non-Volatile Memory Controller IRQ 1 */ + isr_dmac0, /* 31 Direct Memory Access Controller IRQ 0 */ + isr_dmac1, /* 32 Direct Memory Access Controller IRQ 1 */ + isr_dmac2, /* 33 Direct Memory Access Controller IRQ 2 */ + isr_dmac3, /* 34 Direct Memory Access Controller IRQ 3 */ + isr_dmac4, /* 35 Direct Memory Access Controller IRQ 4 */ + isr_evsys0, /* 36 Event System Interface IRQ 0 */ + isr_evsys1, /* 37 Event System Interface IRQ 1 */ + isr_evsys2, /* 38 Event System Interface IRQ 2 */ + isr_evsys3, /* 39 Event System Interface IRQ 3 */ + isr_evsys4, /* 40 Event System Interface IRQ 4 */ + isr_pac, /* 41 Peripheral Access Controller */ + dummy_handler, + dummy_handler, + dummy_handler, + irq_ramecc, /* 45 RAM ECC */ + isr_sercom0_0, /* 46 Serial Communication Interface 0 IRQ 0 */ + isr_sercom0_1, /* 47 Serial Communication Interface 0 IRQ 1 */ + isr_sercom0_2, /* 48 Serial Communication Interface 0 IRQ 2 */ + isr_sercom0_3, /* 49 Serial Communication Interface 0 IRQ 3 */ + isr_sercom1_0, /* 50 Serial Communication Interface 1 IRQ 0 */ + isr_sercom1_1, /* 51 Serial Communication Interface 1 IRQ 1 */ + isr_sercom1_2, /* 52 Serial Communication Interface 1 IRQ 2 */ + isr_sercom1_3, /* 53 Serial Communication Interface 1 IRQ 3 */ + isr_sercom2_0, /* 54 Serial Communication Interface 2 IRQ 0 */ + isr_sercom2_1, /* 55 Serial Communication Interface 2 IRQ 1 */ + isr_sercom2_2, /* 56 Serial Communication Interface 2 IRQ 2 */ + isr_sercom2_3, /* 57 Serial Communication Interface 2 IRQ 3 */ + isr_sercom3_0, /* 58 Serial Communication Interface 3 IRQ 0 */ + isr_sercom3_1, /* 59 Serial Communication Interface 3 IRQ 1 */ + isr_sercom3_2, /* 60 Serial Communication Interface 3 IRQ 2 */ + isr_sercom3_3, /* 61 Serial Communication Interface 3 IRQ 3 */ + isr_sercom4_0, /* 62 Serial Communication Interface 4 IRQ 0 */ + isr_sercom4_1, /* 63 Serial Communication Interface 4 IRQ 1 */ + isr_sercom4_2, /* 64 Serial Communication Interface 4 IRQ 2 */ + isr_sercom4_3, /* 65 Serial Communication Interface 4 IRQ 3 */ + isr_sercom5_0, /* 66 Serial Communication Interface 5 IRQ 0 */ + isr_sercom5_1, /* 67 Serial Communication Interface 5 IRQ 1 */ + isr_sercom5_2, /* 68 Serial Communication Interface 5 IRQ 2 */ + isr_sercom5_3, /* 69 Serial Communication Interface 5 IRQ 3 */ + isr_sercom6_0, /* 70 Serial Communication Interface 6 IRQ 0 */ + isr_sercom6_1, /* 71 Serial Communication Interface 6 IRQ 1 */ + isr_sercom6_2, /* 72 Serial Communication Interface 6 IRQ 2 */ + isr_sercom6_3, /* 73 Serial Communication Interface 6 IRQ 3 */ + isr_sercom7_0, /* 74 Serial Communication Interface 7 IRQ 0 */ + isr_sercom7_1, /* 75 Serial Communication Interface 7 IRQ 1 */ + isr_sercom7_2, /* 76 Serial Communication Interface 7 IRQ 2 */ + isr_sercom7_3, /* 77 Serial Communication Interface 7 IRQ 3 */ + isr_can0, /* 78 Control Area Network 0 */ + isr_can1, /* 79 Control Area Network 1 */ + isr_usb0, /* 80 Universal Serial Bus IRQ 0 */ + isr_usb1, /* 81 Universal Serial Bus IRQ 1 */ + isr_usb2, /* 82 Universal Serial Bus IRQ 2 */ + isr_usb3, /* 83 Universal Serial Bus IRQ 3 */ + isr_gmac, /* 84 Ethernet MAC */ + isr_tcc0_0, /* 85 Timer Counter Control 0 IRQ 0 */ + isr_tcc0_1, /* 86 Timer Counter Control 0 IRQ 1 */ + isr_tcc0_2, /* 87 Timer Counter Control 0 IRQ 2 */ + isr_tcc0_3, /* 88 Timer Counter Control 0 IRQ 3 */ + isr_tcc0_4, /* 89 Timer Counter Control 0 IRQ 4 */ + isr_tcc0_5, /* 90 Timer Counter Control 0 IRQ 5 */ + isr_tcc0_6, /* 91 Timer Counter Control 0 IRQ 6 */ + isr_tcc1_0, /* 92 Timer Counter Control 1 IRQ 0 */ + isr_tcc1_1, /* 93 Timer Counter Control 1 IRQ 1 */ + isr_tcc1_2, /* 94 Timer Counter Control 1 IRQ 2 */ + isr_tcc1_3, /* 95 Timer Counter Control 1 IRQ 3 */ + isr_tcc1_4, /* 96 Timer Counter Control 1 IRQ 4 */ + isr_tcc2_0, /* 97 Timer Counter Control 2 IRQ 0 */ + isr_tcc2_1, /* 98 Timer Counter Control 2 IRQ 1 */ + isr_tcc2_2, /* 99 Timer Counter Control 2 IRQ 2 */ + isr_tcc2_3, /* 100 Timer Counter Control 2 IRQ 3 */ + isr_tcc3_0, /* 101 Timer Counter Control 3 IRQ 0 */ + isr_tcc3_1, /* 102 Timer Counter Control 3 IRQ 1 */ + isr_tcc3_2, /* 103 Timer Counter Control 3 IRQ 2 */ + isr_tcc4_0, /* 104 Timer Counter Control 4 IRQ 0 */ + isr_tcc4_1, /* 105 Timer Counter Control 4 IRQ 1 */ + isr_tcc4_2, /* 106 Timer Counter Control 4 IRQ 2 */ + isr_tc0, /* 107 Basic Timer Counter 0 */ + isr_tc1, /* 108 Basic Timer Counter 1 */ + isr_tc2, /* 109 Basic Timer Counter 2 */ + isr_tc3, /* 110 Basic Timer Counter 3 */ + isr_tc4, /* 111 Basic Timer Counter 4 */ + isr_tc5, /* 112 Basic Timer Counter 5 */ + isr_tc6, /* 113 Basic Timer Counter 6 */ + isr_tc7, /* 114 Basic Timer Counter 7 */ + isr_pdec0, /* 115 Quadrature Decodeur IRQ 0 */ + isr_pdec1, /* 116 Quadrature Decodeur IRQ 1 */ + isr_pdec2, /* 117 Quadrature Decodeur IRQ 2 */ + isr_adc0_0, /* 118 Analog Digital Converter 0 IRQ 0 */ + isr_adc0_1, /* 119 Analog Digital Converter 0 IRQ 1 */ + isr_adc1_0, /* 120 Analog Digital Converter 1 IRQ 0 */ + isr_adc1_1, /* 121 Analog Digital Converter 1 IRQ 1 */ + isr_ac, /* 122 Analog Comparators */ + isr_dac0, /* 123 Digital-to-Analog Converter IRQ 0 */ + isr_dac1, /* 124 Digital-to-Analog Converter IRQ 1 */ + isr_dac2, /* 125 Digital-to-Analog Converter IRQ 2 */ + isr_dac3, /* 126 Digital-to-Analog Converter IRQ 3 */ + isr_dac4, /* 127 Digital-to-Analog Converter IRQ 4 */ + isr_i2s, /* 128 Inter-IC Sound Interface */ + isr_pcc, /* 129 Parallel Capture Controller */ + isr_aes, /* 130 Advanced Encryption Standard */ + isr_trng, /* 131 True Random Generator */ + isr_icm, /* 132 Integrity Check Monitor */ + isr_pukcc, /* 133 PUblic-Key Cryptography Controller */ + isq_qspi, /* 134 Quad SPI interface */ + isr_sdhc0, /* 135 SD/MMC Host Controller 0 */ + isr_sdhc1, /* 136 SD/MMC Host Controller 1 */ +};