@@ -87,7 +87,7 @@ HardwareTimer::HardwareTimer(TIM_TypeDef *instance)
8787
8888 /* Configure timer with some default values */
8989 _timerObj.handle .Init .Prescaler = 0 ;
90- _timerObj.handle .Init .Period = 0xFFFF ; // 16bit max value
90+ _timerObj.handle .Init .Period = MAX_RELOAD;
9191 _timerObj.handle .Init .CounterMode = TIM_COUNTERMODE_UP;
9292 _timerObj.handle .Init .ClockDivision = TIM_CLOCKDIVISION_DIV1;
9393#if defined(TIM_RCR_REP)
@@ -474,6 +474,10 @@ void HardwareTimer::setOverflow(uint32_t overflow, TimerFormat_t format)
474474 break ;
475475 }
476476
477+ // In case ARR computation give 0xFFFFFFFF (equal (0 - 1) ) set ARR register to 0 (the smallest achievable period)
478+ if (ARR_RegisterValue == 0xFFFFFFFF ) {
479+ ARR_RegisterValue = 0 ;
480+ }
477481 __HAL_TIM_SET_AUTORELOAD (&_timerObj.handle , ARR_RegisterValue);
478482}
479483
@@ -520,14 +524,14 @@ void HardwareTimer::setCount(uint32_t counter, TimerFormat_t format)
520524 uint32_t Prescalerfactor = LL_TIM_GetPrescaler (_timerObj.handle .Instance ) + 1 ;
521525 switch (format) {
522526 case MICROSEC_FORMAT:
523- CNT_RegisterValue = ((counter * (getTimerClkFreq () / 1000000 )) / Prescalerfactor) - 1 ;
527+ CNT_RegisterValue = ((counter * (getTimerClkFreq () / 1000000 )) / Prescalerfactor);
524528 break ;
525529 case HERTZ_FORMAT:
526- CNT_RegisterValue = (uint32_t )(( getTimerClkFreq () / (counter * Prescalerfactor)) - 1 );
530+ CNT_RegisterValue = (uint32_t )(getTimerClkFreq () / (counter * Prescalerfactor));
527531 break ;
528532 case TICK_FORMAT:
529533 default :
530- CNT_RegisterValue = counter - 1 ;
534+ CNT_RegisterValue = counter;
531535 break ;
532536 }
533537 __HAL_TIM_SET_COUNTER (&(_timerObj.handle ), CNT_RegisterValue);
@@ -699,11 +703,12 @@ void HardwareTimer::setCaptureCompare(uint32_t channel, uint32_t compare, TimerC
699703
700704 switch (format) {
701705 case MICROSEC_COMPARE_FORMAT:
702- CCR_RegisterValue = ((compare * (getTimerClkFreq () / 1000000 )) / Prescalerfactor) - 1 ;
706+ CCR_RegisterValue = ((compare * (getTimerClkFreq () / 1000000 )) / Prescalerfactor);
703707 break ;
704708 case HERTZ_COMPARE_FORMAT:
705- CCR_RegisterValue = ( getTimerClkFreq () / (compare * Prescalerfactor)) - 1 ;
709+ CCR_RegisterValue = getTimerClkFreq () / (compare * Prescalerfactor);
706710 break ;
711+ // As per Reference Manual PWM reach 100% with CCRx value strictly greater than ARR (So ARR+1 in our case)
707712 case PERCENT_COMPARE_FORMAT:
708713 CCR_RegisterValue = ((__HAL_TIM_GET_AUTORELOAD (&(_timerObj.handle )) + 1 ) * compare) / 100 ;
709714 break ;
@@ -727,10 +732,17 @@ void HardwareTimer::setCaptureCompare(uint32_t channel, uint32_t compare, TimerC
727732 break ;
728733 case TICK_COMPARE_FORMAT:
729734 default :
730- CCR_RegisterValue = compare - 1 ;
735+ CCR_RegisterValue = compare;
731736 break ;
732737 }
733738
739+ // Special case when ARR is set to the max value, it is not possible to set CCRx to ARR+1 to reach 100%
740+ // Then set CCRx to max value. PWM is then 1/0xFFFF = 99.998..%
741+ if ((__HAL_TIM_GET_AUTORELOAD (&(_timerObj.handle )) == MAX_RELOAD)
742+ && (CCR_RegisterValue == MAX_RELOAD + 1 )) {
743+ CCR_RegisterValue = MAX_RELOAD;
744+ }
745+
734746 __HAL_TIM_SET_COMPARE (&(_timerObj.handle ), timChannel, CCR_RegisterValue);
735747}
736748
0 commit comments