The SAMD clock system
- Terms
- SAMD21
-
SAMD51 and SAME51
- The SAMD51 clock system
- SAMD51 Clock Requirements Relevant to ModularSensors
- SAMD51 Settings at Power On
- SAMD51 Arduino Core Setup Clock Generator Configuration
- SAMD51 Arduino Core Library Clock and Peripheral Configuration
- Clocks Used by Non-Core Libraries for the SAMD51
- Summary of Peripheral Clock Assignments
- The Non-Volatile Interrupt Controller (NVIC)
Terms
Essentially every microprocessor or computer needs a consistent way of their own speed of operation so they can communicate with internal components and external devices.
An oscillator is a circuit that makes an oscillating signal - ie, it switches back and forth between to states at a consistent rate. The oscillator works like a metronome. An oscillator alone does not keep track of time; it ticks, but it doesn't count how many ticks have passed.
SAMD processors use these types of oscillators:
- crystal oscillators - which are tiny pieces of quartz that vibrate under current. This is just like the crystals in a quartz watch.
- Digital frequency locked loops (DFLL) and fractional digital phase locked loops (FDPLL) - these phase locked loops (PLL) use a reference clock (like the external crystal) to create a consistent (faster) output frequency.
- Ultra-low-power oscillators - circuits which generate the same frequency vibrations as a crystal power but using lower power consumption to get a less consistent signal.
For any of the oscillators to be useful in keeping track of time, they need to be connected to something else that will count the number of ticks. The oscillator acts as the source for the clock/counter. There can also be a 'divisor' between the ticking source and the counter - that is, the counter can record every 'x' ticks instead of every single tick.
See also: https:/
SAMD21
The SAMD21 clock system
From the SAMD21 Datasheet 14.1:
The clock system on the SAM D21 consists of :
- Clock sources, controlled by SYSCTRL – A clock source provides a time base that is used by other components, such as Generic Clock Generators. Example clock sources are the internal 8MHz oscillator(OSC8M), External crystal oscillator(XOSC) and the Digital frequency locked loop (DFLL48M).
- Generic Clock Controller(GCLK) which controls the clock distribution system, made up of:
- Generic Clock Generators: These are programmable prescalers that can use any of the system clock sources as a time base. The Generic Clock Generator 0 generates the clock signal GCLK_MAIN, which is used by the Power Manager, which in turn generates synchronous clocks.
- Generic clock generators are configured with
GCLK->GENCTRL
- Generic Clocks: These are clock signals generated by Generic Clock Generators and output by the Generic Clock Multiplexer, and serve as clocks for the peripherals of the system. Multiple instances of a peripheral will typically have a separate Generic Clock for each instance. Generic Clock 0 serves as the clock source for the DFLL48M clock input (when multiplying another clock source).
- Generic clocks are configured with
GCLK->CLKCTRL
- Power Manager (PM)
- The PM generates and controls the synchronous clocks on the system. This includes the CPU, bus clocks (APB, AHB) as well as the synchronous (to the CPU) user interfaces of the peripherals. It contains clock masks that can turn on/off the user interface of a peripheral as well as prescalers for the CPU and bus clocks
SAMD21 Clock Requirements Relevant to ModularSensors
The watchdog's peripheral clock must be attached to a currently-on clock source so it can tell how much time has passed and whether it needs to bite. The watchdog peripheral clock is not configured by the core. The flow from a clock source to the WDT on the SAMD21 is:
- Enable the clock source and the WDT peripheral in the power management system
- Configure said a clock source to run in standby
- Configure a divisor between the above source clock and a generic clock generators
- Configure a generic clock to tie the watchdog's peripheral clock to the above generic clock generator
- Configure the watchdog itself.
The external interrupt controller must also be attached to a currently-on clock to tell the difference between rising and HIGH or falling and LOW interrupts. If the external interrupt controller is not attached to a running clock, then interrupts will not work! Thus, if the clock source for interrupts is not running in standby, the interrupts will not be able to wake the device. The flow from a clock source to the EIC is the same as that for the WDT.
SAMD21 Settings at Power On
After a power-on reset, the clock generators for peripherals default to:
- RTC: GCLK0
- WDT: GCLK2
- Anything else: GCLK0
- See 14.8 in the SAMD21 Datasheet
SAMD21 Arduino Core Setup Clock Generator Configuration
Within the SAMD core SystemInit() in startup.c configures clocks with these steps:
- Enable XOSC32K clock (external on-board 32.768Hz oscillator) or OSC32K (if crystalless).
- This will be used as DFLL48M reference.
- SystemInit() uses a default start-up configuration of 0x6 for the (X)OSC (65536 OSCULP32K clock cycles + 3 (X)OSC32K clock cycles = 2000092μs ~= 2s before PCLKSR.XOSC32KRDY is set.)
- Put XOSC32K or OSC32K as source of Generic Clock Generator 1
- Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference)
- Enable DFLL48M clock in closed loop mode, if there is an external crystal available, or in open loop mode if crystalless
- Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz.
- Modify prescaler value of OSCM to have 8MHz
- Put OSC8M as source for Generic Clock Generator 3
Resulting generic clock generator speeds:
- GCLKGEN0 = 48 MHz; sourced from DFLL48M, which does not run in standby.
- GCLKGEN1 = 32kHz; sourced from XOSC32K or OSC32K, which does not run in standby.
- GCLKGEN2 = not configured
- GCLKGEN3 = 8 MHz; sourced from OSC8M, which does not run in standby.
- GCLKGEN4-GCLKGEN8 = not configured
SAMD21 Arduino Core Library Clock Configuration
- WInterrupts.c
- Configures the external interrupt controller (EIC) clock (
GCM_EIC
) to use GCLKGEN0 at 48 MHz - Does not change the source or other configuration for GCLKGEN0
- Configures the external interrupt controller (EIC) clock (
- wiring_
analog.c - Configures timer counter clocks (
GCM_TC4_TC5
orGCM_TC6_TC7
, depending on the analog pin) to use GCLKGEN0 at 48 MHz - Does not change the source or other configuration for GCLKGEN0
- Configures timer counter clocks (
- wiring.c
- Configures the ADC (
GCM_ADC
) and DAC (GCM_DAC
) to use GCLKGEN0 at 48 MHz - Does not change the source or other configuration for GCLKGEN0
- Configures the ADC (
- SERCOM
- Configures the various SERCOM clocks to use GCLKGEN0 at 48 MHz
- GCM_SERCOM0_CORE -> GCM_SERCOM5_CORE, depending on how many SERCOM's are defined in variant.h
- Does not change the source or other configuration for GCLKGEN0
- Configures the various SERCOM clocks to use GCLKGEN0 at 48 MHz
- Tone
- Configures timer counter 4 and 5 clocks (
GCM_TC4_TC5
) to use GCLKGEN0 at 48 MHz - Does not change the source or other configuration for GCLKGEN0
- Configures timer counter 4 and 5 clocks (
- I2S
- Configures the I2S's generic clocks (
I2S_GCLK_ID_0
andI2S_GCLK_ID_1
) to use the generic clock generator specified for I2S in variant.h (likely GCLKGEN3) - Sets the source of the specified generic clock generator to be the DFLL48 or the OSC8M, depending on the I2S speed
- Configures the I2S's generic clocks (
- USB (host, core, TinyUSB)
- Configures the USB (
GCLK_USB
= 0x6) to use GCLKGEN0 at 48 MHz - Does not change the source or other configuration for GCLKGEN0
- NOTE: For some reason, the code uses 0x6 directly instead of the
GCLK_USB
macro for the generic clock selection ID
- Configures the USB (
- Servo
- Configures timer counter clocks (specific clock depending on the analog pin) to use GCLKGEN0 at 48 MHz
- Does not change the source or other configuration for GCLKGEN0
Clocks Used by Non-Core Libraries for the SAMD21
- RTCZero
- Configures the RTC's generic clock (GCM_RTC) to use generic clock generator 2
- Sets the source for GCKL2 as a 32k oscillator
- external preferred, internal ultra-low power if crystalless
- Forces the external 32K oscillator to remain on in standby
- Uses a 32x divisor to get 1024Hz(ish) clock for time keeping.
- Adafruit SleepDog
- Configures the WDT's generic clock (GCM_WDT) to use generic clock generator 2.
- Sets the source for GCKL2 as the internal ultra-low power 32k oscillator
- Uses a 32x divisor to get a 1024Hz(ish) clock to manage the watchdog.
- Arduino Low Power
- Configures the EIC and ADC's generic clocks (GCM_EIC and GCM_ADC) to use generic clock generator 6
- Sets the source for GCKL6 as the internal ultra-low power 32k oscillator
- Does NOT use any clock divisor
- EnviroDIY SDI-12
- Configures the TCC2/TC3 clock (GCM_TCC2_TC3) to use generic clock generator 4 (
GENERIC_CLOCK_GENERATOR_SDI12
= 4) - Sets the source for GCKL4 as the DFLL48M - which is in-turn coming from "main" clock set up in SystemInit() in startup.c.
- Uses a 6x divisor.
- Configures the TCC2/TC3 clock (GCM_TCC2_TC3) to use generic clock generator 4 (
- Modular Sensors (this library)
- Configures the EIC and WDT's generic clocks (GCM_EIC and GCM_WDT) to use generic clock generator 5 (
GENERIC_CLOCK_GENERATOR_MS
= 5) - Sets the source for GCKLGEN5 as the internal ultra-low power 32k oscillator.
- Uses a 32x divisor to get a 1024Hz(ish) clock to manage the watchdog and EIC.
- Configures the EIC and WDT's generic clocks (GCM_EIC and GCM_WDT) to use generic clock generator 5 (
SAMD51 and SAME51
The SAMD51 clock system
From 13.1 of the SAMD51 Datasheet)
The SAM D5x/E5x clock system consists of:
- Clock sources, i.e. oscillators controlled by OSCCTRL and OSC32KCTRL
- A clock source provides a time base that is used by other components, such as Generic Clock Generators. Example clock sources include the external crystal oscillators (XOSC0 and XOSC1) and the Digital Frequency Locked Loop (DFLL48M).
- Generic Clock Controller (GCLK), which generates, controls and distributes asynchronous clocks consisting of:
- Generic Clock Generators: These are programmable prescalers that can use any of the system clock sources as a time base. The Generic Clock Generator 0 generates the clock signal GCLK_MAIN, which is used by the Power Manager and the Main Clock (MCLK) module, which in turn generates synchronous clocks.
- Generic Clocks: These are clock signals generated by Generic Clock Generators and output by the Peripheral Channels, and serve as clocks for the peripherals of the system. Multiple instances of a peripheral will typically have a separate Generic Clock for each instance. Generic Clock 0 serves as the clock source for the DFLL48M clock input (when multiplying another clock source).
- Main Clock Controller (MCLK)
- The MCLK generates and controls the synchronous clocks on the system. This includes the CPU, bus clocks (APB, AHB) as well as the synchronous (to the CPU) user interfaces of the peripherals. It contains clock masks that can turn on/off the user interface of a peripheral as well as prescalers for the CPU and bus clocks.
SAMD51 Clock Requirements Relevant to ModularSensors
The SAMD51 WDT uses the 1K output from the OSCULP32k; there are no other possible clock sources for the WDT. No separate clock generator or peripheral clock configuration is needed. The OSCULP32k cannot be turned off in standby.
The external interrupt controller must be attached to a currently-on clock to tell the difference between rising and HIGH or falling and LOW interrupts. If the external interrupt controller is not attached to a running clock, then interrupts will not work! One the SAMD51, the EIC can be configured to work directly with the OSCULP32k without having to setup a separate clock generator. If the EIC is not configured to connect directly to the OSCULP32k, the GCLK it is configured to must be set to run in standby. The path from a clock source to the EIC on the SAMD51 is very similar to that of the SAMD21.
SAMD51 Settings at Power On
SAMD51 Arduino Core Setup Clock Generator Configuration
Within the SAMD core SystemInit() in startup.c configures clocks with these steps:
- Enable XOSC32K clock (external on-board 32.768Hz oscillator) if a crystal is available
- Also enable the 32k output, the 1k output, standard gain mode, and configure the oscillator pins for a crystal connected between XIN32 and XOUT32
- Sets start-up time to 0x0 = 2048 clock cycles ~= 65.592ms
- Sets on-demand and run-in-standby both to 0, so the external 32k oscillator will always run in active or idle mode and will only run if requested by peripheral in standby mode (table 29-1)
- Set XOSC32K or OSC32K (if crystalless) as source of Generic Clock Generator 3
- Set OSCULP32K (internal ultra-low power 32.768Hz oscillator) as the source for Generic Clock Generator 0
- NOTE: The default power-on source of generic clock generator 0 is the DFLL48.
- NOTE: Farther down, generic clock generator 0 is resourced from DPLL0 (at 120MHz)
- Configure the DFLL48M clock in open loop mode (no reference clock)
- Source generic clock generator 5 (
GENERIC_CLOCK_GENERATOR_1M
) from the DFLL with a divisor of 48 - Sets on-demand and run-in-standby both to 0, so the DFLL48M will always run in active or idle mode and will not run in standby mode (28.8.7, slightly different than table 29-1 for (X)OSC32K)
- Source generic clock generator 5 (
- Configure DPLL peripheral clocks
- Configure PLL0 at 120MHz (or F_CPU), using generic clock generator 5 (DFLL48M / 48) as the reference clock
- Configure PLL1 at 100MHz, using generic clock generator 5 (DFLL48M / 48) as the reference clock
- Sets on-demand and run-in-standby both to 0 for both FDPLL, so the PLLs will always run in active or idle mode and will not run in standby mode (28.8.12)
- Configure other generic clock generators to use for peripheral clocks
- Source generic clock generator 1 from the DFLL48M with no divisor
- 48MHz clock generator; used for the USB and "stuff"
- Source generic clock generator 2 from the PLL1 at 100MHz with no divisor
- 100MHz clock generator; used for "other peripherals"
- Source generic clock generator 4 from the DFLL48M at 48MHz with 4x divisor
- 12MHz clock generator; used for the DAC
- Source generic clock generator 1 from the DFLL48M with no divisor
- Set the main clock source as the source for the main generic clock generator
MAIN_CLOCK_SOURCE
=GCLK_GENCTRL_SRC_DPLL0
GENERIC_CLOCK_GENERATOR_MAIN
= 0- This is resetting the source of generic clock generator 0 to be the DPLL0 at 120MHz, it previously had been set to the OSCULP32K.
Resulting generic clock speeds
- GCLK0 = F_CPU (likely 120MHz, but could be different depending on variant.h); sourced from DLPP0, which does not run in standby.
- GCLK1 = 48 MHz; sourced from DFLL48M, which does not run in standby.
- GCLK2 = 100 MHz; sourced from DLPP1, which does not run in standby.
- GCLK3 = 32 kHz; sourced from XOSC32K, which does run in standby if requested by peripheral (I think?)
- GCLK4 = 12 MHz; sourced from DFLL48M, which does not run in standby.
SAMD51 Arduino Core Library Clock and Peripheral Configuration
- WInterrupts.c
- Configures the external interrupt controller (EIC) clock (
EIC_GCLK_ID
) to use GCLKGEN2 at 100 MHz - Does not change the source or other configuration for GCLKGEN2
- Configures the external interrupt controller (EIC) clock (
- wiring_
analog.c - Configures timer counter clocks (specific clock depending on the analog pin) to use GCLKGEN0 at 120 MHz
- Does not change the source or other configuration for GCLKGEN0
- wiring.c
- Configures the ADC (
ADC0_GCLK_ID
andADC1_GCLK_ID
) to use GCLKGEN1 at 48 MHz - Does not change the source or other configuration for GCLKGEN1
- Configures the DAC (
DAC_GCLK_ID
) to use GCLKGEN4 at 12 MHz - Does not change the source or other configuration for GCLKGEN4
- Configures the ADC (
- SERCOM
- Configures the various SERCOM clocks to various sources depending on the speed of the SERCOM peripheral
- SERCOM0_GCLK_ID_CORE/SERCOM0_GCLK_ID_SLOW -> SERCOM7_GCLK_ID_CORE/SERCOM7_GCLK_ID_SLOW, depending on how many SERCOM's are defined in variant.h
- Does not change the source or other configuration of any of the clock generators
- Configures the various SERCOM clocks to various sources depending on the speed of the SERCOM peripheral
- Tone
- Configures timer counter 0 clock (
TONE_TC_GCLK_ID
=TC0_GCLK_ID
) to use GCLKGEN0 at 120 (or F_CPU) MHz - Does not change the source or other configuration for GCLKGEN0
- Configures timer counter 0 clock (
- I2S
- Configures the I2S's generic clocks (
I2S_GCLK_ID_0
andI2S_GCLK_ID_1
) to use the generic clock generator specified for I2S in variant.h (likely GCLKGEN3) - Sets the source of the specified generic clock generator to be the DFLL48 or the OSC8M, depending on the I2S speed
- Configures the I2S's generic clocks (
- USB (host, core, TinyUSB)
- Configures the USB (
USB_GCLK_ID
) to use GCLKGEN0 at 120 (or F_CPU) MHz - Does not change the source or other configuration for GCLKGEN0
- Configures the USB (
- Servo
- Configures timer counter clocks (specific clock depending on the analog pin) to use GCLKGEN0 at 120 MHz
- Does not change the source or other configuration for GCLKGEN0
Thus, if the clock source for interrupts is not running in standby, the interrupts will not be able to wake the device. In WInterrupts.c in the Adafruit SAMD core, generic clock generator 2 (from the PLL1 at 100MHz with no divisor) is used for the EIC peripheral. The Arduino core does NOT configure the generic clock generator 0 (ie GCLK_MAIN = DFLL48M) to stay awake in standby!
Clocks Used by Non-Core Libraries for the SAMD51
- RTCZero
- The RTC of the SAMD51 is sourced directly from an oscillator, not via the generic clock generator system. This library only configures the RTC oscillator on the SAMD51.
- Adafruit SleepDog
- The WDT on the SAMD51 is directly attached to OSCULP32K. This library doesn't make any clock changes for the SAMD51.
- Arduino Low Power
- This library doesn't support the SAMD51
- EnviroDIY SDI-12
- Configures the TC2 clock (
TC2_GCLK_ID
) to use generic clock generator 6 (GENERIC_CLOCK_GENERATOR_SDI12
= 6) - Sets the source for GCKL6 as the DPLL0 at 120MHz
- Uses a 15x divisor between the DPLL0 and GCKL6.
- Configures the TC2 clock (
- Modular Sensors (this library)
- This library sets OSCULP32K as the source for the EIC and disables GCLK_EIC.
- This library also resets GCLK7 so it is disconnected from any source.
- This library disables the following peripheral timers and ties them to the disabled GCLK7:
- 4 - GCLK_EIC
- 5 - GCLK_FREQM_MSR
- 6 - GCLK_FREQM_REF
- 9 - GCLK_TC0/GCLK_TC1
- 11 - GCLK_EVSYS0
- 12 - GCLK_EVSYS1
- 13 - GCLK_EVSYS2
- 14 - GCLK_EVSYS3
- 15 - GCLK_EVSYS4
- 16 - GCLK_EVSYS5
- 17 - GCLK_EVSYS6
- 18 - GCLK_EVSYS7
- 19 - GCLK_EVSYS8
- 20 - GCLK_EVSYS9
- 21 - GCLK_EVSYS10
- 22 - GCLK_EVSYS11
- 25 - GCLK_TCC0/GCLK_TCC1
- 26 - GCLK_TC2/GCLK_TC3
- 27 - GCLK_CAN0
- 28 - GCLK_CAN1
- 29 - GCLK_TCC2/GCLK_TCC3
- 30 - GCLK_TC4/GCLK_TC5
- 31 - GCLK_PDEC
- 32 - GCLK_AC
- 33 - GCLK_CCL
- 38 - GCLK_TCC4
- 39 - GCLK_TC6/GCLK_TC7
- 42 - GCLK_DAC
- 43 - GCLK_I2S
- 44 - GCLK_I2S
- 45 - GCLK_SDHC0
- 46 - GCLK_SDHC1
- 47 - GCLK_CM4_TRACE
Summary of Peripheral Clock Assignments
- GCLK_SERCOM[0..7]_SLOW/GCLK_SDHC0_SLOW/GCLK_SDHC0_SLOW (3) - potentially any of GCLK0-GCLK4 - SERCOM.cpp
- GCLK_EIC (4) - GCLKGEN0 (F_CPU; sourced from DLPP0) - WInterrupts.c
- This is disabled by Modular Sensors!
- GCLK_TC0/GCLK_TC1 (9) - GCLKGEN0 (F_CPU; sourced from DLPP0) - Tone.cpp, Servo.cpp, wiring_analog.c
- GCLK_USB (10) - GCLKGEN0 (F_CPU; sourced from DLPP0) - samd21_host.c, USBCore.cpp, Adafruit_TinyUSB_samd.cpp
- GCLK_SERCOM2_CORE (23) - potentially any of GCLK0-GCLK4 - SERCOM.cpp
- GCLK_SERCOM3_CORE (24) - potentially any of GCLK0-GCLK4 - SERCOM.cpp
- GCLK_TC2/GCLK_TC3 (26) - GCLKGEN0 (F_CPU; sourced from DLPP0) - Servo.cpp, wiring_analog.c potential conflict with SDI-12, be cautious
- GCLK_TC2/GCLK_TC3 (26) - GCLKGEN6 (F_CPU; sourced from DLPP0) - SDI12_boards.cpp potential conflict with servo, be cautious
- GCLK_TC4/GCLK_TC5 (30) - GCLKGEN0 (F_CPU; sourced from DLPP0) - Servo.cpp, wiring_analog.c
- GCLK_SERCOM4_CORE (34) - potentially any of GCLK0-GCLK4 - SERCOM.cpp
- GCLK_SERCOM5_CORE (35) - potentially any of GCLK0-GCLK4 - SERCOM.cpp
- GCLK_SERCOM6_CORE (36) - potentially any of GCLK0-GCLK4 - SERCOM.cpp
- GCLK_SERCOM7_CORE (37) - potentially any of GCLK0-GCLK4 - SERCOM.cpp
- GCLK_TC6/GCLK_TC7 (39) - GCLKGEN0 (F_CPU; sourced from DLPP0) - Servo.cpp, wiring_analog.c
- GCLK_ADC0 (40) - GCLKGEN1 (48 MHz; sourced from DFLL48M) - wiring.c
- GCLK_ADC12 (41) - GCLKGEN1 (48 MHz; sourced from DFLL48M) - wiring.c
- GCLK_DAC (42) - GCLKGEN4 (12 MHz; sourced from DFLL48M) - wiring.c
- GCLK_I2S[0] (43) - GCLKGEN3 (32 kHz; sourced from XOSC32K) most likely - I2S.cpp
- GCLK_I2S[1] (44) - GCLKGEN3 (32 kHz; sourced from XOSC32K) most likely - I2S.cpp
The Non-Volatile Interrupt Controller (NVIC)
This entire section is copied selections from Microchip's developer help on the NVIC.
NVIC Overview
Priority Levels
Cortex-M0+ processors support three fixed highest priority levels for three of the system exceptions, and four programmable levels for all other exceptions, including interrupts. The four possible programmable priority levels are 0x00 (highest urgency), 0x40, 0x80, and 0xC0 (lowest urgency).
- Out of reset, all interrupts and exceptions with configurable priority have the same default priority of 0x00. This priority number represents the highest-possible interrupt urgency.
- If two exceptions happen at the same time and they have the same programmed priority level, the exception with the lower CMSIS IRQ number will be processed first.
Configuring Interrupt Priority
CMSIS provides a number of functions for NVIC control, including the following for setting priority: void NVIC_SetPriority(IRQn_t IRQn, uint32_t priority);
Where priority values (0, 1, 2, 3) correspond to interrupt priority register (IPRx) settings 0x00, 0x40, 0x80, 0xC0. The CMSIS IRQ numbers (the peripheral-interrupt-to-CMSIS-IRQ-number mapping) are defined in the processor specific include files within the bootloader. That is this file for the UF2 bootloader for the SAMD51 variant the EnviroDIY Stonefly is based on.
Enabling IRQs Globally
Often in real-time embedded programming, it is necessary to perform certain operations atomically to prevent data corruption. The simplest way to achieve the atomicity is to briefly disable and re-enable interrupts. The PRIMASK CPU-core register prevents activation of all exceptions with configurable priority.
NVIC-Specific Functions
CMSIS provides a number of functions for NVIC control, such as:
CMSIS functions associated with NVIC are located in the core_cm0plus.h header file. Functions are implemented as inline code.
From the SAMD51 datasheet, here are the interrupt line mapping numbers for interrupts in the NVIC
[Datasheet Table 10-1 Interrupt Line Mapping](
Module | Source | Line | Enabled? |
---|---|---|---|
EIC NMI - External Interrupt Control | NMI | NMI | enabled |
PM - Power Manager | SLEEPRDY | 0 | disabled |
MCLK - Main Clock | CKRDY | 1 | disabled |
OSCCTRL - Oscillators Control | XOSCFAIL0 | 2 | disabled |
XOSCRDY0 | |||
XOSCFAIL1 | 3 | disabled | |
XOSCRDY1 | |||
DFLLLCKC | 4 | disabled | |
DFLLLCKF | |||
DFLLOOB | |||
DFLLRCS | |||
DFLLRDY | |||
DPLL00LCKF | 5 | disabled | |
DPLL0LCKR | |||
DPLL0LDRTO | |||
DPLL0LTO | |||
DPLL1LCKF | 6 | disabled | |
DPLL1LCKR | |||
DPLL1LDRTO | |||
DPLL1LTO | |||
OSC32KCTRL - 32 kHz Oscillators Control | XOSC32KFAIL | 7 | disabled |
XOSC32KRDY | |||
SUPC - Supply Controller | BOD33RDY | 8 | disabled |
B33SRDY | |||
VCORERDY | |||
VREGRDY | |||
BOD33DET | 9 | disabled | |
WDT - Watchdog Timer | EW | 10 | enabled |
RTC - Real-Time Counter | CMP0 | 11 | disabled |
CMP1 | |||
CMP2 | |||
CMP3 | |||
OVF | |||
PER0 | |||
PER1 | |||
PER2 | |||
PER3 | |||
PER4 | |||
PER5 | |||
PER6 | |||
PER7 | |||
TAMPER | |||
ALARM0 | |||
ALARM1 | |||
EIC - External Interrupt Controller | EXTINT 0 | 12 | enabled |
EXTINT 1 | 13 | enabled | |
EXTINT 2 | 14 | enabled | |
EXTINT 3 | 15 | enabled | |
EXTINT 4 | 16 | enabled | |
EXTINT 5 | 17 | enabled | |
EXTINT 6 | 18 | enabled | |
EXTINT 7 | 19 | enabled | |
EXTINT 8 | 20 | enabled | |
EXTINT 9 | 21 | enabled | |
EXTINT 10 | 22 | enabled | |
EXTINT 11 | 23 | enabled | |
EXTINT 12 | 24 | enabled | |
EXTINT 13 | 25 | enabled | |
EXTINT 14 | 26 | enabled | |
EXTINT 15 | 27 | enabled | |
FREQM - Frequency Meter | DONE | 28 | disabled |
NVMCTRL - Non-Volatile Memory Controller | DONE | 29 | disabled |
ADDRE | |||
PROGE | |||
LOCKE | |||
ECCSE | |||
ECCDE | |||
NVME | |||
SUSPE | |||
SEESFULL | 30 | disabled | |
SEESOVF | |||
SEEWRC | |||
DMAC - Direct Memory Access Controller | SUSP 0 | 31 | enabled |
TCMPL 0 | |||
TERR 0 | |||
SUSP 1 | 32 | enabled | |
TCMPL 1 | |||
TERR 1 | |||
SUSP 2 | 33 | enabled | |
TCMPL 2 | |||
TERR 2 | |||
SUSP 3 | 34 | enabled | |
TCMPL 3 | |||
TERR 3 | |||
SUSP 4..31 | 35 | enabled | |
TCMPL 4..31 | |||
TERR 4..31 | |||
EVSYS - Event System Interface | EVD 0 | 36 | disabled |
OVR 0 | |||
EVD 1 | 37 | disabled | |
OVR 1 | |||
EVD 2 | 38 | disabled | |
OVR 2 | |||
EVD 3 | 39 | disabled | |
OVR 3 | |||
EVD 4..11 | 40 | disabled | |
OVR 4..11 | |||
PAC - Peripheral Access Controller | ERR | 41 | disabled |
RAM ECC | SINGLEE | 45 | disabled |
DUALE | |||
SERCOM0 - Serial Communication Interface 0 | 0 | 46 | disabled |
1 | 47 | disabled | |
2 | 48 | disabled | |
3 | 49 | disabled | |
4 | |||
5 | |||
7 | |||
SERCOM1 - Serial Communication Interface 1 | 0 | 50 | disabled |
1 | 51 | disabled | |
2 | 52 | disabled | |
3 | 53 | disabled | |
4 | |||
5 | |||
7 | |||
SERCOM2 - Serial Communication Interface 2 | 0 | 54 | enabled |
1 | 55 | enabled | |
2 | 56 | enabled | |
3 | 57 | enabled | |
4 | |||
5 | |||
7 | |||
SERCOM3 - Serial Communication Interface 3 | 0 | 58 | enabled |
1 | 59 | enabled | |
2 | 60 | enabled | |
3 | 61 | enabled | |
4 | |||
5 | |||
7 | |||
SERCOM4 - Serial Communication Interface 4 | 0 | 62 | enabled |
1 | 63 | enabled | |
2 | 64 | enabled | |
3 | 65 | enabled | |
4 | |||
5 | |||
7 | |||
SERCOM5 - Serial Communication Interface 5 | 0 | 66 | enabled |
1 | 67 | enabled | |
2 | 68 | enabled | |
3 | 69 | enabled | |
4 | |||
5 | |||
7 | |||
SERCOM6 - Serial Communication Interface 6 | 0 | 70 | enabled |
1 | 71 | enabled | |
2 | 72 | enabled | |
3 | 73 | enabled | |
4 | |||
5 | |||
7 | |||
SERCOM7 - Serial Communication Interface 7 | 0 | 74 | disabled |
1 | 75 | disabled | |
2 | 76 | disabled | |
3 | 77 | disabled | |
4 | |||
5 | |||
7 | |||
CAN0 - Control Area Network 0 | LINE 0 | 78 | disabled |
LINE 1 | |||
CAN1 - Control Area Network 1 | LINE 0 | 79 | disabled |
LINE 1 | |||
USB - Universal Serial Bus | EORSM/DNRSM | 80 | enabled |
EORST/RST | |||
LPM/DCONN | |||
LPMSUSP/DDISC | |||
RAMACER | |||
RXSTP/TXSTP 0..7 | |||
STALL0/STALL 0..7 | |||
STALL1 0..7 | |||
SUSPEND | |||
TRFAIL0/TRFAIL 0..7 | |||
TRFAIL1/PERR 0..7 | |||
UPRSM | |||
WAKEUP | |||
SOF/HSOF | 81 | enabled | |
TRCPT0 0..7 | 82 | enabled | |
TRCPT1 0..7 | 83 | enabled | |
GMAC - Ethernet MAC | GMAC | 84 | disabled |
WOL | |||
TCC0 - Timer Counter Control 0 | CNT | 85 | disabled |
DFS | |||
ERR | |||
FAULTA | |||
FAULTB | |||
FAULT0 | |||
FAULT1 | |||
OVF | |||
TRG | |||
UFS | |||
MC0 | 86 | disabled | |
MC1 | 87 | disabled | |
MC2 | 88 | disabled | |
MC3 | 89 | disabled | |
MC4 | 90 | disabled | |
MC5 | 91 | disabled | |
TCC1 - Timer Counter Control 1 | CNT | 92 | disabled |
DFS | |||
ERR | |||
FAULTA | |||
FAULTB | |||
FAULT0 | |||
FAULT1 | |||
OVF | |||
TRG | |||
UFS | |||
MC0 | 93 | disabled | |
MC1 | 94 | disabled | |
MC2 | 95 | disabled | |
MC3 | 96 | disabled | |
TCC2 - Timer Counter Control 2 | CNT | 97 | disabled |
DFS | |||
ERR | |||
FAULTA | |||
FAULTB | |||
FAULT0 | |||
FAULT1 | |||
OVF | |||
TRG | |||
UFS | |||
MC0 | 98 | disabled | |
MC1 | 99 | disabled | |
MC2 | 100 | disabled | |
TCC3 - Timer Counter Control 3 | CNT | 101 | disabled |
DFS | |||
ERR | |||
FAULTA | |||
FAULTB | |||
FAULT0 | |||
FAULT1 | |||
OVF | |||
TRG | |||
UFS | |||
MC0 | 102 | disabled | |
MC1 | 103 | disabled | |
TCC4 - Timer Counter Control 4 | CNT | 104 | disabled |
DFS | |||
ERR | |||
FAULTA | |||
FAULTB | |||
FAULT0 | |||
FAULT1 | |||
OVF | |||
TRG | |||
UFS | |||
MC0 | 105 | disabled | |
MC1 | 106 | disabled | |
TC0 - Basic Timer Counter 0 | ERR | 107 | disabled |
MC0 | |||
MC1 | |||
OVF | |||
TC1 - Basic Timer Counter 1 | ERR | 108 | disabled |
MC0 | |||
MC1 | |||
OVF | |||
TC2 - Basic Timer Counter 2 | ERR | 109 | disabled |
MC0 | |||
MC1 | |||
OVF | |||
TC3 - Basic Timer Counter 3 | ERR | 110 | disabled |
MC0 | |||
MC1 | |||
OVF | |||
TC4 - Basic Timer Counter 4 | ERR | 111 | disabled |
MC0 | |||
MC1 | |||
OVF | |||
TC5 - Basic Timer Counter 5 | ERR | 112 | disabled |
MC0 | |||
MC1 | |||
OVF | |||
TC6 - Basic Timer Counter 6 | ERR | 113 | disabled |
MC0 | |||
MC1 | |||
OVF | |||
TC7 - Basic Timer Counter 7 | ERR | 114 | disabled |
MC0 | |||
MC1 | |||
OVF | |||
PDEC - Position Decoder | DIR | 115 | disabled |
ERR | |||
OVF | |||
VLC | |||
MC0 | 116 | disabled | |
MC1 | 117 | disabled | |
ADC0 - Analog Digital Converter 0 | OVERRUN | 118 | disabled |
WINMON | |||
RESRDY | 119 | disabled | |
ADC1 - Analog Digital Converter 1 | OVERRUN | 120 | disabled |
WINMON | |||
RESRDY | 121 | disabled | |
AC - Analog Comparators | COMP0 | 122 | disabled |
COMP1 | |||
WIN0 | |||
DAC - Digital-to-Analog Converter | OVERRUN0 | 123 | disabled |
OVERRUN1 | |||
UNDERRUN0 | |||
UNDERRUN1 | |||
EMPTY0 | 124 | disabled | |
EMPTY1 | 125 | disabled | |
RESRDY0 | 126 | disabled | |
RESRDY1 | 127 | disabled | |
I2S - Inter-IC Sound Interface | RXOR0 | 128 | disabled |
RXOR1 | |||
RXRDY0 | |||
RXRDY1 | |||
TXRDY0 | |||
TXRDY1 | |||
TXUR0 | |||
TXUR1 | |||
PCC - Parallel Capture Controller | DRDY | 129 | disabled |
OVRE | |||
AES - Advanced Encryption Standard | ENCCMP | 130 | disabled |
GFMCMP | |||
TRNG - True Random Generator | DATARDY | 131 | disabled |
ICM - Integrity Check Monitor | All ICM Interrupts | 132 | disabled |
Reserved | Reserved | 133 | disabled |
QSPI - Quad SPI interface | RXC | 134 | disabled |
DRE | |||
TXC | |||
ERROR | |||
CSRISE | |||
INSTREND | |||
SDHC0 - SD/MMC Host Controller 0 | All SDHC0 Interrupts | 135 | disabled |
SDHC1 - SD/MMC Host Controller 1 | All SDHC1 Interrupts | 136 | disabled |
Exception and Interrupt Handlers
Default exception handler functions are defined in startup_samd21.c. They're defined as “weak” functions, so you can override the default implementation with your own.
NVIC Interrupts Defined in the Adafruit SAMD U2F Bootloader and Arduino Core
SAMD51 NVIC
- SERCOMs - sercom.cpp - priority of 3
SERCOM0_0_IRQn
->SERCOM5_3_IRQn
SERCOM6_0_IRQn
->SERCOM6_3_IRQn
, iff variant definesSERCOM6
SERCOM7_0_IRQn
->SERCOM7_3_IRQn
, iff variant definesSERCOM7
- Timers:
- TC0 (
TC5_IRQn
) - Tone.cpp - priority of 5(?) - TC1 (
TC1_IRQn
) - Servo.cpp - priority of 0- NOTE: The servo library has a to-do flag in it to allow a second timer, but as of November of 2024 only supports one timer for servo in the SAMD core.rv
- TC0 (
- External Interrupt Controller - WInterrupts.c - priority of 0
EIC_0_IRQn
->EIC_15_IRQn
- A single EIC interrupt for the USB pin is also enabled by Adafruit_USBH_Host.cpp if TinyUSB is used.
- USB - samd21_host.c and USBCore.cpp - priority 0
- NOTE: Despite the name, samd21_host.c is used for all SAMD boards
USB_0_IRQn
->USB_3_IRQn
- DMAC - Adafruit_ZeroDMA.cpp or I2S/../DMA.cpp
DMAC_0_IRQn
->DMAC_4_IRQn
- priority of 3
SAMD21 NVIC
- SERCOMs - sercom.cpp - priority of 3
SERCOM0_IRQn
->SERCOM3_IRQn
SERCOM4_IRQn
, iff variant definesSERCOM4
SERCOM5_IRQn
, iff variant definesSERCOM5
- Timers:
- TC5 (
TC5_IRQn
) - Tone.cpp - priority of 5(?) - TC4 (
TC4_IRQn
) - Servo.cpp - priority of 0- NOTE: The servo library has a to-do flag in it to allow a second timer, but as of November of 2024 only supports one timer for servo in the SAMD core.
- TC5 (
- External Interrupt Controller - WInterrupts.c - priority of 0
EIC_IRQn
- The EIC interrupts are also enabled by Adafruit_USBH_Host.cpp if TinyUSB is used.
- USB - samd21_host.c and USBCore.cpp - priority 0
USB_IRQn
- DMAC - Adafruit_ZeroDMA.cpp or I2S/../DMA.cpp
DMAC_IRQn
- priority of 3