Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions DueTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
Released into the public domain.
*/

#include <Arduino.h>
#if defined(_SAM3XA_)
#include "DueTimer.h"

const DueTimer::Timer DueTimer::Timers[NUM_TIMERS] = {
Expand All @@ -20,10 +18,11 @@ const DueTimer::Timer DueTimer::Timers[NUM_TIMERS] = {
{TC1,0,TC3_IRQn, PIOB, PIO_PER_P0 , PIO_PERIPH_B, PIOB, PIO_PER_P1 , PIO_PERIPH_B, PIOA, PIO_PER_P22, PIO_PERIPH_B},
{TC1,1,TC4_IRQn, PIOB, PIO_PER_P2 , PIO_PERIPH_B, PIOB, PIO_PER_P3 , PIO_PERIPH_B, PIOA, PIO_PER_P23, PIO_PERIPH_B},
{TC1,2,TC5_IRQn, PIOB, PIO_PER_P4 , PIO_PERIPH_B, PIOB, PIO_PER_P5 , PIO_PERIPH_B, PIOB, PIO_PER_P16, PIO_PERIPH_A},
#if NUM_TIMERS > 6
{TC2,0,TC6_IRQn, PIOC, PIO_PER_P25, PIO_PERIPH_B, PIOC, PIO_PER_P26 , PIO_PERIPH_B, PIOC, PIO_PER_P27, PIO_PERIPH_B},
{TC2,1,TC7_IRQn, PIOC, PIO_PER_P28, PIO_PERIPH_B, PIOC, PIO_PER_P29 , PIO_PERIPH_B, PIOC, PIO_PER_P30, PIO_PERIPH_B},
{TC2,2,TC8_IRQn, PIOD, PIO_PER_P7 , PIO_PERIPH_B, PIOD, PIO_PER_P8 , PIO_PERIPH_B, PIOD, PIO_PER_P9, PIO_PERIPH_B},
#endif
};

// Fix for compatibility with Servo library
Expand All @@ -36,15 +35,23 @@ const DueTimer::Timer DueTimer::Timers[NUM_TIMERS] = {
(void (*)()) 1, // Timer 3 - Occupied
(void (*)()) 1, // Timer 4 - Occupied
(void (*)()) 1, // Timer 5 - Occupied
#if NUM_TIMERS > 6
(void (*)()) 0, // Timer 6
(void (*)()) 0, // Timer 7
(void (*)()) 0 // Timer 8
#endif
};
#else
void (*DueTimer::callbacks[NUM_TIMERS])() = {};
#endif

#if NUM_TIMERS > 6
double DueTimer::_frequency[NUM_TIMERS] = {-1,-1,-1,-1,-1,-1,-1,-1,-1};
uint32_t DueTimer::_statusRegister[NUM_TIMERS] = {0,0,0,0,0,0,0,0};
#else
double DueTimer::_frequency[NUM_TIMERS] = {-1,-1,-1,-1,-1,-1};
uint32_t DueTimer::_statusRegister[NUM_TIMERS] = {0,0,0,0,0,0};
#endif

/*
Initializing all timers, so you can use them like this: Timer0.start();
Expand All @@ -60,9 +67,11 @@ DueTimer Timer1(1);
DueTimer Timer4(4);
DueTimer Timer5(5);
#endif
#if NUM_TIMERS > 6
DueTimer Timer6(6);
DueTimer Timer7(7);
DueTimer Timer8(8);
#endif

DueTimer::DueTimer(unsigned short _timer) : timer(_timer){
/*
Expand Down Expand Up @@ -170,7 +179,7 @@ uint8_t DueTimer::bestClock(double frequency, uint32_t& retRC){
float bestError = 9.999e99;
do
{
ticks = (float) VARIANT_MCK / frequency / (float) clockConfig[clkId].divisor;
ticks = (float) SystemCoreClock / frequency / (float) clockConfig[clkId].divisor;
// error = abs(ticks - round(ticks));
error = clockConfig[clkId].divisor * abs(ticks - round(ticks)); // Error comparison needs scaling
if (error < bestError)
Expand All @@ -179,7 +188,7 @@ uint8_t DueTimer::bestClock(double frequency, uint32_t& retRC){
bestError = error;
}
} while (clkId-- > 0);
ticks = (float) VARIANT_MCK / frequency / (float) clockConfig[bestClock].divisor;
ticks = (float) SystemCoreClock / frequency / (float) clockConfig[bestClock].divisor;
retRC = (uint32_t) round(ticks);
return clockConfig[bestClock].flag;
}
Expand Down Expand Up @@ -214,16 +223,16 @@ DueTimer& DueTimer::setFrequency(double frequency){

switch (clock) {
case TC_CMR_TCCLKS_TIMER_CLOCK1:
_frequency[timer] = (double)VARIANT_MCK / 2.0 / (double)rc;
_frequency[timer] = (double)SystemCoreClock / 2.0 / (double)rc;
break;
case TC_CMR_TCCLKS_TIMER_CLOCK2:
_frequency[timer] = (double)VARIANT_MCK / 8.0 / (double)rc;
_frequency[timer] = (double)SystemCoreClock / 8.0 / (double)rc;
break;
case TC_CMR_TCCLKS_TIMER_CLOCK3:
_frequency[timer] = (double)VARIANT_MCK / 32.0 / (double)rc;
_frequency[timer] = (double)SystemCoreClock / 32.0 / (double)rc;
break;
default: // TC_CMR_TCCLKS_TIMER_CLOCK4
_frequency[timer] = (double)VARIANT_MCK / 128.0 / (double)rc;
_frequency[timer] = (double)SystemCoreClock / 128.0 / (double)rc;
break;
}

Expand Down Expand Up @@ -538,6 +547,7 @@ void TC5_Handler(void){
if (DueTimer::callbacks[5]) DueTimer::callbacks[5]();
}
#endif
#if NUM_TIMERS > 6
void TC6_Handler(void){
DueTimer::_statusRegister[6] = TC_GetStatus(TC2, 0);
if (DueTimer::callbacks[6]) DueTimer::callbacks[6]();
Expand Down
19 changes: 16 additions & 3 deletions DueTimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
Released into the public domain.
*/

#ifdef __arm__
#include "Arduino.h"

#if defined(_SAM3XA_)

#ifndef DueTimer_h
#define DueTimer_h

#include "Arduino.h"

#include <inttypes.h>

/*
Expand All @@ -31,7 +31,11 @@
#endif


#if defined TC2
#define NUM_TIMERS 9
#else
#define NUM_TIMERS 6
#endif

class DueTimer
{
Expand All @@ -58,9 +62,11 @@ class DueTimer
friend void TC3_Handler(void);
friend void TC4_Handler(void);
friend void TC5_Handler(void);
#if NUM_TIMERS > 6
friend void TC6_Handler(void);
friend void TC7_Handler(void);
friend void TC8_Handler(void);
#endif

static void (*callbacks[NUM_TIMERS])();

Expand Down Expand Up @@ -98,6 +104,11 @@ class DueTimer
DueTimer& setFrequency(double frequency);
double getFrequency(void) const;
double getPeriod(void) const;

inline __attribute__((always_inline)) bool operator== (const DueTimer& rhs) const
{return timer == rhs.timer; };
inline __attribute__((always_inline)) bool operator!= (const DueTimer& rhs) const
{return timer != rhs.timer; };

DueTimer& setPeriod(double microseconds);
DueTimer& setPeriodMilliSeconds(double milliseconds) {
Expand Down Expand Up @@ -160,9 +171,11 @@ extern DueTimer Timer1;
extern DueTimer Timer4;
extern DueTimer Timer5;
#endif
#if NUM_TIMERS > 6
extern DueTimer Timer6;
extern DueTimer Timer7;
extern DueTimer Timer8;
#endif

#endif

Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ Timer.getAvailable().attachInterrupt(callback1).start(10);
DueTimer::getAvailable().attachInterrupt(callback2).start(10);
// Start timer on second available timer
// And so on...

DueTimer myTimer = Timer.getAvailable();
if (myTimer != DueTimer(0))
// Now we know that the timer returned is actually available
// Can compare timers using == or !=

```

### Activate the output pins (TIOA,TIOB)
Expand Down Expand Up @@ -147,7 +153,8 @@ You will need uncommend the line in `DueTimer.h` in `DueTimer` folder inside the

### You don't need to know:

- `unsigned short timer` - Stores the object timer id (to access Timers struct array).
<<<<<<< HEAD
- `int timer` - Stores the object timer id (to access Timers struct array).

- `DueTimer(unsigned short _timer)` - Instantiate a new DueTimer object for Timer _timer (NOTE: All objects are already instantiated!).

Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"type": "git",
"url": "https://github.com/ivanseidel/DueTimer.git"
},
"version": "1.4.7",
"version": "1.4.8",
"license": "MIT",
"frameworks": "arduino",
"platforms": "atmelsam",
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version=1.4.8
author=Ivan Seidel <ivanseidel@gmail.com>
maintainer=Ivan Seidel <ivanseidel@gmail.com>
sentence=Timer Library fully implemented for Arduino DUE
paragraph=There are 9 Timer objects already instantiated for you: Timer0, Timer1, Timer2, Timer3, Timer4, Timer5, Timer6, Timer7 and Timer8.
paragraph=There are 6 or 9 Timer objects already instantiated for you: Timer0, Timer1, Timer2, Timer3, Timer4, Timer5 and Timer6, Timer7, Timer8 where supported by the hardware.
category=Timing
url=https://github.com/ivanseidel/DueTimer
architectures=sam