Skip to content

Commit

Permalink
Version 0.2.0:
Browse files Browse the repository at this point in the history
 - Add STM32 compatibility.

Tested: AVR and STM32
  • Loading branch information
Naguissa committed Feb 19, 2018
1 parent cb26c02 commit 8e85d5c
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
#include "Arduino.h"
#include "uTimerLib.h"

#ifndef LED_BUILTIN
// change to fit your needs
#define LED_BUILTIN 13
#endif




bool status = 0;
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=uTimerLib
version=0.1.0
version=0.2.0
author=Naguissa <naguissa@foroelectro.net>
maintainer=Naguissa <naguissa@foroelectro.net>
sentence=Tiny and cross-device compatible timer library
Expand Down
106 changes: 74 additions & 32 deletions src/uTimerLib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,35 @@
* Tiny and cross-device compatible timer library.
*
* Timers used by microcontroller
* Atmel AVR: Timer2
* Atmel AVR: Timer2 (3rd timer)
* STM32: Timer3 (3rd timer)
*
* @copyright Naguissa
* @author Naguissa
* @email naguissa@foroelectro.net
* @version 0.1.0
* @created 2018-01-27
*/
#include <Arduino.h>
#include "uTimerLib.h"


/**
* Constructor
*
* Nothing to do here
*/
uTimerLib::uTimerLib() {}
uTimerLib::uTimerLib() {
#ifdef _VARIANT_ARDUINO_STM32_
clearTimer();
#endif
}

/**
* Attaches a callback function to be executed each us microseconds
*
* @param void*() cb Callback function to be called
* @param unsigned long int us Interval in microseconds
*/
void uTimerLib::setInterval_us(void * cb(), unsigned long int us) {
void uTimerLib::setInterval_us(void (* cb)(), unsigned long int us) {
clearTimer();
_cb = cb;
_type = UTIMERLIB_TYPE_INTERVAL;
Expand All @@ -41,7 +44,7 @@ void uTimerLib::setInterval_us(void * cb(), unsigned long int us) {
* @param void*() cb Callback function to be called
* @param unsigned long int us Timeout in microseconds
*/
int uTimerLib::setTimeout_us(void * cb(), unsigned long int us) {
int uTimerLib::setTimeout_us(void (* cb)(), unsigned long int us) {
clearTimer();
_cb = cb;
_type = UTIMERLIB_TYPE_TIMEOUT;
Expand All @@ -55,7 +58,7 @@ int uTimerLib::setTimeout_us(void * cb(), unsigned long int us) {
* @param void*() cb Callback function to be called
* @param unsigned long int s Interval in seconds
*/
void uTimerLib::setInterval_s(void * cb(), unsigned long int s) {
void uTimerLib::setInterval_s(void (* cb)(), unsigned long int s) {
clearTimer();
_cb = cb;
_type = UTIMERLIB_TYPE_INTERVAL;
Expand All @@ -69,7 +72,7 @@ void uTimerLib::setInterval_s(void * cb(), unsigned long int s) {
* @param void*() cb Callback function to be called
* @param unsigned long int s Timeout in seconds
*/
int uTimerLib::setTimeout_s(void * cb(), unsigned long int s) {
int uTimerLib::setTimeout_s(void (* cb)(), unsigned long int s) {
clearTimer();
_cb = cb;
_type = UTIMERLIB_TYPE_TIMEOUT;
Expand Down Expand Up @@ -163,6 +166,23 @@ void uTimerLib::_attachInterrupt_us(unsigned long int us) {

sei();
#endif

// STM32, all variants
#ifdef _VARIANT_ARDUINO_STM32_
Timer3.setMode(TIMER_CH1, TIMER_OUTPUTCOMPARE);
Timer3.setPeriod(us); // in microseconds
Timer3.setCompare(TIMER_CH1, 1);
__overflows = _overflows = 1;
__remaining = _remaining = 0;
if (_toInit) {
_toInit = false;
Timer3.attachInterrupt(TIMER_CH1, uTimerLib_interruptHandle);
}
Timer3.refresh();
Timer3.resume();
#endif


}


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

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


__overflows = _overflows;
__remaining = _remaining;

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

sei();
#endif


// STM32, all variants
#ifdef _VARIANT_ARDUINO_STM32_
Timer3.setMode(TIMER_CH1, TIMER_OUTPUTCOMPARE);
Timer3.setPeriod((unsigned long int) 1000000); // 1s, in microseconds
Timer3.setCompare(TIMER_CH1, 1);
__overflows = _overflows = s;
__remaining = _remaining = 0;
if (_toInit) {
_toInit = false;
Timer3.attachInterrupt(TIMER_CH1, uTimerLib_interruptHandle);
}
Timer3.refresh();
Timer3.resume();
#endif

}


Expand All @@ -235,6 +272,8 @@ void uTimerLib::_loadRemaining() {
#ifdef ARDUINO_ARCH_AVR
TCNT2 = _remaining;
#endif

// STM32: Not needed
}

/**
Expand All @@ -243,13 +282,20 @@ void uTimerLib::_loadRemaining() {
* Note: This is device-dependant
*/
void uTimerLib::clearTimer() {
_type = UTIMERLIB_TYPE_OFF;

#ifdef ARDUINO_ARCH_AVR
TIMSK2 &= ~(1 << TOIE2); // Disable overflow interruption when 0
SREG = (SREG & 0b01111111); // Disable interrupts without modifiying other interrupts
#endif
_type = UTIMERLIB_TYPE_OFF;

#ifdef _VARIANT_ARDUINO_STM32_
Timer3.pause();
#endif
}

// Preinstantiate Object
uTimerLib TimerLib = uTimerLib();


/**
Expand All @@ -258,37 +304,33 @@ void uTimerLib::clearTimer() {
* As timers doesn't give us enougth flexibility for large timings,
* this function implements oferflow control to offer user desired timings.
*/
void uTimerLib::_interruptHandler() {
extern uTimerLib TimerLib;

if (_type == UTIMERLIB_TYPE_OFF) { // Should not happen
void uTimerLib_interruptHandle() {
if (TimerLib._type == UTIMERLIB_TYPE_OFF) { // Should not happen
return;
}
if (_overflows > 0) {
_overflows--;
if (TimerLib._overflows > 0) {
TimerLib._overflows--;
}
if (_overflows == 0 && _remaining > 0) {
if (TimerLib._overflows == 0 && TimerLib._remaining > 0) {
// Load remaining count to counter
_loadRemaining();
TimerLib._loadRemaining();
// And clear remaining count
_remaining = 0;
} else if (_overflows == 0 && _remaining == 0) {
if (_type == UTIMERLIB_TYPE_TIMEOUT) {
clearTimer();
} else if (_type == UTIMERLIB_TYPE_INTERVAL) {
if (__overflows == 0) {
_loadRemaining();
TimerLib._remaining = 0;
} else if (TimerLib._overflows == 0 && TimerLib._remaining == 0) {
if (TimerLib._type == UTIMERLIB_TYPE_TIMEOUT) {
TimerLib.clearTimer();
} else if (TimerLib._type == UTIMERLIB_TYPE_INTERVAL) {
if (TimerLib.__overflows == 0) {
TimerLib._loadRemaining();
} else {
_overflows = __overflows;
_remaining = __remaining;
TimerLib._overflows = TimerLib.__overflows;
TimerLib._remaining = TimerLib.__remaining;
}
}
_cb();
TimerLib._cb();
}
}

// Preinstantiate Object
uTimerLib TimerLib = uTimerLib();



Expand All @@ -301,7 +343,7 @@ uTimerLib TimerLib = uTimerLib();
#ifdef ARDUINO_ARCH_AVR
// Arduino AVR
ISR(TIMER2_OVF_vect) {
TimerLib._interruptHandler();
uTimerLib_interruptHandle();
}
#endif

26 changes: 19 additions & 7 deletions src/uTimerLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,24 @@
#define UTIMERLIB_TYPE_TIMEOUT 1
#define UTIMERLIB_TYPE_INTERVAL 2

#ifdef _VARIANT_ARDUINO_STM32_
#include "HardwareTimer.h"
extern HardwareTimer Timer3;
#endif

class uTimerLib {
public:
uTimerLib();
void setInterval_us(void * (), unsigned long int);
void setInterval_s(void * (), unsigned long int);
int setTimeout_us(void * (), unsigned long int);
int setTimeout_s(void * (), unsigned long int);
void setInterval_us(void (*) (), unsigned long int);
void setInterval_s(void (*) (), unsigned long int);
int setTimeout_us(void (*) (), unsigned long int);
int setTimeout_s(void (*) (), unsigned long int);
void clearTimer();

void _interruptHandler();

private:
/**
* Because several compatibility issues -specially STM32- we need to put
* these as public, but it should be private. Maybe in future upgrades...
*/
unsigned long int _overflows = 0;
unsigned char _remaining = 0;
unsigned long int __overflows = 0;
Expand All @@ -42,13 +47,20 @@

void _loadRemaining();

private:
#ifdef _VARIANT_ARDUINO_STM32_
bool _toInit = true;
#endif
void _attachInterrupt_us(unsigned long int);
void _attachInterrupt_s(unsigned long int);


};

extern uTimerLib TimerLib;
#ifdef _VARIANT_ARDUINO_STM32_
void uTimerLib_interruptHandle();
#endif

#endif

0 comments on commit 8e85d5c

Please sign in to comment.