diff --git a/libraries/CurieTimerOne/CurieTimer.cpp b/libraries/CurieTimerOne/CurieTimer.cpp index d4978511..dea3bc06 100644 --- a/libraries/CurieTimerOne/CurieTimer.cpp +++ b/libraries/CurieTimerOne/CurieTimer.cpp @@ -153,7 +153,8 @@ int CurieTimer::pwmStart(unsigned int outputPin, double dutyPercentage, unsigned { unsigned int pwmPeriod; - if(periodUsec == 0) + // Safe guard against periodUsec overflow when convert to hz. + if((periodUsec == 0) || (periodUsec >= MAX_PERIOD)) return -(INVALID_PERIOD); if((dutyPercentage < 0.0) || (dutyPercentage > 100.0)) @@ -179,11 +180,20 @@ int CurieTimer::pwmStart(unsigned int outputPin, double dutyPercentage, unsigned dutyCycle = (unsigned int)(((double)pwmPeriod / 100.0) * dutyPercentage); nonDutyCycle = pwmPeriod - dutyCycle; + // S/w overhead is about 4-5 usec. The shortest up or down cycle is set to be 10 usec. + if(dutyCycle < (10 * HZ_USEC)) + dutyCycle = (10 * HZ_USEC); + if(nonDutyCycle < (10 * HZ_USEC)) + nonDutyCycle = (10 * HZ_USEC); + + // Account for s/w overhead. + dutyCycle -= (4 * HZ_USEC); + nonDutyCycle -= (4 * HZ_USEC); + dutyToggle = true; digitalWrite(pwmPin, HIGH); - init(dutyCycle, pwmCB); - - return SUCCESS; + // Should return value back to caller. + return init(dutyCycle, pwmCB); } @@ -255,14 +265,14 @@ inline void CurieTimer::timerIsr(void) { unsigned int reg; - // Clear the interrupt pending bit. - reg = aux_reg_read(timerControlAddr) & ~ARC_TIMER_INTR_PENDING_BIT_FLAG; - aux_reg_write(timerControlAddr, reg); - tickCnt++; // Account for the interrupt if(userCB != NULL) // Call user ISR if available userCB(); + + // Clear the interrupt pending bit upon exit. + reg = aux_reg_read(timerControlAddr) & ~ARC_TIMER_INTR_PENDING_BIT_FLAG; + aux_reg_write(timerControlAddr, reg); } diff --git a/libraries/CurieTimerOne/CurieTimer.h b/libraries/CurieTimerOne/CurieTimer.h index 709d131e..0a4cf42e 100644 --- a/libraries/CurieTimerOne/CurieTimer.h +++ b/libraries/CurieTimerOne/CurieTimer.h @@ -124,8 +124,8 @@ class CurieTimer // Start software PWM. Use a range of 0-1023 for duty cycle. 0=always Low, 1023=always high int pwmStart(unsigned int outputPin, int dutyRange, unsigned int periodUsec); - // Stop software PWM. - inline void pwmStop(void) { return kill(); } + // Stop software PWM. Put the time back to default and de-assert the selected port. + inline void pwmStop(void) { kill(); return digitalWrite(pwmPin, LOW); } // Generic timer ISR. It will call user call back routine if set. void timerIsr(void);