2024-02-13 12:13 PM - edited 2024-02-13 12:23 PM
I am trying to configure TIM3 to reset on incoming PWM pulses and call IRQ on overflow, when pulses not coming. The prescaler and ARR are set for 150% of the PWM period. TIM3 in slave reset mode on trigger from CH2 input. MCU is STM32G051F8P.
For some reason IRQ is called all the time, even when pulses coming. And status flags are all over the place, hard to tell what exactly caused the interrupt.
Cube-generated initialization
static void MX_TIM3_Init(void) { /* USER CODE BEGIN TIM3_Init 0 */ /* USER CODE END TIM3_Init 0 */ LL_TIM_InitTypeDef TIM_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Peripheral clock enable */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3); LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); /**TIM3 GPIO Configuration PA7 ------> TIM3_CH2 */ GPIO_InitStruct.Pin = PWM_STATE_Pin; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_1; LL_GPIO_Init(PWM_STATE_GPIO_Port, &GPIO_InitStruct); /* TIM3 interrupt Init */ NVIC_SetPriority(TIM3_IRQn, 0); NVIC_EnableIRQ(TIM3_IRQn); /* USER CODE BEGIN TIM3_Init 1 */ /* USER CODE END TIM3_Init 1 */ TIM_InitStruct.Prescaler = 3; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 65535; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; LL_TIM_Init(TIM3, &TIM_InitStruct); LL_TIM_DisableARRPreload(TIM3); LL_TIM_SetClockSource(TIM3, LL_TIM_CLOCKSOURCE_INTERNAL); LL_TIM_SetTriggerInput(TIM3, LL_TIM_TS_TI2FP2); LL_TIM_SetSlaveMode(TIM3, LL_TIM_SLAVEMODE_RESET); LL_TIM_CC_DisableChannel(TIM3, LL_TIM_CHANNEL_CH2); LL_TIM_IC_SetFilter(TIM3, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); LL_TIM_IC_SetPolarity(TIM3, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING); LL_TIM_DisableIT_TRIG(TIM3); LL_TIM_DisableDMAReq_TRIG(TIM3); LL_TIM_SetTriggerOutput(TIM3, LL_TIM_TRGO_RESET); LL_TIM_DisableMasterSlaveMode(TIM3); LL_TIM_IC_SetActiveInput(TIM3, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI); LL_TIM_IC_SetPrescaler(TIM3, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); /* USER CODE BEGIN TIM3_Init 2 */ /* USER CODE END TIM3_Init 2 */ }
Timer start
LL_TIM_EnableUpdateEvent(TIM3);
LL_TIM_SetUpdateSource(TIM3, LL_TIM_UPDATESOURCE_COUNTER); // Only on counter overflow/underflow
LL_TIM_EnableCounter(TIM3);
LL_TIM_EnableIT_UPDATE(TIM3);
IRQ
void TIM3_IRQHandler(void) { /* USER CODE BEGIN TIM3_IRQn 0 */ if (LL_TIM_IsActiveFlag_UPDATE(TIM3)) { LL_TIM_ClearFlag_UPDATE(TIM3); idle_flag = 1; } /* USER CODE END TIM3_IRQn 0 */ /* USER CODE BEGIN TIM3_IRQn 1 */ /* USER CODE END TIM3_IRQn 1 */ }
Solved! Go to Solution.
2024-02-13 07:19 PM
Disable all interrupts except for the update interrupt. Should work just fine as long as the timer is resetting on PWM inputs.
Show the contents of the TIM3 registers, especially the DIER register.
If TIM3_IRQHandler is firing too much, look at flags in TIM3->SR and TIM3->DIER to determine why.
2024-02-13 07:19 PM
Disable all interrupts except for the update interrupt. Should work just fine as long as the timer is resetting on PWM inputs.
Show the contents of the TIM3 registers, especially the DIER register.
If TIM3_IRQHandler is firing too much, look at flags in TIM3->SR and TIM3->DIER to determine why.
2024-02-15 12:13 PM
It turned out that there was a bug in different place. Specifically, the PWM signal is multiplexed from multiple sources and the mux control code was switching when it was not supposed to. But since your advice helped me to find a bug I'll accept it as a solution. Thanks.