--- /dev/null
+/*
+ * Copyright © 2019 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _SAMD21_H_
+#define _SAMD21_H_
+
+#include <stdint.h>
+
+typedef volatile uint64_t vuint64_t;
+typedef volatile uint32_t vuint32_t;
+typedef volatile void * vvoid_t;
+typedef volatile uint16_t vuint16_t;
+typedef volatile uint8_t vuint8_t;
+
+struct samd21_pac {
+ vuint32_t wpclr;
+ vuint32_t wpset;
+};
+
+extern struct samd21_pac samd21_pac0;
+extern struct samd21_pac samd21_pac1;
+extern struct samd21_pac samd21_pac2;
+
+#define samd21_pac0 (*(struct samd21_pac *) 0x40000000)
+#define samd21_pac1 (*(struct samd21_pac *) 0x41000000)
+#define samd21_pac2 (*(struct samd21_pac *) 0x42000000)
+
+struct samd21_gclk {
+ vuint8_t ctrl;
+ vuint8_t status;
+ vuint16_t clkctrl;
+ vuint32_t genctrl;
+ vuint32_t gendiv;
+};
+
+extern struct samd21_gclk samd21_gclk;
+
+#define samd21_gclk (*(struct samd21_gclk *) 0x40000c00)
+
+#define SAMD21_GCLK_CTRL_SWRST 0
+
+#define SAMD21_GCLK_STATUS_SYNCBUSY 7
+
+#define SAMD21_GCLK_CLKCTRL_ID 0
+#define SAMD21_GCLK_CLKCTRL_ID_DFLL48M_REF 0
+#define SAMD21_GCLK_CLKCTRL_ID_DPLL 1
+#define SAMD21_GCLK_CLKCTRL_ID_DPLL_32K 2
+#define SAMD21_GCLK_CLKCTRL_ID_WDT 3
+#define SAMD21_GCLK_CLKCTRL_ID_RTC 4
+#define SAMD21_GCLK_CLKCTRL_ID_EIC 5
+#define SAMD21_GCLK_CLKCTRL_ID_USB 6
+#define SAMD21_GCLK_CLKCTRL_ID_EVSYS_CHANNEL_0 0x07
+#define SAMD21_GCLK_CLKCTRL_ID_EVSYS_CHANNEL_1 0x08
+#define SAMD21_GCLK_CLKCTRL_ID_EVSYS_CHANNEL_2 0x09
+#define SAMD21_GCLK_CLKCTRL_ID_EVSYS_CHANNEL_3 0x0a
+#define SAMD21_GCLK_CLKCTRL_ID_EVSYS_CHANNEL_4 0x0b
+#define SAMD21_GCLK_CLKCTRL_ID_EVSYS_CHANNEL_5 0x0c
+#define SAMD21_GCLK_CLKCTRL_ID_EVSYS_CHANNEL_6 0x0d
+#define SAMD21_GCLK_CLKCTRL_ID_EVSYS_CHANNEL_7 0x0e
+#define SAMD21_GCLK_CLKCTRL_ID_EVSYS_CHANNEL_8 0e0f
+#define SAMD21_GCLK_CLKCTRL_ID_EVSYS_CHANNEL_9 0x10
+#define SAMD21_GCLK_CLKCTRL_ID_EVSYS_CHANNEL_10 0x11
+#define SAMD21_GCLK_CLKCTRL_ID_EVSYS_CHANNEL_11 0x12
+#define SAMD21_GCLK_CLKCTRL_ID_SERCOMx_SLOW 0x13
+#define SAMD21_GCLK_CLKCTRL_ID_SERCOM0_CORE 0x14
+#define SAMD21_GCLK_CLKCTRL_ID_SERCOM1_CORE 0x15
+#define SAMD21_GCLK_CLKCTRL_ID_SERCOM2_CORE 0x16
+#define SAMD21_GCLK_CLKCTRL_ID_SERCOM3_CORE 0x17
+#define SAMD21_GCLK_CLKCTRL_ID_SERCOM4_CORE 0x18
+#define SAMD21_GCLK_CLKCTRL_ID_SERCOM5_CORE 0x19
+#define SAMD21_GCLK_CLKCTRL_ID_TCC0_TCC1 0x1a
+#define SAMD21_GCLK_CLKCTRL_ID_TCC2_TC3 0x1b
+#define SAMD21_GCLK_CLKCTRL_ID_TC4_TC5 0x1c
+#define SAMD21_GCLK_CLKCTRL_ID_TC6_TC7 0x1d
+#define SAMD21_GCLK_CLKCTRL_ID_ADC 0x1e
+#define SAMD21_GCLK_CLKCTRL_ID_AC_DIG 0x1f
+#define SAMD21_GCLK_CLKCTRL_ID_AC_ANA 0x20
+#define SAMD21_GCLK_CLKCTRL_ID_DAC 0x21
+#define SAMD21_GCLK_CLKCTRL_ID_PTC 0x22
+#define SAMD21_GCLK_CLKCTRL_ID_I2S_0 0x23
+#define SAMD21_GCLK_CLKCTRL_ID_I2S_1 0x24
+#define SAMD21_GCLK_CLKCTRL_ID_TCC3 0x25
+
+#define SAMD21_GCLK_CLKCTRL_GEN 8
+#define SAMD21_GCLK_CLKCTRL_CLKEN 14
+#define SAMD21_GCLK_CLKCTRL_WRTLOCK 15
+
+#define SAMD21_GCLK_GENCTRL_ID 0
+#define SAMD21_GCLK_GENCTRL_SRC 8
+#define SAMD21_GCLK_GENCTRL_SRC_XOSC 0
+#define SAMD21_GCLK_GENCTRL_SRC_GCLKIN 1
+#define SAMD21_GCLK_GENCTRL_SRC_GCLKGEN1 2
+#define SAMD21_GCLK_GENCTRL_SRC_OSCULP32K 3
+#define SAMD21_GCLK_GENCTRL_SRC_OSC32K 4
+#define SAMD21_GCLK_GENCTRL_SRC_XOSC32K 5
+#define SAMD21_GCLK_GENCTRL_SRC_OSC8M 6
+#define SAMD21_GCLK_GENCTRL_SRC_DFLL48M 7
+#define SAMD21_GCLK_GENCTRL_SRC_FDPLL96M 8
+
+#define SAMD21_GCLK_GENCTRL_GENEN 16
+#define SAMD21_GCLK_GENCTRL_IDC 17
+#define SAMD21_GCLK_GENCTRL_OOV 18
+#define SAMD21_GCLK_GENCTRL_OE 19
+#define SAMD21_GCLK_GENCTRL_DIVSEL 20
+#define SAMD21_GCLK_GENCTRL_RUNSTDBY 21
+
+#define SAMD21_GCLK_GENDIV_ID 0
+#define SAMD21_GCLK_GENDIV_DIV 8
+
+struct samd21_pm {
+ vuint8_t ctrl;
+ vuint8_t sleep;
+ vuint8_t reserved_02;
+ vuint8_t reserved_03;
+ vuint32_t reserved_04;
+ vuint8_t cpusel;
+ vuint8_t apbasel;
+ vuint8_t apbbsel;
+ vuint8_t apbcsel;
+ vuint32_t reserved_0c;
+
+ vuint32_t reserved_10;
+ vuint32_t ahbmask;
+ vuint32_t apbamask;
+ vuint32_t apbbmask;
+
+ vuint32_t apbcmask;
+ vuint32_t reserved_24;
+ vuint32_t reserved_28;
+ vuint32_t reserved_2c;
+
+ vuint32_t reserved_30;
+ vuint8_t intenclr;
+ vuint8_t intelset;
+ vuint8_t intflag;
+ vuint8_t reserved_37;
+ vuint8_t rcause;
+};
+
+extern struct samd21_pm samd21_pm;
+
+#define samd21_pm (*(struct samd21_pm *) 0x40000400)
+
+#define SAMD21_PM_CPUSEL_CPUDIV 0
+#define SAMD21_PM_APBASEL_APBADIV 0
+#define SAMD21_PM_APBBSEL_APBBDIV 0
+#define SAMD21_PM_APBCSEL_APBCDIV 0
+
+#define SAMD21_PM_APBAMASK_PAC0 0
+#define SAMD21_PM_APBAMASK_PM 1
+#define SAMD21_PM_APBAMASK_SYSCTRL 2
+#define SAMD21_PM_APBAMASK_GCLK 3
+#define SAMD21_PM_APBAMASK_WDT 4
+#define SAMD21_PM_APBAMASK_RTC 5
+#define SAMD21_PM_APBAMASK_EIC 6
+
+#define SAMD21_PM_AHBMASK_HPB0 0
+#define SAMD21_PM_AHBMASK_HPB1 1
+#define SAMD21_PM_AHBMASK_HPB2 2
+#define SAMD21_PM_AHBMASK_DSU 3
+#define SAMD21_PM_AHBMASK_NVMCTRL 4
+#define SAMD21_PM_AHBMASK_DMAC 5
+#define SAMD21_PM_AHBMASK_USB 6
+
+#define SAMD21_PM_APBBMASK_PAC1 0
+#define SAMD21_PM_APBBMASK_DSU 1
+#define SAMD21_PM_APBBMASK_NVMCTRL 2
+#define SAMD21_PM_APBBMASK_PORT 3
+#define SAMD21_PM_APBBMASK_DMAC 4
+#define SAMD21_PM_APBBMASK_USB 5
+
+#define SAMD21_PM_APBCMASK_PAC2 0
+#define SAMD21_PM_APBCMASK_EVSYS 1
+#define SAMD21_PM_APBCMASK_SERCOM0 2
+#define SAMD21_PM_APBCMASK_SERCOM1 3
+#define SAMD21_PM_APBCMASK_SERCOM2 4
+#define SAMD21_PM_APBCMASK_SERCOM3 5
+#define SAMD21_PM_APBCMASK_SERCOM4 6
+#define SAMD21_PM_APBCMASK_SERCOM5 7
+#define SAMD21_PM_APBCMASK_TCC0 8
+#define SAMD21_PM_APBCMASK_TCC1 9
+#define SAMD21_PM_APBCMASK_TCC2 10
+#define SAMD21_PM_APBCMASK_TC3 11
+#define SAMD21_PM_APBCMASK_TC4 12
+#define SAMD21_PM_APBCMASK_TC5 13
+#define SAMD21_PM_APBCMASK_TC6 14
+#define SAMD21_PM_APBCMASK_TC7 15
+#define SAMD21_PM_APBCMASK_ADC 16
+#define SAMD21_PM_APBCMASK_AC 17
+#define SAMD21_PM_APBCMASK_DAC 18
+#define SAMD21_PM_APBCMASK_PTC 19
+#define SAMD21_PM_APBCMASK_I2S 20
+#define SAMD21_PM_APBCMASK_AC1 21
+#define SAMD21_PM_APBCMASK_TCC3 24
+
+struct samd21_sysctrl {
+ vuint32_t intenclr;
+ vuint32_t intenset;
+ vuint32_t intflag;
+ vuint32_t pclksr;
+
+ vuint32_t xosc;
+ vuint32_t xosc32k;
+ vuint32_t osc32k;
+ vuint32_t osculp32k;
+
+ vuint32_t osc8m;
+ vuint32_t dfllctrl;
+ vuint32_t dfllval;
+ vuint32_t dfllmul;
+
+ vuint32_t dfllsync;
+ vuint32_t bod33;
+ vuint32_t reserved_38;
+ vuint32_t vreg;
+
+ vuint32_t vref;
+ vuint32_t dpllctrla;
+ vuint32_t dpllratio;
+ vuint32_t dpllctrlb;
+
+ vuint32_t dpllstatus;
+};
+
+extern struct samd21_sysctrl samd21_sysctrl;
+
+#define samd21_sysctrl (*(struct samd21_sysctrl *) 0x40000800)
+
+#define SAMD21_SYSCTRL_PCLKSR_XOSCRDY 0
+#define SAMD21_SYSCTRL_PCLKSR_XOSC32KRDY 1
+#define SAMD21_SYSCTRL_PCLKSR_OSC32KRDY 2
+#define SAMD21_SYSCTRL_PCLKSR_OSC8MRDY 3
+#define SAMD21_SYSCTRL_PCLKSR_DFLLRDY 4
+#define SAMD21_SYSCTRL_PCLKSR_DFLLOOB 5
+#define SAMD21_SYSCTRL_PCLKSR_DFLLLCKF 6
+#define SAMD21_SYSCTRL_PCLKSR_DFLLLCKC 7
+#define SAMD21_SYSCTRL_PCLKSR_DFLLRCS 8
+#define SAMD21_SYSCTRL_PCLKSR_BOD33RDY 9
+#define SAMD21_SYSCTRL_PCLKSR_BOD33DET 10
+#define SAMD21_SYSCTRL_PCLKSR_B33SRDY 11
+#define SAMD21_SYSCTRL_PCLKSR_DBPLLLCKR 15
+#define SAMD21_SYSCTRL_PCLKSR_DPLLLCKF 16
+#define SAMD21_SYSCTRL_PCLKSR_DPLLTO 17
+
+#define SAMD21_SYSCTRL_XOSC_ENABLE 1
+#define SAMD21_SYSCTRL_XOSC_XTALEN 2
+#define SAMD21_SYSCTRL_XOSC_RUNSTDBY 6
+#define SAMD21_SYSCTRL_XOSC_ONDEMAND 7
+#define SAMD21_SYSCTRL_XOSC_GAIN 8
+#define SAMD21_SYSCTRL_XOSC_GAIN_2MHz 0
+#define SAMD21_SYSCTRL_XOSC_GAIN_4MHz 1
+#define SAMD21_SYSCTRL_XOSC_GAIN_8MHz 2
+#define SAMD21_SYSCTRL_XOSC_GAIN_16MHz 3
+#define SAMD21_SYSCTRL_XOSC_GAIN_30MHz 4
+#define SAMD21_SYSCTRL_XOSC_AMPGC 11
+#define SAMD21_SYSCTRL_XOSC_STARTUP 12
+#define SAMD21_SYSCTRL_XOSC_STARTUP_1 0
+#define SAMD21_SYSCTRL_XOSC_STARTUP_2 1
+#define SAMD21_SYSCTRL_XOSC_STARTUP_4 2
+#define SAMD21_SYSCTRL_XOSC_STARTUP_8 3
+#define SAMD21_SYSCTRL_XOSC_STARTUP_16 4
+#define SAMD21_SYSCTRL_XOSC_STARTUP_32 5
+#define SAMD21_SYSCTRL_XOSC_STARTUP_64 6
+#define SAMD21_SYSCTRL_XOSC_STARTUP_128 7
+#define SAMD21_SYSCTRL_XOSC_STARTUP_256 8
+#define SAMD21_SYSCTRL_XOSC_STARTUP_512 9
+#define SAMD21_SYSCTRL_XOSC_STARTUP_1024 10
+#define SAMD21_SYSCTRL_XOSC_STARTUP_2048 11
+#define SAMD21_SYSCTRL_XOSC_STARTUP_4096 12
+#define SAMD21_SYSCTRL_XOSC_STARTUP_8192 13
+#define SAMD21_SYSCTRL_XOSC_STARTUP_16384 14
+#define SAMD21_SYSCTRL_XOSC_STARTUP_32768 15
+
+#define SAMD21_SYSCTRL_XOSC32K_ENABLE 1
+#define SAMD21_SYSCTRL_XOSC32K_XTALEN 2
+#define SAMD21_SYSCTRL_XOSC32K_EN32K 3
+#define SAMD21_SYSCTRL_XOSC32K_AAMPEN 5
+#define SAMD21_SYSCTRL_XOSC32K_RUNSTDBY 6
+#define SAMD21_SYSCTRL_XOSC32K_ONDEMAND 7
+#define SAMD21_SYSCTRL_XOSC32K_STARTUP 8
+#define SAMD21_SYSCTRL_XOSC32K_WRTLOCK 12
+
+#define SAMD21_SYSCTRL_OSC8M_ENABLE 1
+#define SAMD21_SYSCTRL_OSC8M_RUNSTDBY 6
+#define SAMD21_SYSCTRL_OSC8M_ONDEMAND 7
+#define SAMD21_SYSCTRL_OSC8M_PRESC 8
+#define SAMD21_SYSCTRL_OSC8M_PRESC_1 0
+#define SAMD21_SYSCTRL_OSC8M_PRESC_2 1
+#define SAMD21_SYSCTRL_OSC8M_PRESC_4 2
+#define SAMD21_SYSCTRL_OSC8M_PRESC_8 3
+#define SAMD21_SYSCTRL_OSC8M_PRESC_MASK 3
+#define SAMD21_SYSCTRL_OSC8M_CALIB 16
+#define SAMD21_SYSCTRL_OSC8M_FRANGE 30
+#define SAMD21_SYSCTRL_OSC8M_FRANGE_4_6 0
+#define SAMD21_SYSCTRL_OSC8M_FRANGE_6_8 1
+#define SAMD21_SYSCTRL_OSC8M_FRANGE_8_11 2
+#define SAMD21_SYSCTRL_OSC8M_FRANGE_11_15 3
+
+#define SAMD21_SYSCTRL_DFLLCTRL_ENABLE 1
+#define SAMD21_SYSCTRL_DFLLCTRL_MODE 2
+#define SAMD21_SYSCTRL_DFLLCTRL_STABLE 3
+#define SAMD21_SYSCTRL_DFLLCTRL_LLAW 4
+#define SAMD21_SYSCTRL_DFLLCTRL_USBCRM 5
+#define SAMD21_SYSCTRL_DFLLCTRL_RUNSTDBY 6
+#define SAMD21_SYSCTRL_DFLLCTRL_ONDEMAND 7
+#define SAMD21_SYSCTRL_DFLLCTRL_CCDIS 8
+#define SAMD21_SYSCTRL_DFLLCTRL_QLDIS 9
+#define SAMD21_SYSCTRL_DFLLCTRL_BPLCKC 10
+#define SAMD21_SYSCTRL_DFLLCTRL_WAITLOCK 11
+
+#define SAMD21_SYSCTRL_DFLLVAL_FINE 0
+#define SAMD21_SYSCTRL_DFLLVAL_COARSE 10
+#define SAMD21_SYSCTRL_DFLLVAL_DIFF 16
+
+#define SAMD21_SYSCTRL_DFLLMUL_MUL 0
+#define SAMD21_SYSCTRL_DFLLMUL_FSTEP 16
+#define SAMD21_SYSCTRL_DFLLMUL_CSTEP 26
+
+#define SAMD21_SYSCTRL_DFLLSYNC_READREQ 7
+
+#define SAMD21_SYSCTRL_DPLLCTRLA_ENABLE 1
+#define SAMD21_SYSCTRL_DPLLCTRLA_RUNSTDBY 6
+#define SAMD21_SYSCTRL_DPLLCTRLA_ONDEMAND 7
+
+#define SAMD21_SYSCTRL_DPLLRATIO_LDR 0
+#define SAMD21_SYSCTRL_DPLLRATIO_LDRFRAC 0
+
+#define SAMD21_SYSCTRL_DPLLCTRLB_FILTER 0
+#define SAMD21_SYSCTRL_DPLLCTRLB_FILTER_DEFAULT 0
+#define SAMD21_SYSCTRL_DPLLCTRLB_FILTER_LBFILT 1
+#define SAMD21_SYSCTRL_DPLLCTRLB_FILTER_HBFILT 2
+#define SAMD21_SYSCTRL_DPLLCTRLB_FILTER_HDFILT 3
+#define SAMD21_SYSCTRL_DPLLCTRLB_LPEN 2
+#define SAMD21_SYSCTRL_DPLLCTRLB_WUF 3
+#define SAMD21_SYSCTRL_DPLLCTRLB_REFCLK 4
+#define SAMD21_SYSCTRL_DPLLCTRLB_REFCLK_XOSC32 0
+#define SAMD21_SYSCTRL_DPLLCTRLB_REFCLK_XOSC 1
+#define SAMD21_SYSCTRL_DPLLCTRLB_REFCLK_GCLK_DPLL 2
+#define SAMD21_SYSCTRL_DPLLCTRLB_LTIME 8
+#define SAMD21_SYSCTRL_DPLLCTRLB_LTIME_DEFAULT 0
+#define SAMD21_SYSCTRL_DPLLCTRLB_LTIME_8MS 4
+#define SAMD21_SYSCTRL_DPLLCTRLB_LTIME_9MS 5
+#define SAMD21_SYSCTRL_DPLLCTRLB_LTIME_10MS 6
+#define SAMD21_SYSCTRL_DPLLCTRLB_LTIME_11MS 7
+#define SAMD21_SYSCTRL_DPLLCTRLB_LBYPASS 12
+#define SAMD21_SYSCTRL_DPLLCTRLB_DIV 16
+
+#define SAMD21_SYSCTRL_DPLLSTATUS_LOCK 0
+#define SAMD21_SYSCTRL_DPLLSTATUS_CLKRDY 1
+#define SAMD21_SYSCTRL_DPLLSTATUS_ENABLE 2
+#define SAMD21_SYSCTRL_DPLLSTATUS_DIV 3
+
+struct samd21_dmac {
+ vuint16_t ctrl;
+ vuint16_t crcctrl;
+ vuint32_t crcdatain;
+ vuint32_t crcchksum;
+ vuint8_t crcstatus;
+ vuint8_t dbgctrl;
+ vuint8_t qosctrl;
+ uint8_t reserved_0f;
+
+ vuint32_t swtrigctrl;
+ vuint32_t prictrl0;
+ uint32_t reserved_18;
+ uint32_t reserved_1c;
+
+ vuint16_t intpend;
+ uint16_t reserved_22;
+ vuint32_t intstatus;
+ vuint32_t busych;
+ vuint32_t pendch;
+
+ vuint32_t active;
+ vuint32_t baseaddr;
+ vuint32_t wrbaddr;
+ uint16_t reserved_3c;
+ uint8_t reserved_3e;
+ vuint8_t chid;
+
+ vuint8_t chctrla;
+ uint8_t reserved_41;
+ uint16_t reserved_42;
+ vuint32_t chctrlb;
+ uint32_t reserved_48;
+ vuint8_t chintenclr;
+ vuint8_t chintenset;
+ vuint8_t chintflag;
+ vuint8_t chstatus;
+};
+
+extern struct samd21_dmac samd21_dmac;
+
+#define samd21_dmac (*(struct samd21_dmac *) 0x41004800)
+
+struct samd21_dmac_desc {
+ vuint16_t btctrl;
+ vuint16_t btcnt;
+ vuint32_t srcaddr;
+ vuint32_t dstaddr;
+ vuint32_t descaddr;
+} __attribute__((aligned(8)));
+
+#define SAMD21_DMAC_NCHAN 12
+
+#define SAMD21_DMAC_CTRL_SWRST 0
+#define SAMD21_DMAC_CTRL_DMAENABLE 1
+#define SAMD21_DMAC_CTRL_CRCENABLE 2
+#define SAMD21_DMAC_CTRL_LVLEN(x) (8 + (x))
+
+#define SAMD21_DMAC_QOSCTRL_WRBQOS 0
+#define SAMD21_DMAC_QOSCTRL_FQOS 2
+#define SAMD21_DMAC_QOSCTRL_DQOS 4
+
+#define SAMD21_DMAC_QOSCTRL_DISABLE 0
+#define SAMD21_DMAC_QOSCTRL_LOW 1
+#define SAMD21_DMAC_QOSCTRL_MEDIUM 2
+#define SAMD21_DMAC_QOSCTRL_HIGH 3
+
+#define SAMD21_DMAC_SWTRIGCTRL_SWTRIG(n) (0 + (n))
+
+#define SAMD21_DMAC_PRICTRL0_LVLPRI0 0
+#define SAMD21_DMAC_PRICTRL0_RRLVLEN0 7
+#define SAMD21_DMAC_PRICTRL0_LVLPRI1 8
+#define SAMD21_DMAC_PRICTRL0_RRLVLEN1 15
+#define SAMD21_DMAC_PRICTRL0_LVLPRI2 16
+#define SAMD21_DMAC_PRICTRL0_RRLVLEN2 23
+#define SAMD21_DMAC_PRICTRL0_LVLPRI3 24
+#define SAMD21_DMAC_PRICTRL0_RRLVLEN3 31
+
+#define SAMD21_DMAC_INTPEND_ID 0
+#define SAMD21_DMAC_INTPEND_ID_MASK 0xf
+#define SAMD21_DMAC_INTPEND_TERR 8
+#define SAMD21_DMAC_INTPEND_TCMPL 9
+#define SAMD21_DMAC_INTPEND_SUSP 10
+#define SAMD21_DMAC_INTPEND_FERR 13
+#define SAMD21_DMAC_INTPEND_BUSY 14
+#define SAMD21_DMAC_INTPEND_PEND 15
+
+#define SAMD21_DMAC_INTSTATUS_CHINT(n) (0 + (n))
+
+#define SAMD21_DMAC_BUSYCH_BUSYCH(n) (0 + (n))
+
+#define SAMD21_DMAC_PENDCH_PENDCH(n) (0 + (n))
+
+#define SAMD21_DMAC_ACTIVE_LVLEX(x) (0 + (x))
+#define SAMD21_DMAC_ACTIVE_ID 8
+#define SAMD21_DMAC_ACTIVE_ABUSY 15
+#define SAMD21_DMAC_ACTIVE_BTCNT 16
+
+#define SAMD21_DMAC_CHCTRLA_SWRST 0
+#define SAMD21_DMAC_CHCTRLA_ENABLE 1
+
+#define SAMD21_DMAC_CHCTRLB_EVACT 0
+#define SAMD21_DMAC_CHCTRLB_EVACT_NOACT 0
+#define SAMD21_DMAC_CHCTRLB_EVACT_TRIG 1
+#define SAMD21_DMAC_CHCTRLB_EVACT_CTRIG 2
+#define SAMD21_DMAC_CHCTRLB_EVACT_CBLOCK 3
+#define SAMD21_DMAC_CHCTRLB_EVACT_SUSPEND 4
+#define SAMD21_DMAC_CHCTRLB_EVACT_RESUME 5
+#define SAMD21_DMAC_CHCTRLB_EVACT_SSKIP 6
+
+#define SAMD21_DMAC_CHCTRLB_EVIE 3
+#define SAMD21_DMAC_CHCTRLB_EVOE 4
+#define SAMD21_DMAC_CHCTRLB_LVL 5
+#define SAMD21_DMAC_CHCTRLB_LVL_LVL0 0UL
+#define SAMD21_DMAC_CHCTRLB_LVL_LVL1 1UL
+#define SAMD21_DMAC_CHCTRLB_LVL_LVL2 2UL
+#define SAMD21_DMAC_CHCTRLB_LVL_LVL3 3UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC 8
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_DISABLE 0x00UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_SERCOM_RX(n) (0x01UL + (n) * 2UL)
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_SERCOM_TX(n) (0x02UL + (n) * 2UL)
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC0_OVF 0x0dUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC0_MC0 0x0eUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC0_MC1 0x0fUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC0_MC2 0x10UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC0_MC3 0x11UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC1_OVF 0x12UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC1_MC0 0x13UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC1_MC1 0x14UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC2_OVF 0x15UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC2_MC0 0x16UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC2_MC1 0x17UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC3_OVF 0x18UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC3_MC0 0x19UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC3_MC1 0x1aUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC4_OVF 0x1bUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC4_MC0 0x1cUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC4_MC1 0x1dUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC5_OVF 0x1eUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC5_MC0 0x1fUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC5_MC1 0x20UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC6_OVF 0x21UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC6_MC0 0x22UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC6_MC1 0x23UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC7_OVF 0x24UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC7_MC0 0x25UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TC7_MC1 0x26UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_ADC_RESRDY 0x27UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_DAC_EMPTY 0x28UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_I2S_RX_0 0x29UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_I2S_RX_1 0x2aUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_I2S_TX_0 0x2bUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_I2S_TX_1 0x2cUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC3_OVF 0x2dUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC3_MC0 0x2eUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC3_MC1 0x2fUL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC3_MC2 0x30UL
+#define SAMD21_DMAC_CHCTRLB_TRIGSRC_TCC3_MC3 0x31UL
+
+#define SAMD21_DMAC_CHCTRLB_TRIGACT 22
+#define SAMD21_DMAC_CHCTRLB_TRIGACT_BLOCK 0UL
+#define SAMD21_DMAC_CHCTRLB_TRIGACT_BEAT 2UL
+#define SAMD21_DMAC_CHCTRLB_TRIGACT_TRANSACTION 3UL
+
+#define SAMD21_DMAC_CHCTRLB_CMD 24
+#define SAMD21_DMAC_CHCTRLB_CMD_NOACT 0UL
+#define SAMD21_DMAC_CHCTRLB_CMD_SUSPEND 1UL
+#define SAMD21_DMAC_CHCTRLB_CMD_RESUME 2UL
+
+#define SAMD21_DMAC_CHINTFLAG_TERR 0
+#define SAMD21_DMAC_CHINTFLAG_TCMPL 1
+#define SAMD21_DMAC_CHINTFLAG_SUSP 2
+
+#define SAMD21_DMAC_CHSTATUS_PEND 0
+#define SAMD21_DMAC_CHSTATUS_BUSY 1
+#define SAMD21_DMAC_CHSTATUS_FERR 2
+
+#define SAMD21_DMAC_DESC_BTCTRL_VALID 0
+#define SAMD21_DMAC_DESC_BTCTRL_EVOSEL 1
+#define SAMD21_DMAC_DESC_BTCTRL_EVOSEL_DISABLE 0UL
+#define SAMD21_DMAC_DESC_BTCTRL_EVOSEL_BLOCK 1UL
+#define SAMD21_DMAC_DESC_BTCTRL_EVOSEL_BEAT 3UL
+#define SAMD21_DMAC_DESC_BTCTRL_BLOCKACT 3
+#define SAMD21_DMAC_DESC_BTCTRL_BLOCKACT_NOACT 0UL
+#define SAMD21_DMAC_DESC_BTCTRL_BLOCKACT_INT 1UL
+#define SAMD21_DMAC_DESC_BTCTRL_BLOCKACT_SUSPEND 2UL
+#define SAMD21_DMAC_DESC_BTCTRL_BLOCKACT_BOTH 3UL
+#define SAMD21_DMAC_DESC_BTCTRL_BEATSIZE 8
+#define SAMD21_DMAC_DESC_BTCTRL_BEATSIZE_BYTE 0UL
+#define SAMD21_DMAC_DESC_BTCTRL_BEATSIZE_HWORD 1UL
+#define SAMD21_DMAC_DESC_BTCTRL_BEATSIZE_WORD 2UL
+#define SAMD21_DMAC_DESC_BTCTRL_SRCINC 10
+#define SAMD21_DMAC_DESC_BTCTRL_DSTINC 11
+#define SAMD21_DMAC_DESC_BTCTRL_STEPSEL 12
+#define SAMD21_DMAC_DESC_BTCTRL_STEPSEL_DST 0UL
+#define SAMD21_DMAC_DESC_BTCTRL_STEPSEL_SRC 1UL
+#define SAMD21_DMAC_DESC_BTCTRL_STEPSIZE 13
+#define SAMD21_DMAC_DESC_BTCTRL_STEPSIZE_X1 0UL
+#define SAMD21_DMAC_DESC_BTCTRL_STEPSIZE_X2 1UL
+#define SAMD21_DMAC_DESC_BTCTRL_STEPSIZE_X4 2UL
+#define SAMD21_DMAC_DESC_BTCTRL_STEPSIZE_X8 3UL
+#define SAMD21_DMAC_DESC_BTCTRL_STEPSIZE_X16 4UL
+#define SAMD21_DMAC_DESC_BTCTRL_STEPSIZE_X32 5UL
+#define SAMD21_DMAC_DESC_BTCTRL_STEPSIZE_X64 6UL
+#define SAMD21_DMAC_DESC_BTCTRL_STEPSIZE_X128 7UL
+
+struct samd21_eic {
+ vuint8_t ctrl;
+ vuint8_t status;
+ vuint8_t nmictrl;
+ vuint8_t nmiflag;
+ vuint32_t evctrl;
+ vuint32_t intenclr;
+ vuint32_t intenset;
+
+ vuint32_t intflag;
+ vuint32_t wakeup;
+ vuint32_t config[2];
+};
+
+extern struct samd21_eic samd21_eic;
+
+#define samd21_eic (*(struct samd21_eic *) 0x40001800)
+
+#define SAMD21_NUM_EIC 16
+
+#define SAMD21_EIC_CTRL_ENABLE 1
+#define SAMD21_EIC_CTRL_SWRST 0
+
+#define SAMD21_EIC_STATUS_SYNCBUSY 7
+
+#define SAMD21_EIC_NMICTRL_NMIFILTEN 3
+#define SAMD21_EIC_NMICTRL_NMISENSE 0
+
+#define SAMD21_EIC_NMIFLAG_NMI 0
+
+#define SAMD21_EIC_EVCTRL_EXTINTEO(n) (n)
+
+#define SAMD21_EIC_INTENCLR_EXTINT(n) (n)
+
+#define SAMD21_EIC_INTENSET_EXTINT(n) (n)
+
+#define SAMD21_EIC_INTFLAG_EXTINT(n) (n)
+#define SAMD21_EIC_WAKEUP_WAKEUPEN(n) (n)
+#define SAMD21_EIC_CONFIG_N(n) ((n) >> 3)
+#define SAMD21_EIC_CONFIG_SENSE(n) (((n) & 7) << 2)
+#define SAMD21_EIC_CONFIG_FILTEN(n) (SAMD21_EIC_CONFIG_SENSE(n) + 3)
+#define SAMD21_EIC_CONFIG_SENSE_NONE 0
+#define SAMD21_EIC_CONFIG_SENSE_RISE 1
+#define SAMD21_EIC_CONFIG_SENSE_FALL 2
+#define SAMD21_EIC_CONFIG_SENSE_BOTH 3
+#define SAMD21_EIC_CONFIG_SENSE_HIGH 4
+#define SAMD21_EIC_CONFIG_SENSE_LOW 5
+#define SAMD21_EIC_CONFIG_SENSE_MASK 7UL
+
+struct samd21_nvmctrl {
+ vuint32_t ctrla;
+ vuint32_t ctrlb;
+ vuint32_t param;
+ vuint32_t intenclr;
+
+ vuint32_t intenset;
+ vuint32_t intflag;
+ vuint32_t status;
+ vuint32_t addr;
+
+ vuint32_t lock;
+};
+
+extern struct samd21_nvmctrl samd21_nvmctrl;
+
+#define samd21_nvmctrl (*(struct samd21_nvmctrl *) 0x41004000)
+
+#define SAMD21_NVMCTRL_CTRLA_CMD 0
+#define SAMD21_NVMCTRL_CTRLA_CMD_ER 0x02
+#define SAMD21_NVMCTRL_CTRLA_CMD_WP 0x04
+#define SAMD21_NVMCTRL_CTRLA_CMD_EAR 0x05
+#define SAMD21_NVMCTRL_CTRLA_CMD_WAP 0x06
+#define SAMD21_NVMCTRL_CTRLA_CMD_RWWEEER 0x1a
+#define SAMD21_NVMCTRL_CTRLA_CMD_RWEEEWP 0x1c
+#define SAMD21_NVMCTRL_CTRLA_CMD_LR 0x40
+#define SAMD21_NVMCTRL_CTRLA_CMD_UR 0x41
+#define SAMD21_NVMCTRL_CTRLA_CMD_SPRM 0x42
+#define SAMD21_NVMCTRL_CTRLA_CMD_CPRM 0x43
+#define SAMD21_NVMCTRL_CTRLA_CMD_PBC 0x44
+#define SAMD21_NVMCTRL_CTRLA_CMD_SSB 0x45
+#define SAMD21_NVMCTRL_CTRLA_CMD_INVALL 0x46
+#define SAMD21_NVMCTRL_CTRLA_CMD_LDR 0x47
+#define SAMD21_NVMCTRL_CTRLA_CMD_UDR 0x48
+#define SAMD21_NVMCTRL_CTRLA_CMDEX 8
+#define SAMD21_NVMCTRL_CTRLA_CMDEX_KEY 0xa5
+
+#define SAMD21_NVMCTRL_CTRLB_RWS 1
+#define SAMD21_NVMCTRL_CTRLB_MANW 7
+#define SAMD21_NVMCTRL_CTRLB_SLEEPRM 8
+#define SAMD21_NVMCTRL_CTRLB_READMODE 16
+#define SAMD21_NVMCTRL_CTRLB_CACHEDIS 18
+
+#define SAMD21_NVMCTRL_INTENCLR_READY 0
+#define SAMD21_NVMCTRL_INTENCLR_ERROR 1
+
+#define SAMD21_NVMCTRL_INTENSET_READY 0
+#define SAMD21_NVMCTRL_INTENSET_ERROR 1
+
+#define SAMD21_NVMCTRL_INTFLAG_READY 0
+#define SAMD21_NVMCTRL_INTFLAG_ERROR 1
+
+#define SAMD21_NVMCTRL_STATUS_PRM 0
+#define SAMD21_NVMCTRL_STATUS_LOAD 1
+#define SAMD21_NVMCTRL_STATUS_PROGE 2
+#define SAMD21_NVMCTRL_STATUS_LOCKE 3
+#define SAMD21_NVMCTRL_STATUS_NVME 4
+#define SAMD21_NVMCTRL_STATUS_SB 8
+
+#define SAMD21_NVMCTRL_PARAM_NVMP 0
+#define SAMD21_NVMCTRL_PARAM_NVMP_MASK 0xffff
+#define SAMD21_NVMCTRL_PARAM_PSZ 16
+#define SAMD21_NVMCTRL_PARAM_PSZ_MASK 0x7
+#define SAMD21_NVMCTRL_PARAM_RWWEEP 20
+#define SAMD21_NVMCTRL_PARAM_RWWEEP_MASK 0xfff
+
+static inline uint32_t
+samd21_nvmctrl_page_shift(void)
+{
+ return(3 + ((samd21_nvmctrl.param >> SAMD21_NVMCTRL_PARAM_PSZ) &
+ SAMD21_NVMCTRL_PARAM_PSZ_MASK));
+}
+
+static inline uint32_t
+samd21_nvmctrl_page_size(void)
+{
+ return 1 << samd21_nvmctrl_page_shift();
+}
+
+uint32_t
+samd21_flash_size(void);
+
+struct samd21_port {
+ vuint32_t dir;
+ vuint32_t dirclr;
+ vuint32_t dirset;
+ vuint32_t dirtgl;
+
+ vuint32_t out;
+ vuint32_t outclr;
+ vuint32_t outset;
+ vuint32_t outtgl;
+
+ vuint32_t in;
+ vuint32_t ctrl;
+ vuint32_t wrconfig;
+ vuint32_t reserved_2c;
+
+ vuint8_t pmux[16];
+
+ vuint8_t pincfg[32];
+};
+
+extern struct samd21_port samd21_port_a;
+extern struct samd21_port samd21_port_b;
+
+#define samd21_port_a (*(struct samd21_port *) 0x41004400)
+#define samd21_port_b (*(struct samd21_port *) 0x41004480)
+
+#define SAMD21_PORT_PINCFG_PMUXEN 0
+#define SAMD21_PORT_PINCFG_INEN 1
+#define SAMD21_PORT_PINCFG_PULLEN 2
+#define SAMD21_PORT_PINCFG_DRVSTR 6
+
+#define SAMD21_PORT_PMUX_FUNC_A 0
+#define SAMD21_PORT_PMUX_FUNC_B 1
+#define SAMD21_PORT_PMUX_FUNC_C 2
+#define SAMD21_PORT_PMUX_FUNC_D 3
+#define SAMD21_PORT_PMUX_FUNC_E 4
+#define SAMD21_PORT_PMUX_FUNC_F 5
+#define SAMD21_PORT_PMUX_FUNC_G 6
+#define SAMD21_PORT_PMUX_FUNC_H 7
+#define SAMD21_PORT_PMUX_FUNC_I 8
+
+#define SAMD21_PORT_DIR_OUT 1
+#define SAMD21_PORT_DIR_IN 0
+
+static inline void
+samd21_port_dir_set(struct samd21_port *port, uint8_t pin, uint8_t dir)
+{
+ if (dir)
+ port->dirset = (1 << pin);
+ else
+ port->dirclr = (1 << pin);
+}
+
+static inline void
+samd21_port_pincfg_set(struct samd21_port *port, uint8_t pin, uint8_t pincfg_mask, uint8_t pincfg)
+{
+ port->pincfg[pin] = (uint8_t) ((port->pincfg[pin] & ~pincfg_mask) | pincfg);
+}
+
+static inline uint8_t
+samd21_port_pincfg_get(struct samd21_port *port, uint8_t pin)
+{
+ return port->pincfg[pin];
+}
+
+static inline void
+samd21_port_pmux_set(struct samd21_port *port, uint8_t pin, uint8_t func)
+{
+ uint8_t byte = pin >> 1;
+ uint8_t bit = (pin & 1) << 2;
+ uint8_t mask = 0xf << bit;
+ uint8_t value = (uint8_t) ((port->pmux[byte] & ~mask) | (func << bit));
+ port->pmux[byte] = value;
+ samd21_port_pincfg_set(port, pin,
+ (1 << SAMD21_PORT_PINCFG_PMUXEN),
+ (1 << SAMD21_PORT_PINCFG_PMUXEN));
+}
+
+static inline uint8_t
+samd21_port_pmux_get(struct samd21_port *port, uint8_t pin)
+{
+ uint8_t byte = pin >> 1;
+ uint8_t bit = (pin & 1) << 2;
+ uint8_t mask = 0xf << bit;
+ uint8_t value = (uint8_t) ((port->pmux[byte] & mask) >> bit);
+ return value;
+}
+
+static inline void
+samd21_port_pmux_clr(struct samd21_port *port, uint8_t pin)
+{
+ samd21_port_pincfg_set(port, pin,
+ (0 << SAMD21_PORT_PINCFG_PMUXEN),
+ (1 << SAMD21_PORT_PINCFG_PMUXEN));
+}
+
+struct samd21_adc {
+ vuint8_t ctrla;
+ vuint8_t refctrl;
+ vuint8_t avgctrl;
+ vuint8_t sampctrl;
+ vuint16_t ctrlb;
+ vuint16_t reserved_06;
+ vuint8_t winctrl;
+ vuint8_t reserved_09;
+ vuint16_t reserved_0a;
+ vuint8_t swtrig;
+ vuint8_t reserved_0d;
+ vuint16_t reserved_0e;
+
+ vuint32_t inputctrl;
+ vuint8_t evctrl;
+ vuint8_t reserved_15;
+ vuint8_t intenclr;
+ vuint8_t intenset;
+ vuint8_t intflag;
+ vuint8_t status;
+ vuint16_t result;
+ vuint16_t winlt;
+ vuint16_t reserved_1e;
+
+ vuint16_t winut;
+ vuint16_t reserved_22;
+ vuint16_t gaincorr;
+ vuint16_t offsetcorr;
+ vuint16_t calib;
+ vuint8_t dbgctrl;
+ vuint8_t reserved_2b;
+ vuint32_t reserved_2c;
+};
+
+#define SAMD21_ADC_CTRLA_SWRST 0
+#define SAMD21_ADC_CTRLA_ENABLE 1
+#define SAMD21_ADC_CTRLA_RUNSTDBY 2
+
+#define SAMD21_ADC_REFCTRL_REFSEL 0
+#define SAMD21_ADC_REFCTRL_REFSEL_INT1V 0
+#define SAMD21_ADC_REFCTRL_REFSEL_INTVCC0 1
+#define SAMD21_ADC_REFCTRL_REFSEL_INTVCC1 2
+#define SAMD21_ADC_REFCTRL_REFSEL_VREFA 3
+#define SAMD21_ADC_REFCTRL_REFSEL_VREFB 4
+#define SAMD21_ADC_REFCTRL_REFCOMP 7
+
+#define SAMD21_ADC_AVGCTRL_SAMPLENUM 0
+#define SAMD21_ADC_AVGCTRL_ADJRES 4
+
+#define SAMD21_ADC_SAMPCTRL_SAMPLEN 0
+
+#define SAMD21_ADC_CTRLB_DIFFMODE 0
+#define SAMD21_ADC_CTRLB_LEFTADJ 1
+#define SAMD21_ADC_CTRLB_FREERUN 2
+#define SAMD21_ADC_CTRLB_CORREN 3
+#define SAMD21_ADC_CTRLB_RESSEL 4
+#define SAMD21_ADC_CTRLB_RESSEL_12BIT 0
+#define SAMD21_ADC_CTRLB_RESSEL_16BIT 1
+#define SAMD21_ADC_CTRLB_RESSEL_10BIT 2
+#define SAMD21_ADC_CTRLB_RESSEL_8BIT 3
+#define SAMD21_ADC_CTRLB_PRESCALER 8
+#define SAMD21_ADC_CTRLB_PRESCALER_DIV4 0
+#define SAMD21_ADC_CTRLB_PRESCALER_DIV8 1
+#define SAMD21_ADC_CTRLB_PRESCALER_DIV16 2
+#define SAMD21_ADC_CTRLB_PRESCALER_DIV32 3
+#define SAMD21_ADC_CTRLB_PRESCALER_DIV64 4
+#define SAMD21_ADC_CTRLB_PRESCALER_DIV128 5
+#define SAMD21_ADC_CTRLB_PRESCALER_DIV256 6
+#define SAMD21_ADC_CTRLB_PRESCALER_DIV512 7
+
+#define SAMD21_ADC_SWTRIG_FLUSH 0
+#define SAMD21_ADC_SWTRIG_START 1
+
+#define SAMD21_ADC_INPUTCTRL_MUXPOS 0
+# define SAMD21_ADC_INPUTCTRL_MUXPOS_TEMP 0x18
+# define SAMD21_ADC_INPUTCTRL_MUXPOS_BANDGAP 0x19
+# define SAMD21_ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC 0x1a
+# define SAMD21_ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC 0x1b
+# define SAMD21_ADC_INPUTCTRL_MUXPOS_DAC 0x1c
+#define SAMD21_ADC_INPUTCTRL_MUXNEG 8
+# define SAMD21_ADC_INPUTCTRL_MUXNEG_GND 0x18
+# define SAMD21_ADC_INPUTCTRL_MUXNEG_IOGND 0x19
+#define SAMD21_ADC_INPUTCTRL_INPUTSCAN 16
+#define SAMD21_ADC_INPUTCTRL_INPUTOFFSET 20
+#define SAMD21_ADC_INPUTCTRL_GAIN 24
+#define SAMD21_ADC_INPUTCTRL_GAIN_1X 0
+#define SAMD21_ADC_INPUTCTRL_GAIN_DIV2 0xf
+
+#define SAMD21_ADC_INTFLAG_RESRDY 0
+#define SAMD21_ADC_INTFLAG_OVERRUN 1
+#define SAMD21_ADC_INTFLAG_WINMON 2
+#define SAMD21_ADC_INTFLAG_SYNCRDY 3
+
+#define SAMD21_ADC_STATUS_SYNCBUSY 7
+
+#define SAMD21_ADC_CALIB_LINEARITY_CAL 0
+#define SAMD21_ADC_CALIB_BIAS_CAL 16
+
+extern struct samd21_adc samd21_adc;
+
+#define samd21_adc (*(struct samd21_adc *) 0x42004000)
+
+struct samd21_dac {
+ vuint8_t ctrla;
+ vuint8_t ctrlb;
+ vuint8_t evctrl;
+ uint8_t reserved_03;
+
+ vuint8_t intenclr;
+ vuint8_t intenset;
+ vuint8_t intflag;
+ vuint8_t status;
+
+ vuint16_t data;
+ uint16_t reserved_0a;
+
+ vuint16_t databuf;
+};
+
+#define SAMD21_DAC_CTRLA_SWRST 0
+#define SAMD21_DAC_CTRLA_ENABLE 1
+#define SAMD21_DAC_CTRLA_RUNSTDBY 2
+
+#define SAMD21_DAC_CTRLB_EOEN 0
+#define SAMD21_DAC_CTRLB_IOEN 1
+#define SAMD21_DAC_CTRLB_LEFTADJ 2
+#define SAMD21_DAC_CTRLB_VPD 3
+#define SAMD21_DAC_CTRLB_BDWP 4
+#define SAMD21_DAC_CTRLB_REFSEL 6
+#define SAMD21_DAC_CTRLB_REFSEL_INTREF 0
+#define SAMD21_DAC_CTRLB_REFSEL_VDDANA 1
+#define SAMD21_DAC_CTRLB_REFSEL_VREFA 2
+#define SAMD21_DAC_CTRLB_REFSEL_MASK 3
+
+#define SAMD21_DAC_EVCTRL_STARTEI 0
+#define SAMD21_DAC_EVCTRL_EMPTYEO 1
+
+#define SAMD21_DAC_INTENCLR_UNDERRUN 0
+#define SAMD21_DAC_INTENCLR_EMPTY 1
+#define SAMD21_DAC_INTENCLR_SYNCRDY 2
+
+#define SAMD21_DAC_INTENSET_UNDERRUN 0
+#define SAMD21_DAC_INTENSET_EMPTY 1
+#define SAMD21_DAC_INTENSET_SYNCRDY 2
+
+#define SAMD21_DAC_INTFLAG_UNDERRUN 0
+#define SAMD21_DAC_INTFLAG_EMPTY 1
+#define SAMD21_DAC_INTFLAG_SYNCRDY 2
+
+#define SAMD21_DAC_STATUS_SYNCBUSY 7
+
+extern struct samd21_dac samd21_dac;
+#define samd21_dac (*(struct samd21_dac *) 0x42004800)
+
+/* TC */
+struct samd21_tc {
+ vuint16_t ctrla;
+ vuint16_t readreq;
+ vuint8_t ctrlbclr;
+ vuint8_t ctrlbset;
+ vuint8_t ctrlc;
+ vuint8_t reserved_07;
+ vuint8_t dbgctrl;
+ vuint8_t reserved_09;
+ vuint16_t evctrl;
+ vuint8_t intenclr;
+ vuint8_t intenset;
+ vuint8_t intflag;
+ vuint8_t status;
+
+ union {
+ struct {
+ vuint8_t count;
+ vuint8_t reserved_11;
+ vuint16_t reserved_12;
+ vuint8_t per;
+ vuint8_t reserved_15;
+ vuint16_t reserved_16;
+ vuint8_t cc[2];
+ } mode_8;
+ struct {
+ vuint16_t count;
+ vuint16_t reserved_12;
+ vuint32_t reserved_14;
+ vuint16_t cc[2];
+ } mode_16;
+ struct {
+ vuint32_t count;
+ vuint32_t reserved_14;
+ vuint32_t cc[2];
+ } mode_32;
+ };
+};
+
+extern struct samd21_tc samd21_tc3;
+#define samd21_tc3 (*(struct samd21_tc *) 0x42002c00)
+
+extern struct samd21_tc samd21_tc4;
+#define samd21_tc4 (*(struct samd21_tc *) 0x42003000)
+
+extern struct samd21_tc samd21_tc5;
+#define samd21_tc5 (*(struct samd21_tc *) 0x42003400)
+
+#ifdef ATSAMD21J
+/* Present on all of the samd21j parts and the samd21g16l */
+extern struct samd21_tc samd21_tc6;
+#define samd21_tc6 (*(struct samd21_tc *) 0x42003800)
+
+extern struct samd21_tc samd21_tc7;
+#define samd21_tc7 (*(struct samd21_tc *) 0x42003c00)
+#endif
+
+#define SAMD21_TC_CTRLA_SWRST 0
+#define SAMD21_TC_CTRLA_ENABLE 1
+#define SAMD21_TC_CTRLA_MODE 2
+#define SAMD21_TC_CTRLA_MODE_COUNT16 0
+#define SAMD21_TC_CTRLA_MODE_COUNT8 1
+#define SAMD21_TC_CTRLA_MODE_COUNT32 2
+#define SAMD21_TC_CTRLA_WAVEGEN 5
+#define SAMD21_TC_CTRLA_WAVEGEN_NFRQ 0
+#define SAMD21_TC_CTRLA_WAVEGEN_MFRQ 1
+#define SAMD21_TC_CTRLA_WAVEGEN_NPWM 2
+#define SAMD21_TC_CTRLA_WAVEGEN_MPWM 3
+#define SAMD21_TC_CTRLA_PRESCALER 8
+#define SAMD21_TC_CTRLA_PRESCALER_DIV1 0
+#define SAMD21_TC_CTRLA_PRESCALER_DIV2 1
+#define SAMD21_TC_CTRLA_PRESCALER_DIV4 2
+#define SAMD21_TC_CTRLA_PRESCALER_DIV8 3
+#define SAMD21_TC_CTRLA_PRESCALER_DIV16 4
+#define SAMD21_TC_CTRLA_PRESCALER_DIV64 5
+#define SAMD21_TC_CTRLA_PRESCALER_DIV256 6
+#define SAMD21_TC_CTRLA_PRESCALER_DIV1024 7
+#define SAMD21_TC_CTRLA_RUNSTDBY 11
+#define SAMD21_TC_CTRLA_PRESCSYNC 12
+#define SAMD21_TC_CTRLA_PRESCSYNC_GCLK 0
+#define SAMD21_TC_CTRLA_PRESCSYNC_PRSEC 1
+#define SAMD21_TC_CTRLA_PRESCSYNC_RESYNC 2
+
+#define SAMD21_TC_READREQ_ADDR 0
+#define SAMD21_TC_READREQ_RCONT 14
+#define SAMD21_TC_READREQ_RREQ 15
+#define SAMD21_TC_CTRLB_DIR 0
+#define SAMD21_TC_CTRLB_ONESHOT 2
+#define SAMD21_TC_CTRLB_CMD 6
+#define SAMD21_TC_CTRLC_INVEN(x) (0 + (x))
+#define SAMD21_TC_CTRLC_CPTEN(x) (4 + (x))
+#define SAMD21_TC_DBGCTRL_DBGRUN 0
+#define SAMD21_TC_EVCTRL_EVACT 0
+#define SAMD21_TC_EVCTRL_TCINV 4
+#define SAMD21_TC_EVCTRL_TCEI 5
+#define SAMD21_TC_EVCTRL_OVFEO 8
+#define SAMD21_TC_EVCTRL_MCEO(x) (12 + (x))
+
+#define SAMD21_TC_INTFLAG_MC(x) (4 + (x))
+#define SAMD21_TC_INTFLAG_SYNCRDY 3
+#define SAMD21_TC_INTFLAG_ERR 1
+#define SAMD21_TC_INTFLAG_OVF 0
+
+#define SAMD21_TC_STATUS_STOP 3
+#define SAMD21_TC_STATUS_FOLLOWER 4
+#define SAMD21_TC_STATUS_SYNCBUSY 7
+
+/* TCC */
+
+struct samd21_tcc {
+ vuint32_t ctrla;
+ vuint8_t ctrlbclr;
+ vuint8_t ctrlbset;
+ vuint16_t reserved_06;
+ vuint32_t syncbusy;
+ vuint32_t fctrla;
+
+ vuint32_t fctlrb;
+ vuint32_t wexctrl;
+ vuint32_t drvctrl;
+ vuint16_t reserved_1c;
+ vuint8_t dbgctrl;
+ vuint8_t reserved_1f;
+
+ vuint32_t evctrl;
+ vuint32_t intenclr;
+ vuint32_t intenset;
+ vuint32_t intflag;
+
+ vuint32_t status;
+ vuint32_t count;
+ vuint16_t patt;
+ vuint16_t reserved_3a;
+ vuint32_t wave;
+
+ vuint32_t per;
+ vuint32_t cc[4];
+ vuint32_t reserved_54;
+ vuint32_t reserved_58;
+ vuint32_t reserved_5c;
+
+ vuint32_t reserved_60;
+ vuint16_t pattb;
+ vuint16_t reserved_66;
+ vuint32_t waveb;
+ vuint32_t perb;
+
+ vuint32_t ccb[4];
+};
+
+extern struct samd21_tcc samd21_tcc0;
+#define samd21_tcc0 (*(struct samd21_tcc *) 0x42002000)
+
+extern struct samd21_tcc samd21_tcc1;
+#define samd21_tcc1 (*(struct samd21_tcc *) 0x42002400)
+
+extern struct samd21_tcc samd21_tcc2;
+#define samd21_tcc2 (*(struct samd21_tcc *) 0x42002800)
+
+#ifdef SAMD21E17D
+/* only on the samd21e17d */
+extern struct samd21_tcc samd21_tcc3;
+#define samd21_tcc3 (*(struct samd21_tcc *) 0x42006000)
+#endif
+
+#define SAMD21_TCC_CTRLA_SWRST 0
+#define SAMD21_TCC_CTRLA_ENABLE 1
+#define SAMD21_TCC_CTRLA_RESOLUTION 5
+#define SAMD21_TCC_CTRLA_RESOLUTION_NONE 0
+#define SAMD21_TCC_CTRLA_RESOLUTION_DITH4 1
+#define SAMD21_TCC_CTRLA_RESOLUTION_DITH5 2
+#define SAMD21_TCC_CTRLA_RESOLUTION_DITH6 3
+#define SAMD21_TCC_CTRLA_PRESCALER 8
+#define SAMD21_TCC_CTRLA_PRESCALER_DIV1 0
+#define SAMD21_TCC_CTRLA_PRESCALER_DIV2 1
+#define SAMD21_TCC_CTRLA_PRESCALER_DIV4 2
+#define SAMD21_TCC_CTRLA_PRESCALER_DIV8 3
+#define SAMD21_TCC_CTRLA_PRESCALER_DIV16 4
+#define SAMD21_TCC_CTRLA_PRESCALER_DIV64 5
+#define SAMD21_TCC_CTRLA_PRESCALER_DIV256 6
+#define SAMD21_TCC_CTRLA_PRESCALER_DIV1024 7
+#define SAMD21_TCC_CTRLA_RUNSTDBY 11
+#define SAMD21_TCC_CTRLA_PRESYNC 12
+#define SAMD21_TCC_CTRLA_PRESYNC_GCLK 0
+#define SAMD21_TCC_CTRLA_PRESYNC_PRESC 1
+#define SAMD21_TCC_CTRLA_PRESYNC_RESYNC 2
+#define SAMD21_TCC_CTRLA_ALOCK 14
+#define SAMD21_TCC_CTRLA_CPTEN(n) (24 + (n))
+
+#define SAMD21_TCC_CTRLB_DIR 0
+#define SAMD21_TCC_CTRLB_LUPD 1
+#define SAMD21_TCC_CTRLB_ONESHOT 2
+#define SAMD21_TCC_CTRLB_IDXCMD 3
+#define SAMD21_TCC_CTRLB_IDXCMD_DISABLE 0
+#define SAMD21_TCC_CTRLB_IDXCMD_SET 1
+#define SAMD21_TCC_CTRLB_IDXCMD_CLEAR 2
+#define SAMD21_TCC_CTRLB_IDXCMD_HOLD 3
+#define SAMD21_TCC_CTRLB_CMD 5
+#define SAMD21_TCC_CTRLB_CMD_NONE 0
+#define SAMD21_TCC_CTRLB_CMD_RETRIGGER 1
+#define SAMD21_TCC_CTRLB_CMD_STOP 2
+#define SAMD21_TCC_CTRLB_CMD_UPDATE 3
+#define SAMD21_TCC_CTRLB_CMD_READSYNC 4
+#define SAMD21_TCC_CTRLB_CMD_DMAOS 5
+
+#define SAMD21_TCC_SYNCBUSY_SWRST 0
+#define SAMD21_TCC_SYNCBUSY_ENABLE 1
+#define SAMD21_TCC_SYNCBUSY_CTRLB 2
+#define SAMD21_TCC_SYNCBUSY_STATUS 3
+#define SAMD21_TCC_SYNCBUSY_COUNT 4
+#define SAMD21_TCC_SYNCBUSY_PATT 5
+#define SAMD21_TCC_SYNCBUSY_WAVE 6
+#define SAMD21_TCC_SYNCBUSY_PER 7
+#define SAMD21_TCC_SYNCBUSY_CC(x) (8 + (x))
+#define SAMD21_TCC_SYNCBUSY_PATTB 16
+#define SAMD21_TCC_SYNCBUSY_WAVEB 17
+#define SAMD21_TCC_SYNCBUSY_PERB 18
+#define SAMD21_TCC_SYNCBUSY_CCB(x) ((19 + (x))
+
+#define SAMD21_TCC_DBGCTRL_FDDBD 2
+#define SAMD21_TCC_DBGCTRL_DBGRUN 0
+
+#define SAMD21_TCC_EVCTRL_EVACTO 0
+#define SAMD21_TCC_EVCTRL_EVACT1 3
+#define SAMD21_TCC_EVCTRL_CNTSEL 6
+#define SAMD21_TCC_EVCTRL_OVFEO 8
+#define SAMD21_TCC_EVCTRL_TRGEO 9
+#define SAMD21_TCC_EVCTRL_CNTEO 10
+#define SAMD21_TCC_EVCTRL_TCINV(x) (12 + (x))
+#define SAMD21_TCC_EVCTRL_MCEI(x) (16 + (x))
+#define SAMD21_TCC_EVCTRL_MCEO(x) (24 + (x))
+
+#define SAMD21_TCC_INTFLAG_OVF 0
+#define SAMD21_TCC_INTFLAG_TRG 1
+#define SAMD21_TCC_INTFLAG_CNT 2
+#define SAMD21_TCC_INTFLAG_ERR 3
+#define SAMD21_TCC_INTFLAG_UFS 10
+#define SAMD21_TCC_INTFLAG_DFS 11
+#define SAMD21_TCC_INTFLAG_FAULTA 12
+#define SAMD21_TCC_INTFLAG_FAULTB 13
+#define SAMD21_TCC_INTFLAG_FAULT0 14
+#define SAMD21_TCC_INTFLAG_FAULT1 15
+#define SAMD21_TCC_INTFLAG_MC(x) (16 + (x))
+
+#define SAMD21_TCC_WAVE_WAVEGEN 0
+#define SAMD21_TCC_WAVE_WAVEGEN_NFRQ 0
+#define SAMD21_TCC_WAVE_WAVEGEN_MFRQ 1
+#define SAMD21_TCC_WAVE_WAVEGEN_NPWM 2
+#define SAMD21_TCC_WAVE_WAVEGEN_DSCRITICAL 4
+#define SAMD21_TCC_WAVE_WAVEGEN_DSBOTTOM 5
+#define SAMD21_TCC_WAVE_WAVEGEN_DSBOTH 6
+#define SAMD21_TCC_WAVE_WAVEGEN_DSTOP 7
+#define SAMD21_TCC_WAVE_RAMP 4
+#define SAMD21_TCC_WAVE_CIPEREN 7
+#define SAMD21_TCC_WAVE_CCCEN(x) (8 + (x))
+#define SAMD21_TCC_WAVE_POL(x) (16 + (x))
+#define SAMD21_TCC_WAVE_SWAP(x) (24 + (x))
+
+/* USB */
+
+struct samd21_usb {
+ vuint8_t ctrla;
+ vuint8_t reserved_01;
+ vuint8_t syncbusy;
+ vuint8_t qosctrl;
+
+ vuint32_t reserved_04;
+ vuint16_t ctrlb;
+ vuint8_t dadd;
+ vuint8_t reserved_0b;
+ vuint8_t status;
+ vuint8_t fsmstatus;
+ vuint16_t reserved_0e;
+
+ vuint16_t fnum;
+ vuint16_t reserved_12;
+ vuint16_t intenclr;
+ vuint16_t reserved_16;
+ vuint16_t intenset;
+ vuint16_t reserved_1a;
+ vuint16_t intflag;
+ vuint16_t reserved_1e;
+
+ vuint16_t epintsmry;
+ vuint16_t reserved_22;
+
+ vuint32_t descadd;
+ vuint16_t padcal;
+ uint8_t reserved_2a[0x100 - 0x2a];
+
+ struct {
+ vuint8_t epcfg;
+ vuint8_t reserved_01;
+ vuint8_t reserved_02;
+ vuint8_t binterval;
+ vuint8_t epstatusclr;
+ vuint8_t epstatusset;
+ vuint8_t epstatus;
+ vuint8_t epintflag;
+ vuint8_t epintenclr;
+ vuint8_t epintenset;
+ vuint8_t reserved_0a[0x20 - 0x0a];
+ } ep[8];
+};
+
+extern struct samd21_usb samd21_usb;
+
+#define samd21_usb (*(struct samd21_usb *) 0x41005000)
+
+#define SAMD21_USB_CTRLA_SWRST 0
+#define SAMD21_USB_CTRLA_ENABLE 1
+#define SAMD21_USB_CTRLA_RUNSTDBY 2
+#define SAMD21_USB_CTRLA_MODE 7
+
+#define SAMD21_USB_SYNCBUSY_SWRST 0
+#define SAMD21_USB_SYNCBUSY_ENABLE 1
+
+#define SAMD21_USB_QOSCTRL_CQOS 0
+#define SAMD21_USB_QOSCTRL_DQOS 2
+
+#define SAMD21_USB_CTRLB_DETACH 0
+#define SAMD21_USB_CTRLB_UPRSM 1
+#define SAMD21_USB_CTRLB_SPDCONF 2
+#define SAMD21_USB_CTRLB_SPDCONF_FS 0
+#define SAMD21_USB_CTRLB_SPDCONF_LS 1
+#define SAMD21_USB_CTRLB_SPDCONF_MASK 0x3
+#define SAMD21_USB_CTRLB_NREPLY 4
+#define SAMD21_USB_CTRLB_GNAK 9
+#define SAMD21_USB_CTRLB_LPMHDSK 10
+#define SAMD21_USB_CTRLB_LPMHDSK_NONE 0
+#define SAMD21_USB_CTRLB_LPMHDSK_ACK 1
+#define SAMD21_USB_CTRLB_LPMHDSK_NYET 2
+#define SAMD21_USB_CTRLB_LPMHDSK_MASK 3
+
+#define SAMD21_USB_DADD_DADD 0
+#define SAMD21_USB_DADD_ADDEN 7
+
+#define SAMD21_USB_STATUS_SPEED 2
+#define SAMD21_USB_STATUS_LINESTATE 6
+#define SAMD21_USB_FNUM_MFNUM 0
+#define SAMD21_USB_FNUM_FNUM 3
+#define SAMD21_USB_FNUM_FNCERR 15
+#define SAMD21_USB_INTFLAG_SUSPEND 0
+#define SAMD21_USB_INTFLAG_SOF 2
+#define SAMD21_USB_INTFLAG_EORST 3
+#define SAMD21_USB_INTFLAG_WAKEUP 4
+#define SAMD21_USB_INTFLAG_EORSM 5
+#define SAMD21_USB_INTFLAG_UPRSM 6
+#define SAMD21_USB_INTFLAG_RAMACER 7
+#define SAMD21_USB_INTFLAG_LPMNYET 8
+#define SAMD21_USB_INTFLAG_LPMSUSP 9
+
+#define SAMD21_USB_PADCAL_TRANSP 0
+#define SAMD21_USB_PADCAL_TRANSN 6
+#define SAMD21_USB_PADCAL_TRIM 12
+
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_OUT 0
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_OUT_DISABLED 0
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_OUT_CONTROL 1
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_OUT_ISOCHRONOUS 2
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_OUT_BULK 3
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_OUT_INTERRUPT 4
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_OUT_DUAL_BANK 5
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_IN 4
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_IN_DISABLED 0
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_IN_CONTROL 1
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_IN_ISOCHRONOUS 2
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_IN_BULK 3
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_IN_INTERRUPT 4
+#define SAMD21_USB_EP_EPCFG_EP_TYPE_IN_DUAL_BANK 5
+
+#define SAMD21_USB_EP_EPSTATUS_DTGLOUT 0
+#define SAMD21_USB_EP_EPSTATUS_DTGLIN 1
+#define SAMD21_USB_EP_EPSTATUS_CURBK 2
+#define SAMD21_USB_EP_EPSTATUS_STALLRQ0 4
+#define SAMD21_USB_EP_EPSTATUS_STALLRQ1 5
+#define SAMD21_USB_EP_EPSTATUS_BK0RDY 6
+#define SAMD21_USB_EP_EPSTATUS_BK1RDY 7
+
+#define SAMD21_USB_EP_EPINTFLAG_TRCPT0 0
+#define SAMD21_USB_EP_EPINTFLAG_TRCPT1 1
+#define SAMD21_USB_EP_EPINTFLAG_TRFAIL0 2
+#define SAMD21_USB_EP_EPINTFLAG_TRFAIL1 3
+#define SAMD21_USB_EP_EPINTFLAG_RXSTP 4
+#define SAMD21_USB_EP_EPINTFLAG_STALL 5
+
+struct samd21_usb_desc_bank {
+ vuint32_t addr;
+ vuint32_t pcksize;
+ vuint16_t extreg;
+ vuint8_t status_bk;
+ vuint8_t reserved_0b;
+ vuint32_t reserved_0c;
+};
+
+struct samd21_usb_desc {
+ struct samd21_usb_desc_bank bank[2];
+};
+
+extern struct samd21_usb_desc samd21_usb_desc[8];
+
+#define SAMD21_USB_DESC_PCKSIZE_BYTE_COUNT 0
+#define SAMD21_USB_DESC_PCKSIZE_BYTE_COUNT_MASK 0x3fffU
+#define SAMD21_USB_DESC_PCKSIZE_MULTI_PACKET_SIZE 14
+#define SAMD21_USB_DESC_PCKSIZE_MULTI_PACKET_SIZE_MASK 0x3fffU
+#define SAMD21_USB_DESC_PCKSIZE_SIZE 28
+#define SAMD21_USB_DESC_PCKSIZE_SIZE_8 0
+#define SAMD21_USB_DESC_PCKSIZE_SIZE_16 1
+#define SAMD21_USB_DESC_PCKSIZE_SIZE_32 2
+#define SAMD21_USB_DESC_PCKSIZE_SIZE_64 3
+#define SAMD21_USB_DESC_PCKSIZE_SIZE_128 4
+#define SAMD21_USB_DESC_PCKSIZE_SIZE_256 5
+#define SAMD21_USB_DESC_PCKSIZE_SIZE_512 6
+#define SAMD21_USB_DESC_PCKSIZE_SIZE_1023 7
+#define SAMD21_USB_DESC_PCKSIZE_SIZE_MASK 7U
+#define SAMD21_USB_DESC_PCKSIZE_AUTO_ZLP 31
+
+static inline uint16_t
+samd21_usb_desc_get_byte_count(uint8_t ep, uint8_t bank)
+{
+ return ((samd21_usb_desc[ep].bank[bank].pcksize >> SAMD21_USB_DESC_PCKSIZE_BYTE_COUNT) &
+ SAMD21_USB_DESC_PCKSIZE_BYTE_COUNT_MASK);
+}
+
+static inline void
+samd21_usb_desc_set_byte_count(uint8_t ep, uint8_t bank, uint32_t count)
+{
+ uint32_t pcksize = samd21_usb_desc[ep].bank[bank].pcksize;
+
+ pcksize &= ~(SAMD21_USB_DESC_PCKSIZE_BYTE_COUNT_MASK << SAMD21_USB_DESC_PCKSIZE_BYTE_COUNT);
+ pcksize &= ~(SAMD21_USB_DESC_PCKSIZE_MULTI_PACKET_SIZE_MASK << SAMD21_USB_DESC_PCKSIZE_MULTI_PACKET_SIZE);
+ pcksize |= (count << SAMD21_USB_DESC_PCKSIZE_BYTE_COUNT);
+ samd21_usb_desc[ep].bank[bank].pcksize = pcksize;
+}
+
+static inline void
+samd21_usb_desc_set_size(uint8_t ep, uint8_t bank, uint32_t size)
+{
+ uint32_t pcksize = samd21_usb_desc[ep].bank[bank].pcksize;
+
+ pcksize &= ~(SAMD21_USB_DESC_PCKSIZE_SIZE_MASK << SAMD21_USB_DESC_PCKSIZE_SIZE);
+
+ uint32_t size_bits = 0;
+ switch (size) {
+ case 8: size_bits = SAMD21_USB_DESC_PCKSIZE_SIZE_8; break;
+ case 16: size_bits = SAMD21_USB_DESC_PCKSIZE_SIZE_16; break;
+ case 32: size_bits = SAMD21_USB_DESC_PCKSIZE_SIZE_32; break;
+ case 64: size_bits = SAMD21_USB_DESC_PCKSIZE_SIZE_64; break;
+ case 128: size_bits = SAMD21_USB_DESC_PCKSIZE_SIZE_128; break;
+ case 256: size_bits = SAMD21_USB_DESC_PCKSIZE_SIZE_256; break;
+ case 512: size_bits = SAMD21_USB_DESC_PCKSIZE_SIZE_512; break;
+ case 1023: size_bits = SAMD21_USB_DESC_PCKSIZE_SIZE_1023; break;
+ }
+ pcksize |= (size_bits << SAMD21_USB_DESC_PCKSIZE_SIZE);
+ samd21_usb_desc[ep].bank[bank].pcksize = pcksize;
+}
+
+static inline void
+samd21_usb_ep_set_ready(uint8_t ep, uint8_t bank)
+{
+ samd21_usb.ep[ep].epstatusset = (1 << (SAMD21_USB_EP_EPSTATUS_BK0RDY + bank));
+ samd21_usb.ep[ep].epintflag = (1 << (SAMD21_USB_EP_EPINTFLAG_TRFAIL0 + bank));
+}
+
+static inline void
+samd21_usb_ep_clr_ready(uint8_t ep, uint8_t bank)
+{
+ samd21_usb.ep[ep].epstatusclr = (1 << (SAMD21_USB_EP_EPSTATUS_BK0RDY + bank));
+}
+
+static inline uint8_t
+samd21_usb_ep_ready(uint8_t ep)
+{
+ return (samd21_usb.ep[ep].epstatus >> SAMD21_USB_EP_EPSTATUS_BK0RDY) & 3;
+}
+
+static inline uint8_t
+samd21_usb_ep_curbk(uint8_t ep)
+{
+ return (samd21_usb.ep[ep].epstatus >> SAMD21_USB_EP_EPSTATUS_CURBK) & 1;
+}
+
+/* evsys */
+
+struct samd21_evsys {
+ vuint8_t ctrl;
+ vuint8_t reserved_01;
+ vuint16_t reserved_02;
+ vuint32_t channel;
+ vuint16_t user;
+ vuint16_t reserved_0a;
+ vuint32_t chstatus;
+
+ vuint32_t intenclr;
+ vuint32_t intenset;
+ vuint32_t intflag;
+};
+
+extern struct samd21_evsys samd21_evsys;
+
+#define SAMD21_NUM_EVSYS 16
+
+#define samd21_evsys (*(struct samd21_evsys *) 0x42000400)
+
+#define SAMD21_EVSYS_CONTROL_SWRST 0
+#define SAMD21_EVSYS_CONTROL_GCLKREQ 4
+
+#define SAMD21_EVSYS_CHANNEL_CHANNEL 0
+
+#define SAMD21_EVSYS_CHANNEL_SWEVT 8
+
+#define SAMD21_EVSYS_CHANNEL_EVGEN 16
+#define SAMD21_EVSYS_CHANNEL_EVGEN_NONE 0x00
+#define SAMD21_EVSYS_CHANNEL_EVGEN_RTC_CMP(i) (0x01 + (i))
+#define SAMD21_EVSYS_CHANNEL_EVGEN_OVF 0x03
+#define SAMD21_EVSYS_CHANNEL_EVGEN_PER(i) (0x04 + (i))
+#define SAMD21_EVSYS_CHANNEL_EVGEN_EXTINT(i) (0x0c + (i))
+#define SAMD21_EVSYS_CHANNEL_EVGEN_DMAC_CH(i) (0x1e + (i))
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC0_OVF 0x22
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC0_TRG 0x23
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC0_CNT 0x29
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC0_MCX(i) (0x25 + (i))
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC1_OVF 0x29
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC1_TRG 0x2a
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC1_CNT 0x2b
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC1_MCX(i) (0x2c + (i))
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC2_OVF 0x2e
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC2_TRG 0x2f
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC2_CNT 0x30
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC2_MCX(i) (0x31 + (i))
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TC3_OVF 0x33
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TC3_MC(i) (0x34 + (i))
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TC4_OVF 0x36
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TC4_MC(i) (0x37 + (i))
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TC5_OVF 0x39
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TC5_MC(i) (0x3a + (i))
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TC6_OVF 0x3c
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TC6_MC(i) (0x3d + (i))
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TC7_OVF 0x3f
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TC7_MC(i) (0x40 + (i))
+#define SAMD21_EVSYS_CHANNEL_EVGEN_ADC_RESRDY 0x42
+#define SAMD21_EVSYS_CHANNEL_EVGEN_ADC_WINMON 0x43
+#define SAMD21_EVSYS_CHANNEL_EVGEN_AC_COMP0 0x44
+#define SAMD21_EVSYS_CHANNEL_EVGEN_AC_COMP1 0x45
+#define SAMD21_EVSYS_CHANNEL_EVGEN_AC_WIN0 0x46
+#define SAMD21_EVSYS_CHANNEL_EVGEN_DAC_EMPTY 0x47
+#define SAMD21_EVSYS_CHANNEL_EVGEN_PTC_EOC 0x48
+#define SAMD21_EVSYS_CHANNEL_EVGEN_PTC_WCOMP 0x49
+#define SAMD21_EVSYS_CHANNEL_EVGEN_AC_COMP2 0x4a
+#define SAMD21_EVSYS_CHANNEL_EVGEN_AC_COMP3 0x4b
+#define SAMD21_EVSYS_CHANNEL_EVGEN_AC_WIN1 0x4c
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC3_OVF 0x4d
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC3_TRG 0x4e
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC3_CNT 0x4f
+#define SAMD21_EVSYS_CHANNEL_EVGEN_TCC3_MCX(i) (0x50 + (i))
+
+#define SAMD21_EVSYS_CHANNEL_PATH 24
+#define SAMD21_EVSYS_CHANNEL_PATH_SYNCHRONOUS 0
+#define SAMD21_EVSYS_CHANNEL_PATH_RESYNCHRONIZED 1
+#define SAMD21_EVSYS_CHANNEL_PATH_ASYNCHRONOUS 2
+
+#define SAMD21_EVSYS_CHANNEL_EDGESEL 26
+#define SAMD21_EVSYS_CHANNEL_EDGESEL_NO_EVT_OUTPUT 0
+#define SAMD21_EVSYS_CHANNEL_EDGESEL_RISING_EDGE 1
+#define SAMD21_EVSYS_CHANNEL_EDGESEL_FALLING_EDGE 2
+#define SAMD21_EVSYS_CHANNEL_EDGESEL_BOTH_EDGES 3
+
+#define SAMD21_EVSYS_USER_USER 0
+#define SAMD21_EVSYS_USER_USER_DMAC_CH(n) (0x00 + (n))
+#define SAMD21_EVSYS_USER_USER_TCC0_EV(n) (0x04 + (n))
+#define SAMD21_EVSYS_USER_USER_TCC0_MC(n) (0x06 + (n))
+#define SAMD21_EVSYS_USER_USER_TCC1_EV(n) (0x0a + (n))
+#define SAMD21_EVSYS_USER_USER_TCC1_MC(n) (0x0c + (n))
+#define SAMD21_EVSYS_USER_USER_TCC2_EV(n) (0x0e + (n))
+#define SAMD21_EVSYS_USER_USER_TCC2_MC(n) (0x10 + (n))
+#define SAMD21_EVSYS_USER_USER_TC(n) (0x12 + (n))
+#define SAMD21_EVSYS_USER_USER_ADC_START (0x17)
+#define SAMD21_EVSYS_USER_USER_ADC_SYNC 0x18
+#define SAMD21_EVSYS_USER_USER_AC_COMP0 0x19
+#define SAMD21_EVSYS_USER_USER_AC_COMP1 0x1a
+#define SAMD21_EVSYS_USER_USER_DAC_START 0x1b
+#define SAMD21_EVSYS_USER_USER_PTC_STCONV 0x1c
+#define SAMD21_EVSYS_USER_USER_AC_COMP2 0x1d
+#define SAMD21_EVSYS_USER_USER_AC_COMP3 0x1e
+#define SAMD21_EVSYS_USER_USER_TCC3_EV(n) (0x1f + (n))
+#define SAMD21_EVSYS_USER_USER_TCC3_MC(n) (0x21 + (n))
+
+#define SAMD21_EVSYS_USER_CHANNEL 8
+#define SAMD21_EVSYS_USER_CHANNEL_NONE 0
+#define SAMD21_EVSYS_USER_CHANNEL_NUM(n) ((n) + 1)
+
+
+#define SAMD21_EVSYS_CHSTATUS_USRRDY(n) (((n) & 7) | (((n) & 8) << 1))
+#define SAMD21_EVSYS_CHSTATUS_CHBUSY(n) (((n) & 7) | (((n) & 8) << 1) | 8)
+
+/* sercom */
+
+struct samd21_sercom {
+ vuint32_t ctrla;
+ vuint32_t ctrlb;
+ vuint32_t reserved_08;
+ vuint16_t baud;
+ vuint8_t rxpl;
+ vuint8_t reserved_0f;
+
+ vuint32_t reserved_10;
+ vuint8_t intenclr;
+ vuint8_t reserved_15;
+ vuint8_t intenset;
+ vuint8_t reserved_17;
+ vuint8_t intflag;
+ vuint8_t reserved_19;
+ vuint16_t status;
+ vuint32_t syncbusy;
+
+ vuint32_t reserved_20;
+ vuint32_t addr;
+ vuint16_t data;
+ vuint16_t reserved_2a;
+ vuint32_t reserved_2c;
+
+ vuint8_t dbgctrl;
+ vuint8_t reserved_31;
+ vuint16_t reserved_32;
+ vuint16_t fifospace;
+ vuint16_t fifoptr;
+};
+
+extern struct samd21_sercom samd21_sercom0;
+extern struct samd21_sercom samd21_sercom1;
+extern struct samd21_sercom samd21_sercom2;
+extern struct samd21_sercom samd21_sercom3;
+extern struct samd21_sercom samd21_sercom4;
+extern struct samd21_sercom samd21_sercom5;
+
+#define SAMD21_NUM_SERCOM 6
+
+#define samd21_sercom0 (*(struct samd21_sercom *) 0x42000800)
+#define samd21_sercom1 (*(struct samd21_sercom *) 0x42000c00)
+#define samd21_sercom2 (*(struct samd21_sercom *) 0x42001000)
+#define samd21_sercom3 (*(struct samd21_sercom *) 0x42001400)
+#define samd21_sercom4 (*(struct samd21_sercom *) 0x42001800)
+#define samd21_sercom5 (*(struct samd21_sercom *) 0x42001c00)
+
+#define SAMD21_SERCOM_CTRLA_SWRST 0
+#define SAMD21_SERCOM_CTRLA_ENABLE 1
+#define SAMD21_SERCOM_CTRLA_MODE 2
+# define SAMD21_SERCOM_CTRLA_MODE_USART 1
+# define SAMD21_SERCOM_CTRLA_MODE_SPI_CLIENT 2
+# define SAMD21_SERCOM_CTRLA_MODE_SPI_HOST 3
+# define SAMD21_SERCOM_CTRLA_MODE_I2C_CLIENT 4
+# define SAMD21_SERCOM_CTRLA_MODE_I2C_HOST 5
+
+#define SAMD21_SERCOM_CTRLA_RUNSTDBY 7
+
+/* USART mode */
+#define SAMD21_SERCOM_CTRLA_IBON 8
+#define SAMD21_SERCOM_CTRLA_SAMPR 13
+#define SAMD21_SERCOM_CTRLA_TXPO 16
+#define SAMD21_SERCOM_CTRLA_TXPO_TX_0 0
+#define SAMD21_SERCOM_CTRLA_TXPO_TX_2 1
+#define SAMD21_SERCOM_CTRLA_TXPO_TX_0_RTS_2_CTS_3 2
+#define SAMD21_SERCOM_CTRLA_RXPO 20
+#define SAMD21_SERCOM_CTRLA_RXPO_RX_0 0
+#define SAMD21_SERCOM_CTRLA_RXPO_RX_1 1
+#define SAMD21_SERCOM_CTRLA_RXPO_RX_2 2
+#define SAMD21_SERCOM_CTRLA_RXPO_RX_3 3
+#define SAMD21_SERCOM_CTRLA_SAMPA 22
+#define SAMD21_SERCOM_CTRLA_FORM 24
+#define SAMD21_SERCOM_CTRLA_CMODE 28
+#define SAMD21_SERCOM_CTRLA_CPOL 29
+#define SAMD21_SERCOM_CTRLA_DORD 30
+
+/* I2C controller mode */
+#define SAMD21_SERCOM_CTRLA_PINOUT 16
+#define SAMD21_SERCOM_CTRLA_SDAHOLD 20
+#define SAMD21_SERCOM_CTRLA_SDAHOLD_DIS 0
+#define SAMD21_SERCOM_CTRLA_SDAHOLD_75NS 1
+#define SAMD21_SERCOM_CTRLA_SDAHOLD_450NS 2
+#define SAMD21_SERCOM_CTRLA_SDAHOLD_600NS 3
+#define SAMD21_SERCOM_CTRLA_MEXTTOEN 22
+#define SAMD21_SERCOM_CTRLA_SEXTTOEN 23
+#define SAMD21_SERCOM_CTRLA_SPEED 24
+#define SAMD21_SERCOM_CTRLA_SPEED_STANDARD 0
+#define SAMD21_SERCOM_CTRLA_SPEED_FAST 1
+#define SAMD21_SERCOM_CTRLA_SPEED_HIGH 2
+#define SAMD21_SERCOM_CTRLA_SCLSM 27
+#define SAMD21_SERCOM_CTRLA_INACTOUT 28
+#define SAMD21_SERCOM_CTRLA_INACTOUT_DIS 0
+#define SAMD21_SERCOM_CTRLA_INACTOUT_55US 1
+#define SAMD21_SERCOM_CTRLA_INACTOUT_105US 2
+#define SAMD21_SERCOM_CTRLA_INACTOUT_205US 3
+#define SAMD21_SERCOM_CTRLA_LOWTOUT 30
+
+/* SPI controller mode */
+#define SAMD21_SERCOM_CTRLA_DOPO 16
+#define SAMD21_SERCOM_CTRLA_DOPO_MOSI_0_SCLK_1 0UL
+#define SAMD21_SERCOM_CTRLA_DOPO_MOSI_2_SCLK_3 1UL
+#define SAMD21_SERCOM_CTRLA_DOPO_MOSI_3_SCLK_1 2UL
+#define SAMD21_SERCOM_CTRLA_DOPO_MOSI_0_SCLK_3 3UL
+#define SAMD21_SERCOM_CTRLA_DOPO_MASK 3UL
+
+#define SAMD21_SERCOM_CTRLA_DIPO 20
+#define SAMD21_SERCOM_CTRLA_DIPO_MISO_0 0UL
+#define SAMD21_SERCOM_CTRLA_DIPO_MISO_1 1UL
+#define SAMD21_SERCOM_CTRLA_DIPO_MISO_2 2UL
+#define SAMD21_SERCOM_CTRLA_DIPO_MISO_3 3UL
+#define SAMD21_SERCOM_CTRLA_DIPO_MASK 3UL
+
+#define SAMD21_SERCOM_CTRLA_FORM 24
+#define SAMD21_SERCOM_CTRLA_CPHA 28
+#define SAMD21_SERCOM_CTRLA_CPOL 29
+#define SAMD21_SERCOM_CTRLA_DORD 30
+#define SAMD21_SERCOM_CTRLA_DORD_LSB 1
+#define SAMD21_SERCOM_CTRLA_DORD_MSB 0
+
+/* USART mode */
+#define SAMD21_SERCOM_CTRLB_CHSIZE 0
+#define SAMD21_SERCOM_CTRLB_SBMODE 6
+#define SAMD21_SERCOM_CTRLB_COLDEN 8
+#define SAMD21_SERCOM_CTRLB_SFDE 9
+#define SAMD21_SERCOM_CTRLB_ENC 10
+#define SAMD21_SERCOM_CTRLB_PMODE 13
+#define SAMD21_SERCOM_CTRLB_TXEN 16
+#define SAMD21_SERCOM_CTRLB_RXEN 17
+#define SAMD21_SERCOM_CTRLB_FIFOCLR 22
+
+/* I2C mode */
+#define SAMD21_SERCOM_CTRLB_SMEN 8
+#define SAMD21_SERCOM_CTRLB_QCEN 9
+#define SAMD21_SERCOM_CTRLB_CMD 16
+#define SAMD21_SERCOM_CTRLB_CMD_NOP 0
+#define SAMD21_SERCOM_CTRLB_CMD_START 1
+#define SAMD21_SERCOM_CTRLB_CMD_READ 2
+#define SAMD21_SERCOM_CTRLB_CMD_STOP 3
+#define SAMD21_SERCOM_CTRLB_ACKACT 18
+#define SAMD21_SERCOM_CTRLB_ACKACT_ACK 0
+#define SAMD21_SERCOM_CTRLB_ACKACT_NACK 1
+#define SAMD21_SERCOM_CTRLB_FIFOCLR 22
+
+/* SPI mode */
+#define SAMD21_SERCOM_CTRLB_CHSIZE 0
+# define SAMD21_SERCOM_CTRLB_CHSIZE_8 0
+#define SAMD21_SERCOM_CTRLB_PLOADEN 6
+#define SAMD21_SERCOM_CTRLB_SSDE 9
+#define SAMD21_SERCOM_CTRLB_MSSEN 13
+#define SAMD21_SERCOM_CTRLB_AMODE 14
+#define SAMD21_SERCOM_CTRLB_RXEN 17
+
+/* USART mode */
+#define SAMD21_SERCOM_INTFLAG_DRE 0
+#define SAMD21_SERCOM_INTFLAG_TXC 1
+#define SAMD21_SERCOM_INTFLAG_RXC 2
+#define SAMD21_SERCOM_INTFLAG_RXS 3
+#define SAMD21_SERCOM_INTFLAG_CTSIC 4
+#define SAMD21_SERCOM_INTFLAG_RXBRK 5
+#define SAMD21_SERCOM_INTFLAG_ERROR 7
+
+/* I2C mode */
+#define SAMD21_SERCOM_INTFLAG_ERROR 7
+#define SAMD21_SERCOM_INTFLAG_RXFF 4
+#define SAMD21_SERCOM_INTFLAG_TXFE 3
+#define SAMD21_SERCOM_INTFLAG_SB 1
+#define SAMD21_SERCOM_INTFLAG_MB 0
+
+/* SPI mode */
+#define SAMD21_SERCOM_INTFLAG_SSL 3
+
+#define SAMD21_SERCOM_INTENCLR_DRE 0
+#define SAMD21_SERCOM_INTENCLR_TXC 1
+#define SAMD21_SERCOM_INTENCLR_RXC 2
+#define SAMD21_SERCOM_INTENCLR_RXS 3
+#define SAMD21_SERCOM_INTENCLR_CTSIC 4
+#define SAMD21_SERCOM_INTENCLR_RXBRK 5
+#define SAMD21_SERCOM_INTENCLR_ERROR 7
+
+#define SAMD21_SERCOM_STATUS_PERR 0
+#define SAMD21_SERCOM_STATUS_FERR 1
+#define SAMD21_SERCOM_STATUS_BUFOVF 2
+#define SAMD21_SERCOM_STATUS_CTS 3
+#define SAMD21_SERCOM_STATUS_ISF 4
+#define SAMD21_SERCOM_STATUS_COLL 5
+#define SAMD21_SERCOM_STATUS_TXE 6
+
+#define SAMD21_SERCOM_SYNCBUSY_SWRST 0
+#define SAMD21_SERCOM_SYNCBUSY_ENABLE 1
+#define SAMD21_SERCOM_SYNCBUSY_CTRLB 2
+#define SAMD21_SERCOM_SYNCBUSY_SYSOP 2
+
+#define SAMD21_SERCOM_ADDR_ADDR 0
+#define SAMD21_SERCOM_ADDR_LENEN 13
+#define SAMD21_SERCOM_ADDR_HS 14
+#define SAMD21_SERCOM_ADDR_TENBITEN 15
+#define SAMD21_SERCOM_ADDR_LEN 16
+
+#define SAMD21_SERCOM_DBGCTRL_DBGSTOP 0
+
+#define SAMD21_SERCOM_FIFOSPACE_TXSPACE 0
+#define SAMD21_SERCOM_FIFOSPACE_TXSPACE_MASK 0x1f
+#define SAMD21_SERCOM_FIFOSPACE_RXSPACE 8
+#define SAMD21_SERCOM_FIFOSPACE_RXSPACE_MASK 0x1f
+
+#define SAMD21_SERCOM_FIFOPTR_CPUWRPTR 0
+#define SAMD21_SERCOM_FIFOPTR_CPUWRPTR_MASK 0xf
+#define SAMD21_SERCOM_FIFOPTR_CPURDPTR 8
+#define SAMD21_SERCOM_FIFOPTR_CPURDPTR_MASK 0xf
+
+/* The SYSTICK starts at 0xe000e010 */
+struct samd21_systick {
+ vuint32_t csr;
+ vuint32_t rvr;
+ vuint32_t cvr;
+ vuint32_t calib;
+};
+
+extern struct samd21_systick samd21_systick;
+
+#define samd21_systick (*(struct samd21_systick *) 0xe000e010)
+
+#define SAMD21_SYSTICK_CSR_ENABLE 0
+#define SAMD21_SYSTICK_CSR_TICKINT 1
+#define SAMD21_SYSTICK_CSR_CLKSOURCE 2
+#define SAMD21_SYSTICK_CSR_CLKSOURCE_EXTERNAL 0
+#define SAMD21_SYSTICK_CSR_CLKSOURCE_HCLK_8 1
+#define SAMD21_SYSTICK_CSR_COUNTFLAG 16
+
+#define SAMD21_SYSTICK_PRI 15
+
+/* The NVIC starts at 0xe000e100, so add that to the offsets to find the absolute address */
+
+struct samd21_nvic {
+ vuint32_t iser; /* 0x000 0xe000e100 Set Enable Register */
+
+ uint8_t _unused020[0x080 - 0x004];
+
+ vuint32_t icer; /* 0x080 0xe000e180 Clear Enable Register */
+
+ uint8_t _unused0a0[0x100 - 0x084];
+
+ vuint32_t ispr; /* 0x100 0xe000e200 Set Pending Register */
+
+ uint8_t _unused120[0x180 - 0x104];
+
+ vuint32_t icpr; /* 0x180 0xe000e280 Clear Pending Register */
+
+ uint8_t _unused1a0[0x300 - 0x184];
+
+ vuint32_t ipr[8]; /* 0x300 0xe000e400 Priority Register */
+};
+
+extern struct samd21_nvic samd21_nvic;
+
+#define samd21_nvic (*(struct samd21_nvic *) 0xe000e100)
+
+#define SAMD21_NVIC_ISR_PM_POS 0
+#define SAMD21_NVIC_ISR_SYSCTRL_POS 1
+#define SAMD21_NVIC_ISR_WDT_POS 2
+#define SAMD21_NVIC_ISR_RTC_POS 3
+#define SAMD21_NVIC_ISR_EIC_POS 4
+#define SAMD21_NVIC_ISR_NVMCTRL_POS 5
+#define SAMD21_NVIC_ISR_DMAC_POS 6
+#define SAMD21_NVIC_ISR_USB_POS 7
+#define SAMD21_NVIC_ISR_EVSYS_POS 8
+#define SAMD21_NVIC_ISR_SERCOM0_POS 9
+#define SAMD21_NVIC_ISR_SERCOM1_POS 10
+#define SAMD21_NVIC_ISR_SERCOM2_POS 11
+#define SAMD21_NVIC_ISR_SERCOM3_POS 12
+#define SAMD21_NVIC_ISR_SERCOM4_POS 13
+#define SAMD21_NVIC_ISR_SERCOM5_POS 14
+#define SAMD21_NVIC_ISR_TCC0_POS 15
+#define SAMD21_NVIC_ISR_TCC1_POS 16
+#define SAMD21_NVIC_ISR_TCC2_POS 17
+#define SAMD21_NVIC_ISR_TC3_POS 18
+#define SAMD21_NVIC_ISR_TC4_POS 19
+#define SAMD21_NVIC_ISR_TC5_POS 20
+#define SAMD21_NVIC_ISR_TC6_POS 21
+#define SAMD21_NVIC_ISR_TC7_POS 22
+#define SAMD21_NVIC_ISR_ADC_POS 23
+#define SAMD21_NVIC_ISR_AC_POS 24
+#define SAMD21_NVIC_ISR_DAC_POS 25
+#define SAMD21_NVIC_ISR_PTC_POS 26
+#define SAMD21_NVIC_ISR_I2S_POS 27
+#define SAMD21_NVIC_ISR_AC1_POS 28
+#define SAMD21_NVIC_ISR_TCC3_POS 29
+
+#define IRQ_MASK(irq) (1 << (irq))
+#define IRQ_BOOL(v,irq) (((v) >> (irq)) & 1)
+
+static inline void
+samd21_nvic_set_enable(int irq) {
+ samd21_nvic.iser = IRQ_MASK(irq);
+}
+
+static inline void
+samd21_nvic_clear_enable(int irq) {
+ samd21_nvic.icer = IRQ_MASK(irq);
+}
+
+static inline int
+samd21_nvic_enabled(int irq) {
+ return IRQ_BOOL(samd21_nvic.iser, irq);
+}
+
+static inline void
+samd21_nvic_set_pending(int irq) {
+ samd21_nvic.ispr = IRQ_MASK(irq);
+}
+
+static inline void
+samd21_nvic_clear_pending(int irq) {
+ samd21_nvic.icpr = IRQ_MASK(irq);
+}
+
+static inline int
+samd21_nvic_pending(int irq) {
+ return IRQ_BOOL(samd21_nvic.ispr, irq);
+}
+
+#define IRQ_PRIO_REG(irq) ((irq) >> 2)
+#define IRQ_PRIO_BIT(irq) (((irq) & 3) << 3)
+#define IRQ_PRIO_MASK(irq) (0xffU << IRQ_PRIO_BIT(irq))
+
+static inline void
+samd21_nvic_set_priority(int irq, uint8_t prio) {
+ int n = IRQ_PRIO_REG(irq);
+ uint32_t v;
+
+ v = samd21_nvic.ipr[n];
+ v &= ~IRQ_PRIO_MASK(irq);
+ v |= (prio) << IRQ_PRIO_BIT(irq);
+ samd21_nvic.ipr[n] = v;
+}
+
+static inline uint8_t
+samd21_nvic_get_priority(int irq) {
+ return (samd21_nvic.ipr[IRQ_PRIO_REG(irq)] >> IRQ_PRIO_BIT(irq)) & IRQ_PRIO_MASK(0);
+}
+
+
+
+/* Cortex M0+ SCB */
+
+struct samd21_scb {
+ vuint32_t cpuid;
+ vuint32_t icsr;
+ vuint32_t vtor;
+ vuint32_t aircr;
+
+ vuint32_t scr;
+ vuint32_t ccr;
+ vuint32_t shpr1;
+ vuint32_t shpr2;
+
+ vuint32_t shpr3;
+ vuint32_t shcrs;
+ vuint32_t cfsr;
+ vuint32_t hfsr;
+
+ uint32_t unused_30;
+ vuint32_t mmfar;
+ vuint32_t bfar;
+};
+
+extern struct samd21_scb samd21_scb;
+
+#define samd21_scb (*(struct samd21_scb *) 0xe000ed00)
+
+#define SAMD21_SCB_AIRCR_VECTKEY 16
+#define SAMD21_SCB_AIRCR_VECTKEY_KEY 0x05fa
+#define SAMD21_SCB_AIRCR_PRIGROUP 8
+#define SAMD21_SCB_AIRCR_SYSRESETREQ 2
+#define SAMD21_SCB_AIRCR_VECTCLRACTIVE 1
+#define SAMD21_SCB_AIRCR_VECTRESET 0
+
+/* The NVM Calibration and auxiliary space starts at 0x00800000 */
+
+struct samd21_aux0 {
+ vuint64_t userrow;
+};
+
+extern struct samd21_aux0 samd21_aux0;
+
+#define samd21_aux0 (*(struct samd21_aux0 *) 0x00804000)
+
+#define SAMD21_AUX0_USERROW_BOOTPROT 0
+#define SAMD21_AUX0_USERROW_EEPROM 4
+#define SAMD21_AUX0_USERROW_BOD33_LEVEL 8
+#define SAMD21_AUX0_USERROW_BOD33_ENABLE 14
+#define SAMD21_AUX0_USERROW_BOD33_ACTION 15
+#define SAMD21_AUX0_USERROW_WDT_ENABLE 25
+#define SAMD21_AUX0_USERROW_WDT_ALWAYS_ON 26
+#define SAMD21_AUX0_USERROW_WDT_PERIOD 27
+#define SAMD21_AUX0_USERROW_WDT_WINDOW 31
+#define SAMD21_AUX0_USERROW_WDT_EWOFFSET 35
+#define SAMD21_AUX0_USERROW_WDT_WEN 39
+#define SAMD21_AUX0_USERROW_BOD33_HYST 40
+#define SAMD21_AUX0_USERROW_LOCK 48
+
+struct samd21_aux1 {
+ vuint64_t reserved_00;
+ vuint64_t device_config;
+
+ vuint64_t reserved_10;
+ vuint64_t reserved_18;
+
+ vuint64_t calibration;
+ vuint64_t reserved_28;
+};
+
+extern struct samd21_aux1 samd21_aux1;
+
+#define samd21_aux1 (*(struct samd21_aux1 *) 0x00806000)
+
+#define SAMD21_AUX1_CALIBRATION_ADC_LINEARITY 27
+#define SAMD21_AUX1_CALIBRATION_ADC_LINEARITY_MASK 0xff
+#define SAMD21_AUX1_CALIBRATION_ADC_BIASCAL 35
+#define SAMD21_AUX1_CALIBRATION_ADC_BIASCAL_MASK 0x7
+#define SAMD21_AUX1_CALIBRATION_OSC32K_CAL 38
+#define SAMD21_AUX1_CALIBRATION_USB_TRANSN 45
+#define SAMD21_AUX1_CALIBRATION_USB_TRANSN_MASK 0x1f
+#define SAMD21_AUX1_CALIBRATION_USB_TRANSP 50
+#define SAMD21_AUX1_CALIBRATION_USB_TRANSP_MASK 0x1f
+#define SAMD21_AUX1_CALIBRATION_USB_TRIM 55
+#define SAMD21_AUX1_CALIBRATION_USB_TRIM_MASK 0x07
+#define SAMD21_AUX1_CALIBRATION_DFLL48M_COARSE_CAL 58
+#define SAMD21_AUX1_CALIBRATION_DFLL48M_COARSE_CAL_MASK 0x3f
+
+struct samd21_serial {
+ vuint32_t reserved_00;
+ vuint32_t reserved_04;
+ vuint32_t reserved_08;
+ vuint32_t word0;
+
+ vuint32_t reserved_10;
+ vuint32_t reserved_14;
+ vuint32_t reserved_18;
+ vuint32_t reserved_1c;
+
+ vuint32_t reserved_20;
+ vuint32_t reserved_24;
+ vuint32_t reserved_28;
+ vuint32_t reserved_2c;
+
+ vuint32_t reserved_30;
+ vuint32_t reserved_34;
+ vuint32_t reserved_38;
+ vuint32_t reserved_3c;
+
+ vuint32_t word1;
+ vuint32_t word2;
+ vuint32_t word3;
+ vuint32_t reserved_4c;
+};
+
+extern struct samd21_serial samd21_serial;
+
+#define samd21_serial (*(struct samd21_serial *) 0x0080a000)
+
+static inline void
+samd21_gclk_wait_sync(void)
+{
+ while (samd21_gclk.status & (1 << SAMD21_GCLK_STATUS_SYNCBUSY))
+ ;
+}
+
+static inline void
+samd21_dfll_wait_sync(void)
+{
+ while ((samd21_sysctrl.pclksr & (1 << SAMD21_SYSCTRL_PCLKSR_DFLLRDY)) == 0)
+ ;
+}
+
+static inline void
+samd21_gclk_gendiv(uint32_t id, uint32_t div)
+{
+ if (div == 1)
+ div = 0;
+ samd21_gclk.gendiv = ((id << SAMD21_GCLK_GENDIV_ID) |
+ (div << SAMD21_GCLK_GENDIV_DIV));
+ samd21_gclk_wait_sync();
+}
+
+static inline void
+samd21_gclk_genctrl(uint32_t src, uint32_t id)
+{
+ samd21_gclk.genctrl = ((id << SAMD21_GCLK_GENCTRL_ID) |
+ (src << SAMD21_GCLK_GENCTRL_SRC) |
+ (0 << SAMD21_GCLK_GENCTRL_OE) |
+ (1 << SAMD21_GCLK_GENCTRL_GENEN));
+ samd21_gclk_wait_sync();
+}
+
+static inline void
+samd21_gclk_clkctrl(uint32_t gen, uint32_t id)
+{
+ samd21_gclk.clkctrl = (uint16_t) ((gen << SAMD21_GCLK_CLKCTRL_GEN) |
+ (id << SAMD21_GCLK_CLKCTRL_ID) |
+ (1U << SAMD21_GCLK_CLKCTRL_CLKEN));
+ samd21_gclk_wait_sync();
+}
+
+#define isr_decl(name) \
+ void samd21_ ## name ## _isr(void)
+
+isr_decl(halt);
+isr_decl(ignore);
+isr_decl(nmi);
+isr_decl(hardfault);
+isr_decl(memmanage);
+isr_decl(busfault);
+isr_decl(usagefault);
+isr_decl(svc);
+isr_decl(debugmon);
+isr_decl(pendsv);
+isr_decl(systick);
+isr_decl(pm); /* IRQ0 */
+isr_decl(sysctrl);
+isr_decl(wdt);
+isr_decl(rtc);
+isr_decl(eic);
+isr_decl(nvmctrl);
+isr_decl(dmac);
+isr_decl(usb);
+isr_decl(evsys);
+isr_decl(sercom0);
+isr_decl(sercom1);
+isr_decl(sercom2);
+isr_decl(sercom3);
+isr_decl(sercom4);
+isr_decl(sercom5);
+isr_decl(tcc0);
+isr_decl(tcc1);
+isr_decl(tcc2);
+isr_decl(tc3);
+isr_decl(tc4);
+isr_decl(tc5);
+isr_decl(tc6);
+isr_decl(tc7);
+isr_decl(adc);
+isr_decl(ac);
+isr_decl(dac);
+isr_decl(ptc);
+isr_decl(i2s);
+isr_decl(ac1);
+isr_decl(tcc3);
+
+#undef isr_decl
+
+#endif /* _SAMD21_H_ */