How to trigger IRQ on overflow only?
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 */ }
