@@ -123,7 +123,7 @@ void HardwareTimer::setup(TIM_TypeDef *instance)
123
123
// Initialize channel mode and complementary
124
124
for (int i = 0 ; i < TIMER_CHANNELS; i++) {
125
125
__ChannelsUsed[i] = 0x00 ;
126
- _ChannelMode[i] = TIMER_DISABLED ;
126
+ _ChannelMode[i] = TIMER_OUTPUT_DISABLED ;
127
127
}
128
128
129
129
/* Configure timer with some default values */
@@ -181,9 +181,9 @@ void HardwareTimer::pauseChannel(uint32_t channel)
181
181
return ;
182
182
}
183
183
184
- int timAssociatedInputChannel;
185
- int LLChannel = getLLChannel (channel);
186
- int interrupt = getIT (channel);
184
+ uint32_t timAssociatedInputChannel;
185
+ uint32_t LLChannel = getLLChannel (channel);
186
+ uint32_t interrupt = getIT (channel);
187
187
188
188
// Disable channel and corresponding interrupt
189
189
__HAL_TIM_DISABLE_IT (&(_timerObj.handle ), interrupt);
@@ -217,144 +217,147 @@ void HardwareTimer::pauseChannel(uint32_t channel)
217
217
*/
218
218
void HardwareTimer::resume (void )
219
219
{
220
+ bool baseStart = true ;
221
+ for (uint8_t i = 1 ; i <= TIMER_CHANNELS; i++) {
222
+ if (_ChannelMode[i - 1 ] != TIMER_OUTPUT_DISABLED) {
223
+ resumeChannel (i);
224
+ baseStart = false ;
225
+ }
226
+ }
220
227
// Clear flag and enable IT
221
228
if (callbacks[0 ]) {
222
229
__HAL_TIM_CLEAR_FLAG (&(_timerObj.handle ), TIM_FLAG_UPDATE);
223
230
__HAL_TIM_ENABLE_IT (&(_timerObj.handle ), TIM_IT_UPDATE);
231
+ }
224
232
225
- // Start timer in Time base mode. Required when there is no channel used but only update interrupt.
233
+ // Start timer in Time base mode. Required when there is no channel used but only update interrupt.
234
+ if (baseStart && (!LL_TIM_IsEnabledCounter (_timerObj.handle .Instance ))) {
226
235
HAL_TIM_Base_Start (&(_timerObj.handle ));
227
236
}
228
-
229
- // Resume all channels
230
- resumeChannel (1 );
231
- resumeChannel (2 );
232
- resumeChannel (3 );
233
- resumeChannel (4 );
234
237
}
235
238
236
239
/* *
237
240
* @brief Convert arduino channel into HAL channel
238
241
* @param Arduino channel [1..4]
239
242
* @retval HAL channel. Error handler called if arduino channel is invalid
240
243
*/
241
- int HardwareTimer::getChannel (uint32_t channel)
244
+ uint32_t HardwareTimer::getChannel (uint32_t channel)
242
245
{
243
- int return_value = -1 ;
246
+ uint32_t timChannel = -1 ;
244
247
245
248
switch (channel) {
246
249
case 1 :
247
- return_value = TIM_CHANNEL_1;
250
+ timChannel = TIM_CHANNEL_1;
248
251
break ;
249
252
case 2 :
250
- return_value = TIM_CHANNEL_2;
253
+ timChannel = TIM_CHANNEL_2;
251
254
break ;
252
255
case 3 :
253
- return_value = TIM_CHANNEL_3;
256
+ timChannel = TIM_CHANNEL_3;
254
257
break ;
255
258
case 4 :
256
- return_value = TIM_CHANNEL_4;
259
+ timChannel = TIM_CHANNEL_4;
257
260
break ;
258
261
default :
259
262
Error_Handler ();
260
263
}
261
- return return_value ;
264
+ return timChannel ;
262
265
}
263
266
264
267
/* *
265
268
* @brief Convert arduino channel into LL channels used (regular and/or complementary)
266
269
* @param Arduino channel [1..4]
267
270
* @retval LL channel. Error handler called if arduino channel is invalid
268
271
*/
269
- int HardwareTimer::getLLChannel (uint32_t channel)
272
+ uint32_t HardwareTimer::getLLChannel (uint32_t channel)
270
273
{
271
- int return_value = 0 ;
274
+ bool error = false ;
275
+ uint32_t ll_channel = 0 ;
272
276
273
277
#if defined(TIM_CCER_CC1NE)
274
278
if (__ChannelsUsed[channel - 1 ] & COMPLEMENTARY_CHAN_MASK) {
275
279
// Complementary channel
276
280
switch (channel) {
277
281
case 1 :
278
- return_value = LL_TIM_CHANNEL_CH1N;
282
+ ll_channel = LL_TIM_CHANNEL_CH1N;
279
283
break ;
280
284
case 2 :
281
- return_value = LL_TIM_CHANNEL_CH2N;
285
+ ll_channel = LL_TIM_CHANNEL_CH2N;
282
286
break ;
283
287
case 3 :
284
- return_value = LL_TIM_CHANNEL_CH3N;
288
+ ll_channel = LL_TIM_CHANNEL_CH3N;
285
289
break ;
286
290
#if defined(LL_TIM_CHANNEL_CH4N)
287
291
case 4 :
288
- return_value = LL_TIM_CHANNEL_CH4N;
292
+ ll_channel = LL_TIM_CHANNEL_CH4N;
289
293
break ;
290
294
#endif
291
295
default :
292
- return_value = - 1 ;
296
+ error = true ;
293
297
}
294
298
}
295
299
#endif
296
- if ((return_value != - 1 ) && (__ChannelsUsed[channel - 1 ] & REGULAR_CHAN_MASK)) {
300
+ if ((!error ) && (__ChannelsUsed[channel - 1 ] & REGULAR_CHAN_MASK)) {
297
301
// Regular channel not complementary
298
302
switch (channel) {
299
303
case 1 :
300
- return_value |= LL_TIM_CHANNEL_CH1;
304
+ ll_channel |= LL_TIM_CHANNEL_CH1;
301
305
break ;
302
306
case 2 :
303
- return_value |= LL_TIM_CHANNEL_CH2;
307
+ ll_channel |= LL_TIM_CHANNEL_CH2;
304
308
break ;
305
309
case 3 :
306
- return_value |= LL_TIM_CHANNEL_CH3;
310
+ ll_channel |= LL_TIM_CHANNEL_CH3;
307
311
break ;
308
312
case 4 :
309
- return_value |= LL_TIM_CHANNEL_CH4;
313
+ ll_channel |= LL_TIM_CHANNEL_CH4;
310
314
break ;
311
315
default :
312
- return_value = - 1 ;
316
+ error = true ;
313
317
}
314
318
}
315
- if (return_value == - 1 ) {
319
+ if (error ) {
316
320
Error_Handler ();
317
321
}
318
- return return_value ;
322
+ return ll_channel ;
319
323
}
320
324
321
325
/* *
322
326
* @brief Convert arduino channel into HAL Interrupt ID
323
327
* @param Arduino channel [1..4]
324
328
* @retval HAL channel. Error handler called if arduino channel is invalid
325
329
*/
326
- int HardwareTimer::getIT (uint32_t channel)
330
+ uint32_t HardwareTimer::getIT (uint32_t channel)
327
331
{
328
- int return_value = -1 ;
329
-
332
+ uint32_t interrupt = 0 ;
330
333
switch (channel) {
331
334
case 1 :
332
- return_value = TIM_IT_CC1;
335
+ interrupt = TIM_IT_CC1;
333
336
break ;
334
337
case 2 :
335
- return_value = TIM_IT_CC2;
338
+ interrupt = TIM_IT_CC2;
336
339
break ;
337
340
case 3 :
338
- return_value = TIM_IT_CC3;
341
+ interrupt = TIM_IT_CC3;
339
342
break ;
340
343
case 4 :
341
- return_value = TIM_IT_CC4;
344
+ interrupt = TIM_IT_CC4;
342
345
break ;
343
346
default :
344
347
Error_Handler ();
345
348
}
346
- return return_value ;
349
+ return interrupt ;
347
350
}
348
351
349
352
/* *
350
353
* @brief Get input associated channel
351
354
* Channel 1 and 2 are associated; channel 3 and 4 are associated
352
355
* @param Arduino channel [1..4]
353
- * @retval HAL channel. return -1 if arduino channel is invalid
356
+ * @retval HAL channel. Error handler called if arduino channel is invalid
354
357
*/
355
- int HardwareTimer::getAssociatedChannel (uint32_t channel)
358
+ uint32_t HardwareTimer::getAssociatedChannel (uint32_t channel)
356
359
{
357
- int timAssociatedInputChannel = - 1 ;
360
+ uint32_t timAssociatedInputChannel = 0 ;
358
361
switch (channel) {
359
362
case 1 :
360
363
timAssociatedInputChannel = 2 ;
@@ -369,6 +372,7 @@ int HardwareTimer::getAssociatedChannel(uint32_t channel)
369
372
timAssociatedInputChannel = 3 ;
370
373
break ;
371
374
default :
375
+ Error_Handler ();
372
376
break ;
373
377
}
374
378
return timAssociatedInputChannel;
@@ -381,9 +385,9 @@ int HardwareTimer::getAssociatedChannel(uint32_t channel)
381
385
*/
382
386
void HardwareTimer::resumeChannel (uint32_t channel)
383
387
{
384
- int timChannel = getChannel (channel);
385
- int timAssociatedInputChannel;
386
- int interrupt = getIT (channel);
388
+ uint32_t timChannel = getChannel (channel);
389
+ uint32_t timAssociatedInputChannel;
390
+ uint32_t interrupt = getIT (channel);
387
391
388
392
// Clear flag and enable IT
389
393
if (callbacks[channel]) {
@@ -437,8 +441,7 @@ void HardwareTimer::resumeChannel(uint32_t channel)
437
441
HAL_TIM_IC_Start (&(_timerObj.handle ), timChannel);
438
442
}
439
443
break ;
440
- case TIMER_OUTPUT_COMPARE:
441
- case TIMER_DISABLED:
444
+ case TIMER_OUTPUT_DISABLED:
442
445
if (!LL_TIM_IsEnabledCounter (_timerObj.handle .Instance )) {
443
446
HAL_TIM_Base_Start (&(_timerObj.handle ));
444
447
}
@@ -631,8 +634,8 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, uint32_t pin, C
631
634
*/
632
635
void HardwareTimer::setMode (uint32_t channel, TimerModes_t mode, PinName pin, ChannelInputFilter_t filter)
633
636
{
634
- int timChannel = getChannel (channel);
635
- int timAssociatedInputChannel;
637
+ uint32_t timChannel = getChannel (channel);
638
+ uint32_t timAssociatedInputChannel;
636
639
TIM_OC_InitTypeDef channelOC;
637
640
TIM_IC_InitTypeDef channelIC;
638
641
@@ -656,21 +659,10 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin, Ch
656
659
channelIC.ICFilter = filter;
657
660
658
661
switch (mode) {
659
- case TIMER_DISABLED :
662
+ case TIMER_OUTPUT_DISABLED :
660
663
channelOC.OCMode = TIM_OCMODE_TIMING;
661
664
HAL_TIM_OC_ConfigChannel (&(_timerObj.handle ), &channelOC, timChannel);
662
665
break ;
663
- case TIMER_OUTPUT_COMPARE:
664
- /* In case of TIMER_OUTPUT_COMPARE, there is no output and thus no pin to
665
- * configure, and no channel. So nothing to do. For compatibility reason
666
- * restore TIMER_DISABLED if necessary.
667
- */
668
- if (_ChannelMode[channel - 1 ] != TIMER_DISABLED) {
669
- _ChannelMode[channel - 1 ] = TIMER_DISABLED;
670
- channelOC.OCMode = TIM_OCMODE_TIMING;
671
- HAL_TIM_OC_ConfigChannel (&(_timerObj.handle ), &channelOC, timChannel);
672
- }
673
- return ;
674
666
case TIMER_OUTPUT_COMPARE_ACTIVE:
675
667
channelOC.OCMode = TIM_OCMODE_ACTIVE;
676
668
HAL_TIM_OC_ConfigChannel (&(_timerObj.handle ), &channelOC, timChannel);
@@ -737,24 +729,25 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin, Ch
737
729
738
730
// Save channel selected mode to object attribute
739
731
_ChannelMode[channel - 1 ] = mode;
740
-
741
- if (pin != NC) {
742
- if (( int ) getTimerChannel (pin) == timChannel) {
743
- /* Configure PWM GPIO pins */
744
- pinmap_pinout (pin, PinMap_TIM);
732
+ if (mode != TIMER_OUTPUT_DISABLED) {
733
+ if (pin != NC) {
734
+ if (getTimerChannel (pin) == timChannel) {
735
+ /* Configure PWM GPIO pins */
736
+ pinmap_pinout (pin, PinMap_TIM);
745
737
#if defined(STM32F1xx)
746
- if ((mode == TIMER_INPUT_CAPTURE_RISING) || (mode == TIMER_INPUT_CAPTURE_FALLING) \
747
- || (mode == TIMER_INPUT_CAPTURE_BOTHEDGE) || (mode == TIMER_INPUT_FREQ_DUTY_MEASUREMENT)) {
748
- // on F1 family, input alternate function must configure GPIO in input mode
749
- pinMode (pinNametoDigitalPin (pin), INPUT);
750
- }
738
+ if ((mode == TIMER_INPUT_CAPTURE_RISING) || (mode == TIMER_INPUT_CAPTURE_FALLING) \
739
+ || (mode == TIMER_INPUT_CAPTURE_BOTHEDGE) || (mode == TIMER_INPUT_FREQ_DUTY_MEASUREMENT)) {
740
+ // on F1 family, input alternate function must configure GPIO in input mode
741
+ pinMode (pinNametoDigitalPin (pin), INPUT);
742
+ }
751
743
#endif
752
- } else {
753
- // Pin doesn't match with timer output channels
754
- Error_Handler ();
755
- }
744
+ } else {
745
+ // Pin doesn't match with timer output channels
746
+ Error_Handler ();
747
+ }
756
748
757
- __ChannelsUsed[channel - 1 ] |= (STM_PIN_INVERTED (pinmap_function (pin, PinMap_TIM))) ? COMPLEMENTARY_CHAN_MASK : REGULAR_CHAN_MASK;
749
+ __ChannelsUsed[channel - 1 ] |= (STM_PIN_INVERTED (pinmap_function (pin, PinMap_TIM))) ? COMPLEMENTARY_CHAN_MASK : REGULAR_CHAN_MASK;
750
+ }
758
751
}
759
752
}
760
753
@@ -765,11 +758,7 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin, Ch
765
758
*/
766
759
TimerModes_t HardwareTimer::getMode (uint32_t channel)
767
760
{
768
- if ((1 <= channel) && (channel <= TIMER_CHANNELS)) {
769
- return _ChannelMode[channel - 1 ];
770
- } else {
771
- return TIMER_DISABLED;
772
- }
761
+ return ((1 <= channel) && (channel <= TIMER_CHANNELS)) ? _ChannelMode[channel - 1 ] : TIMER_OUTPUT_DISABLED;
773
762
}
774
763
775
764
/* *
@@ -807,7 +796,7 @@ void HardwareTimer::setPreloadEnable(bool value)
807
796
*/
808
797
void HardwareTimer::setCaptureCompare (uint32_t channel, uint32_t compare, TimerCompareFormat_t format)
809
798
{
810
- int timChannel = getChannel (channel);
799
+ uint32_t timChannel = getChannel (channel);
811
800
uint32_t Prescalerfactor = LL_TIM_GetPrescaler (_timerObj.handle .Instance ) + 1 ;
812
801
uint32_t CCR_RegisterValue;
813
802
@@ -869,7 +858,7 @@ void HardwareTimer::setCaptureCompare(uint32_t channel, uint32_t compare, TimerC
869
858
*/
870
859
uint32_t HardwareTimer::getCaptureCompare (uint32_t channel, TimerCompareFormat_t format)
871
860
{
872
- int timChannel = getChannel (channel);
861
+ uint32_t timChannel = getChannel (channel);
873
862
uint32_t CCR_RegisterValue = __HAL_TIM_GET_COMPARE (&(_timerObj.handle ), timChannel);
874
863
uint32_t Prescalerfactor = LL_TIM_GetPrescaler (_timerObj.handle .Instance ) + 1 ;
875
864
uint32_t return_value;
@@ -936,7 +925,10 @@ void HardwareTimer::setPWM(uint32_t channel, uint32_t pin, uint32_t frequency, u
936
925
*/
937
926
void HardwareTimer::setPWM (uint32_t channel, PinName pin, uint32_t frequency, uint32_t dutycycle, callback_function_t PeriodCallback, callback_function_t CompareCallback)
938
927
{
939
- setMode (channel, TIMER_OUTPUT_COMPARE_PWM1, pin);
928
+ TimerModes_t previousMode = getMode (channel);
929
+ if (previousMode != TIMER_OUTPUT_COMPARE_PWM1) {
930
+ setMode (channel, TIMER_OUTPUT_COMPARE_PWM1, pin);
931
+ }
940
932
setOverflow (frequency, HERTZ_FORMAT);
941
933
setCaptureCompare (channel, dutycycle, PERCENT_COMPARE_FORMAT);
942
934
if (PeriodCallback) {
@@ -945,7 +937,9 @@ void HardwareTimer::setPWM(uint32_t channel, PinName pin, uint32_t frequency, ui
945
937
if (CompareCallback) {
946
938
attachInterrupt (channel, CompareCallback);
947
939
}
948
- resume ();
940
+ if (previousMode != TIMER_OUTPUT_COMPARE_PWM1) {
941
+ resume ();
942
+ }
949
943
}
950
944
951
945
/* *
@@ -1010,7 +1004,7 @@ void HardwareTimer::detachInterrupt()
1010
1004
*/
1011
1005
void HardwareTimer::attachInterrupt (uint32_t channel, callback_function_t callback)
1012
1006
{
1013
- int interrupt = getIT (channel);
1007
+ uint32_t interrupt = getIT (channel);
1014
1008
1015
1009
if ((channel == 0 ) || (channel > (TIMER_CHANNELS + 1 ))) {
1016
1010
Error_Handler (); // only channel 1..4 have an interrupt
@@ -1036,7 +1030,7 @@ void HardwareTimer::attachInterrupt(uint32_t channel, callback_function_t callba
1036
1030
*/
1037
1031
void HardwareTimer::detachInterrupt (uint32_t channel)
1038
1032
{
1039
- int interrupt = getIT (channel);
1033
+ uint32_t interrupt = getIT (channel);
1040
1034
1041
1035
if ((channel == 0 ) || (channel > (TIMER_CHANNELS + 1 ))) {
1042
1036
Error_Handler (); // only channel 1..4 have an interrupt
@@ -1169,14 +1163,14 @@ bool HardwareTimer::isRunning()
1169
1163
*/
1170
1164
bool HardwareTimer::isRunningChannel (uint32_t channel)
1171
1165
{
1172
- int LLChannel = getLLChannel (channel);
1173
- int interrupt = getIT (channel);
1166
+ uint32_t LLChannel = getLLChannel (channel);
1167
+ uint32_t interrupt = getIT (channel);
1174
1168
bool ret;
1175
1169
1176
1170
// channel is running if: timer is running, and either output channel is
1177
1171
// enabled or interrupt is set
1178
1172
ret = LL_TIM_CC_IsEnabledChannel (_timerObj.handle .Instance , LLChannel)
1179
- || (__HAL_TIM_GET_IT_SOURCE (&(_timerObj.handle ), ( uint32_t ) interrupt) == SET);
1173
+ || (__HAL_TIM_GET_IT_SOURCE (&(_timerObj.handle ), interrupt) == SET);
1180
1174
return (isRunning () && ret);
1181
1175
}
1182
1176
0 commit comments