Skip to content

Commit 60b3b30

Browse files
94xhnfpistm
authored andcommitted
fix(HardwareTimer): use ARR+1 in getCaptureCompare percent/resolution
getCaptureCompare() divided by LL_TIM_GetAutoReload() (ARR) for PERCENT_COMPARE_FORMAT and all RESOLUTION_xB_COMPARE_FORMAT cases, while its counterpart setCaptureCompare() multiplies by ARR+1, per the code's own comment: "PWM reach 100% with CCRx value strictly greater than ARR (So ARR+1 in our case)". This makes get/set inconsistent: reading back a duty cycle written via setCaptureCompare(ch, 100, PERCENT_COMPARE_FORMAT) does not return 100, and overshoots more as ARR gets smaller (e.g. ARR=9 reads back 111, ARR=1 reads back 200). When ARR is 0 (a reachable state, e.g. after setOverflow(1, TICK_FORMAT)), the getter performs a division by zero. Use ARR+1 in the getter too, matching the setter and its own documented rationale. Signed-off-by: 94xhn <87560781+94xhn@users.noreply.github.com>
1 parent 594ee29 commit 60b3b30

1 file changed

Lines changed: 5 additions & 2 deletions

File tree

‎libraries/SrcWrapper/src/HardwareTimer.cpp‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,8 +1205,11 @@ uint32_t HardwareTimer::getCaptureCompare(uint32_t channel, TimerCompareFormat_
12051205
case HERTZ_COMPARE_FORMAT:
12061206
return_value = (uint32_t)(getTimerClkFreq() / (CCR_RegisterValue * Prescalerfactor));
12071207
break;
1208+
// As per Reference Manual PWM reach 100% with CCRx value strictly greater than ARR
1209+
// (So ARR+1 in our case). Use the same ARR+1 "full scale" as setCaptureCompare()
1210+
// so that get/set are consistent, and to avoid a divide by zero when ARR is 0.
12081211
case PERCENT_COMPARE_FORMAT:
1209-
return_value = (CCR_RegisterValue * 100) / LL_TIM_GetAutoReload(_timerObj.instance);
1212+
return_value = (CCR_RegisterValue * 100) / (LL_TIM_GetAutoReload(_timerObj.instance) + 1);
12101213
break;
12111214
case RESOLUTION_1B_COMPARE_FORMAT:
12121215
case RESOLUTION_2B_COMPARE_FORMAT:
@@ -1224,7 +1227,7 @@ uint32_t HardwareTimer::getCaptureCompare(uint32_t channel, TimerCompareFormat_
12241227
case RESOLUTION_14B_COMPARE_FORMAT:
12251228
case RESOLUTION_15B_COMPARE_FORMAT:
12261229
case RESOLUTION_16B_COMPARE_FORMAT:
1227-
return_value = (CCR_RegisterValue * ((1 << format) - 1)) / LL_TIM_GetAutoReload(_timerObj.instance);
1230+
return_value = (CCR_RegisterValue * ((1 << format) - 1)) / (LL_TIM_GetAutoReload(_timerObj.instance) + 1);
12281231
break;
12291232
case TICK_COMPARE_FORMAT:
12301233
default :

0 commit comments

Comments
 (0)