Skip to content

Commit f8bf924

Browse files
ABOSTMfpistm
authored andcommitted
HardwareTimer: call refresh() after parameter update when timer not running
In case timer is not running, after an update of parameters (setOverflow(), setCaptureCompare(), setPrescaleFactor()), call refresh() to force register update independently of Preload setting. Fixes https://www.stm32duino.com/viewtopic.php?f=7&t=1563 Signed-off-by: Alexandre Bourdiol <[email protected]>
1 parent 0e00a8d commit f8bf924

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

cores/arduino/HardwareTimer.h

+2
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ class HardwareTimer {
151151
static void captureCompareCallback(TIM_HandleTypeDef *htim); // Generic Capture and Compare callback which will call user callback
152152
static void updateCallback(TIM_HandleTypeDef *htim); // Generic Update (rollover) callback which will call user callback
153153

154+
void updateRegistersIfNotRunning(TIM_TypeDef *TIMx); // Take into account registers update immediately if timer is not running,
155+
154156
bool isRunning(); // return true if HardwareTimer is running
155157
bool isRunningChannel(uint32_t channel); // return true if channel is running
156158

libraries/SrcWrapper/src/HardwareTimer.cpp

+30-2
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@ void HardwareTimer::setPrescaleFactor(uint32_t prescaler)
471471
{
472472
// Hardware register correspond to prescaler-1. Example PSC register value 0 means divided by 1
473473
LL_TIM_SetPrescaler(_timerObj.handle.Instance, prescaler - 1);
474+
475+
updateRegistersIfNotRunning(_timerObj.handle.Instance);
474476
}
475477

476478
/**
@@ -550,6 +552,8 @@ void HardwareTimer::setOverflow(uint32_t overflow, TimerFormat_t format)
550552
ARR_RegisterValue = 0;
551553
}
552554
__HAL_TIM_SET_AUTORELOAD(&_timerObj.handle, ARR_RegisterValue);
555+
556+
updateRegistersIfNotRunning(_timerObj.handle.Instance);
553557
}
554558

555559
/**
@@ -640,7 +644,7 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin)
640644

641645
/* Configure some default values. Maybe overwritten later */
642646
channelOC.OCMode = TIMER_NOT_USED;
643-
channelOC.Pulse = __HAL_TIM_GET_COMPARE(&(_timerObj.handle), timChannel); // keep same value already written in hardware <register
647+
channelOC.Pulse = __HAL_TIM_GET_COMPARE(&(_timerObj.handle), timChannel); // keep same value already written in hardware register
644648
channelOC.OCPolarity = TIM_OCPOLARITY_HIGH;
645649
channelOC.OCFastMode = TIM_OCFAST_DISABLE;
646650
#if defined(TIM_CR2_OIS1)
@@ -857,6 +861,8 @@ void HardwareTimer::setCaptureCompare(uint32_t channel, uint32_t compare, TimerC
857861
}
858862

859863
__HAL_TIM_SET_COMPARE(&(_timerObj.handle), timChannel, CCR_RegisterValue);
864+
865+
updateRegistersIfNotRunning(_timerObj.handle.Instance);
860866
}
861867

862868
/**
@@ -1082,7 +1088,8 @@ bool HardwareTimer::hasInterrupt(uint32_t channel)
10821088

10831089
/**
10841090
* @brief Generate an update event to force all registers (Autoreload, prescaler, compare) to be taken into account
1085-
* @note Refresh() can only be called after a 1st call to resume() to be sure timer is initialised.
1091+
* @note @note Refresh() can only be called after timer has been initialized,
1092+
either by calling setup() function or thanks to constructor with TIM instance parameter.
10861093
* It is useful while timer is running after some registers update
10871094
* @retval None
10881095
*/
@@ -1198,6 +1205,27 @@ bool HardwareTimer::isRunningChannel(uint32_t channel)
11981205
return (isRunning() && ret);
11991206
}
12001207

1208+
/**
1209+
* @brief Take into account registers update immediately if timer is not running,
1210+
* (independently from Preload setting)
1211+
* @param TIMx Timer instance
1212+
* @retval None
1213+
*/
1214+
void HardwareTimer::updateRegistersIfNotRunning(TIM_TypeDef *TIMx)
1215+
{
1216+
if (!isRunning()) {
1217+
if (LL_TIM_IsEnabledIT_UPDATE(TIMx)) {
1218+
// prevent Interrupt generation from refresh()
1219+
LL_TIM_DisableIT_UPDATE(TIMx);
1220+
refresh();
1221+
LL_TIM_ClearFlag_UPDATE(TIMx);
1222+
LL_TIM_EnableIT_UPDATE(TIMx);
1223+
} else {
1224+
refresh();
1225+
}
1226+
}
1227+
}
1228+
12011229
/**
12021230
* @brief HardwareTimer destructor
12031231
* @retval None

0 commit comments

Comments
 (0)