Skip to content

Commit 38a508e

Browse files
SidLeungcalvinatintel
authored andcommitted
Jira-528. Make CurieTimerOne library to be compatible with the TimerOne library originated from Paul. Created methods that have the same name and functionalities as in the TimerOne library.
1 parent 98ee736 commit 38a508e

File tree

4 files changed

+168
-52
lines changed

4 files changed

+168
-52
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include <CurieTimerOne.h>
2+
3+
const int blinkPin = 13;
4+
5+
void setup(void)
6+
{
7+
CurieTimerOne.initialize(50000);
8+
Serial.begin(9600);
9+
}
10+
11+
void loop(void)
12+
{
13+
unsigned int range;
14+
15+
Serial.println("PWM blink: low -> high duty cycle");
16+
17+
for (float dutyCycle = 5.0; dutyCycle <= 100.0; dutyCycle++) {
18+
range = (dutyCycle / 100) * 1023;
19+
CurieTimerOne.pwm(blinkPin, range);
20+
delay(50);
21+
}
22+
23+
Serial.println("PWM blink: high -> low duty cycle");
24+
25+
for (float dutyCycle = 100.0; dutyCycle > 5.0; dutyCycle--) {
26+
range = (dutyCycle / 100) * 1023;
27+
CurieTimerOne.setPwmDuty(blinkPin, range);
28+
delay(50);
29+
}
30+
}

libraries/CurieTimerOne/keywords.txt

+18-12
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,24 @@ CurieTimer KEYWORD1
1111
#######################################
1212
# Methods and Functions (KEYWORD2)
1313
#######################################
14-
start KEYWORD2
15-
restart KEYWORD2
16-
kill KEYWORD2
17-
attachInterrupt KEYWORD2
18-
detachInterrupt KEYWORD2
19-
readTickCount KEYWORD2
20-
rdRstTickCount KEYWORD2
21-
pause KEYWORD2
22-
resume KEYWORD2
23-
pwmStart KEYWORD2
24-
pwmStop KEYWORD2
14+
initialize KEYWORD2
15+
setPeriod KEYWORD2
16+
start KEYWORD2
17+
stop KEYWORD2
18+
restart KEYWORD2
19+
resume KEYWORD2
20+
setPwmDuty KEYWORD2
21+
pwm KEYWORD2
22+
disablePwm KEYWORD2
23+
attachInterrupt KEYWORD2
24+
detachInterrupt KEYWORD2
25+
kill KEYWORD2
26+
readTickCount KEYWORD2
27+
rdRstTickCount KEYWORD2
28+
pause KEYWORD2
29+
pwmStart KEYWORD2
30+
pwmStop KEYWORD2
2531
#######################################
2632
# Instances (KEYWORD2)
2733
#######################################
28-
CurieTimerOne KEYWORD2
34+
CurieTimerOne KEYWORD2

libraries/CurieTimerOne/src/CurieTimerOne.cpp

+41-24
Original file line numberDiff line numberDiff line change
@@ -50,25 +50,15 @@ static void timerOnePwmCbWrapper(void)
5050
}
5151

5252

53-
CurieTimer::CurieTimer(const unsigned int timerNum) :
53+
CurieTimer::CurieTimer() :
5454
tickCnt(0), currState(IDLE), userCB(NULL)
5555
{
56-
if(timerNum == 0) {
57-
timerCountAddr = ARC_V2_TMR0_COUNT;
58-
timerControlAddr = ARC_V2_TMR0_CONTROL;
59-
timerLimitAddr = ARC_V2_TMR0_LIMIT;
60-
timerIrqNum = ARCV2_IRQ_TIMER0;
61-
isrFuncPtr = NULL;
62-
pwmCB = NULL;
63-
}
64-
else {
65-
timerCountAddr = ARC_V2_TMR1_COUNT;
66-
timerControlAddr = ARC_V2_TMR1_CONTROL;
67-
timerLimitAddr = ARC_V2_TMR1_LIMIT;
68-
timerIrqNum = ARCV2_IRQ_TIMER1;
69-
isrFuncPtr = &timerOneIsrWrapper;
70-
pwmCB = &timerOnePwmCbWrapper;
71-
}
56+
timerCountAddr = ARC_V2_TMR1_COUNT;
57+
timerControlAddr = ARC_V2_TMR1_CONTROL;
58+
timerLimitAddr = ARC_V2_TMR1_LIMIT;
59+
timerIrqNum = ARCV2_IRQ_TIMER1;
60+
isrFuncPtr = &timerOneIsrWrapper;
61+
pwmCB = &timerOnePwmCbWrapper;
7262
}
7363

7464

@@ -86,6 +76,7 @@ void CurieTimer::kill()
8676
tickCnt = 0;
8777
userCB = NULL;
8878
currState = IDLE;
79+
pauseCntrl = pauseCount = pwmPin = dutyCycle = nonDutyCycle = periodInUsec = 0;
8980
}
9081

9182

@@ -154,25 +145,26 @@ int CurieTimer::pwmStart(unsigned int outputPin, double dutyPercentage, unsigned
154145
unsigned int pwmPeriod;
155146

156147
// Safe guard against periodUsec overflow when convert to hz.
157-
if((periodUsec == 0) || (periodUsec >= MAX_PERIOD))
148+
if((periodUsec == 0) || (periodUsec >= MAX_PERIOD_USEC))
158149
return -(INVALID_PERIOD);
159150

160151
if((dutyPercentage < 0.0) || (dutyPercentage > 100.0))
161152
return -(INVALID_DUTY_CYCLE);
162153

154+
periodInUsec = periodUsec;
163155
pwmPin = outputPin;
164156
pinMode(pwmPin, OUTPUT);
165157

166158
if(dutyPercentage == 0.0) {
167-
// If PWM is already running, reset the timer and set pin to LOW
168-
kill();
159+
// If PWM is already running, pause to stop it from interfering, and set pin to LOW
160+
pause();
169161
digitalWrite(pwmPin, LOW);
170162
return SUCCESS;
171163
}
172164

173165
if(dutyPercentage == 100.0) {
174-
// If PWM is already running, reset the timer and set pin to HIGH
175-
kill();
166+
// If PWM is already running, pause to stop it from interfering, and set pin to HIGH
167+
pause();
176168
digitalWrite(pwmPin, HIGH);
177169
return SUCCESS;
178170
}
@@ -204,7 +196,7 @@ int CurieTimer::pwmStart(unsigned int outputPin, int dutyRange, unsigned int per
204196
if((dutyRange < 0) || (dutyRange > MAX_DUTY_RANGE))
205197
return -(INVALID_DUTY_CYCLE);
206198

207-
return pwmStart(outputPin, ((double)dutyRange * 100.0)/(double)MAX_DUTY_RANGE, periodUsec);
199+
return pwmStart(outputPin, ((double)dutyRange/(double)MAX_DUTY_RANGE) * 100.0, periodUsec);
208200
}
209201

210202

@@ -224,6 +216,31 @@ inline void CurieTimer::pwmCallBack(void)
224216
}
225217

226218

219+
// Method: setPeriod
220+
// This method is for making this library backward compatible to the AVR
221+
// TimerOne library. The routine changs the time period by pausing the timer
222+
// and resume it with the new period. This is not timer re-initialization.
223+
224+
void CurieTimer::setPeriod(unsigned long microseconds)
225+
{
226+
unsigned int periodHz;
227+
228+
if((microseconds == 0) || (microseconds > MAX_PERIOD_USEC))
229+
microseconds = 1000000;
230+
231+
periodInUsec = microseconds;
232+
periodHz = microseconds * HZ_USEC;
233+
pause();
234+
235+
aux_reg_write(timerLimitAddr, periodHz); // Load Timer period
236+
237+
if(pauseCount >= periodHz)
238+
pauseCount = 0;
239+
240+
resume();
241+
}
242+
243+
227244
// Method: init
228245
// Kick off the timer with a period, in Hz, provided. Initialize
229246
// timer to run in non-halt mode, enable timer interrupt. Always install
@@ -232,7 +249,7 @@ inline void CurieTimer::pwmCallBack(void)
232249
int CurieTimer::init(const unsigned int periodHz,
233250
void (*userCallBack)())
234251
{
235-
if((periodHz == 0) || (periodHz > MAX_PERIOD))
252+
if((periodHz == 0) || (periodHz > MAX_PERIOD_HZ))
236253
return -(INVALID_PERIOD);
237254

238255
interrupt_disable(timerIrqNum); // Disable Timer at controller

libraries/CurieTimerOne/src/CurieTimerOne.h

+79-16
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,8 @@
4848

4949
// Timer-1 is clocked at ARCV2_TIMER1_CLOCK_FREQ defined in conf.h
5050
const unsigned int HZ_USEC = (ARCV2_TIMER1_CLOCK_FREQ / 1000000); // Hz per micro second.
51-
const unsigned int MAX_PERIOD = (0x0FFFFFFFF / HZ_USEC);
52-
53-
// The two ARC timers.
54-
const unsigned int ARC_TIMER_0 = 0;
55-
const unsigned int ARC_TIMER_1 = 1;
51+
const unsigned int MAX_PERIOD_HZ = 0x0FFFFFFFF;
52+
const unsigned int MAX_PERIOD_USEC = (MAX_PERIOD_HZ / HZ_USEC);
5653

5754
// Duty cycle range.
5855
const int MAX_DUTY_RANGE = 1023;
@@ -80,21 +77,91 @@ typedef enum {
8077
// Class: CurieTimer
8178
//
8279
// Description:
83-
// This class describes the functionalities of a Arc Timer. It has the knowledge
84-
// of only 2 timers available in the h/w - a limitation. The timers are sourced by
85-
// a 32 HHz clock, a constant, used in this class, defined in the conf.h file.
80+
// This class describes the functionalities of a Arc Timer, in particular, timer-1.
81+
// Timer-0 is not available for this module to utilize. The timers are clocked by
82+
// a 32 HHz source and have 32-bit counters.
8683
//
8784

8885
class CurieTimer
8986
{
9087
public:
91-
// Constructor. Default is timer-1.
92-
CurieTimer(const unsigned int timerNum = ARC_TIMER_1);
88+
// Constructor.
89+
CurieTimer();
90+
91+
// The following methods are similar to the ones found in the AVR TimerOne library.
92+
93+
//****************************
94+
// Configuration
95+
//****************************
96+
97+
inline void initialize(unsigned long microseconds = 1000000) {
98+
if((microseconds == 0) || (microseconds > MAX_PERIOD_USEC))
99+
microseconds = 1000000;
100+
periodInUsec = microseconds;
101+
init( (microseconds * HZ_USEC), NULL );
102+
}
103+
104+
void setPeriod(unsigned long microseconds);
105+
106+
//****************************
107+
// Run Control
108+
//****************************
109+
110+
inline void start(void) {
111+
pause();
112+
pauseCount = 0;
113+
resume();
114+
}
115+
116+
inline void stop(void) { return pause(); }
117+
118+
inline void restart(void) { start(); }
119+
120+
// Resume the timer from where it was paused.
121+
void resume(void);
122+
123+
//****************************
124+
// PWM outputs
125+
//****************************
126+
127+
inline void setPwmDuty(char pin, unsigned int duty) {
128+
pwmStart( pin, (int) duty, periodInUsec );
129+
}
130+
131+
inline void pwm(char pin, unsigned int duty) {
132+
pwmStart( pin, (int) duty, periodInUsec );
133+
}
134+
135+
inline void pwm(char pin, unsigned int duty, unsigned long microseconds) {
136+
pwmStart( pin, (int) duty, microseconds );
137+
}
138+
139+
inline void disablePwm(char pin) {
140+
pwmStop();
141+
}
142+
143+
//****************************
144+
// Interrupt Function
145+
//****************************
146+
147+
void attachInterrupt(void (*isr)());
148+
149+
inline void attachInterrupt(void (*isr)(), unsigned long microseconds) {
150+
attachInterrupt( isr );
151+
setPeriod( microseconds );
152+
}
153+
154+
inline void detachInterrupt(void) { attachInterrupt(NULL); };
155+
156+
/////////
157+
// The following are additional methods provided by Intel for the Curie platform.
158+
////////
93159

94160
// Set up the timer with the input period, in usec, and the call back routine.
95161
// Period stays with the timer until it is killed or re/start another round.
96-
inline int start(const unsigned int timerPeriodUsec = 0,
162+
inline int start(const unsigned int timerPeriodUsec,
97163
void (*userCallBack)() = NULL) {
164+
periodInUsec = timerPeriodUsec;
98165
return( init((timerPeriodUsec * HZ_USEC), userCallBack) ); }
99166

100167
// Restarting the timer, start counter from 0.
@@ -104,8 +171,6 @@ class CurieTimer
104171
void kill(void);
105172

106173
// Attach or detach the user call back routine.
107-
void attachInterrupt(void (*userCallBack)());
108-
void detachInterrupt(void) { return attachInterrupt(NULL); };
109174

110175
// Timer interrupt count.
111176
inline unsigned int readTickCount(void) { return tickCnt; }
@@ -114,9 +179,6 @@ class CurieTimer
114179

115180
// Pausing the timer = no count up, no interrupt.
116181
void pause(void);
117-
inline void stop(void) { return pause(); }
118-
// Resume the timer from where it was paused.
119-
void resume(void);
120182

121183
// Start software PWM. Note that the timer is consumed once PWM is set.
122184
int pwmStart(unsigned int outputPin, double dutyPercentage, unsigned int periodUsec);
@@ -148,6 +210,7 @@ class CurieTimer
148210
unsigned int pwmPin;
149211
unsigned int dutyCycle;
150212
unsigned int nonDutyCycle;
213+
unsigned int periodInUsec;
151214

152215
void (*isrFuncPtr)();
153216
void (*userCB)();

0 commit comments

Comments
 (0)