Description
Hey,
I've been struggling with the implementation of the current HardwareTimer
class with a custom stm32f401 board and would like to share a few points that caused some problems here and there.
What i've been trying to do is using the HardwareTimer class to setup a PWM output for a buzzer and used a specific timer channel to do so. But the first problem I encountered was that the timer or channel was not disabled when the Pause()
function is called. Looking at the code I found out that in the HAL stm32f4xx_hal_tim.h
, the timer would only be disabled when all timer channels are disabled:
Arduino_Core_STM32/system/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h
Lines 1022 to 1031 in 1e2a598
So disabling the timer never happens because the HAL_TIM_OC_Stop
macro is never called with the correct timer channel in the pause()
function.
Arduino_Core_STM32/cores/arduino/HardwareTimer.cpp
Lines 101 to 109 in 1e2a598
Only the interrupts are being stopped over there as you can see, but never the channel itself and thus the timer is never stopped.
To resolve this:
- At least give the option to disable a timer channel, but leave the timer enabled when another Input Capture/Output Capture channel is still in use, so that concurrent channel can be used.
- It would probably be a good idea to be able to disable independent channels in place of enabling all of the channels at once (also for concurrent timer channel usage).
- I also wonder about the purpose of
pause()
andresume()
. Essentially, these functions really stop/disable and start/enable the timer, where pause would suggest it just stops the timer without reconfiguring anything (in particular, I would not expect pause to change the current pin output), Perhaps these functions should be renamed and/or better documented? Maybe real pause/resume methods should be added?
Another thing that I found questionable is the setMode()
function. AFAIK is that the channels modes are first stored in RAM, but only written to registers when resume()
is called. This means that the only way to change a channel's configuration is by restarting the timer. It might be feasible to sometimes reconfigure a channel while the timer is running (an obvious usecase is to disable or re-enable a single channel without affecting the others, but also changing other setttings on the fly would make sense). Maybe setMode should just apply the changes directly? As long as the timer is disabled, there should be no harm in applying the channel settings, I believe?