Skip to content

Commit e82fe90

Browse files
SidLeungcalvinatintel
authored andcommitted
Jira-507 and 514: 1. Bug corrected in timer ISR where the clearing of the pending interrupt was at the entrance instead of exit. When interrupts could happen fast enough to put the ISR in a loop. 2. The overhead for the s/w pwm code is 4-5 usec. Thus, limited the shortest pwm pulse to 10 usec (high and low).
1 parent 2299da2 commit e82fe90

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

libraries/CurieTimerOne/CurieTimer.cpp

+18-8
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ int CurieTimer::pwmStart(unsigned int outputPin, double dutyPercentage, unsigned
153153
{
154154
unsigned int pwmPeriod;
155155

156-
if(periodUsec == 0)
156+
// Safe guard against periodUsec overflow when convert to hz.
157+
if((periodUsec == 0) || (periodUsec >= MAX_PERIOD))
157158
return -(INVALID_PERIOD);
158159

159160
if((dutyPercentage < 0.0) || (dutyPercentage > 100.0))
@@ -181,11 +182,20 @@ int CurieTimer::pwmStart(unsigned int outputPin, double dutyPercentage, unsigned
181182
dutyCycle = (unsigned int)(((double)pwmPeriod / 100.0) * dutyPercentage);
182183
nonDutyCycle = pwmPeriod - dutyCycle;
183184

185+
// S/w overhead is about 4-5 usec. The shortest up or down cycle is set to be 10 usec.
186+
if(dutyCycle < (10 * HZ_USEC))
187+
dutyCycle = (10 * HZ_USEC);
188+
if(nonDutyCycle < (10 * HZ_USEC))
189+
nonDutyCycle = (10 * HZ_USEC);
190+
191+
// Account for s/w overhead.
192+
dutyCycle -= (4 * HZ_USEC);
193+
nonDutyCycle -= (4 * HZ_USEC);
194+
184195
dutyToggle = true;
185196
digitalWrite(pwmPin, HIGH);
186-
init(dutyCycle, pwmCB);
187-
188-
return SUCCESS;
197+
// Should return value back to caller.
198+
return init(dutyCycle, pwmCB);
189199
}
190200

191201

@@ -257,14 +267,14 @@ inline void CurieTimer::timerIsr(void)
257267
{
258268
unsigned int reg;
259269

260-
// Clear the interrupt pending bit.
261-
reg = aux_reg_read(timerControlAddr) & ~ARC_TIMER_INTR_PENDING_BIT_FLAG;
262-
aux_reg_write(timerControlAddr, reg);
263-
264270
tickCnt++; // Account for the interrupt
265271

266272
if(userCB != NULL) // Call user ISR if available
267273
userCB();
274+
275+
// Clear the interrupt pending bit upon exit.
276+
reg = aux_reg_read(timerControlAddr) & ~ARC_TIMER_INTR_PENDING_BIT_FLAG;
277+
aux_reg_write(timerControlAddr, reg);
268278
}
269279

270280

libraries/CurieTimerOne/CurieTimer.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ class CurieTimer
124124
// Start software PWM. Use a range of 0-1023 for duty cycle. 0=always Low, 1023=always high
125125
int pwmStart(unsigned int outputPin, int dutyRange, unsigned int periodUsec);
126126

127-
// Stop software PWM.
128-
inline void pwmStop(void) { return kill(); }
127+
// Stop software PWM. Put the time back to default and de-assert the selected port.
128+
inline void pwmStop(void) { kill(); return digitalWrite(pwmPin, LOW); }
129129

130130
// Generic timer ISR. It will call user call back routine if set.
131131
void timerIsr(void);

0 commit comments

Comments
 (0)