Skip to content

HardwareTimer incomplete? #763

Closed
@HendryKaak

Description

@HendryKaak

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:

#define __HAL_TIM_DISABLE(__HANDLE__) \
do { \
if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL) \
{ \
if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \
{ \
(__HANDLE__)->Instance->CR1 &= ~(TIM_CR1_CEN); \
} \
} \
} while(0)

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.

/**
* @brief Pause HardwareTimer: stop timer
* @param None
* @retval None
*/
void HardwareTimer::pause()
{
HAL_TIM_Base_Stop_IT(&(_timerObj.handle));
}

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() and resume(). 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?

Metadata

Metadata

Assignees

Labels

bug 🐛Something isn't workingenhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions