2022-10-31 03:33 PM
I'm using the STM32H735 to create a sequence of PWM signals. I have timers TIM1, TIM2, TIM4, and TIM24 all connected in a slave timer chain. TIM1 triggers TIM2 with ITR0. TIM2 triggers TIM4 with ITR1, and TIM4 triggers TIM24 with ITR3. Each link in the trigger chain is done with a timer channel in "Output Compare no Output" mode setup as the TRGO event. These are the slave modes in the chain:
TIM1: disable
TIM2: Trigger Mode (ITR0)
TIM4: Trigger Mode (ITR1)
TIM24: Trigger Mode (ITR3)
This all works perfectly but only the first time. If I stop all 4 timers and try to restart the sequence, only the PWM output from TIM1 starts again. The PWM output from TIM2, TIM4 and TIM24 fails to start.
Here is some pseudo code to show what I have.
The sequence is started with:
// TIMER 24
HAL_TIM_Base_Start(&htim24);
HAL_TIM_PWM_Start(&htim24, TIM_CHANNEL_4);
// TIMER 4
HAL_TIM_Base_Start(&htim4);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3);
HAL_TIM_OC_Start(&htim4, TIM_CHANNEL_2);
// TIMER 2
HAL_TIM_Base_Start(&htim2);
HAL_TIM_OC_Start(&htim2, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4);
// TIMER 1
HAL_TIM_Base_Start(&htim1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_2);
The sequence is then stopped with:
// TIMER 1
HAL_TIM_Base_Stop(&htim1);
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_2);
// TIMER 2
HAL_TIM_Base_Stop(&htim2);
HAL_TIM_OC_Stop(&htim2, TIM_CHANNEL_3);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_4);
// TIMER 4
HAL_TIM_Base_Stop(&htim4);
HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_3);
HAL_TIM_OC_Stop(&htim4, TIM_CHANNEL_2);
// TIMER 24
HAL_TIM_Base_Stop(&htim24);
HAL_TIM_PWM_Stop(&htim24, TIM_CHANNEL_4);
After the stop code the all 4 PWM signals stop. When the start code is run again, only TIM1_CH1 has PWM output. I suspect there needs to be a manual reset of the Internal Trigger connections for TIM2, TIM4 and TIM24 but I don't see anything for this in the HAL. Does anyone know what's required to reset the timers in this situation? Thanks in advance.
2024-11-25 02:57 AM
Dear@waclawek.jan ,
First of all, thank you for taking the time to answer my questions, I sincerely appreciate it.
Secondly, my question is not regarding the usage of HALs, but more of a function question - getting my head around the resetting of the OCxREF signal when set to "active level on match":
If I were to set "active level on match" for a certain timer's output compare channel, then I would expect that upon stopping the timer there should be a way to reset the OCxREF signal, but I couldn't find any. Can you advise on the proper way to reset the timer so that when I reactivate it the next time, the OCxREF signal will generate a positive edge on match again?
Thanks again for the help,
BA
2024-11-25 04:13 AM
In microcontrollers, there's never one single "proper" way to do things; everything is context-dependent and there are myriads of combinations of circumstances and settings.
One way to clear OCxREF is to set TIMx.CCMRx.OCxM=0b100 for Force inactive level.
(A nice exercise for this is to write the basic loopdelay blinky by replacing GPIO Out toggling by alternately setting a TIMx_CHx pin using the Force Inactive and Force Active).
JW
2024-11-28 11:58 AM
Thank you for the assistance @waclawek.jan , going to Force Inactive Level and then going back to Active On Match solved the entire issue.
Another thing that I have noticed is that if I want to maintain the synchronization between channels, then I would have to force an update by setting the UG flag prior to reinitializing the timers.
Thanks again!
BA