cancel
Showing results for 
Search instead for 
Did you mean: 

How do I restart a timer in one pulse mode after its overflow?

PB1
Associate III

Maybe I am naive, but last year this code worked and now it doesn't...

I have this small lab experience where I manually implement PWM to control the brightness of the LEDs on a Nucleo F767ZI board. My idea was: let's ensure that the switching of the LEDs is synchronized with the overflow of the PWM timer (TIM6 to be precise) by setting the timer in one pulse mode, and restarting the timer in the period elapsed callback, after having switched the LEDs. The code of the callback is something like this:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {

   if (htim->Instance == TIM6) {

      PWM_status_high = /*alternatively true or false*/;

      HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin|LD2_Pin, (PWM_status_high ?

            GPIO_PIN_SET : GPIO_PIN_RESET));

      htim->Instance->ARR = (PWM_status_high ? PWM_high_semiperiod : (PWM_MAX -

            PWM_high_semiperiod));

      HAL_TIM_Base_Start_IT(htim);

   }

}

The problem is, the last call to HAL_TIM_Base_Start_IT fails because the timer is in state HAL_TIM_STATE_BUSY when invoked. As I said, the same code one year ago worked.

Can you spot what I am doing wrong? If my mistake is not immediately apparent tell me and I will post the STM32CubeIDE project. Of course I accept advices about possibly better approaches than mine.

Best,

Pietro

3 REPLIES 3
TDK
Guru

There appears to have been a change to HAL_TIM_Base_Start_IT in recent versions.

It now checks the state:

https://github.com/STMicroelectronics/STM32CubeF7/blob/f8cefdf02e8ad7fd06bd38a2dd85a55ecdbe92a9/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim.c#L469

whereas before it did not:

https://github.com/STMicroelectronics/STM32CubeF7/blob/79acbf8ec060d3ec751f2eaba6ee050269995357/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim.c#L439

To avoid, just set the state to ready before the call. Or just enable the timer yourself by setting the CEN bit.

Another good reason not to upgrade libraries unless absolutely necessary.

If you feel a post has answered your question, please click "Accept as Solution".
PB1
Associate III

Thank you for the quick answer. Unfortunately not upgrading libraries is not an option for me: Since I am using the Nucleo boards for teaching a course, every year the students download and install the STM32CubeIDE from scratch, and the IDE in turns fetches the latest version of the libraries. Also, in my opinion not upgrading the libraries means assuming that who produces them will regress, rather than progress them. Quite the opposite should be the case: With the passing of time well-maintained libraries should have less and less defects, and occasional breakage of interfaces because of stricter checks, in my context, is a price I am willing to pay for a better quality of software.

This said, my fault: I forgot that last year I already had a similar issue and I solved it by adding the following user code to MX_TIM6_Init:

 if (HAL_TIM_OnePulse_Init(&htim6, TIM_OPMODE_REPETITIVE) != HAL_OK)

   {

       Error_Handler();

   }

Apparently the HAL always initializes one-pulse timers with TIM_OPMODE_SINGLE, so my workaround was re-initializing it manually with TIM_OPMODE_REPETITIVE.

Thank you again

Pietro

In your use case, I agree it makes sense to use the latest library version. The libraries do get better in general with the occasional regression.

Thanks for replying with the solution.

If you feel a post has answered your question, please click "Accept as Solution".