Skip to content
This repository was archived by the owner on Jan 29, 2023. It is now read-only.

Commit 271bca4

Browse files
authored
Update README.md
1 parent 5350969 commit 271bca4

File tree

1 file changed

+4
-348
lines changed

1 file changed

+4
-348
lines changed

README.md

Lines changed: 4 additions & 348 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing)
77
[![GitHub issues](https://img.shields.io/github/issues/khoih-prog/SAMD_TimerInterrupt.svg)](http://github.com/khoih-prog/SAMD_TimerInterrupt/issues)
88

9-
<a href="https://www.buymeacoffee.com/khoihprog6" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 50px !important;width: 181px !important;" ></a>
9+
<a href="https://www.buymeacoffee.com/khoihprog6" title="Donate to my libraries using BuyMeACoffee"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Donate to my libraries using BuyMeACoffee" style="height: 50px !important;width: 181px !important;" ></a>
10+
<a href="https://www.buymeacoffee.com/khoihprog6" title="Donate to my libraries using BuyMeACoffee"><img src="https://img.shields.io/badge/buy%20me%20a%20coffee-donate-orange.svg?logo=buy-me-a-coffee&logoColor=FFDD00" style="height: 20px !important;width: 200px !important;" ></a>
1011

1112
---
1213
---
@@ -153,7 +154,7 @@ The catch is **your function is now part of an ISR (Interrupt Service Routine),
153154
## Prerequisites
154155

155156
1. [`Arduino IDE 1.8.19+` for Arduino](https://github.com/arduino/Arduino). [![GitHub release](https://img.shields.io/github/release/arduino/Arduino.svg)](https://github.com/arduino/Arduino/releases/latest)
156-
2. [`Arduino SAMD core 1.8.12+`](https://github.com/arduino/ArduinoCore-samd) for SAMD ARM Cortex-M0+ boards. [![GitHub release](https://img.shields.io/github/release/arduino/ArduinoCore-samd.svg)](https://github.com/arduino/ArduinoCore-samd/releases/latest)
157+
2. [`Arduino SAMD core 1.8.13+`](https://github.com/arduino/ArduinoCore-samd) for SAMD ARM Cortex-M0+ boards. [![GitHub release](https://img.shields.io/github/release/arduino/ArduinoCore-samd.svg)](https://github.com/arduino/ArduinoCore-samd/releases/latest)
157158
3. [`Adafruit SAMD core 1.7.9+`](https://github.com/adafruit/ArduinoCore-samd) for SAMD ARM Cortex-M0+ and M4 boards (Nano 33 IoT, etc.). [![GitHub release](https://img.shields.io/github/release/adafruit/ArduinoCore-samd.svg)](https://github.com/adafruit/ArduinoCore-samd/releases/latest)
158159
4. [`Seeeduino SAMD core 1.8.2+`](https://github.com/Seeed-Studio/ArduinoCore-samd) for SAMD21/SAMD51 boards (XIAO M0, Wio Terminal, etc.). [![Latest release](https://img.shields.io/github/release/Seeed-Studio/ArduinoCore-samd.svg)](https://github.com/Seeed-Studio/ArduinoCore-samd/releases/latest/)
159160
5. [`Sparkfun SAMD core 1.8.1+`](https://github.com/sparkfun/Arduino_Boards) for SAMD21/SAMD51 boards (SparkFun_RedBoard_Turbo, SparkFun_SAMD51_Thing_Plus, etc.).
@@ -523,354 +524,9 @@ void setup()
523524

524525
### Example [ISR_16_Timers_Array_Complex](examples/ISR_16_Timers_Array_Complex)
525526

526-
```
527-
#if !( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
528-
|| defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
529-
|| defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) \
530-
|| defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD51__) || defined(__SAMD51J20A__) \
531-
|| defined(__SAMD51J19A__) || defined(__SAMD51G19A__) || defined(__SAMD51P19A__) \
532-
|| defined(__SAMD21E15A__) || defined(__SAMD21E16A__) || defined(__SAMD21E17A__) || defined(__SAMD21E18A__) \
533-
|| defined(__SAMD21G15A__) || defined(__SAMD21G16A__) || defined(__SAMD21G17A__) || defined(__SAMD21G18A__) \
534-
|| defined(__SAMD21J15A__) || defined(__SAMD21J16A__) || defined(__SAMD21J17A__) || defined(__SAMD21J18A__) )
535-
#error This code is designed to run on SAMD21/SAMD51 platform! Please check your Tools->Board setting.
536-
#endif
537-
538-
// These define's must be placed at the beginning before #include "SAMDTimerInterrupt.h"
539-
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
540-
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
541-
// Don't define TIMER_INTERRUPT_DEBUG > 2. Only for special ISR debugging only. Can hang the system.
542-
#define TIMER_INTERRUPT_DEBUG 0
543-
#define _TIMERINTERRUPT_LOGLEVEL_ 0
544-
545-
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
546-
#include "SAMDTimerInterrupt.h"
547-
548-
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
549-
#include "SAMD_ISR_Timer.h"
550-
551-
#include <SimpleTimer.h> // https://github.com/jfturcot/SimpleTimer
552-
553-
#ifndef LED_BUILTIN
554-
#define LED_BUILTIN 13
555-
#endif
556-
557-
#ifndef LED_BLUE
558-
#define LED_BLUE 2
559-
#endif
560-
561-
#ifndef LED_RED
562-
#define LED_RED 3
563-
#endif
564-
565-
#define HW_TIMER_INTERVAL_US 10000L
566-
567-
volatile uint32_t startMillis = 0;
568-
569-
// You can select SAMD Hardware Timer from SAMD_TIMER_1 or SAMD_TIMER_3
570-
571-
// Depending on the board, you can select SAMD21 Hardware Timer from TC3-TCC
572-
// SAMD21 Hardware Timer from TC3 or TCC
573-
// SAMD51 Hardware Timer only TC3
574-
575-
// Init SAMD timer TIMER_TC3
576-
SAMDTimer ITimer(TIMER_TC3);
577-
578-
#if (TIMER_INTERRUPT_USING_SAMD21)
579-
// Init SAMD timer TIMER_TCC
580-
//SAMDTimer ITimer(TIMER_TCC);
581-
#endif
582-
583-
// Init SAMD_ISR_Timer
584-
// Each SAMD_ISR_Timer can service 16 different ISR-based timers
585-
SAMD_ISR_Timer ISR_Timer;
586-
587-
#define LED_TOGGLE_INTERVAL_MS 2000L
588-
589-
void TimerHandler()
590-
{
591-
static bool toggle = false;
592-
static int timeRun = 0;
593-
594-
ISR_Timer.run();
595-
596-
// Toggle LED every LED_TOGGLE_INTERVAL_MS = 2000ms = 2s
597-
if (++timeRun == ((LED_TOGGLE_INTERVAL_MS * 1000) / HW_TIMER_INTERVAL_US) )
598-
{
599-
timeRun = 0;
600-
601-
//timer interrupt toggles pin LED_BUILTIN
602-
digitalWrite(LED_BUILTIN, toggle);
603-
toggle = !toggle;
604-
}
605-
}
606-
607-
/////////////////////////////////////////////////
608-
609-
#define NUMBER_ISR_TIMERS 16
527+
https://github.com/khoih-prog/SAMD_TimerInterrupt/blob/329513558a9d43b15533a469ceabc30b5896fd80/examples/ISR_16_Timers_Array_Complex/ISR_16_Timers_Array_Complex.ino#L35-L380
610528

611-
typedef void (*irqCallback) ();
612-
613-
/////////////////////////////////////////////////
614-
615-
#define USE_COMPLEX_STRUCT true
616-
617-
#if USE_COMPLEX_STRUCT
618-
619-
typedef struct
620-
{
621-
irqCallback irqCallbackFunc;
622-
uint32_t TimerInterval;
623-
unsigned long deltaMillis;
624-
unsigned long previousMillis;
625-
} ISRTimerData;
626-
627-
// In NRF52, avoid doing something fancy in ISR, for example Serial.print()
628-
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
629-
// Or you can get this run-time error / crash
630-
631-
void doingSomething(int index);
632-
633-
#else
634-
635-
volatile unsigned long deltaMillis [NUMBER_ISR_TIMERS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
636-
volatile unsigned long previousMillis [NUMBER_ISR_TIMERS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
637-
638-
// You can assign any interval for any timer here, in milliseconds
639-
uint32_t TimerInterval[NUMBER_ISR_TIMERS] =
640-
{
641-
5000L, 10000L, 15000L, 20000L, 25000L, 30000L, 35000L, 40000L,
642-
45000L, 50000L, 55000L, 60000L, 65000L, 70000L, 75000L, 80000L
643-
};
644-
645-
void doingSomething(int index)
646-
{
647-
unsigned long currentMillis = millis();
648-
649-
deltaMillis[index] = currentMillis - previousMillis[index];
650-
previousMillis[index] = currentMillis;
651-
}
652-
653-
#endif
654-
655-
////////////////////////////////////
656-
// Shared
657-
////////////////////////////////////
658-
659-
void doingSomething0()
660-
{
661-
doingSomething(0);
662-
}
663-
664-
void doingSomething1()
665-
{
666-
doingSomething(1);
667-
}
668-
669-
void doingSomething2()
670-
{
671-
doingSomething(2);
672-
}
673-
674-
void doingSomething3()
675-
{
676-
doingSomething(3);
677-
}
678-
679-
void doingSomething4()
680-
{
681-
doingSomething(4);
682-
}
683-
684-
void doingSomething5()
685-
{
686-
doingSomething(5);
687-
}
688529

689-
void doingSomething6()
690-
{
691-
doingSomething(6);
692-
}
693-
694-
void doingSomething7()
695-
{
696-
doingSomething(7);
697-
}
698-
699-
void doingSomething8()
700-
{
701-
doingSomething(8);
702-
}
703-
704-
void doingSomething9()
705-
{
706-
doingSomething(9);
707-
}
708-
709-
void doingSomething10()
710-
{
711-
doingSomething(10);
712-
}
713-
714-
void doingSomething11()
715-
{
716-
doingSomething(11);
717-
}
718-
719-
void doingSomething12()
720-
{
721-
doingSomething(12);
722-
}
723-
724-
void doingSomething13()
725-
{
726-
doingSomething(13);
727-
}
728-
729-
void doingSomething14()
730-
{
731-
doingSomething(14);
732-
}
733-
734-
void doingSomething15()
735-
{
736-
doingSomething(15);
737-
}
738-
739-
#if USE_COMPLEX_STRUCT
740-
741-
ISRTimerData curISRTimerData[NUMBER_ISR_TIMERS] =
742-
{
743-
//irqCallbackFunc, TimerInterval, deltaMillis, previousMillis
744-
{ doingSomething0, 5000L, 0, 0 },
745-
{ doingSomething1, 10000L, 0, 0 },
746-
{ doingSomething2, 15000L, 0, 0 },
747-
{ doingSomething3, 20000L, 0, 0 },
748-
{ doingSomething4, 25000L, 0, 0 },
749-
{ doingSomething5, 30000L, 0, 0 },
750-
{ doingSomething6, 35000L, 0, 0 },
751-
{ doingSomething7, 40000L, 0, 0 },
752-
{ doingSomething8, 45000L, 0, 0 },
753-
{ doingSomething9, 50000L, 0, 0 },
754-
{ doingSomething10, 55000L, 0, 0 },
755-
{ doingSomething11, 60000L, 0, 0 },
756-
{ doingSomething12, 65000L, 0, 0 },
757-
{ doingSomething13, 70000L, 0, 0 },
758-
{ doingSomething14, 75000L, 0, 0 },
759-
{ doingSomething15, 80000L, 0, 0 }
760-
};
761-
762-
void doingSomething(int index)
763-
{
764-
unsigned long currentMillis = millis();
765-
766-
curISRTimerData[index].deltaMillis = currentMillis - curISRTimerData[index].previousMillis;
767-
curISRTimerData[index].previousMillis = currentMillis;
768-
}
769-
770-
#else
771-
772-
irqCallback irqCallbackFunc[NUMBER_ISR_TIMERS] =
773-
{
774-
doingSomething0, doingSomething1, doingSomething2, doingSomething3,
775-
doingSomething4, doingSomething5, doingSomething6, doingSomething7,
776-
doingSomething8, doingSomething9, doingSomething10, doingSomething11,
777-
doingSomething12, doingSomething13, doingSomething14, doingSomething15
778-
};
779-
780-
#endif
781-
///////////////////////////////////////////
782-
783-
#define SIMPLE_TIMER_MS 2000L
784-
785-
// Init SimpleTimer
786-
SimpleTimer simpleTimer;
787-
788-
// Here is software Timer, you can do somewhat fancy stuffs without many issues.
789-
// But always avoid
790-
// 1. Long delay() it just doing nothing and pain-without-gain wasting CPU power.Plan and design your code / strategy ahead
791-
// 2. Very long "do", "while", "for" loops without predetermined exit time.
792-
void simpleTimerDoingSomething2s()
793-
{
794-
static unsigned long previousMillis = startMillis;
795-
796-
unsigned long currMillis = millis();
797-
798-
Serial.print(F("SimpleTimer : ")); Serial.print(SIMPLE_TIMER_MS / 1000);
799-
Serial.print(F(", ms : ")); Serial.print(currMillis);
800-
Serial.print(F(", Dms : ")); Serial.println(currMillis - previousMillis);
801-
802-
for (uint16_t i = 0; i < NUMBER_ISR_TIMERS; i++)
803-
{
804-
#if USE_COMPLEX_STRUCT
805-
Serial.print(F("Timer : ")); Serial.print(i);
806-
Serial.print(F(", programmed : ")); Serial.print(curISRTimerData[i].TimerInterval);
807-
Serial.print(F(", actual : ")); Serial.println(curISRTimerData[i].deltaMillis);
808-
#else
809-
Serial.print(F("Timer : ")); Serial.print(i);
810-
Serial.print(F(", programmed : ")); Serial.print(TimerInterval[i]);
811-
Serial.print(F(", actual : ")); Serial.println(deltaMillis[i]);
812-
#endif
813-
}
814-
815-
previousMillis = currMillis;
816-
}
817-
818-
void setup()
819-
{
820-
pinMode(LED_BUILTIN, OUTPUT);
821-
822-
Serial.begin(115200);
823-
while (!Serial);
824-
825-
delay(100);
826-
827-
Serial.print(F("\nStarting ISR_16_Timers_Array_Complex on ")); Serial.println(BOARD_NAME);
828-
Serial.println(SAMD_TIMER_INTERRUPT_VERSION);
829-
Serial.print(F("CPU Frequency = ")); Serial.print(F_CPU / 1000000); Serial.println(F(" MHz"));
830-
831-
// Interval in microsecs
832-
if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_US, TimerHandler))
833-
{
834-
startMillis = millis();
835-
Serial.print(F("Starting ITimer OK, millis() = ")); Serial.println(startMillis);
836-
}
837-
else
838-
Serial.println(F("Can't set ITimer. Select another freq. or timer"));
839-
840-
startMillis = millis();
841-
842-
// Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
843-
// You can use up to 16 timer for each ISR_Timer
844-
for (uint16_t i = 0; i < NUMBER_ISR_TIMERS; i++)
845-
{
846-
#if USE_COMPLEX_STRUCT
847-
curISRTimerData[i].previousMillis = startMillis;
848-
ISR_Timer.setInterval(curISRTimerData[i].TimerInterval, curISRTimerData[i].irqCallbackFunc);
849-
#else
850-
previousMillis[i] = millis();
851-
ISR_Timer.setInterval(TimerInterval[i], irqCallbackFunc[i]);
852-
#endif
853-
}
854-
855-
// You need this timer for non-critical tasks. Avoid abusing ISR if not absolutely necessary.
856-
simpleTimer.setInterval(SIMPLE_TIMER_MS, simpleTimerDoingSomething2s);
857-
}
858-
859-
#define BLOCKING_TIME_MS 10000L
860-
861-
void loop()
862-
{
863-
// This unadvised blocking task is used to demonstrate the blocking effects onto the execution and accuracy to Software timer
864-
// You see the time elapse of ISR_Timer still accurate, whereas very unaccurate for Software Timer
865-
// The time elapse for 2000ms software timer now becomes 3000ms (BLOCKING_TIME_MS)
866-
// While that of ISR_Timer is still prefect.
867-
delay(BLOCKING_TIME_MS);
868-
869-
// You need this Software timer for non-critical tasks. Avoid abusing ISR if not absolutely necessary
870-
// You don't need to and never call ISR_Timer.run() here in the loop(). It's already handled by ISR timer.
871-
simpleTimer.run();
872-
}
873-
```
874530
---
875531
---
876532

0 commit comments

Comments
 (0)