Problem with using RTC and timer counter together

I am doing a project in which I am using xiao’s RTC for a stop watch and timer counter for interrupt generation and then outputting to a 128 x 64 SSD1306 OLED screen. For these purposes, I am using RTCZero library and SAMD_TimerInterrupt library in my program.

My program works fine with just RTC functionality and RTCZero library. I update the time every second on the screen and it all works flawlessly. But when using SAMD_TimerInterrupt library with any interrupt interval greater than about 1.4 seconds (max interval supported by TC of SAMD21 aboard the Xiao) my program kind of freezes just as the counter for interrupt generation is started. Also I think not just the program but the board freezes entirely as I have problem uploading fresh sketches to the board after it has frozen. Same happens when I use TCC (timer counter for control) which are also supported by the library but I don’t know if they are any different than the TC (timer counter) from above.
When I increase the timer interval above 1.4 seconds, the program starts working again. I though the board freezing might have something to do with the complexity of ISR but even with an empty ISR the problem remains.

I was going to post the code here but as the code was quite lengthy I decided against it but I can post if it is required.

Thanks for reading and any help will be much appreciated.

Hello, I am sorry you are having this problem, and your description is a bit abstract, I would like to get your program to analyze and solve it. Thanks

Thank you for replying. So, I did some more testing and whatever it is, the problem is with the SAMD_TimerInterrupt library only. I started experimenting with the just this library and I cannot even get a basic sketch with a very lean ISR to run without crashing/freezing the board.

My code is :

#include <Arduino.h>
#include <SAMDTimerInterrupt.h>

SAMDTimer myTimer(TIMER_TCC);

volatile bool interrupt = 0;

void myISR(){
  interrupt = 1;
}

void setup() {
  // put your setup code here, to run once:

  SerialUSB.begin(9600);
  while(!SerialUSB);

  myTimer.attachInterruptInterval_MS(500, myISR);
}

void loop() {
  // put your main code here, to run repeatedly:
  static unsigned long timer1;

  if (millis() - timer1 > 2000){
    SerialUSB.println("Normal print");
    timer1 = millis();
  }

  if (interrupt){
    SerialUSB.println("Interrupt generated");
    interrupt = 0;
  }

}

For reference, an example sketch from the library which did ran correctly on the board is

#include <Arduino.h>

#if !( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
      || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
      || defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) \
      || defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD51__) || defined(__SAMD51J20A__) \
      || defined(__SAMD51J19A__) || defined(__SAMD51G19A__) || defined(__SAMD51P19A__)  \
      || defined(__SAMD21E15A__) || defined(__SAMD21E16A__) || defined(__SAMD21E17A__) || defined(__SAMD21E18A__) \
      || defined(__SAMD21G15A__) || defined(__SAMD21G16A__) || defined(__SAMD21G17A__) || defined(__SAMD21G18A__) \
      || defined(__SAMD21J15A__) || defined(__SAMD21J16A__) || defined(__SAMD21J17A__) || defined(__SAMD21J18A__) )
  #error This code is designed to run on SAMD21/SAMD51 platform! Please check your Tools->Board setting.
#endif

/////////////////////////////////////////////////////////////////

// These define's must be placed at the beginning before #include "SAMDTimerInterrupt.h"
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
// Don't define TIMER_INTERRUPT_DEBUG > 2. Only for special ISR debugging only. Can hang the system.
#define TIMER_INTERRUPT_DEBUG         0
#define _TIMERINTERRUPT_LOGLEVEL_     0

// Select only one to be true for SAMD21. Must must be placed at the beginning before #include "SAMDTimerInterrupt.h"
#define USING_TIMER_TC3         true      // Only TC3 can be used for SAMD51
#define USING_TIMER_TC4         false     // Not to use with Servo library
#define USING_TIMER_TC5         false
#define USING_TIMER_TCC         false
#define USING_TIMER_TCC1        false
#define USING_TIMER_TCC2        false     // Don't use this, can crash on some boards

// Uncomment To test if conflict with Servo library
//#include "Servo.h"

/////////////////////////////////////////////////////////////////

#include "SAMDTimerInterrupt.h"

#ifndef LED_BUILTIN
  #define LED_BUILTIN       13
#endif

unsigned int SWPin = 7;

// TC3, TC4, TC5 max permissible TIMER_INTERVAL_MS is 1398.101 ms, larger will overflow, therefore not permitted
// Use TCC, TCC1, TCC2 for longer TIMER_INTERVAL_MS
#define TIMER_INTERVAL_MS        1000

#define TIMER_DURATION_MS        5000

volatile uint32_t preMillisTimer = 0;

///////////////////////////////////////////////

#if (TIMER_INTERRUPT_USING_SAMD21)

  #if USING_TIMER_TC3
    #define SELECTED_TIMER      TIMER_TC3
  #elif USING_TIMER_TC4
    #define SELECTED_TIMER      TIMER_TC4
  #elif USING_TIMER_TC5
    #define SELECTED_TIMER      TIMER_TC5
  #elif USING_TIMER_TCC
    #define SELECTED_TIMER      TIMER_TCC
  #elif USING_TIMER_TCC1
    #define SELECTED_TIMER      TIMER_TCC1
  #elif USING_TIMER_TCC2
    #define SELECTED_TIMER      TIMER_TCC
  #else
    #error You have to select 1 Timer  
  #endif

#else

  #if !(USING_TIMER_TC3)
    #error You must select TC3 for SAMD51
  #endif
  
  #define SELECTED_TIMER      TIMER_TC3

#endif  

// Init selected SAMD timer
SAMDTimer ITimer(SELECTED_TIMER);

////////////////////////////////////////////////

void TimerHandler()
{
  static bool toggle = false;
 
#if (TIMER_INTERRUPT_DEBUG > 0)
    static uint32_t curMillis = 0;
      
    curMillis = millis();
    
    if (curMillis > TIMER_INTERVAL_MS)
    {
      Serial.print("ITimer: millis() = "); Serial.print(curMillis);
      Serial.print(", delta = "); Serial.println(curMillis - preMillisTimer);
    }
    
    preMillisTimer = curMillis;
#endif

  //timer interrupt toggles pin LED_BUILTIN
  digitalWrite(LED_BUILTIN, toggle);
  toggle = !toggle;
}

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  
  Serial.begin(9600);
  while (!Serial && millis() < 5000);
  
  delay(100);

  Serial.print(F("\nStarting TimerInterruptTest on ")); Serial.println(BOARD_NAME);
  Serial.println(SAMD_TIMER_INTERRUPT_VERSION);
  Serial.print(F("CPU Frequency = ")); Serial.print(F_CPU / 1000000); Serial.println(F(" MHz"));

  // Interval in millisecs
  if (ITimer.attachInterruptInterval_MS(TIMER_INTERVAL_MS, TimerHandler))
  {
    preMillisTimer = millis();
    Serial.print(F("Starting ITimer OK, millis() = ")); Serial.println(preMillisTimer);
  }
  else
    Serial.println(F("Can't set ITimer. Select another freq. or timer"));
}

void loop()
{
  static unsigned long lastTimer   = 0; 
  static bool timerStopped         = false;
  

  if (millis() - lastTimer > TIMER_DURATION_MS)
  {
    lastTimer = millis();

    if (timerStopped)
    {
      preMillisTimer = millis();
      Serial.print(F("Start ITimer, millis() = ")); Serial.println(preMillisTimer);
      ITimer.restartTimer();
    }
    else
    {
      Serial.print(F("Stop ITimer, millis() = ")); Serial.println(millis());
      ITimer.stopTimer();
    }
    
    timerStopped = !timerStopped;
  }
}

I am not able to figure out what the problem could be with such a simple sketch. I am sure I am missing something very simple.

Thanks for reading and waiting for your reply.

I tested it with the provided code and found no problems. The ISR can be executed normally. I think the problem lies in the SAMD_TimerInterrupt library. This is the SAMD_TimerInterrupt library I use.

I posted two codes. First one was written by me and the second was an example sketch from the library.
I had no problems running the example sketch, the second code but my board was freezing while running the first code that I had written myself.
Are you sure the first code that was in my post ran successfully on your board?

Ok so after doing a ‘thorough’ reading of the library’s documentation and comparing the example sketch, it was infact a very silly mistake of not including a couple of define statements in the beginning of my sketch.
The define statements are

#define USING_TIMER_TC3         true      // Only TC3 can be used for SAMD51
#define USING_TIMER_TC4         false     // Not to use with Servo library
#define USING_TIMER_TC5         false
#define USING_TIMER_TCC         false
#define USING_TIMER_TCC1        false
#define USING_TIMER_TCC2        false     // Don't use this, can crash on some boards