Skip to main content
Visitor II
February 13, 2024
Solved

How to trigger IRQ on overflow only?

  • February 13, 2024
  • 1 reply
  • 1212 views

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 */
}

 

    This topic has been closed for replies.
    Best answer by TDK

    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.

    1 reply

    TDKAnswer
    Super User
    February 14, 2024

    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.

    mapleAuthor
    Visitor II
    February 15, 2024

    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.