Identical PWM output setting behave differently on General and Advanced timer at duty 0
Hi!
The PWM signals are identical and work as normal except when HAL_TIM_PWM_Stop (or HAL_TIM_PWM_Start) is called at duty 0. The Advanced timer work as expected and cause the output PWM to go low, while both PWM signals go low for the General timer.
I've tried reading the RM0440 Reference manual sections "28 Advanced-control timers (TIM1/TIM8/TIM20)" and "30 General purpose timers (TIM15/TIM16/TIM17)", but has found no clear cause of this.
Below are both my configurations and Oscilloskop output for both control signals and output PWM
Advacned timerTIM8 configuration
__HAL_RCC_TIM8_CLK_ENABLE();
htim8.Instance = TIM8;
htim8.Init.Prescaler = PRESCALER_VALUE;
htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
htim8.Init.Period = HAL_PWM_DEFAULT_PERIOD;
htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim8.Init.RepetitionCounter = 0;
htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
TIM8->AF2 = 0;
if (HAL_TIM_PWM_Init(&htim8) != HAL_OK)
{
// Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig)
!= HAL_OK)
{
// Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_1)
!= HAL_OK)
{
// Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0xff;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim8, &sBreakDeadTimeConfig)
!= HAL_OK)
{
// Error_Handler();
}
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**TIM8 GPIO Configuration
PC10 ------> TIM8_CH1N PWM_5_CPU
PA15 ------> TIM8_CH1 PWM_6_CPU
*/
HAL_PWM_TIM8_GPIO_ReInit_PWM(FALSE);
HAL_PWM_TIM8_GPIO_ReInit_PWMN(FALSE);
/* Special handling, always keep PWM running, just enable/disable output pin */
HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_1);
General timer TIM15 configuration:
__HAL_RCC_TIM15_CLK_ENABLE();
htim15.Instance = TIM15;
htim15.Init.Prescaler = PRESCALER_VALUE;
htim15.Init.Period = HAL_PWM_DEFAULT_PERIOD;
htim15.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim15.Init.RepetitionCounter = 0;
htim15.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim15) != HAL_OK)
{
// Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim15, &sMasterConfig)
!= HAL_OK)
{
// Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
/* Use HIGH polarity, different from TIM8 due to the fact that 1 and 1N are swapped for TIM8 vs TIM15:
PC10 ------> TIM8_CH1N PWM_5_CPU
PA15 ------> TIM8_CH1 PWM_6_CPU
PB14 ------> TIM15_CH1 PWM_7_CPU
PB15 ------> TIM15_CH1N PWM_8_CPU
*/
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim15, &sConfigOC, TIM_CHANNEL_1)
!= HAL_OK)
{
// Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0xFF;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim15, &sBreakDeadTimeConfig)
!= HAL_OK)
{
// Error_Handler();
}
__HAL_RCC_GPIOB_CLK_ENABLE();
/**TIM15 GPIO Configuration
PB14 ------> TIM15_CH1 PWM_7_CPU
PB15 ------> TIM15_CH1N PWM_8_CPU
*/
HAL_PWM_TIM15_GPIO_ReInit_PWM(FALSE);
HAL_PWM_TIM15_GPIO_ReInit_PWMN(FALSE);
/* Special handling, always keep PWM running, just enable/disable output pin */
HAL_TIM_PWM_Start(&htim15, TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim15, TIM_CHANNEL_1);
This is both PWM signals at 50% duty, and work as intended

This is the Advanced timer at 0% duty, and as expected the output is now 0 with 1 signals hight and 1 low

This is the General timer at duty 0%

