Skip to content

Timer not enabled when using only CC Interrupts #1544

Closed
@fjulian79

Description

@fjulian79

Hi!

When using only CC interrupts callbacks on a timer, the timer is not started by resume() if there has no OV interrupt callback been added.

My example code to reproduce the issue:

pTimer->setPrescaleFactor(prescaler);
// using TIMER_DISABLED here as suggested when only interested in the interrupt
pTimer->setMode(ch, TIMER_DISABLED);
pTimer->setOverflow(UINT16_MAX);
pTimer->attachInterrupt(ch, cc_callback); 
pTimer->setCaptureCompare(ch, value);
pTimer->setCount(0);
// remove the following line and the timer will not be started, leave it as it is and will work fine.
pTimer->attachInterrupt(ov_callback);
pTimer->resume();

I have debugged this using STLink and VSCode, when resume() is done the CE Bit in TimX_CR1 should be set but it isn't when the ov_callback has not been registered.

The problem seems to be in resume:

void HardwareTimer::resume(void)
{
  // callbacks[0] is not set if no OV callback has been added 
  if (callbacks[0]) {
    __HAL_TIM_CLEAR_FLAG(&(_timerObj.handle), TIM_FLAG_UPDATE);
    __HAL_TIM_ENABLE_IT(&(_timerObj.handle), TIM_IT_UPDATE);

    // never reached when callbacks[0] is unset.
    HAL_TIM_Base_Start(&(_timerObj.handle));
  }

  resumeChannel(1);
  resumeChannel(2);
  resumeChannel(3);
  resumeChannel(4);
}

When HAL_TIM_Base_Start() is not executed no one else sets the CE bit so the timer get' just not started at all. For a quick test I have moved HAL_TIM_Base_Start(...) out of the if condition. This works fine just fine .. at least in this particular use case.

Expected behavior
The following code should work:

pTimer->setPrescaleFactor(prescaler);
pTimer->setMode(ch, TIMER_DISABLED);
pTimer->setOverflow(UINT16_MAX);
pTimer->attachInterrupt(ch, cc_callback); 
pTimer->setCaptureCompare(ch, value);
pTimer->setCount(0);
pTimer->resume();

My Usecase:
I need up to 4 timer interrupts related to the same time base but don't need a OV callback as the code can handle wrap arounds. I have seen others using only the OV interrupt in such use cases but then it is not possible to have 4 different interrupts by just using one timer unit.

So at least for now I have not found a flaw in my basic design. Beside of that the HW is able to get this done. I also have searched for infos on possible restrictions in case of interrupt only scenarios, but haven't found any hints.

Details on my Setup:

  • PlatformIO with VSCode IDE on MacOS, i see no host relation at all.
  • STM32 Nucleo F446RE
  • Using Arduino_Code_STM32 Version 2.1.0
  • Uploading the Firmware with STLink, i see no impact of this.

Br J.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions