Differences between PWM channels 2, 3, 4 in TIM8?
I think I am missing something obvious about a difference between channels 2&3 vs channel 4 in the TIM8 after staring at this for some hours now...
I am using the STM32H750 discovery board, and created a project in CubeMX which configures PI2, PB14 and PB15 as PWM outputs for channels 4, 2, 3 of timer 8. (ignore the maximum frequency, I changed it after taking this screenshot)

CubeMX provides a warning about a conflict for PB14 and PB15 assignment, but I can't tell which potential conflict is the real one.


The SDMMC is enabled but not using these pins:

I don't think it is ITRx nor TI1_ED because I'm using the internal clock source and no external triggers:

Break and dead time functions are all disabled in the configuration. Looking in the description of the timer in the reference manual (figure 344 of RM0433) it seems like these channels should be configured with the same behaviors. But when I run my program (even just using the default PWM duty cycle I have configured in the CubeMX) the pins PB14 and PB15 have no PWM output.
I have eliminated everything else from main.c, now it is just initializing the timer base and these 3 channels:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_FMC_Init();
MX_QUADSPI_Init();
MX_SDMMC1_MMC_Init();
MX_TIM8_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim8);
HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_4);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}This is the timer initialization, as generated by CubeMX:
static void MX_TIM8_Init(void)
{
/* USER CODE BEGIN TIM8_Init 0 */
/* USER CODE END TIM8_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
/* USER CODE BEGIN TIM8_Init 1 */
/* USER CODE END TIM8_Init 1 */
htim8.Instance = TIM8;
htim8.Init.Prescaler = 0;
htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
htim8.Init.Period = 480;
htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim8.Init.RepetitionCounter = 0;
htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim8) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim8, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim8) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 48;
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_2) != HAL_OK)
{
Error_Handler();
}
sConfigOC.Pulse = 32;
if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
{
Error_Handler();
}
sConfigOC.Pulse = 24;
if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
sBreakDeadTimeConfig.Break2Filter = 0;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim8, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM8_Init 2 */
/* USER CODE END TIM8_Init 2 */
HAL_TIM_MspPostInit(&htim8);
}I am initializing the timer interrupt, because I eventually would like to adjust the PWM duty cycle for all 3 channel outputs after the update event. Right now this of course does nothing since 2 of 3 channels produce no PWM output. But this is what is in the callback:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim8)
{
temp_pulse_counter1 = __HAL_TIM_GET_COUNTER(htim8);
//set period equal to counter value
__HAL_TIM_SET_COMPARE(htim8,TIM_CHANNEL_4,temp_pulse_counter1);
__HAL_TIM_SET_COMPARE(htim8,TIM_CHANNEL_3,temp_pulse_counter1);
__HAL_TIM_SET_COMPARE(htim8,TIM_CHANNEL_2,temp_pulse_counter1);
}I think I am just missing a simple fundamental aspect of configuring the channels or outputs and have become blind to it now. Any help is appreciated!
