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

Commit 5fae6b5

Browse files
authored
v1.0.0 for ATmega using MightyCore
### Releases v1.0.0 1. Initial coding for AVR **ATmega164(A/P), ATmega324(A/P/PA/PB), ATmega644(A/P), ATmega1284(P)** using [MightyCore](https://github.com/MCUdude/MightyCore)
1 parent 1f2990e commit 5fae6b5

30 files changed

+5358
-0
lines changed

CONTRIBUTING.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
## Contributing to ATmega_TimerInterrupt
2+
3+
### Reporting Bugs
4+
5+
Please report bugs in ATmega_TimerInterrupt if you find them.
6+
7+
However, before reporting a bug please check through the following:
8+
9+
* [Existing Open Issues](https://github.com/khoih-prog/ATmega_TimerInterrupt/issues) - someone might have already encountered this.
10+
11+
If you don't find anything, please [open a new issue](https://github.com/khoih-prog/ATmega_TimerInterrupt/issues/new).
12+
13+
---
14+
15+
### How to submit a bug report
16+
17+
Please ensure to specify the following:
18+
19+
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
20+
* `Arduino MightyCore` Core Version (e.g. Arduino MightyCore Core v2.1.3)
21+
* Board type (e.g. ATmega164, ATmega324, ATmega644, ATmega1284, etc.)
22+
* Contextual information (e.g. what you were trying to achieve)
23+
* Simplest possible steps to reproduce
24+
* Anything that might be relevant in your opinion, such as:
25+
* Operating system (Windows, Ubuntu, etc.) and the output of `uname -a`
26+
* Network configuration
27+
28+
---
29+
30+
### Example
31+
32+
```
33+
Arduino IDE version: 1.8.19
34+
Arduino MightyCore Core v2.1.3
35+
ATmega1284 with Optiboot
36+
OS: Ubuntu 20.04 LTS
37+
Linux xy-Inspiron-3593 5.15.0-46-generic #49~20.04.1-Ubuntu SMP Thu Aug 4 19:15:44 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
38+
39+
Context:
40+
I encountered a crash while trying to use the Timer Interrupt.
41+
42+
Steps to reproduce:
43+
1. ...
44+
2. ...
45+
3. ...
46+
4. ...
47+
```
48+
49+
---
50+
51+
### Sending Feature Requests
52+
53+
Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful.
54+
55+
There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/ATmega_TimerInterrupt/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them.
56+
57+
### Sending Pull Requests
58+
59+
Pull Requests with changes and fixes are also welcome!
60+

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Khoi Hoang
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

changelog.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
## ATmega_TimerInterrupt Library
2+
3+
[![arduino-library-badge](https://www.ardu-badge.com/badge/ATmega_TimerInterrupt.svg?)](https://www.ardu-badge.com/ATmega_TimerInterrupt)
4+
[![GitHub release](https://img.shields.io/github/release/khoih-prog/ATmega_TimerInterrupt.svg)](https://github.com/khoih-prog/ATmega_TimerInterrupt/releases)
5+
[![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/khoih-prog/ATmega_TimerInterrupt/blob/main/LICENSE)
6+
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing)
7+
[![GitHub issues](https://img.shields.io/github/issues/khoih-prog/ATmega_TimerInterrupt.svg)](http://github.com/khoih-prog/ATmega_TimerInterrupt/issues)
8+
9+
---
10+
---
11+
12+
## Table of Contents
13+
14+
* [Changelog](#changelog)
15+
* [Releases v1.0.0](#releases-v100)
16+
17+
---
18+
---
19+
20+
## Changelog
21+
22+
23+
### Releases v1.0.0
24+
25+
1. Initial coding for AVR **ATmega164(A/P), ATmega324(A/P/PA/PB), ATmega644(A/P), ATmega1284(P)** using [MightyCore](https://github.com/MCUdude/MightyCore)
26+
27+
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/****************************************************************************************************************************
2+
Argument_Complex.ino
3+
For AVR ATmega164, ATmega324, ATmega644, ATmega1284 with MightyCore
4+
Written by Khoi Hoang
5+
6+
Built by Khoi Hoang https://github.com/khoih-prog/ATmega_TimerInterrupt
7+
Licensed under MIT license
8+
9+
Now with we can use these new 16 ISR-based timers, while consuming only 1 hwarware Timer.
10+
Their independently-selected, maximum interval is practically unlimited (limited only by unsigned long miliseconds)
11+
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
12+
Therefore, their executions are not blocked by bad-behaving functions / tasks.
13+
This important feature is absolutely necessary for mission-critical tasks.
14+
15+
Notes:
16+
Special design is necessary to share data between interrupt code and the rest of your program.
17+
Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
18+
variable can not spontaneously change. Because your function may change variables while your program is using them,
19+
the compiler needs this hint. But volatile alone is often not enough.
20+
When accessing shared variables, usually interrupts must be disabled. Even with volatile,
21+
if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
22+
If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
23+
or the entire sequence of your code which accesses the data.
24+
*****************************************************************************************************************************/
25+
26+
// These define's must be placed at the beginning before #include "TimerInterrupt.h"
27+
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
28+
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
29+
#define TIMER_INTERRUPT_DEBUG 0
30+
#define _TIMERINTERRUPT_LOGLEVEL_ 0
31+
32+
// Select just 1 TIMER to be true
33+
#define USE_TIMER_1 true
34+
#define USE_TIMER_2 false
35+
// TIMER_3 Only valid for ATmega1284 and ATmega324PB (not ready in core yet)
36+
#define USE_TIMER_3 false
37+
// TIMER_4 Only valid for ATmega324PB, not ready in core yet
38+
#define USE_TIMER_4 false
39+
40+
#if (USE_TIMER_1)
41+
#warning Using Timer1
42+
#elif (USE_TIMER_2)
43+
#warning Using Timer2
44+
#elif (USE_TIMER_3)
45+
#warning Using Timer3
46+
#elif (USE_TIMER_4)
47+
#warning Using Timer4
48+
#endif
49+
50+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
51+
#include "ATmega_TimerInterrupt.h"
52+
53+
#if !defined(LED_BUILTIN)
54+
#define LED_BUILTIN 13
55+
#endif
56+
57+
struct pinStruct
58+
{
59+
unsigned int Pin1;
60+
unsigned int Pin2;
61+
unsigned int Pin3;
62+
};
63+
64+
volatile pinStruct myOutputPins = { LED_BUILTIN, A0, A1 };
65+
66+
void TimerHandler(unsigned int outputPinsAddress)
67+
{
68+
static bool toggle = false;
69+
70+
//timer interrupt toggles pins
71+
#if (TIMER_INTERRUPT_DEBUG > 1)
72+
Serial.print("Toggle pin1 = "); Serial.println( ((pinStruct *) outputPinsAddress)->Pin1 );
73+
#endif
74+
75+
digitalWrite(((pinStruct *) outputPinsAddress)->Pin1, toggle);
76+
77+
#if (TIMER_INTERRUPT_DEBUG > 1)
78+
Serial.print("Read pin2 A0 ("); Serial.print(((pinStruct *) outputPinsAddress)->Pin2 );
79+
Serial.print(") = ");
80+
Serial.println(digitalRead(((pinStruct *) outputPinsAddress)->Pin2) ? "HIGH" : "LOW" );
81+
82+
Serial.print("Read pin3 A1 ("); Serial.print(((pinStruct *) outputPinsAddress)->Pin3 );
83+
Serial.print(") = ");
84+
Serial.println(digitalRead(((pinStruct *) outputPinsAddress)->Pin3) ? "HIGH" : "LOW" );
85+
#endif
86+
87+
toggle = !toggle;
88+
}
89+
90+
#define TIMER_INTERVAL_MS 1000
91+
92+
void setup()
93+
{
94+
pinMode(myOutputPins.Pin1, OUTPUT);
95+
pinMode(myOutputPins.Pin2, OUTPUT);
96+
pinMode(myOutputPins.Pin3, OUTPUT);
97+
98+
Serial.begin(115200);
99+
while (!Serial && millis() < 5000);
100+
101+
Serial.print(F("\nStarting Argument_Complex on ")); Serial.println(BOARD_TYPE);
102+
Serial.println(ATMEGA_TIMER_INTERRUPT_VERSION);
103+
Serial.print(F("CPU Frequency = ")); Serial.print(F_CPU / 1000000); Serial.println(F(" MHz"));
104+
105+
// Timer0 is already used for micros(), millis(), delay(), etc and can't be used
106+
// Select Timer 1-2
107+
// Timer 2 is 8-bit timer, only for higher frequency
108+
109+
#if USE_TIMER_1
110+
111+
ITimer1.init();
112+
113+
// Using ATmega324 with 16MHz CPU clock ,
114+
// For 16-bit timer 1, set frequency from 0.2385 to some KHz
115+
// For 8-bit timer 2 (prescaler up to 1024, set frequency from 61.5Hz to some KHz
116+
117+
if (ITimer1.attachInterruptInterval(TIMER_INTERVAL_MS, TimerHandler, (unsigned int) &myOutputPins))
118+
{
119+
Serial.print(F("Starting ITimer1 OK, millis() = ")); Serial.println(millis());
120+
}
121+
else
122+
Serial.println(F("Can't set ITimer1. Select another freq. or timer"));
123+
124+
#elif USE_TIMER_2
125+
126+
// Using ATmega324 with 16MHz CPU clock ,
127+
// For 16-bit timer 1, set frequency from 0.2385 to some KHz
128+
// For 8-bit timer 2 (prescaler up to 1024, set frequency from 61.5Hz to some KHz
129+
ITimer2.init();
130+
131+
if (ITimer2.attachInterruptInterval(TIMER_INTERVAL_MS, TimerHandler))
132+
{
133+
Serial.print(F("Starting ITimer2 OK, millis() = ")); Serial.println(millis());
134+
}
135+
else
136+
Serial.println(F("Can't set ITimer2. Select another freq. or timer"));
137+
138+
#elif USE_TIMER_3
139+
140+
ITimer3.init();
141+
142+
if (ITimer3.attachInterruptInterval(TIMER_INTERVAL_MS, TimerHandler, outputPin))
143+
{
144+
Serial.print(F("Starting ITimer3 OK, millis() = ")); Serial.println(millis());
145+
146+
#if (TIMER_INTERRUPT_DEBUG > 1)
147+
Serial.print(F("OutputPin = ")); Serial.print(outputPin);
148+
Serial.print(F(" address: ")); Serial.println((uint32_t) &outputPin );
149+
#endif
150+
}
151+
else
152+
Serial.println(F("Can't set ITimer3. Select another freq. or timer"));
153+
154+
#endif
155+
}
156+
157+
void loop()
158+
{
159+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/****************************************************************************************************************************
2+
Argument_Complex_Multi.cpp
3+
For Arduino and Adadruit AVR 328(P) and 32u4 boards
4+
Written by Khoi Hoang
5+
6+
Built by Khoi Hoang https://github.com/khoih-prog/TimerInterrupt
7+
Licensed under MIT license
8+
9+
Now we can use these new 16 ISR-based timers, while consuming only 1 hardware Timer.
10+
Their independently-selected, maximum interval is practically unlimited (limited only by unsigned long miliseconds)
11+
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
12+
Therefore, their executions are not blocked by bad-behaving functions / tasks.
13+
This important feature is absolutely necessary for mission-critical tasks.
14+
15+
Notes:
16+
Special design is necessary to share data between interrupt code and the rest of your program.
17+
Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
18+
variable can not spontaneously change. Because your function may change variables while your program is using them,
19+
the compiler needs this hint. But volatile alone is often not enough.
20+
When accessing shared variables, usually interrupts must be disabled. Even with volatile,
21+
if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
22+
If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
23+
or the entire sequence of your code which accesses the data.
24+
*****************************************************************************************************************************/
25+
26+
// To demonstrate the usage of complex multiple files to avoid `multi definition linker` error
27+
// by using TimerInterrupt.hpp in multiple files but TimerInterrupt.h in only main file
28+
29+
#include "Argument_Complex_Multi.h"
30+
31+
void TimerHandler(unsigned int outputPinsAddress)
32+
{
33+
static bool toggle = false;
34+
35+
//timer interrupt toggles pins
36+
#if (TIMER_INTERRUPT_DEBUG > 1)
37+
Serial.print("Toggle pin1 = "); Serial.println( ((pinStruct *) outputPinsAddress)->Pin1 );
38+
#endif
39+
40+
digitalWrite(((pinStruct *) outputPinsAddress)->Pin1, toggle);
41+
42+
#if (TIMER_INTERRUPT_DEBUG > 1)
43+
Serial.print("Read pin2 A0 ("); Serial.print(((pinStruct *) outputPinsAddress)->Pin2 );
44+
Serial.print(") = ");
45+
Serial.println(digitalRead(((pinStruct *) outputPinsAddress)->Pin2) ? "HIGH" : "LOW" );
46+
47+
Serial.print("Read pin3 A1 ("); Serial.print(((pinStruct *) outputPinsAddress)->Pin3 );
48+
Serial.print(") = ");
49+
Serial.println(digitalRead(((pinStruct *) outputPinsAddress)->Pin3) ? "HIGH" : "LOW" );
50+
#endif
51+
52+
toggle = !toggle;
53+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/****************************************************************************************************************************
2+
Argument_Complex_Multi.h
3+
For Arduino and Adadruit AVR 328(P) and 32u4 boards
4+
Written by Khoi Hoang
5+
6+
Built by Khoi Hoang https://github.com/khoih-prog/TimerInterrupt
7+
Licensed under MIT license
8+
9+
Now we can use these new 16 ISR-based timers, while consuming only 1 hardware Timer.
10+
Their independently-selected, maximum interval is practically unlimited (limited only by unsigned long miliseconds)
11+
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
12+
Therefore, their executions are not blocked by bad-behaving functions / tasks.
13+
This important feature is absolutely necessary for mission-critical tasks.
14+
15+
Notes:
16+
Special design is necessary to share data between interrupt code and the rest of your program.
17+
Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
18+
variable can not spontaneously change. Because your function may change variables while your program is using them,
19+
the compiler needs this hint. But volatile alone is often not enough.
20+
When accessing shared variables, usually interrupts must be disabled. Even with volatile,
21+
if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
22+
If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
23+
or the entire sequence of your code which accesses the data.
24+
*****************************************************************************************************************************/
25+
26+
// To demonstrate the usage of complex multiple files to avoid `multi definition linker` error
27+
// by using TimerInterrupt.hpp in multiple files but TimerInterrupt.h in only main file
28+
29+
#ifndef Argument_Complex_Multi_h
30+
#define Argument_Complex_Multi_h
31+
32+
// These define's must be placed at the beginning before #include "TimerInterrupt.h"
33+
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
34+
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
35+
#define TIMER_INTERRUPT_DEBUG 0
36+
#define _TIMERINTERRUPT_LOGLEVEL_ 3
37+
38+
// Select just 1 TIMER to be true
39+
#define USE_TIMER_1 true
40+
#define USE_TIMER_2 false
41+
// TIMER_3 Only valid for ATmega1284 and ATmega324PB (not ready in core yet)
42+
#define USE_TIMER_3 false
43+
// TIMER_4 Only valid for ATmega324PB, not ready in core yet
44+
#define USE_TIMER_4 false
45+
46+
#if (USE_TIMER_1)
47+
#warning Using Timer1
48+
#elif (USE_TIMER_2)
49+
#warning Using Timer2
50+
#elif (USE_TIMER_3)
51+
#warning Using Timer3
52+
#elif (USE_TIMER_4)
53+
#warning Using Timer4
54+
#endif
55+
56+
// Can be included in many files without `Multiple Definitions` Linker Error
57+
#include "ATmega_TimerInterrupt.hpp"
58+
59+
#if !defined(LED_BUILTIN)
60+
#define LED_BUILTIN 13
61+
#endif
62+
63+
struct pinStruct
64+
{
65+
unsigned int Pin1;
66+
unsigned int Pin2;
67+
unsigned int Pin3;
68+
};
69+
70+
#define TIMER_INTERVAL_MS 1000
71+
72+
void TimerHandler(unsigned int outputPinsAddress);
73+
74+
#endif // Argument_Complex_Multi_h

0 commit comments

Comments
 (0)