As I’ve been going far inside the SAMD21 Arduino boards, I’ve realized the main distinction of the ARM-core SAMD21 compared to the AVR architecture ATMega microcontrollers, and indeed to other microcontrollers I’ve used in the past. The ARM-core microcontrollers are actually a two part design. There is the ARM designed processor core, and the vendor (Microchip in this case) designed peripherals. This design shows up abruptly in the design of the interrupt system!
In a traditional (non-ARM) microcontroller, each peripheral device has in its control/status register(s) a bit that enables the device to trigger an interrupt, the Interrupt Enable bit, and a bit that indicates that the peripheral is ready to be serviced, the Interrupt Flag bit. If IE=1 and IF=1 and interrupts are enabled then the interrupt will be triggered.
In the SAMD21, the ARM core handles the interrupts. This is done in the Nested Vectored Interrupt Controller (NVIC). The interrupt enable bits and the interrupt flag bits (here called interrupt pending bits) are in registers within the NVIC and not the peripheral registers! The only exception is the SysTick interrupt. The SysTick counter is part of the core and the interrupt enable for SysTick is in one of the SysTick registers while the pending bit is hidden in a System Control Block register. (Why??)
Also giving away this design is that the interrupt/exceptions that originate in the ARM core are grouped together and are before those that originate in the peripherals. While exceptions are numbered from 1, the ones originating in the peripherals, which are called interrupts, also numbered from 0, with the core exceptions having negative interrupt numbers.
Just to add to the fun, IRQ #4 is for the External Interrupt Controller, yet another level of hierarchy, which handles all the external pin change interrupts. These in turn have another set of numbers assigned to them. But more on that later.