Skip to content

Commit 29c3ae1

Browse files
authored
Add files via upload
1 parent 217a24f commit 29c3ae1

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

avdweb_SAMDtimer.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
Copyright (C) 2012 Albert van Dalen http://www.avdweb.nl
3+
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
4+
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
5+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
6+
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at http://www.gnu.org/licenses .
7+
8+
Version 26-1-2017
9+
10+
16 bit timer: max period_us = 1398080us (0.7Hz), min period_us = 1us (1MHz)
11+
12+
note *1 SCK, MOSI, MISO are on Arduino Zero SPI header
13+
14+
Timer Arduino Zero pins SAM15x15 pins
15+
SAMDtimer 0 8bit D3 D18/A4 D17 D4 d[9] d[5] d[4] d[8] timer not yet implemented
16+
SAMDtimer 0 16bit D3 D18/A4 d[9] d[5] timer not yet implemented
17+
SAMDtimer 1 8bit D0 D9 D33 D8 D1 D30 d[11] d[7] d[31] d[6] d[10] d[27] timer not yet implemented
18+
SAMDtimer 1 16bit D0 D9 D33 d[11] d[7] d[31] timer not yet implemented
19+
SAMDtimer 2 8bit D13 (D28) D22/MISO*1 D16 d[19] d[15] d[14] d[3] timer not yet implemented
20+
SAMDtimer 2 16bit D13 (D28) d[19] d[15] timer not yet implemented
21+
22+
SAMDtimer 3 8bit D5 D12 D2 D10 d[17] d[21] d[16] d[20] timer not yet implemented
23+
SAMDtimer 3 16bit D5 D12 d[17] d[21]
24+
SAMDtimer 4 8bit D16/A2 D21/SCL D15/A1 D20/SDA d[3] d[25] d[2] d[24] timer not yet implemented
25+
SAMDtimer 4 16bit D16/A2 D21/SCL d[3] d[25]
26+
SAMDtimer 5 8bit D24/SCK*1 D23/MOSI*1 d[13] d[12] timer not yet implemented
27+
SAMDtimer 5 16bit D24/SCK*1 d[13]
28+
*/
29+
30+
#include "avdweb_SAMDtimer.h"
31+
32+
SAMDtimer::SAMDtimer(byte timerNr, tc_counter_size countersize, byte pin, unsigned period_us, int pulseWidth_us, bool timerEnable):
33+
Adafruit_ZeroTimer(timerNr), pin(pin), countersize(countersize), period_us(period_us)
34+
{ if(pulseWidth_us==-1) calc(period_us, period_us/2);
35+
else calc(period_us, pulseWidth_us);
36+
init(timerEnable);
37+
}
38+
39+
SAMDtimer::SAMDtimer(byte timerNr, tc_callback_t _ISR, unsigned period_us, bool ISRenable):
40+
Adafruit_ZeroTimer(timerNr)
41+
{ ISR = _ISR;
42+
countersize = TC_COUNTER_SIZE_16BIT;
43+
calc(period_us, period_us/2);
44+
init(1);
45+
setCallback(ISRenable, TC_CALLBACK_CC_CHANNEL1, ISR);
46+
}
47+
48+
void SAMDtimer::setPulseWidth(unsigned pulseWidth_us)
49+
{ calc(period_us, pulseWidth_us);
50+
setPeriodMatch(periodCounter, PWcounter, 1);
51+
}
52+
53+
void SAMDtimer::attachInterrupt(tc_callback_t _ISR, bool interruptEnable)
54+
{ ISR = _ISR;
55+
setCallback(interruptEnable, TC_CALLBACK_CC_CHANNEL1, ISR);
56+
}
57+
58+
void SAMDtimer::enableTimer(bool timerEnable)
59+
{ enable(timerEnable);
60+
}
61+
62+
void SAMDtimer::enableInterrupt(bool interruptEnable)
63+
{ setCallback(interruptEnable, TC_CALLBACK_CC_CHANNEL1, ISR);
64+
}
65+
66+
void SAMDtimer::init(bool enabled)
67+
{ configure(prescale, countersize, TC_WAVE_GENERATION_MATCH_PWM);
68+
PWMout(true, 1, pin); // must be ch1 for 16bit
69+
setPeriodMatch(periodCounter, PWcounter, 1);
70+
enable(enabled);
71+
}
72+
73+
void SAMDtimer::calc(unsigned period_us, unsigned pulseWidth_us)
74+
{ periodCounter = (F_CPU * (signed)period_us) / 1000000; // why signed?
75+
PWcounter = (F_CPU * (signed)pulseWidth_us) / 1000000;
76+
if(periodCounter < 65536) prescale = TC_CLOCK_PRESCALER_DIV1;
77+
else if((PWcounter >>= 1, periodCounter >>= 1) < 65536) prescale = TC_CLOCK_PRESCALER_DIV2; // = 256
78+
else if((PWcounter >>= 1, periodCounter >>= 1) < 65536) prescale = TC_CLOCK_PRESCALER_DIV4;
79+
else if((PWcounter >>= 1, periodCounter >>= 1) < 65536) prescale = TC_CLOCK_PRESCALER_DIV8;
80+
else if((PWcounter >>= 1, periodCounter >>= 1) < 65536) prescale = TC_CLOCK_PRESCALER_DIV16;
81+
else if((PWcounter >>= 2, periodCounter >>= 2) < 65536) prescale = TC_CLOCK_PRESCALER_DIV64;
82+
else if((PWcounter >>= 2, periodCounter >>= 2) < 65536) prescale = TC_CLOCK_PRESCALER_DIV256;
83+
else if((PWcounter >>= 2, periodCounter >>= 2) < 65536) prescale = TC_CLOCK_PRESCALER_DIV1024;
84+
}
85+
86+
87+
88+
89+

avdweb_SAMDtimer.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
Copyright (C) 2012 Albert van Dalen http://www.avdweb.nl
3+
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
4+
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
5+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
6+
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at http://www.gnu.org/licenses .
7+
8+
Version 26-1-2017
9+
*/
10+
11+
#ifndef SAMDtimer_H
12+
#define SAMDtimer_H
13+
14+
#include <Adafruit_ZeroTimer.h>
15+
16+
class SAMDtimer : public Adafruit_ZeroTimer
17+
{ public:
18+
SAMDtimer(byte timerNr, tc_counter_size countersize, byte pin, unsigned period_us, int pulseWidth_us=-1, bool timerEnable=1); // For timer with output
19+
SAMDtimer(byte timerNr, tc_callback_t _ISR, unsigned period_us, bool ISRenable=1); // For timer interrupt, without output
20+
21+
void attachInterrupt(tc_callback_t _ISR, bool interruptEnable=1); // attach ISR to a timer with output, or exchange the ISR
22+
void enableTimer(bool timerEnable);
23+
void enableInterrupt(bool interruptEnable);
24+
void setPulseWidth(unsigned pulseWidth_us);
25+
26+
protected:
27+
void init(bool enabled);
28+
void calc(unsigned period_us, unsigned pulseWidth_us);
29+
30+
byte pin;
31+
tc_callback_t ISR;
32+
unsigned period_us, periodCounter, PWcounter;
33+
tc_clock_prescaler prescale;
34+
tc_counter_size countersize;
35+
};
36+
#endif

0 commit comments

Comments
 (0)