STM32G4 Problem restarting Slave Timers after the "TRGO" (OC3_REF) event on the Master Timer
Hello! How are you?
I'm having trouble again with the "TRGO" trigger event on the Master and Slave Timers. I need multi-channel PWM, but Timer 1 (the Master) and Timer 2 (which simply starts simultaneously with Timer 1) generate PWM with a single (initial) phase, and each timer operates on two PWM channel outputs. However, Slave Timers 15 and 3 should start generating PWM on their outputs (each timer uses two PWM channels) with some delay. This delay is provided by Timer Master 1 on its "TRGO" output, and I'm using the "OC3_REF" channel for this. Please see the diagram for this multi-channel PWM operation. Everything works perfectly, as expected, but only until all the specified Timers are stopped and then restarted. After that, Slave Timers 15 and 3 stop starting (see the screenshot of the oscilloscope display of all PWM channels for these Timers). I'll now provide the code for starting and stopping these Timers. There's a lot of code, so this is the most important part for now. I've already thoroughly reviewed the initial setup code for the Timers, and it no longer contains any problems, in my opinion. I've converted it to work directly with registers (not HAL), and everything works the same. I'll also provide the stop code in detail for now, since I believe the problem lies there. Please help. If you need any other code, I'll provide that, too. Thank you.
while (1)
{
Start_MultiPWM();
HAL_Delay(8000);
Stop_MultiPWM();
HAL_Delay(4000);
}void Start_MultiPWM(void)
{
/* Setting up registers for Timers (exactly the same as for "HAL") */
SetupTimers(TIM3);
SetupTimers(TIM15);
SetupTimers(TIM2);
SetupTimers(TIM1);
/* For compatibility with "HAL" these structures also need to be initialized */
{
htim1.Instance = TIM1;
htim1.DMABurstState = HAL_DMA_BURST_STATE_READY;
TIM_CHANNEL_STATE_SET_ALL(&htim1, HAL_TIM_CHANNEL_STATE_READY);
TIM_CHANNEL_N_STATE_SET_ALL(&htim1, HAL_TIM_CHANNEL_STATE_READY);
htim1.State = HAL_TIM_STATE_READY;
htim2.Instance = TIM2;
htim2.DMABurstState = HAL_DMA_BURST_STATE_READY;
TIM_CHANNEL_STATE_SET_ALL(&htim2, HAL_TIM_CHANNEL_STATE_READY);
TIM_CHANNEL_N_STATE_SET_ALL(&htim2, HAL_TIM_CHANNEL_STATE_READY);
htim2.State = HAL_TIM_STATE_READY;
htim3.Instance = TIM3;
htim3.DMABurstState = HAL_DMA_BURST_STATE_READY;
TIM_CHANNEL_STATE_SET_ALL(&htim3, HAL_TIM_CHANNEL_STATE_READY);
TIM_CHANNEL_N_STATE_SET_ALL(&htim3, HAL_TIM_CHANNEL_STATE_READY);
htim3.State = HAL_TIM_STATE_READY;
htim15.Instance = TIM15;
htim15.DMABurstState = HAL_DMA_BURST_STATE_READY;
TIM_CHANNEL_STATE_SET_ALL(&htim15, HAL_TIM_CHANNEL_STATE_READY);
TIM_CHANNEL_N_STATE_SET_ALL(&htim15, HAL_TIM_CHANNEL_STATE_READY);
htim15.State = HAL_TIM_STATE_READY;
}
__attribute__((unused)) HAL_StatusTypeDef res;
/* Enable interrupts for TIM2 (we will use them to change duty cycle of its PWMs CH3 and CH4) */
res = HAL_TIM_Base_Start_IT(&htim2);
/* Enable interrupts for TIM3 (we will use them to change duty cycle of its PWMs CH3 and CH4) */
res = HAL_TIM_Base_Start_IT(&htim3);
/* Launch the PWM channels of the TIM15 Slave Timer (50 Hz, CH1 and CH1N) */
res = HAL_TIM_PWM_Start(&htim15, TIM_CHANNEL_1);
res = HAL_TIMEx_PWMN_Start(&htim15, TIM_CHANNEL_1);
/* Enable the corresponding channels for PWM 48kHz TIM3 (Slave for TIM1) */
res = HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
res = HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);
HAL_Delay(50);
/* Launch the PWM channels TIM1 (50 Hz, CH1 and CH1N) */
res = HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
res = HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
HAL_Delay(50);
/* Start TIM1_OC3REF and this, after the required phase shift, will start TIM15 and TIM3 */
res = HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_3);
/* Enable the corresponding channels for PWM 48kHz TIM2 */
res = HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);
res = HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4);
__NOP();
}
void Stop_MultiPWM(void)
{
FullTimerReset(TIM2);
FullTimerReset(TIM3);
FullTimerReset(TIM15);
HAL_Delay(50);
FullTimerReset(TIM1);
TIM1->EGR = TIM_EGR_CC3G;
TIM1->SR = 0;
__HAL_RCC_TIM1_CLK_DISABLE();
__HAL_RCC_TIM2_CLK_DISABLE();
__HAL_RCC_TIM3_CLK_DISABLE();
__HAL_RCC_TIM15_CLK_DISABLE();
HAL_NVIC_DisableIRQ(TIM2_IRQn);
HAL_NVIC_DisableIRQ(TIM3_IRQn);
memset(&htim1, 0x00, sizeof(TIM_HandleTypeDef));
memset(&htim2, 0x00, sizeof(TIM_HandleTypeDef));
memset(&htim3, 0x00, sizeof(TIM_HandleTypeDef));
memset(&htim15, 0x00, sizeof(TIM_HandleTypeDef));
tim2_index = 0;
tim3_index = 0;
tim2_bottom = 0;
tim3_bottom = 0;
}
