2
2
* Tiny and cross-device compatible timer library.
3
3
*
4
4
* Timers used by microcontroller
5
- * Atmel AVR: Timer2
5
+ * Atmel AVR: Timer2 (3rd timer)
6
+ * STM32: Timer3 (3rd timer)
6
7
*
7
8
* @copyright Naguissa
8
9
* @author Naguissa
9
10
* @email naguissa@foroelectro.net
10
11
* @version 0.1.0
11
12
* @created 2018-01-27
12
13
*/
13
- #include < Arduino.h>
14
14
#include " uTimerLib.h"
15
15
16
-
17
16
/* *
18
17
* Constructor
19
18
*
20
19
* Nothing to do here
21
20
*/
22
- uTimerLib::uTimerLib () {}
21
+ uTimerLib::uTimerLib () {
22
+ #ifdef _VARIANT_ARDUINO_STM32_
23
+ clearTimer ();
24
+ #endif
25
+ }
23
26
24
27
/* *
25
28
* Attaches a callback function to be executed each us microseconds
26
29
*
27
30
* @param void*() cb Callback function to be called
28
31
* @param unsigned long int us Interval in microseconds
29
32
*/
30
- void uTimerLib::setInterval_us (void * cb (), unsigned long int us) {
33
+ void uTimerLib::setInterval_us (void ( * cb) (), unsigned long int us) {
31
34
clearTimer ();
32
35
_cb = cb;
33
36
_type = UTIMERLIB_TYPE_INTERVAL;
@@ -41,7 +44,7 @@ void uTimerLib::setInterval_us(void * cb(), unsigned long int us) {
41
44
* @param void*() cb Callback function to be called
42
45
* @param unsigned long int us Timeout in microseconds
43
46
*/
44
- int uTimerLib::setTimeout_us (void * cb (), unsigned long int us) {
47
+ int uTimerLib::setTimeout_us (void ( * cb) (), unsigned long int us) {
45
48
clearTimer ();
46
49
_cb = cb;
47
50
_type = UTIMERLIB_TYPE_TIMEOUT;
@@ -55,7 +58,7 @@ int uTimerLib::setTimeout_us(void * cb(), unsigned long int us) {
55
58
* @param void*() cb Callback function to be called
56
59
* @param unsigned long int s Interval in seconds
57
60
*/
58
- void uTimerLib::setInterval_s (void * cb (), unsigned long int s) {
61
+ void uTimerLib::setInterval_s (void ( * cb) (), unsigned long int s) {
59
62
clearTimer ();
60
63
_cb = cb;
61
64
_type = UTIMERLIB_TYPE_INTERVAL;
@@ -69,7 +72,7 @@ void uTimerLib::setInterval_s(void * cb(), unsigned long int s) {
69
72
* @param void*() cb Callback function to be called
70
73
* @param unsigned long int s Timeout in seconds
71
74
*/
72
- int uTimerLib::setTimeout_s (void * cb (), unsigned long int s) {
75
+ int uTimerLib::setTimeout_s (void ( * cb) (), unsigned long int s) {
73
76
clearTimer ();
74
77
_cb = cb;
75
78
_type = UTIMERLIB_TYPE_TIMEOUT;
@@ -163,6 +166,23 @@ void uTimerLib::_attachInterrupt_us(unsigned long int us) {
163
166
164
167
sei ();
165
168
#endif
169
+
170
+ // STM32, all variants
171
+ #ifdef _VARIANT_ARDUINO_STM32_
172
+ Timer3.setMode (TIMER_CH1, TIMER_OUTPUTCOMPARE);
173
+ Timer3.setPeriod (us); // in microseconds
174
+ Timer3.setCompare (TIMER_CH1, 1 );
175
+ __overflows = _overflows = 1 ;
176
+ __remaining = _remaining = 0 ;
177
+ if (_toInit) {
178
+ _toInit = false ;
179
+ Timer3.attachInterrupt (TIMER_CH1, uTimerLib_interruptHandle);
180
+ }
181
+ Timer3.refresh ();
182
+ Timer3.resume ();
183
+ #endif
184
+
185
+
166
186
}
167
187
168
188
@@ -174,7 +194,7 @@ void uTimerLib::_attachInterrupt_us(unsigned long int us) {
174
194
* @param unsigned long int s Desired timing in seconds
175
195
*/
176
196
void uTimerLib::_attachInterrupt_s (unsigned long int s) {
177
- // Using longest mode from _ms function
197
+ // Arduino AVR
178
198
#ifdef ARDUINO_ARCH_AVR
179
199
unsigned char CSMask = 0 ;
180
200
// For this notes, we asume 16MHz CPU. We recalculate 's' if not:
@@ -185,6 +205,7 @@ void uTimerLib::_attachInterrupt_s(unsigned long int s) {
185
205
cli ();
186
206
187
207
/*
208
+ Using longest mode from _ms function
188
209
CS22 CS21 CS20 Freq Divisor Base Delay Overflow delay
189
210
1 1 1 15.625KHz 1024 64us 16384us
190
211
*/
@@ -203,7 +224,6 @@ void uTimerLib::_attachInterrupt_s(unsigned long int s) {
203
224
_remaining = 256 - round (((s * 1000000 ) % 16384 ) / 64 );
204
225
}
205
226
206
-
207
227
__overflows = _overflows;
208
228
__remaining = _remaining;
209
229
@@ -222,6 +242,23 @@ void uTimerLib::_attachInterrupt_s(unsigned long int s) {
222
242
223
243
sei ();
224
244
#endif
245
+
246
+
247
+ // STM32, all variants
248
+ #ifdef _VARIANT_ARDUINO_STM32_
249
+ Timer3.setMode (TIMER_CH1, TIMER_OUTPUTCOMPARE);
250
+ Timer3.setPeriod ((unsigned long int ) 1000000 ); // 1s, in microseconds
251
+ Timer3.setCompare (TIMER_CH1, 1 );
252
+ __overflows = _overflows = s;
253
+ __remaining = _remaining = 0 ;
254
+ if (_toInit) {
255
+ _toInit = false ;
256
+ Timer3.attachInterrupt (TIMER_CH1, uTimerLib_interruptHandle);
257
+ }
258
+ Timer3.refresh ();
259
+ Timer3.resume ();
260
+ #endif
261
+
225
262
}
226
263
227
264
@@ -235,6 +272,8 @@ void uTimerLib::_loadRemaining() {
235
272
#ifdef ARDUINO_ARCH_AVR
236
273
TCNT2 = _remaining;
237
274
#endif
275
+
276
+ // STM32: Not needed
238
277
}
239
278
240
279
/* *
@@ -243,13 +282,20 @@ void uTimerLib::_loadRemaining() {
243
282
* Note: This is device-dependant
244
283
*/
245
284
void uTimerLib::clearTimer () {
285
+ _type = UTIMERLIB_TYPE_OFF;
286
+
246
287
#ifdef ARDUINO_ARCH_AVR
247
288
TIMSK2 &= ~(1 << TOIE2); // Disable overflow interruption when 0
248
289
SREG = (SREG & 0b01111111 ); // Disable interrupts without modifiying other interrupts
249
290
#endif
250
- _type = UTIMERLIB_TYPE_OFF;
291
+
292
+ #ifdef _VARIANT_ARDUINO_STM32_
293
+ Timer3.pause ();
294
+ #endif
251
295
}
252
296
297
+ // Preinstantiate Object
298
+ uTimerLib TimerLib = uTimerLib();
253
299
254
300
255
301
/* *
@@ -258,37 +304,33 @@ void uTimerLib::clearTimer() {
258
304
* As timers doesn't give us enougth flexibility for large timings,
259
305
* this function implements oferflow control to offer user desired timings.
260
306
*/
261
- void uTimerLib::_interruptHandler () {
262
- extern uTimerLib TimerLib;
263
-
264
- if (_type == UTIMERLIB_TYPE_OFF) { // Should not happen
307
+ void uTimerLib_interruptHandle () {
308
+ if (TimerLib._type == UTIMERLIB_TYPE_OFF) { // Should not happen
265
309
return ;
266
310
}
267
- if (_overflows > 0 ) {
268
- _overflows--;
311
+ if (TimerLib. _overflows > 0 ) {
312
+ TimerLib. _overflows --;
269
313
}
270
- if (_overflows == 0 && _remaining > 0 ) {
314
+ if (TimerLib. _overflows == 0 && TimerLib. _remaining > 0 ) {
271
315
// Load remaining count to counter
272
- _loadRemaining ();
316
+ TimerLib. _loadRemaining ();
273
317
// And clear remaining count
274
- _remaining = 0 ;
275
- } else if (_overflows == 0 && _remaining == 0 ) {
276
- if (_type == UTIMERLIB_TYPE_TIMEOUT) {
277
- clearTimer ();
278
- } else if (_type == UTIMERLIB_TYPE_INTERVAL) {
279
- if (__overflows == 0 ) {
280
- _loadRemaining ();
318
+ TimerLib. _remaining = 0 ;
319
+ } else if (TimerLib. _overflows == 0 && TimerLib. _remaining == 0 ) {
320
+ if (TimerLib. _type == UTIMERLIB_TYPE_TIMEOUT) {
321
+ TimerLib. clearTimer ();
322
+ } else if (TimerLib. _type == UTIMERLIB_TYPE_INTERVAL) {
323
+ if (TimerLib. __overflows == 0 ) {
324
+ TimerLib. _loadRemaining ();
281
325
} else {
282
- _overflows = __overflows;
283
- _remaining = __remaining;
326
+ TimerLib. _overflows = TimerLib. __overflows ;
327
+ TimerLib. _remaining = TimerLib. __remaining ;
284
328
}
285
329
}
286
- _cb ();
330
+ TimerLib. _cb ();
287
331
}
288
332
}
289
333
290
- // Preinstantiate Object
291
- uTimerLib TimerLib = uTimerLib();
292
334
293
335
294
336
@@ -301,7 +343,7 @@ uTimerLib TimerLib = uTimerLib();
301
343
#ifdef ARDUINO_ARCH_AVR
302
344
// Arduino AVR
303
345
ISR (TIMER2_OVF_vect) {
304
- TimerLib. _interruptHandler ();
346
+ uTimerLib_interruptHandle ();
305
347
}
306
348
#endif
307
349
0 commit comments