Skip to content

Commit 8e85d5c

Browse files
committed
Version 0.2.0:
- Add STM32 compatibility. Tested: AVR and STM32
1 parent cb26c02 commit 8e85d5c

File tree

4 files changed

+100
-40
lines changed

4 files changed

+100
-40
lines changed

examples/uTimerLib_setInterval_us_example_led/uTimerLib_setInterval_us_example_led.ino

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
#include "Arduino.h"
1010
#include "uTimerLib.h"
1111

12+
#ifndef LED_BUILTIN
13+
// change to fit your needs
14+
#define LED_BUILTIN 13
15+
#endif
16+
17+
1218

1319

1420
bool status = 0;

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=uTimerLib
2-
version=0.1.0
2+
version=0.2.0
33
author=Naguissa <naguissa@foroelectro.net>
44
maintainer=Naguissa <naguissa@foroelectro.net>
55
sentence=Tiny and cross-device compatible timer library

src/uTimerLib.cpp

Lines changed: 74 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,35 @@
22
* Tiny and cross-device compatible timer library.
33
*
44
* Timers used by microcontroller
5-
* Atmel AVR: Timer2
5+
* Atmel AVR: Timer2 (3rd timer)
6+
* STM32: Timer3 (3rd timer)
67
*
78
* @copyright Naguissa
89
* @author Naguissa
910
* @email naguissa@foroelectro.net
1011
* @version 0.1.0
1112
* @created 2018-01-27
1213
*/
13-
#include <Arduino.h>
1414
#include "uTimerLib.h"
1515

16-
1716
/**
1817
* Constructor
1918
*
2019
* Nothing to do here
2120
*/
22-
uTimerLib::uTimerLib() {}
21+
uTimerLib::uTimerLib() {
22+
#ifdef _VARIANT_ARDUINO_STM32_
23+
clearTimer();
24+
#endif
25+
}
2326

2427
/**
2528
* Attaches a callback function to be executed each us microseconds
2629
*
2730
* @param void*() cb Callback function to be called
2831
* @param unsigned long int us Interval in microseconds
2932
*/
30-
void uTimerLib::setInterval_us(void * cb(), unsigned long int us) {
33+
void uTimerLib::setInterval_us(void (* cb)(), unsigned long int us) {
3134
clearTimer();
3235
_cb = cb;
3336
_type = UTIMERLIB_TYPE_INTERVAL;
@@ -41,7 +44,7 @@ void uTimerLib::setInterval_us(void * cb(), unsigned long int us) {
4144
* @param void*() cb Callback function to be called
4245
* @param unsigned long int us Timeout in microseconds
4346
*/
44-
int uTimerLib::setTimeout_us(void * cb(), unsigned long int us) {
47+
int uTimerLib::setTimeout_us(void (* cb)(), unsigned long int us) {
4548
clearTimer();
4649
_cb = cb;
4750
_type = UTIMERLIB_TYPE_TIMEOUT;
@@ -55,7 +58,7 @@ int uTimerLib::setTimeout_us(void * cb(), unsigned long int us) {
5558
* @param void*() cb Callback function to be called
5659
* @param unsigned long int s Interval in seconds
5760
*/
58-
void uTimerLib::setInterval_s(void * cb(), unsigned long int s) {
61+
void uTimerLib::setInterval_s(void (* cb)(), unsigned long int s) {
5962
clearTimer();
6063
_cb = cb;
6164
_type = UTIMERLIB_TYPE_INTERVAL;
@@ -69,7 +72,7 @@ void uTimerLib::setInterval_s(void * cb(), unsigned long int s) {
6972
* @param void*() cb Callback function to be called
7073
* @param unsigned long int s Timeout in seconds
7174
*/
72-
int uTimerLib::setTimeout_s(void * cb(), unsigned long int s) {
75+
int uTimerLib::setTimeout_s(void (* cb)(), unsigned long int s) {
7376
clearTimer();
7477
_cb = cb;
7578
_type = UTIMERLIB_TYPE_TIMEOUT;
@@ -163,6 +166,23 @@ void uTimerLib::_attachInterrupt_us(unsigned long int us) {
163166

164167
sei();
165168
#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+
166186
}
167187

168188

@@ -174,7 +194,7 @@ void uTimerLib::_attachInterrupt_us(unsigned long int us) {
174194
* @param unsigned long int s Desired timing in seconds
175195
*/
176196
void uTimerLib::_attachInterrupt_s(unsigned long int s) {
177-
// Using longest mode from _ms function
197+
// Arduino AVR
178198
#ifdef ARDUINO_ARCH_AVR
179199
unsigned char CSMask = 0;
180200
// For this notes, we asume 16MHz CPU. We recalculate 's' if not:
@@ -185,6 +205,7 @@ void uTimerLib::_attachInterrupt_s(unsigned long int s) {
185205
cli();
186206

187207
/*
208+
Using longest mode from _ms function
188209
CS22 CS21 CS20 Freq Divisor Base Delay Overflow delay
189210
1 1 1 15.625KHz 1024 64us 16384us
190211
*/
@@ -203,7 +224,6 @@ void uTimerLib::_attachInterrupt_s(unsigned long int s) {
203224
_remaining = 256 - round(((s * 1000000) % 16384) / 64);
204225
}
205226

206-
207227
__overflows = _overflows;
208228
__remaining = _remaining;
209229

@@ -222,6 +242,23 @@ void uTimerLib::_attachInterrupt_s(unsigned long int s) {
222242

223243
sei();
224244
#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+
225262
}
226263

227264

@@ -235,6 +272,8 @@ void uTimerLib::_loadRemaining() {
235272
#ifdef ARDUINO_ARCH_AVR
236273
TCNT2 = _remaining;
237274
#endif
275+
276+
// STM32: Not needed
238277
}
239278

240279
/**
@@ -243,13 +282,20 @@ void uTimerLib::_loadRemaining() {
243282
* Note: This is device-dependant
244283
*/
245284
void uTimerLib::clearTimer() {
285+
_type = UTIMERLIB_TYPE_OFF;
286+
246287
#ifdef ARDUINO_ARCH_AVR
247288
TIMSK2 &= ~(1 << TOIE2); // Disable overflow interruption when 0
248289
SREG = (SREG & 0b01111111); // Disable interrupts without modifiying other interrupts
249290
#endif
250-
_type = UTIMERLIB_TYPE_OFF;
291+
292+
#ifdef _VARIANT_ARDUINO_STM32_
293+
Timer3.pause();
294+
#endif
251295
}
252296

297+
// Preinstantiate Object
298+
uTimerLib TimerLib = uTimerLib();
253299

254300

255301
/**
@@ -258,37 +304,33 @@ void uTimerLib::clearTimer() {
258304
* As timers doesn't give us enougth flexibility for large timings,
259305
* this function implements oferflow control to offer user desired timings.
260306
*/
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
265309
return;
266310
}
267-
if (_overflows > 0) {
268-
_overflows--;
311+
if (TimerLib._overflows > 0) {
312+
TimerLib._overflows--;
269313
}
270-
if (_overflows == 0 && _remaining > 0) {
314+
if (TimerLib._overflows == 0 && TimerLib._remaining > 0) {
271315
// Load remaining count to counter
272-
_loadRemaining();
316+
TimerLib._loadRemaining();
273317
// 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();
281325
} else {
282-
_overflows = __overflows;
283-
_remaining = __remaining;
326+
TimerLib._overflows = TimerLib.__overflows;
327+
TimerLib._remaining = TimerLib.__remaining;
284328
}
285329
}
286-
_cb();
330+
TimerLib._cb();
287331
}
288332
}
289333

290-
// Preinstantiate Object
291-
uTimerLib TimerLib = uTimerLib();
292334

293335

294336

@@ -301,7 +343,7 @@ uTimerLib TimerLib = uTimerLib();
301343
#ifdef ARDUINO_ARCH_AVR
302344
// Arduino AVR
303345
ISR(TIMER2_OVF_vect) {
304-
TimerLib._interruptHandler();
346+
uTimerLib_interruptHandle();
305347
}
306348
#endif
307349

src/uTimerLib.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,24 @@
2020
#define UTIMERLIB_TYPE_TIMEOUT 1
2121
#define UTIMERLIB_TYPE_INTERVAL 2
2222

23+
#ifdef _VARIANT_ARDUINO_STM32_
24+
#include "HardwareTimer.h"
25+
extern HardwareTimer Timer3;
26+
#endif
2327

2428
class uTimerLib {
2529
public:
2630
uTimerLib();
27-
void setInterval_us(void * (), unsigned long int);
28-
void setInterval_s(void * (), unsigned long int);
29-
int setTimeout_us(void * (), unsigned long int);
30-
int setTimeout_s(void * (), unsigned long int);
31+
void setInterval_us(void (*) (), unsigned long int);
32+
void setInterval_s(void (*) (), unsigned long int);
33+
int setTimeout_us(void (*) (), unsigned long int);
34+
int setTimeout_s(void (*) (), unsigned long int);
3135
void clearTimer();
3236

33-
void _interruptHandler();
34-
35-
private:
37+
/**
38+
* Because several compatibility issues -specially STM32- we need to put
39+
* these as public, but it should be private. Maybe in future upgrades...
40+
*/
3641
unsigned long int _overflows = 0;
3742
unsigned char _remaining = 0;
3843
unsigned long int __overflows = 0;
@@ -42,13 +47,20 @@
4247

4348
void _loadRemaining();
4449

50+
private:
51+
#ifdef _VARIANT_ARDUINO_STM32_
52+
bool _toInit = true;
53+
#endif
4554
void _attachInterrupt_us(unsigned long int);
4655
void _attachInterrupt_s(unsigned long int);
4756

4857

4958
};
5059

5160
extern uTimerLib TimerLib;
61+
#ifdef _VARIANT_ARDUINO_STM32_
62+
void uTimerLib_interruptHandle();
63+
#endif
5264

5365
#endif
5466

0 commit comments

Comments
 (0)