Timer interrupts on XIAO

Does the XIAO support timer interrupts? If so, does anyone have a sample sketch for Arduino that demonstrates? I’m familiar with interrupts on the Uno, but my code fails to compile for the XIAO. Thanks.

You can try the API. I hope it meets your needs.
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Thank you, that is most helpful.

That doesn’t look like a timer interrupt to me it looks like an interrupt on a pin.

Yeah, you’re right, that is all about interrupt pins

You’ve probably found something by now, so I guess this is for the benefit of anyone else looking

#include <Arduino.h>
#include <TimerTC3.h>

#define Transmission_Timer TimerTc3 

/****************
 * Forward declarations of functions
 *************************************************************/
void TRANSMISSION_ISR();
void transmit();

/****************
 * Evaluated to determine whether or not we need to send a message
 *************************************************************/
volatile bool TransmitNextMessage = false;

void setup()
{
  Serial.begin(115200);
  // allow time for serial start and port monitoring tool connection
  uint32_t timestamp = millis();
  while(millis() - timestamp < 2000)
    ;

  /****************
   * Initialize the timer and register the ISR function
   *************************************************************/
  Transmission_Timer.initialize();    // The default interval is 1000000 microseconds
  Transmission_Timer.attachInterrupt(TRANSMISSION_ISR);
}

unsigned long packetnum = 1; // packet counter, we increment per xmission
void loop()
{
  /****************
   * Disable the IRQ so that we can safely access the shared resource
   *************************************************************/
  __disable_irq();
  
  bool run = TransmitNextMessage;
  if(run)
    TransmitNextMessage = !TransmitNextMessage;

  /****************
   * Don't forget to reenable the IRQ
   *************************************************************/
  __enable_irq();

  if(run)
    transmit();
}

/****************
 * The ISR must return as quickly as possible
 *************************************************************/
void TRANSMISSION_ISR() { TransmitNextMessage = true; }

/****************
 * This function is called each time the Timer period elapses
 * but it happens as part of the main loop()
 * 
 * Remember that you should NEVER write to Serial
 * from within an ISR
 *************************************************************/
void transmit()
{
  Serial.printf("Hello World # %lu", packetnum++);
}


One of my teammates was working with an arduino mega while writing this code. now i have to use the Seeeduino XIAO, therefore the time interrupts isn’t working and i get compilation error. any suggestion ? (without too much change in the code)

hi this is Timer intterupt basic code

#include <TimerTC3.h>

void setup() 
{
    TimerTc3.initialize(1000000);
    TimerTc3.attachInterrupt(timerIsr);
}
void loop()
{    } 
void timerIsr()
{  /in your code  }
4 Likes

A very good hint. Simple and clear.

I think TimerTC3 has a bug.
I tried TimerTc3.initialize 10922 → 10923 and 10923 → 10922 in order.
Then the timer slowed down.

ex.
08:25:40.101 → CountUp:10922
08:25:40.101 → CountUp:10922
08:25:40.135 → CountUp:10922
08:25:40.135 → CountUp:10922
08:25:40.821 → CountUp:10923 <= +686msec
08:25:41.543 → CountUp:10923 <= +722msec
08:25:42.234 → CountUp:10923 <= +691msec

08:41:01.160 → CountUp:10923
08:41:01.160 → CountUp:10923
08:41:01.194 → CountUp:10923
08:41:01.194 → CountUp:10923
08:41:02.605 → CountUp:10922 <= +1.411sec
08:41:04.010 → CountUp:10922 <= +1.405sec
08:41:05.386 → CountUp:10922 <= +1.376sec

Setting from 10922 or less to 10923 or more or from 10923 or more to 10922 or less is NG ?

#include <Arduino.h>
#include <TimerTC3.h>

uint32_t tc_time = 10920;
int  count = 0;

void setup()
{
  Serial.begin(115200);

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  TimerTc3.initialize(tc_time);
  TimerTc3.attachInterrupt(int_timer);
  Serial.println("Start");
}

void loop()
{
  delay(10);
}

void int_timer()
{
  Serial.print("CountUp:");
  Serial.println(tc_time);
  if(++count >= 10)
  {
    tc_time++;
    TimerTc3.stop();
    TimerTc3.initialize(tc_time);
    TimerTc3.attachInterrupt(int_timer);
    count = 0;
  }
}

Self-resolved!
I fixed TimerTC3.cpp.
Thanks.

void TimerTC3::setPeriod(long microseconds)
{
    TcCount16 *TC = (TcCount16 *)TC3;

    uint32_t cycles = (CPU_HZ / 1000000) * microseconds;
    uint32_t prescalerConfigBits;

    if (cycles < RESOLUTION)
        prescalerConfigBits = TC_CTRLA_PRESCALER_DIV1;
    else if ((cycles >>= 1) < RESOLUTION)
        prescalerConfigBits = TC_CTRLA_PRESCALER_DIV2;
    else if ((cycles >>= 1) < RESOLUTION)
        prescalerConfigBits = TC_CTRLA_PRESCALER_DIV4;
    else if ((cycles >>= 1) < RESOLUTION)
        prescalerConfigBits = TC_CTRLA_PRESCALER_DIV8;
    else if ((cycles >>= 1) < RESOLUTION)
        prescalerConfigBits = TC_CTRLA_PRESCALER_DIV16;
    else if ((cycles >>= 2) < RESOLUTION)
        prescalerConfigBits = TC_CTRLA_PRESCALER_DIV64;
    else if ((cycles >>= 2) < RESOLUTION)
        prescalerConfigBits = TC_CTRLA_PRESCALER_DIV256;
    else if ((cycles >>= 2) < RESOLUTION)
        prescalerConfigBits = TC_CTRLA_PRESCALER_DIV1024;
    else
        cycles = RESOLUTION - 1, prescalerConfigBits = TC_CTRLA_PRESCALER_DIV1024;
/*
    SerialUSB.print("cycles is ");
    SerialUSB.println(cycles);
    SerialUSB.print("prescalerConfigBits is ");
    SerialUSB.println(prescalerConfigBits);
*/
    // Set prescaler
    uint32_t CtrlA = TC->CTRLA.reg;
    uint32_t Enable = CtrlA & TC_CTRLA_ENABLE;

    TC->CTRLA.reg = CtrlA & ~TC_CTRLA_ENABLE;
    CtrlA &= ~TC_CTRLA_PRESCALER_Msk;
    CtrlA |= prescalerConfigBits;
    //TC->CTRLA.reg |= prescalerConfigBits;
    TC->CTRLA.reg = CtrlA;
    while (TC->STATUS.bit.SYNCBUSY == 1)
        ;

    TC->CC[0].reg = cycles;
    while (TC->STATUS.bit.SYNCBUSY == 1)
        ;

    TC->CTRLA.reg |= Enable;
    while (TC->STATUS.bit.SYNCBUSY == 1)
        ;

    //TC->PER.reg = cycles;
    //while (TC->STATUS.bit.SYNCBUSY == 1);
}
1 Like

Can you please point to the Github repo of TimerTC3 library for Xiao NRF52 Sense? Thanks

Sorry,I don’t know.

Can do the same thing with the this source, but I don’t know how to use it.
ArduinoData\packages\Seeeduino\hardware\nrf52\1.1.1\cores\nRF5\nordic\nrfx\drivers\src\nrfx_timer.c

If you want to reset the Seeed Studio XIAO SAMD21 , perform the following steps:

Connect the Seeed Studio XIAO SAMD21 to your computer.
Use tweezers or short lines to short the RST pins only once
The orange LED lights flicker on and light up.
Please note: The behavior of the built-in LED is reversed to the one on an Arduino. On the Seeed Studio XIAO SAMD21 , the pin has to be pulled low, whereas on other micro-controllers it has to be pulled high.

Regards,
Rachel Gomez