Which interrupts are used in SAMD21?

Hello all,

in the below code for SAMD21 the pin D6 pin is toggled as fast as possible. This pin is tested with an oscilloscope, which is triggered on pulse length. Obviously there are several interrupt sources in use. One source is repeating each millisecond and takes about 5 microseconds. There seem to be other interrupts as well, these take about 2 microseconds.

My questions:

  1. Which interrupt sources are in use?
  2. Which timers are used? (With other words: Which timers can’t be used in my own software?)
  3. What happens (what won’t work any longer) if I disable these interrupts?
  4. Which priority have these interrupts?

Thanks, Michael

#define repeat_10(a) a;a;a;a;a;a;a;a;a;a

#define repeat_100(a) repeat_10(repeat_10(a))

#define repeat_1000(a) repeat_10(repeat_100(a))

void setup()

{

pinMode(D6,OUTPUT); // test pin

}

void loop()

{

repeat_1000

(

PORT->Group[1].OUTSET.reg = 256;  // D6 = 1

PORT->Group[1].OUTCLR.reg = 256;  // D6 = 0

)

}

Hi there,

So, Is this a Homework assignment?:grin:

What have you tried so far?

The race condition is conditional,and is Interrupted by the Last interrupt is what It appears to me. :grin: :+1:

add some Delay and you will be able to see it better, Too!

HTH
GL :slight_smile: PJ :v:

no.

I have tried exactly the code that I’ve posted. In the main loop a pin is toggled as fast as possible, so that I can see any interrupts on the oscilloscope. There are no interrupts used in my code. But obviously there are some interrupts active. I’d like to know which interrupts are these, which priority do they have, and what would happen if I disable them.

I found out that the 5 microseconds interrupt is the USB interrupt. It can be disabled with

NVIC_DisableIRQ(USB_IRQn);

Now there is still another interrupt which takes 2 microseconds. I haven’t yet figured out which one it is. Any ideas?

1 Like

Hi there,

Ok Then, Good to know we aren’t part of a Homework assighnment.
ON ESP chips there is a RTOS, also on the Nrf parts. The Samd21 is slightly different,
Even in a simple sketch, Certain Interrupts are in use Always(well almost)
The main one is the SYSTEMs Core timer " SysTick" used fo things like Millis() and micros() and the Delay timing in the SAMD21 Arduino CORE.
This one fires every 1 ms.
Next would be Your Output, Think Serial port Interrupt (data available) or Receive Buffer notification Interrupt, or anything on the USB stack can generate an int. EVen if you don’t print , the USB stacks can generate a periodic interrupt.
then there’s the
“SERCOM” interrupts , early users of the SAMD parts got there first taste of interrupts for all serial devices, Rx/TX and I2C transactions, etc.
There may be others depending on board support packages (ADC, event system, watchdog), but the big three above explain the behavior 99% of the time.

Which timers are used (which ones are “off limits”?)

For Arduino SAMD21, the core timing (millis/micros/delay) uses SysTick, not the peripheral TC/TCC timers.

That means the peripheral timers TCC0/1/2 and TC3/4/5 are generally available for your own use (unless your libraries claim one). This is a classic difference from AVR Arduino where a hardware timer is often consumed.

What happens if you disable these interrupts?

Depends what you disable:

If you disable SysTick interrupt:

  • millis() stops incrementing
  • delay() stops working properly
  • micros() can become wrong/non-monotonic depending how the core is written/configured

If you disable global interrupts (noInterrupts()):

  • Everything time-based stops behaving
  • USB can stall / disconnect
  • Serial RX/TX and most drivers stop (buffers won’t drain/fill)
  • Any attachInterrupt() pin interrupts stop

So yes, your D6 pulse train becomes “clean,” but you’ve basically turned Arduino’s runtime off.
I found this as well, may explain the priorities better.

What priority are these interrupts?

SAMD21 (Cortex-M0+) supports multiple priority levels. Microchip documents 4 priority levels (0–3) and NVIC_SetPriority() is how you set them; higher number = lower priority.

In ArduinoCore-samd, SysTick is often configured at a low priority (specifically called out as “2nd lowest” in the core discussion).
That means “more important” ISRs (GPIO/EIC, some SERCOM, etc.) can preempt it.

If you want a truly stable “as fast as possible” output, don’t bit-bang in loop():

  • Use a hardware timer (TCC/TC) to toggle a pin via waveform output, or
  • Use the event system if he wants it ultra-clean. :backhand_index_pointing_left: :face_with_open_eyes_and_hand_over_mouth: I have a post on here about it, offloads it to the Peripheral interface.

HTH
GL :slight_smile: PJ :v:

1 Like

Do you know the command for disabling the SysTick interrupt?

Hi there,

Yes, Depends on How HARD of a stop you want?
"It’s not the fall the kills you , It’s that sudden STOP! " :grin:

Disable the SysTick interrupt only, not all interrupts:

SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;

this stops the Systick ISR
SO no millis, etc. Timing related.
other ints still work, GPIO, SERCOM and discrete Timers still work.
This is the cleanest way to prove SysTick is the 1 ms disturbance you’re seeing on the scope.

To re-enable it:

SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;

If you want SysTick completely off:

SysTick->CTRL = 0;

Effects:

  • Stops the counter
  • Stops the interrupt
  • Arduino timekeeping is totally dead
  • Only use this for short diagnostic experiments

Don’t get confused with “noInterrupts();”

noInterrupts();

That disables all interrupts globally:

  • USB dies
  • Serial dies
  • External interrupts die
  • Timing dies

That’s not what you want if you’re isolating SysTick jitter.

You can try this too:

void setup() {
  pinMode(D6, OUTPUT);

  // Disable SysTick interrupt
  SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
}

If the 1 ms jitter vanishes but faster jitter remains:
Your Systick is confirmed, the remaining jitter would be from the other’s or the ISR for those USB / SERCOM
:+1:

HTH
GL :slight_smile: PJ :v:

When SysTick is disabled, the 2 microsecond interrupt is gone. That’s very good. Now another interrupt with 700 ns is still there, but that’s so short that it doesn’t matter for my application.

I’m still a little bit confused how this SysTick works. Because it’s not a hardware interrupt source. It’s not listed on pages 49-50 in the datasheet:

Hi there,

You may need to look for a SMAD21 *TRG, Technical Reference Guide , They usually have the Nuance stuff in there. Atmel forum will have more on there as well. :+1:

It is a System Exception, Not a Peripheral Interrupt

In ARM Cortex-M nomenclature, including the Microchip SAMD21 (which uses a Cortex-M0+ core).
The reason you don’t find it in pages 49-50 of the SAMD21 datasheet is precisely because there is a distinction between Interrupts (IRQ 0-240) and System Exceptions (Exception 1-15).

  • Peripheral Interrupts: These are listed in your datasheet (e.g., UART, TIM2, EXTI) and are handled by the NVIC.
  • System Exceptions: These are built into the core, such as HardFault, NMI, and SysTick.
  • SysTick is exception number 15 and is handled by the System Control Block (SCB) within the CPU core, not by the vendor-specific interrupt controller, even though it can be prioritized like an interrupt.
  1. How SysTick Works (2𝜇s interval)
  • 24-bit Counter: It is a 24-bit down-counter (SysTick->VAL) that counts down to zero.
  • Reload Value: When it hits 0, it triggers the SysTick_Handler and immediately reloads the value from the SysTick->LOAD register.
  • Clock Source: It is usually clocked by the CPU clock (HCLK), making it extremely fast. For a 2𝜇s interval, the reload value is low.
  1. Why It’s Not on Pages 49-50

The datasheet pages you are referencing usually list peripheral IRQs (lines 0 and above). SysTick is officially defined as exception number 15, which is fixed by ARM for all Cortex-M devices. It is a standard component for OS scheduling (e.g., 1ms tick for FreeRTOS)
(specifically section 8, “Interrupts” or 13, “System Handler and Interrupts” if available in your version) to see the full vector table, which lists SysTick as a “System Exception” distinct from the external interrupts (EIC, PM, SYSCTRL, GCLK, etc.) that the rest of the datasheet focuses on.

HTH
GL :slight_smile: PJ :v:

1 Like

Thank you very much for your detailed explanations!

Michael

1 Like

Hi there,

No Problem, Glad to help. It’s a Great Nuanced topic thanks for the contribution.
You can do Us a SOLID and mark post #6 as the solution, or #8 :grin:
this will help others find it fast :+1:

GL :slight_smile: PJ :v: