11/* ***************************************************************************************************************************
22 ISR_16_Timers_Array.ino
3- For NRF52 boards
3+ For SAMD boards
44 Written by Khoi Hoang
55
6- Built by Khoi Hoang https://github.com/khoih-prog/NRF52_TimerInterrupt
6+ Built by Khoi Hoang https://github.com/khoih-prog/SAMD_TimerInterrupt
77 Licensed under MIT license
8-
8+
99 Now even you use all these new 16 ISR-based timers,with their maximum interval practically unlimited (limited only by
10- unsigned long miliseconds), you just consume only one NRF52 timer and avoid conflicting with other cores' tasks.
10+ unsigned long miliseconds), you just consume only one SAMD timer and avoid conflicting with other cores' tasks.
1111 The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
1212 Therefore, their executions are not blocked by bad-behaving functions / tasks.
1313 This important feature is absolutely necessary for mission-critical tasks.
4747 written
4848*/
4949
50- #if !(defined(NRF52840_FEATHER) || defined(NRF52832_FEATHER) || defined(NRF52_SERIES) || defined(ARDUINO_NRF52_ADAFRUIT) || \
51- defined (NRF52840_FEATHER_SENSE) || defined(NRF52840_ITSYBITSY) || defined(NRF52840_CIRCUITPLAY) || \
52- defined(NRF52840_CLUE) || defined(NRF52840_METRO) || defined(NRF52840_PCA10056) || defined(PARTICLE_XENON) \
53- || defined(NINA_B302_ublox) || defined(NINA_B112_ublox) )
54- #error This code is designed to run on nRF52 platform! Please check your Tools->Board setting.
50+ #if !( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
51+ || defined (ARDUINO_SAMD_NANO_33_IOT) || defined (ARDUINO_SAMD_MKRFox1200) || defined (ARDUINO_SAMD_MKRWAN1300) || defined (ARDUINO_SAMD_MKRWAN1310) \
52+ || defined (ARDUINO_SAMD_MKRGSM1400) || defined (ARDUINO_SAMD_MKRNB1500) || defined (ARDUINO_SAMD_MKRVIDOR4000) || defined (__SAMD21G18A__) \
53+ || defined (ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined (__SAMD21E18A__) || defined (__SAMD51__) || defined (__SAMD51J20A__) || defined (__SAMD51J19A__) \
54+ || defined (__SAMD51G19A__) || defined (__SAMD51P19A__) || defined (__SAMD21G18A__) )
55+ #error This code is designed to run on SAMD21/SAMD51 platform! Please check your Tools->Board setting.
5556#endif
5657
57- // These define's must be placed at the beginning before #include "NRF52TimerInterrupt .h"
58- // Don't define NRF52_TIMER_INTERRUPT_DEBUG > 0 . Only for special ISR debugging only. Can hang the system.
59- #define NRF52_TIMER_INTERRUPT_DEBUG 1
58+ // These define's must be placed at the beginning before #include "SAMDTimerInterrupt .h"
59+ // Don't define SAMD_TIMER_INTERRUPT_DEBUG > 2 . Only for special ISR debugging only. Can hang the system.
60+ #define SAMD_TIMER_INTERRUPT_DEBUG 1
6061
61- #include " NRF52TimerInterrupt .h"
62- #include " NRF52_ISR_Timer .h"
62+ #include " SAMDTimerInterrupt .h"
63+ #include " SAMD_ISR_Timer .h"
6364
6465#include < SimpleTimer.h> // https://github.com/schinken/SimpleTimer
6566
6869#endif
6970
7071#ifndef LED_BLUE
71- #define LED_BLUE 7
72+ #define LED_BLUE 2
7273#endif
7374
7475#ifndef LED_RED
75- #define LED_RED 8
76+ #define LED_RED 3
7677#endif
7778
7879#define HW_TIMER_INTERVAL_US 10000L
7980
8081volatile uint32_t startMillis = 0 ;
8182
82- // Depending on the board, you can select NRF52 Hardware Timer from NRF_TIMER_1-NRF_TIMER_4 (1 to 4)
83- // If you select the already-used NRF_TIMER_0, it'll be auto modified to use NRF_TIMER_1
83+ // You can select SAMD Hardware Timer from SAMD_TIMER_1 or SAMD_TIMER_3
84+
85+ // Depending on the board, you can select SAMD21 Hardware Timer from TC3-TCC
86+ // SAMD21 Hardware Timer from TC3 or TCC
87+ // SAMD51 Hardware Timer only TC3
88+
89+ // Init SAMD timer TIMER_TC3
90+ SAMDTimer ITimer (TIMER_TC3);
8491
85- // Init NRF52 timer NRF_TIMER1
86- NRF52Timer ITimer (NRF_TIMER_2);
92+ #if (TIMER_INTERRUPT_USING_SAMD21)
93+ // Init SAMD timer TIMER_TCC
94+ // SAMDTimer ITimer(TIMER_TCC);
95+ #endif
8796
88- // Init NRF52_ISR_Timer
89- // Each NRF52_ISR_Timer can service 16 different ISR-based timers
90- NRF52_ISR_Timer ISR_Timer;
97+ // Init SAMD_ISR_Timer
98+ // Each SAMD_ISR_Timer can service 16 different ISR-based timers
99+ SAMD_ISR_Timer ISR_Timer;
91100
92101#define LED_TOGGLE_INTERVAL_MS 2000L
93102
@@ -300,15 +309,18 @@ void simpleTimerDoingSomething2s()
300309
301310 unsigned long currMillis = millis ();
302311
303- Serial.printf (" SimpleTimer : %lus, ms = %lu, Dms : %lu\n " , SIMPLE_TIMER_MS / 1000 , currMillis, currMillis - previousMillis);
312+ Serial.println (" SimpleTimer : " + String (SIMPLE_TIMER_MS / 1000 ) + " , ms = " + String (currMillis)
313+ + " , Dms : " + String (currMillis - previousMillis));
304314
305315 for (int i = 0 ; i < NUMBER_ISR_TIMERS; i++)
306316 {
307317#if USE_COMPLEX_STRUCT
308- Serial.printf (" Timer : %d, programmed : %lu, actual : %lu\n " , i, curISRTimerData[i].TimerInterval , curISRTimerData[i].deltaMillis );
318+ Serial.println (" Timer : " + String (i) + " , programmed : " + String (curISRTimerData[i].TimerInterval )
319+ + " , actual : " + String (curISRTimerData[i].deltaMillis ));
309320#else
310- Serial.printf (" Timer : %d, programmed : %lu, actual : %lu\n " , i, TimerInterval[i], deltaMillis[i]);
311- #endif
321+ Serial.println (" Timer : " + String (i) + " , programmed : " + String (TimerInterval[i])
322+ + " , actual : " + String (deltaMillis[i]));
323+ #endif
312324 }
313325
314326 previousMillis = currMillis;
@@ -329,11 +341,13 @@ void setup()
329341 if (ITimer.attachInterruptInterval (HW_TIMER_INTERVAL_US, TimerHandler))
330342 {
331343 startMillis = millis ();
332- Serial.printf (" Starting ITimer OK, millis() = %ld \n " , startMillis);
344+ Serial.println (" Starting ITimer OK, millis() = " + String ( startMillis) );
333345 }
334346 else
335347 Serial.println (" Can't set ITimer correctly. Select another freq. or interval" );
336348
349+ startMillis = millis ();
350+
337351 // Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
338352 // You can use up to 16 timer for each ISR_Timer
339353 for (int i = 0 ; i < NUMBER_ISR_TIMERS; i++)
@@ -342,7 +356,7 @@ void setup()
342356 curISRTimerData[i].previousMillis = startMillis;
343357 ISR_Timer.setInterval (curISRTimerData[i].TimerInterval , curISRTimerData[i].irqCallbackFunc );
344358#else
345- previousMillis[i] = startMillis ;
359+ previousMillis[i] = millis () ;
346360 ISR_Timer.setInterval (TimerInterval[i], irqCallbackFunc[i]);
347361#endif
348362 }
0 commit comments